static void subtract_em( struct timespec *start, struct timespec *stop, struct timespec *t ) { t->tv_sec = 0; t->tv_nsec = 0; _Timespec_Subtract( start, stop, t ); }
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 */ }
/* * The abstime is a walltime. We turn it into an interval. */ TOD_Absolute_timeout_conversion_results _TOD_Absolute_timeout_to_ticks( const struct timespec *abstime, Watchdog_Interval *ticks_out ) { struct timespec current_time; struct timespec difference; /* * Make sure there is always a value returned. */ *ticks_out = 0; /* * Is the absolute time even valid? */ if ( !_Timespec_Is_valid(abstime) ) return TOD_ABSOLUTE_TIMEOUT_INVALID; /* * Is the absolute time in the past? */ _TOD_Get_as_timespec( ¤t_time ); if ( _Timespec_Less_than( abstime, ¤t_time ) ) return TOD_ABSOLUTE_TIMEOUT_IS_IN_PAST; /* * How long until the requested absolute time? */ _Timespec_Subtract( ¤t_time, abstime, &difference ); /* * Internally the SuperCore uses ticks, so convert to them. */ *ticks_out = _Timespec_To_ticks( &difference ); /* * If the difference was 0, then the future is now. It is so bright * we better wear shades. */ if ( !*ticks_out ) return TOD_ABSOLUTE_TIMEOUT_IS_NOW; /* * This is the case we were expecting and it took this long to * get here. */ return TOD_ABSOLUTE_TIMEOUT_IS_IN_FUTURE; }
void _Rate_monotonic_Initiate_statistics( Rate_monotonic_Control *the_period ) { Thread_Control *owning_thread = the_period->owner; /* * If using nanosecond statistics, we need to obtain the uptime. */ #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ Timestamp_Control uptime; _TOD_Get_uptime( &uptime ); #endif /* * Set the starting point and the CPU time used for the statistics. */ #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ the_period->time_period_initiated = uptime; #else the_period->time_period_initiated = _Watchdog_Ticks_since_boot; #endif the_period->cpu_usage_period_initiated = owning_thread->cpu_time_used; /* * If using nanosecond statistics and the period's thread is currently * executing, then we need to take into account how much time the * executing thread has run since the last context switch. When this * routine is invoked from rtems_rate_monotonic_period, the owner will * be the executing thread. When this routine is invoked from * _Rate_monotonic_Timeout, it will not. */ #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ if (owning_thread == _Thread_Executing) { rtems_thread_cpu_usage_t ran; /* * Adjust the CPU time used to account for the time since last * context switch. */ _Timespec_Subtract( &_Thread_Time_of_last_context_switch, &uptime, &ran ); _Timespec_Add_to( &the_period->cpu_usage_period_initiated, &ran ); } #endif }