/* * This is the operation that is run when a timer expires */ void _POSIX_Timer_TSR( Watchdog_Control *the_watchdog ) { POSIX_Timer_Control *ptimer; ISR_lock_Context lock_context; Per_CPU_Control *cpu; ptimer = RTEMS_CONTAINER_OF( the_watchdog, POSIX_Timer_Control, Timer ); _ISR_lock_ISR_disable( &lock_context ); cpu = _POSIX_Timer_Acquire_critical( ptimer, &lock_context ); /* Increment the number of expirations. */ ptimer->overrun = ptimer->overrun + 1; /* The timer must be reprogrammed */ if ( ( ptimer->timer_data.it_interval.tv_sec != 0 ) || ( ptimer->timer_data.it_interval.tv_nsec != 0 ) ) { _POSIX_Timer_Insert( ptimer, cpu, ptimer->ticks ); } else { /* Indicates that the timer is stopped */ ptimer->state = POSIX_TIMER_STATE_CREATE_STOP; } _POSIX_Timer_Release( cpu, &lock_context ); /* * The sending of the signal to the process running the handling function * specified for that signal is simulated */ if ( pthread_kill ( ptimer->thread_id, ptimer->inf.sigev_signo ) ) { _Assert( FALSE ); /* * TODO: What if an error happens at run-time? This should never * occur because the timer should be canceled if the thread * is deleted. This method is being invoked from the Clock * Tick ISR so even if we decide to take action on an error, * we don't have many options. We shouldn't shut the system down. */ } /* After the signal handler returns, the count of expirations of the * timer must be set to 0. */ ptimer->overrun = 0; }
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 ); }