void _TOD_Tickle_ticks( void ) { TOD_Control *tod = &_TOD; ISR_lock_Context lock_context; Timestamp_Control tick; uint32_t nanoseconds_per_tick; nanoseconds_per_tick = rtems_configuration_get_nanoseconds_per_tick(); /* Convert the tick quantum to a timestamp */ _Timestamp_Set( &tick, 0, nanoseconds_per_tick ); /* Update the counter of ticks since boot */ _Watchdog_Ticks_since_boot += 1; _TOD_Acquire( tod, &lock_context ); /* Update the uptime */ _Timestamp_Add_to( &tod->uptime, &tick ); /* Update the current TOD */ _Timestamp_Add_to( &tod->now, &tick ); _TOD_Release( tod, &lock_context ); _TOD.seconds_trigger += nanoseconds_per_tick; if ( _TOD.seconds_trigger >= 1000000000UL ) { _TOD.seconds_trigger -= 1000000000UL; _Watchdog_Tickle_seconds(); } }
/** * POSIX 1003.1b 4.5.2 - Get Process Times */ clock_t _times( struct tms *ptms ) { rtems_interval ticks, us_per_tick; Thread_Control *executing; if ( !ptms ) rtems_set_errno_and_return_minus_one( EFAULT ); /* * This call does not depend on TOD being initialized and can't fail. */ ticks = rtems_clock_get_ticks_since_boot(); us_per_tick = rtems_configuration_get_microseconds_per_tick(); /* * RTEMS technically has no notion of system versus user time * since there is no separation of OS from application tasks. * But we can at least make a distinction between the number * of ticks since boot and the number of ticks executed by this * this thread. */ { Timestamp_Control per_tick; uint32_t ticks_of_executing; uint32_t fractional_ticks; Per_CPU_Control *cpu_self; _Timestamp_Set( &per_tick, rtems_configuration_get_microseconds_per_tick() / TOD_MICROSECONDS_PER_SECOND, (rtems_configuration_get_nanoseconds_per_tick() % TOD_NANOSECONDS_PER_SECOND) ); cpu_self = _Thread_Dispatch_disable(); executing = _Thread_Executing; _Thread_Update_cpu_time_used( executing, &_Thread_Time_of_last_context_switch ); _Timestamp_Divide( &executing->cpu_time_used, &per_tick, &ticks_of_executing, &fractional_ticks ); _Thread_Dispatch_enable( cpu_self ); ptms->tms_utime = ticks_of_executing * us_per_tick; } ptms->tms_stime = ticks * us_per_tick; ptms->tms_cutime = 0; ptms->tms_cstime = 0; return ticks * us_per_tick; }
clock_t _times( struct tms *ptms ) { rtems_interval ticks; if ( !ptms ) { errno = EFAULT; return -1; } /* * This call does not depend on TOD being initialized and can't fail. */ ticks = rtems_clock_get_ticks_since_boot(); /* * RTEMS technically has no notion of system versus user time * since there is no separation of OS from application tasks. * But we can at least make a distinction between the number * of ticks since boot and the number of ticks executed by this * this thread. */ #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ { Timestamp_Control per_tick; uint32_t ticks; uint32_t fractional_ticks; _Timestamp_Set( &per_tick, rtems_configuration_get_microseconds_per_tick() / TOD_MICROSECONDS_PER_SECOND, (rtems_configuration_get_nanoseconds_per_tick() % TOD_NANOSECONDS_PER_SECOND) ); _Timestamp_Divide( &_Thread_Executing->cpu_time_used, &per_tick, &ticks, &fractional_ticks ); ptms->tms_utime = ticks; } #else ptms->tms_utime = _Thread_Executing->cpu_time_used; #endif ptms->tms_stime = ticks; ptms->tms_cutime = 0; ptms->tms_cstime = 0; return ticks; }
void _TOD_Handler_initialization(void) { /* POSIX format TOD (timespec) */ _Timestamp_Set( &_TOD_Now, TOD_SECONDS_1970_THROUGH_1988, 0 ); /* Uptime (timespec) */ _Timestamp_Set_to_zero( &_TOD_Uptime ); /* TOD has not been set */ _TOD_Is_set = false; _TOD_Activate(); }
void _TOD_Handler_initialization(void) { TOD_Control *tod = &_TOD; _ISR_lock_Initialize( &tod->lock ); _Timestamp_Set( &tod->now, TOD_SECONDS_1970_THROUGH_1988, 0 ); _Timestamp_Set_to_zero( &tod->uptime ); tod->nanoseconds_since_last_tick = _TOD_Nanoseconds_since_tick_default_handler; /* TOD has not been set */ tod->is_set = false; }
void _TOD_Get_uptime( Timestamp_Control *uptime ) { ISR_Level level; Timestamp_Control offset; Timestamp_Control up; long nanoseconds; /* assume time checked for NULL by caller */ /* _TOD_Uptime is in native timestamp format */ _ISR_Disable( level ); up = _TOD_Uptime; nanoseconds = (*_Watchdog_Nanoseconds_since_tick_handler)(); _ISR_Enable( level ); _Timestamp_Set( &offset, 0, nanoseconds ); _Timestamp_Add_to( &up, &offset ); *uptime = up; }
void _TOD_Get_as_timestamp( Timestamp_Control *tod ) { ISR_Level level; Timestamp_Control offset; Timestamp_Control now; long nanoseconds; /* assume time checked for NULL by caller */ /* _TOD.now is the native current time */ _ISR_Disable( level ); now = _TOD.now; nanoseconds = (*_Watchdog_Nanoseconds_since_tick_handler)(); _ISR_Enable( level ); _Timestamp_Set( &offset, 0, nanoseconds ); _Timestamp_Add_to( &now, &offset ); *tod = now; }
void _TOD_Tickle_ticks( void ) { Timestamp_Control tick; uint32_t seconds; /* Convert the tick quantum to a timestamp */ _Timestamp_Set( &tick, 0, rtems_configuration_get_nanoseconds_per_tick() ); /* Update the counter of ticks since boot */ _Watchdog_Ticks_since_boot += 1; /* Update the timespec format uptime */ _Timestamp_Add_to( &_TOD_Uptime, &tick ); /* we do not care how much the uptime changed */ /* Update the timespec format TOD */ seconds = _Timestamp_Add_to_at_tick( &_TOD_Now, &tick ); while ( seconds ) { _Watchdog_Tickle_seconds(); seconds--; } }
void _TOD_Get( struct timespec *time ) { ISR_Level level; Timestamp_Control offset; Timestamp_Control now; long nanoseconds; /* assume time checked for NULL by caller */ /* _TOD_Now is the native current time */ nanoseconds = 0; _ISR_Disable( level ); now = _TOD_Now; if ( _Watchdog_Nanoseconds_since_tick_handler ) nanoseconds = (*_Watchdog_Nanoseconds_since_tick_handler)(); _ISR_Enable( level ); _Timestamp_Set( &offset, 0, nanoseconds ); _Timestamp_Add_to( &now, &offset ); _Timestamp_To_timespec( &now, time ); }
rtems_status_code rtems_clock_set( const rtems_time_of_day *tod ) { if ( !tod ) return RTEMS_INVALID_ADDRESS; if ( _TOD_Validate( tod ) ) { Timestamp_Control tod_as_timestamp; uint32_t seconds = _TOD_To_seconds( tod ); uint32_t nanoseconds = tod->ticks * rtems_configuration_get_nanoseconds_per_tick(); _Timestamp_Set( &tod_as_timestamp, seconds, nanoseconds ); _Thread_Disable_dispatch(); _TOD_Set_with_timestamp( &tod_as_timestamp ); _Thread_Enable_dispatch(); return RTEMS_SUCCESSFUL; } return RTEMS_INVALID_CLOCK; }
void _TOD_Set( const struct timespec *time ) { long seconds; _Thread_Disable_dispatch(); _TOD_Deactivate(); seconds = _TOD_Seconds_since_epoch(); if ( time->tv_sec < seconds ) _Watchdog_Adjust_seconds( WATCHDOG_BACKWARD, seconds - time->tv_sec ); else _Watchdog_Adjust_seconds( WATCHDOG_FORWARD, time->tv_sec - seconds ); /* POSIX format TOD (timespec) */ _Timestamp_Set( &_TOD_Now, time->tv_sec, time->tv_nsec ); _TOD_Is_set = true; _TOD_Activate(); _Thread_Enable_dispatch(); }