int timer_delete( timer_t timerid ) { /* * IDEA: This function must probably stop the timer first and then delete it * * It will have to do a call to rtems_timer_cancel and then another * call to rtems_timer_delete. * The call to rtems_timer_delete will be probably unnecessary, * because rtems_timer_delete stops the timer before deleting it. */ POSIX_Timer_Control *ptimer; Objects_Locations location; ptimer = _POSIX_Timer_Get( timerid, &location ); switch ( location ) { case OBJECTS_LOCAL: _Objects_Close( &_POSIX_Timer_Information, &ptimer->Object ); ptimer->state = POSIX_TIMER_STATE_FREE; (void) _Watchdog_Remove( &ptimer->Timer ); _POSIX_Timer_Free( ptimer ); _Thread_Enable_dispatch(); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } rtems_set_errno_and_return_minus_one( EINVAL ); }
int timer_getoverrun( timer_t timerid ) { int overrun; POSIX_Timer_Control *ptimer; Objects_Locations location; ptimer = _POSIX_Timer_Get( timerid, &location ); switch ( location ) { case OBJECTS_REMOTE: #if defined(RTEMS_MULTIPROCESSING) _Thread_Dispatch(); rtems_set_errno_and_return_minus_one( EINVAL ); #endif case OBJECTS_ERROR: rtems_set_errno_and_return_minus_one( EINVAL ); case OBJECTS_LOCAL: overrun = ptimer->overrun; ptimer->overrun = 0; _Thread_Enable_dispatch(); return overrun; } return -1; /* unreached - only to remove warnings */ }
/* * timer_getoverrun * * The expiration of a timer must increase by one a counter. * After the signal handler associated to the timer finishes * its execution, _POSIX_Timer_TSR will have to set this counter to 0. */ int timer_getoverrun( timer_t timerid ) { int overrun; POSIX_Timer_Control *ptimer; Objects_Locations location; ptimer = _POSIX_Timer_Get( timerid, &location ); switch ( location ) { case OBJECTS_LOCAL: overrun = ptimer->overrun; ptimer->overrun = 0; _Thread_Enable_dispatch(); return overrun; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } rtems_set_errno_and_return_minus_one( EINVAL ); }
int timer_gettime( timer_t timerid, struct itimerspec *value ) { /* * IDEA: This function does not use functions of RTEMS to the handle * of timers. It uses some functions for managing the time. * * A possible form to do this is the following: * * - When a timer is initialized, the value of the time in * that moment is stored. * - When this function is called, it returns the difference * between the current time and the initialization time. */ POSIX_Timer_Control *ptimer; Objects_Locations location; struct timespec current_time; /* Reads the current time */ _TOD_Get( ¤t_time ); ptimer = _POSIX_Timer_Get( timerid, &location ); switch ( location ) { case OBJECTS_REMOTE: #if defined(RTEMS_MULTIPROCESSING) _Thread_Dispatch(); rtems_set_errno_and_return_minus_one( EINVAL ); #endif case OBJECTS_ERROR: rtems_set_errno_and_return_minus_one( EINVAL ); case OBJECTS_LOCAL: /* Calculates the time left before the timer finishes */ _Timespec_Subtract( &ptimer->timer_data.it_value, ¤t_time, &value->it_value ); value->it_interval = ptimer->timer_data.it_interval; _Thread_Enable_dispatch(); return 0; } return -1; /* unreached - only to remove warnings */ }
int timer_gettime( timer_t timerid, struct itimerspec *value ) { POSIX_Timer_Control *ptimer; Objects_Locations location; struct timespec current_time; Watchdog_Interval left; if ( !value ) rtems_set_errno_and_return_minus_one( EINVAL ); /* Reads the current time */ _TOD_Get( ¤t_time ); ptimer = _POSIX_Timer_Get( timerid, &location ); switch ( location ) { case OBJECTS_LOCAL: /* Calculates the time left before the timer finishes */ left = (ptimer->Timer.start_time + ptimer->Timer.initial) - /* expire */ _Watchdog_Ticks_since_boot; /* now */ _Timespec_From_ticks( left, &value->it_value ); value->it_interval = ptimer->timer_data.it_interval; _Thread_Enable_dispatch(); return 0; #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: #endif case OBJECTS_ERROR: break; } rtems_set_errno_and_return_minus_one( EINVAL ); }
int timer_getoverrun( timer_t timerid ) { POSIX_Timer_Control *ptimer; ISR_lock_Context lock_context; ptimer = _POSIX_Timer_Get( timerid, &lock_context ); if ( ptimer != NULL ) { Per_CPU_Control *cpu; int overrun; cpu = _POSIX_Timer_Acquire_critical( ptimer, &lock_context ); overrun = ptimer->overrun; ptimer->overrun = 0; _POSIX_Timer_Release( cpu, &lock_context ); return overrun; } rtems_set_errno_and_return_minus_one( EINVAL ); }
int timer_delete( timer_t timerid ) { /* * IDEA: This function must probably stop the timer first and then delete it * * It will have to do a call to rtems_timer_cancel and then another * call to rtems_timer_delete. * The call to rtems_timer_delete will be probably unnecessary, * because rtems_timer_delete stops the timer before deleting it. */ POSIX_Timer_Control *ptimer; ISR_lock_Context lock_context; _Objects_Allocator_lock(); ptimer = _POSIX_Timer_Get( timerid, &lock_context ); if ( ptimer != NULL ) { Per_CPU_Control *cpu; _Objects_Close( &_POSIX_Timer_Information, &ptimer->Object ); cpu = _POSIX_Timer_Acquire_critical( ptimer, &lock_context ); ptimer->state = POSIX_TIMER_STATE_FREE; _Watchdog_Remove( &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ], &ptimer->Timer ); _POSIX_Timer_Release( cpu, &lock_context ); _POSIX_Timer_Free( ptimer ); _Objects_Allocator_unlock(); return 0; } _Objects_Allocator_unlock(); rtems_set_errno_and_return_minus_one( EINVAL ); }
int timer_settime( timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue ) { POSIX_Timer_Control *ptimer; Objects_Locations location; boolean activated; if ( value == NULL ) { rtems_set_errno_and_return_minus_one( EINVAL ); } /* First, it verifies if the structure "value" is correct */ if ( ( value->it_value.tv_nsec > TOD_NANOSECONDS_PER_SECOND ) || ( value->it_value.tv_nsec < 0 ) ) { /* The number of nanoseconds is not correct */ rtems_set_errno_and_return_minus_one( EINVAL ); } /* XXX check for seconds in the past */ if ( flags != TIMER_ABSTIME && flags != POSIX_TIMER_RELATIVE ) { rtems_set_errno_and_return_minus_one( EINVAL ); } /* If the function reaches this point, then it will be necessary to do * something with the structure of times of the timer: to stop, start * or start it again */ ptimer = _POSIX_Timer_Get( timerid, &location ); switch ( location ) { case OBJECTS_REMOTE: #if defined(RTEMS_MULTIPROCESSING) _Thread_Dispatch(); return -1; rtems_set_errno_and_return_minus_one( EINVAL ); #endif case OBJECTS_ERROR: return -1; case OBJECTS_LOCAL: /* First, it verifies if the timer must be stopped */ if ( value->it_value.tv_sec == 0 && value->it_value.tv_nsec == 0 ) { /* Stop the timer */ (void) _Watchdog_Remove( &ptimer->Timer ); /* The old data of the timer are returned */ if ( ovalue ) *ovalue = ptimer->timer_data; /* The new data are set */ ptimer->timer_data = *value; /* Indicates that the timer is created and stopped */ ptimer->state = POSIX_TIMER_STATE_CREATE_STOP; /* Returns with success */ _Thread_Enable_dispatch(); return 0; } /* absolute or relative? */ switch (flags) { case TIMER_ABSTIME: /* The fire time is absolute: use "rtems_time_fire_when" */ /* First, it converts from struct itimerspec to rtems_time_of_day */ _Watchdog_Initialize( &ptimer->Timer, _POSIX_Timer_TSR, ptimer->Object.id, ptimer ); _Watchdog_Insert_seconds( &ptimer->Timer, value->it_value.tv_sec - _TOD_Seconds_since_epoch ); /* Returns the old ones in "ovalue" */ if ( ovalue ) *ovalue = ptimer->timer_data; ptimer->timer_data = *value; /* Indicate that the time is running */ ptimer->state = POSIX_TIMER_STATE_CREATE_RUN; /* Stores the time in which the timer was started again */ _TOD_Get( &ptimer->time ); _Thread_Enable_dispatch(); return 0; break; /* The fire time is relative: use "rtems_time_fire_after" */ case POSIX_TIMER_RELATIVE: /* First, convert from seconds and nanoseconds to ticks */ ptimer->ticks = _Timespec_To_ticks( &value->it_value ); activated = _Watchdog_Insert_ticks_helper( &ptimer->Timer, ptimer->ticks, ptimer->Object.id, _POSIX_Timer_TSR, ptimer ); if ( !activated ) { _Thread_Enable_dispatch(); return 0; } /* The timer has been started and is running */ /* return the old ones in "ovalue" */ if ( ovalue ) *ovalue = ptimer->timer_data; ptimer->timer_data = *value; /* Indicate that the time is running */ ptimer->state = POSIX_TIMER_STATE_CREATE_RUN; _TOD_Get( &ptimer->time ); _Thread_Enable_dispatch(); return 0; } _Thread_Enable_dispatch(); rtems_set_errno_and_return_minus_one( EINVAL ); } return -1; /* unreached - only to remove warnings */ }