From eb37f9dc5d00c381717376d0dfd00ce86107b3a0 Mon Sep 17 00:00:00 2001 From: Glenn Humphrey Date: Tue, 8 Dec 2009 23:05:30 +0000 Subject: 2009-12-08 Glenn Humphrey * rtems/include/rtems/rtems/ratemon.h, rtems/src/ratemongetstatus.c, rtems/src/ratemonperiod.c: Factored out common code to ensure consistent behavior between rtems_rate_monotonic_get_status and rtems_rate_monotonic_report_statistics. --- cpukit/rtems/include/rtems/rtems/ratemon.h | 67 +++++++++----- cpukit/rtems/src/ratemongetstatus.c | 40 +++++---- cpukit/rtems/src/ratemonperiod.c | 138 +++++++++++++++++------------ 3 files changed, 150 insertions(+), 95 deletions(-) (limited to 'cpukit/rtems') diff --git a/cpukit/rtems/include/rtems/rtems/ratemon.h b/cpukit/rtems/include/rtems/rtems/ratemon.h index 04f45d29a6..74b4022ceb 100644 --- a/cpukit/rtems/include/rtems/rtems/ratemon.h +++ b/cpukit/rtems/include/rtems/rtems/ratemon.h @@ -47,6 +47,11 @@ * * This encapsulates functionality related to the * Classic API Rate Monotonic Manager. + * + * Statistics are kept for each period and can be obtained or printed via + * API calls. The statistics kept include minimum, maximum and average times + * for both cpu usage and wall time. The statistics indicate the execution time + * used by the owning thread between successive calls to rtems_rate_monotonic_period. */ /**@{*/ @@ -223,18 +228,6 @@ typedef struct { /** This field indicates the current state of the period. */ rtems_rate_monotonic_period_states state; - /** - * This field contains the total CPU usage used while executing - * the body of the loop that is executed each period. - */ - Thread_CPU_usage_t owner_executed_at_period; - - /** - * This field contains the total wall timer that passed while - * executing the body of the loop that is executed each period. - */ - Rate_monotonic_Period_time_t time_at_period; - /** * This field contains the length of the next period to be * executed. @@ -248,8 +241,20 @@ typedef struct { Thread_Control *owner; /** - * This field contains the statistics which are maintained - * on each period. + * This field contains the cpu usage value of the owning thread when + * the period was initiated. It is used to compute the period's + * statistics. + */ + Thread_CPU_usage_t cpu_usage_period_initiated; + + /** + * This field contains the wall time value when the period + * was initiated. It is used to compute the period's statistics. + */ + Rate_monotonic_Period_time_t time_period_initiated; + + /** + * This field contains the statistics maintained for the period. */ Rate_monotonic_Statistics Statistics; } Rate_monotonic_Control; @@ -285,9 +290,8 @@ rtems_status_code rtems_rate_monotonic_create( * @brief rtems_rate_monotonic_ident * * This routine implements the rtems_rate_monotonic_ident directive. - * This directive returns the period ID associated with name. - * If more than one period is named name, then the period - * to which the ID belongs is arbitrary. + * It returns the period ID associated with name. If more than one period + * is named name, then the period to which the ID belongs is arbitrary. */ rtems_status_code rtems_rate_monotonic_ident( rtems_name name, @@ -341,7 +345,7 @@ rtems_status_code rtems_rate_monotonic_get_statistics( /** * @brief rtems_rate_monotonic_reset_statistics * - * This directive allows a thread to reset the statistics information + * This routine allows a thread to reset the statistics information * on a specific period instance. */ rtems_status_code rtems_rate_monotonic_reset_statistics( @@ -351,7 +355,7 @@ rtems_status_code rtems_rate_monotonic_reset_statistics( /** * @brief rtems_rate_monotonic_reset_all_statistics * - * This directive allows a thread to reset the statistics information + * This routine allows a thread to reset the statistics information * on ALL period instances. */ void rtems_rate_monotonic_reset_all_statistics( void ); @@ -359,7 +363,7 @@ void rtems_rate_monotonic_reset_all_statistics( void ); /** * @brief rtems_rate_monotonic_report_statistics * - * This directive allows a thread to print the statistics information + * This routine allows a thread to print the statistics information * on ALL period instances which have non-zero counts using printk. */ void rtems_rate_monotonic_report_statistics_with_plugin( @@ -370,7 +374,7 @@ void rtems_rate_monotonic_report_statistics_with_plugin( /** * @brief rtems_rate_monotonic_report_statistics * - * This directive allows a thread to print the statistics information + * This routine allows a thread to print the statistics information * on ALL period instances which have non-zero counts using printk. */ void rtems_rate_monotonic_report_statistics( void ); @@ -403,6 +407,27 @@ void _Rate_monotonic_Timeout( void *ignored ); +/** + * @brief _Rate_monotonic_Get_status( + * + * This routine is invoked to compute the elapsed wall time and cpu + * time for a period. + * + * @param[in] the_period points to the period being operated upon. + * @param[out] wall_since_last_period is set to the wall time elapsed + * since the period was initiated. + * @param[out] cpu_since_last_period is set to the cpu time used by the + * owning thread since the period was initiated. + * + * @return This routine returns true if the status can be determined + * and false otherwise. + */ +bool _Rate_monotonic_Get_status( + Rate_monotonic_Control *the_period, + Rate_monotonic_Period_time_t *wall_since_last_period, + Thread_CPU_usage_t *cpu_since_last_period +); + /** * @brief _Rate_monotonic_Initiate_statistics( * diff --git a/cpukit/rtems/src/ratemongetstatus.c b/cpukit/rtems/src/ratemongetstatus.c index bb22254563..5cc6b56a5e 100644 --- a/cpukit/rtems/src/ratemongetstatus.c +++ b/cpukit/rtems/src/ratemongetstatus.c @@ -49,12 +49,11 @@ rtems_status_code rtems_rate_monotonic_get_status( rtems_rate_monotonic_period_status *status ) { + Thread_CPU_usage_t executed; Objects_Locations location; + Rate_monotonic_Period_time_t since_last_period; Rate_monotonic_Control *the_period; - #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ - Timestamp_Control uptime; - Timestamp_Control temp; - #endif + bool valid_status; if ( !status ) return RTEMS_INVALID_ADDRESS; @@ -79,22 +78,29 @@ rtems_status_code rtems_rate_monotonic_get_status( #endif } else { + + /* + * Grab the current status. + */ + valid_status = + _Rate_monotonic_Get_status( + the_period, &since_last_period, &executed + ); + if (!valid_status) { + _Thread_Enable_dispatch(); + return RTEMS_NOT_DEFINED; + } + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ - _TOD_Get_uptime( &uptime ); - _Timestamp_Subtract( &the_period->time_at_period, &uptime, &temp ); - _Timestamp_To_timespec( &temp, &status->since_last_period ); - _Timestamp_Subtract( - &_Thread_Time_of_last_context_switch, - &uptime, - &temp + _Timestamp_To_timespec( + &since_last_period, &status->since_last_period + ); + _Timestamp_To_timespec( + &executed, &status->executed_since_last_period ); - _Timestamp_To_timespec( &temp, &status->executed_since_last_period ); #else - status->since_last_period = - _Watchdog_Ticks_since_boot - the_period->time_at_period; - status->executed_since_last_period = - the_period->owner->cpu_time_used - - the_period->owner_executed_at_period; + status->since_last_period = since_last_period; + status->executed_since_last_period = executed; #endif } diff --git a/cpukit/rtems/src/ratemonperiod.c b/cpukit/rtems/src/ratemonperiod.c index a09de1d3e2..0a0d526950 100644 --- a/cpukit/rtems/src/ratemonperiod.c +++ b/cpukit/rtems/src/ratemonperiod.c @@ -23,6 +23,76 @@ #include #include +bool _Rate_monotonic_Get_status( + Rate_monotonic_Control *the_period, + Rate_monotonic_Period_time_t *wall_since_last_period, + Thread_CPU_usage_t *cpu_since_last_period +) +{ + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + Timestamp_Control uptime; + #endif + Thread_Control *owning_thread = the_period->owner; + Thread_CPU_usage_t used; + + /* + * Determine elapsed wall time since period initiated. + */ + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + _TOD_Get_uptime( &uptime ); + _Timestamp_Subtract( + &the_period->time_period_initiated, &uptime, wall_since_last_period + ); + #else + *wall_since_last_period = + _Watchdog_Ticks_since_boot - the_period->time_period_initiated; + #endif + + /* + * Determine cpu usage since period initiated. + */ + used = owning_thread->cpu_time_used; + + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + if (owning_thread == _Thread_Executing) { + + Thread_CPU_usage_t ran; + + /* How much time time since last context switch */ + _Timestamp_Subtract( + &_Thread_Time_of_last_context_switch, &uptime, &ran + ); + + /* cpu usage += ran */ + _Timestamp_Add_to( &used, &ran ); + + /* + * The cpu usage info was reset while executing. Can't + * determine a status. + */ + if (_Timestamp_Less_than(&used, &the_period->cpu_usage_period_initiated)) + return false; + + /* used = current cpu usage - cpu usage at start of period */ + _Timestamp_Subtract( + &the_period->cpu_usage_period_initiated, + &used, + cpu_since_last_period + ); + } + #else + /* + * The cpu usage info was reset while executing. Can't + * determine a status. + */ + if (used < the_period->cpu_usage_period_initiated) + return false; + + *cpu_since_last_period = used - the_period->cpu_usage_period_initiated; + #endif + return true; +} + void _Rate_monotonic_Initiate_statistics( Rate_monotonic_Control *the_period ) @@ -42,12 +112,12 @@ void _Rate_monotonic_Initiate_statistics( * Set the starting point and the CPU time used for the statistics. */ #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ - the_period->time_at_period = uptime; + the_period->time_period_initiated = uptime; #else - the_period->time_at_period = _Watchdog_Ticks_since_boot; + the_period->time_period_initiated = _Watchdog_Ticks_since_boot; #endif - the_period->owner_executed_at_period = owning_thread->cpu_time_used; + the_period->cpu_usage_period_initiated = owning_thread->cpu_time_used; /* * If using nanosecond statistics and the period's thread is currently @@ -70,7 +140,7 @@ void _Rate_monotonic_Initiate_statistics( &_Thread_Time_of_last_context_switch, &uptime, &ran ); - _Timespec_Add_to( &the_period->owner_executed_at_period, &ran ); + _Timespec_Add_to( &the_period->cpu_usage_period_initiated, &ran ); } #endif } @@ -79,18 +149,10 @@ void _Rate_monotonic_Update_statistics( Rate_monotonic_Control *the_period ) { - Rate_monotonic_Statistics *stats; Thread_CPU_usage_t executed; Rate_monotonic_Period_time_t since_last_period; - - /* - * If using nanosecond statistics, we need to obtain the uptime. - */ - #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ - Timestamp_Control uptime; - - _TOD_Get_uptime( &uptime ); - #endif + Rate_monotonic_Statistics *stats; + bool valid_status; /* * Assume we are only called in states where it is appropriate @@ -108,50 +170,12 @@ void _Rate_monotonic_Update_statistics( stats->missed_count++; /* - * Grab basic information for time statistics. + * Grab status for time statistics. */ - #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ - _Timespec_Subtract( - &the_period->time_at_period, - &uptime, - &since_last_period - ); - #else - since_last_period = _Watchdog_Ticks_since_boot - the_period->time_at_period; - #endif - - #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ - { - Thread_CPU_usage_t ran, used; - - /* Grab CPU usage when the thread got switched in */ - used = _Thread_Executing->cpu_time_used; - - /* partial period, cpu usage info reset while executing. Throw away */ - if (_Timestamp_Less_than( &used, &the_period->owner_executed_at_period)) - return; - - /* How much time time since last context switch */ - _Timestamp_Subtract(&_Thread_Time_of_last_context_switch, &uptime, &ran); - - /* executed += ran */ - _Timestamp_Add_to( &used, &ran ); - - /* executed = current cpu usage - value at start of period */ - _Timestamp_Subtract( - &the_period->owner_executed_at_period, - &used, - &executed - ); - } - #else - /* partial period, cpu usage info reset while executing. Throw away */ - if (the_period->owner->cpu_time_used < - the_period->owner_executed_at_period) - return; - executed = the_period->owner->cpu_time_used - - the_period->owner_executed_at_period; - #endif + valid_status = + _Rate_monotonic_Get_status( the_period, &since_last_period, &executed ); + if (!valid_status) + return; /* * Update CPU time -- cgit v1.2.3