File indexing completed on 2025-05-11 08:24:22
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039 #ifdef HAVE_CONFIG_H
0040 #include "config.h"
0041 #endif
0042
0043 #include <time.h>
0044 #include <errno.h>
0045
0046 #include <rtems/posix/timerimpl.h>
0047 #include <rtems/score/todimpl.h>
0048 #include <rtems/score/watchdogimpl.h>
0049 #include <rtems/seterr.h>
0050
0051 static void _POSIX_Timer_Insert(
0052 POSIX_Timer_Control *ptimer,
0053 Per_CPU_Control *cpu,
0054 Watchdog_Interval ticks
0055 )
0056 {
0057
0058 ptimer->state = POSIX_TIMER_STATE_CREATE_RUN;
0059
0060
0061 _TOD_Get( &ptimer->time );
0062
0063 _Watchdog_Insert(
0064 &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ],
0065 &ptimer->Timer,
0066 cpu->Watchdog.ticks + ticks
0067 );
0068 }
0069
0070
0071
0072
0073 void _POSIX_Timer_TSR( Watchdog_Control *the_watchdog )
0074 {
0075 POSIX_Timer_Control *ptimer;
0076 ISR_lock_Context lock_context;
0077 Per_CPU_Control *cpu;
0078
0079 ptimer = RTEMS_CONTAINER_OF( the_watchdog, POSIX_Timer_Control, Timer );
0080 _ISR_lock_ISR_disable( &lock_context );
0081 cpu = _POSIX_Timer_Acquire_critical( ptimer, &lock_context );
0082
0083
0084 ptimer->overrun = ptimer->overrun + 1;
0085
0086
0087 if ( ( ptimer->timer_data.it_interval.tv_sec != 0 ) ||
0088 ( ptimer->timer_data.it_interval.tv_nsec != 0 ) ) {
0089 _POSIX_Timer_Insert( ptimer, cpu, ptimer->ticks );
0090 } else {
0091
0092 ptimer->state = POSIX_TIMER_STATE_CREATE_STOP;
0093 }
0094
0095 _POSIX_Timer_Release( cpu, &lock_context );
0096
0097
0098
0099
0100
0101
0102 if ( pthread_kill ( ptimer->thread_id, ptimer->inf.sigev_signo ) ) {
0103 _Assert( FALSE );
0104
0105
0106
0107
0108
0109
0110
0111 }
0112
0113
0114
0115
0116 ptimer->overrun = 0;
0117 }
0118
0119 int timer_settime(
0120 timer_t timerid,
0121 int flags,
0122 const struct itimerspec *__restrict value,
0123 struct itimerspec *__restrict ovalue
0124 )
0125 {
0126 POSIX_Timer_Control *ptimer;
0127 ISR_lock_Context lock_context;
0128 uint32_t initial_period;
0129 struct itimerspec normalize;
0130
0131 if ( !value )
0132 rtems_set_errno_and_return_minus_one( EINVAL );
0133
0134
0135
0136
0137
0138 if ( !_Timespec_Is_valid( &(value->it_value) ) ) {
0139 rtems_set_errno_and_return_minus_one( EINVAL );
0140 }
0141 if ( !_Timespec_Is_valid( &(value->it_interval) ) ) {
0142 rtems_set_errno_and_return_minus_one( EINVAL );
0143 }
0144
0145 if ( flags != TIMER_ABSTIME && flags != POSIX_TIMER_RELATIVE ) {
0146 rtems_set_errno_and_return_minus_one( EINVAL );
0147 }
0148
0149 normalize = *value;
0150
0151
0152 if (flags == TIMER_ABSTIME) {
0153 struct timespec now;
0154 _TOD_Get( &now );
0155
0156 if ( _Timespec_Greater_than( &now, &normalize.it_value ) )
0157 rtems_set_errno_and_return_minus_one( EINVAL );
0158 _Timespec_Subtract( &now, &normalize.it_value, &normalize.it_value );
0159 }
0160
0161
0162
0163
0164
0165
0166 ptimer = _POSIX_Timer_Get( timerid, &lock_context );
0167 if ( ptimer != NULL ) {
0168 Per_CPU_Control *cpu;
0169
0170 cpu = _POSIX_Timer_Acquire_critical( ptimer, &lock_context );
0171
0172
0173 _Watchdog_Remove(
0174 &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ],
0175 &ptimer->Timer
0176 );
0177
0178
0179 if ( normalize.it_value.tv_sec == 0 && normalize.it_value.tv_nsec == 0 ) {
0180
0181 if ( ovalue )
0182 *ovalue = ptimer->timer_data;
0183
0184 ptimer->timer_data = normalize;
0185
0186 ptimer->state = POSIX_TIMER_STATE_CREATE_STOP;
0187
0188 _POSIX_Timer_Release( cpu, &lock_context );
0189 return 0;
0190 }
0191
0192
0193 ptimer->ticks = _Timespec_To_ticks( &value->it_interval );
0194 initial_period = _Timespec_To_ticks( &normalize.it_value );
0195
0196 _POSIX_Timer_Insert( ptimer, cpu, initial_period );
0197
0198
0199
0200
0201
0202 if ( ovalue )
0203 *ovalue = ptimer->timer_data;
0204 ptimer->timer_data = normalize;
0205 _POSIX_Timer_Release( cpu, &lock_context );
0206 return 0;
0207 }
0208
0209 rtems_set_errno_and_return_minus_one( EINVAL );
0210 }