From 9dc2c8d16e3d54daeb394d71b2455da114bbd5c9 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Wed, 10 Dec 2008 22:13:28 +0000 Subject: 2008-12-10 Joel Sherrill * rtems/include/rtems/rtems/ratemon.h, rtems/include/rtems/rtems/types.h, rtems/src/ratemongetstatistics.c, rtems/src/ratemongetstatus.c, rtems/src/ratemonperiod.c, rtems/src/ratemonreportstatistics.c, score/include/rtems/score/thread.h, score/src/coretodgetuptime.c: Make all Thread and Period Statistics use publicly defined types. Do not leak the SuperCore Timestamp type through the APIs. --- cpukit/rtems/include/rtems/rtems/ratemon.h | 55 ++++++++++++++++++++++++++---- cpukit/rtems/include/rtems/rtems/types.h | 13 +++++++ cpukit/rtems/src/ratemongetstatistics.c | 31 +++++++++++++++-- cpukit/rtems/src/ratemongetstatus.c | 20 ++++++----- cpukit/rtems/src/ratemonperiod.c | 22 ++++++------ cpukit/rtems/src/ratemonreportstatistics.c | 47 +++++++++++++------------ 6 files changed, 134 insertions(+), 54 deletions(-) (limited to 'cpukit/rtems') diff --git a/cpukit/rtems/include/rtems/rtems/ratemon.h b/cpukit/rtems/include/rtems/rtems/ratemon.h index 3c5d1b65dc..e0111d6c71 100644 --- a/cpukit/rtems/include/rtems/rtems/ratemon.h +++ b/cpukit/rtems/include/rtems/rtems/ratemon.h @@ -66,17 +66,29 @@ extern "C" { #endif /** - * This is the type used to manage the rate monotonic timing + * This is the public type used for the rate monotonic timing * statistics. */ #if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) - #include + #include - typedef Timestamp_Control rtems_rate_monotonic_period_time_t; + typedef struct timespec rtems_rate_monotonic_period_time_t; #else typedef uint32_t rtems_rate_monotonic_period_time_t; #endif +/** + * This is the internal type used for the rate monotonic timing + * statistics. + */ +#if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) + #include + + typedef Timestamp_Control Rate_monotonic_Period_time_t; +#else + typedef uint32_t Rate_monotonic_Period_time_t; +#endif + #include #include #include @@ -131,7 +143,11 @@ typedef enum { #define RTEMS_PERIOD_STATUS WATCHDOG_NO_TIMEOUT /** - * The following defines the statistics kept on each period instance. + * The following defines the PUBLIC data structure that has the + * statistics kept on each period instance. + * + * @note The public structure uses struct timespec while the + * internal one uses Timestamp_Control. */ typedef struct { /** This field contains the number of periods executed. */ @@ -154,6 +170,31 @@ typedef struct { rtems_rate_monotonic_period_time_t total_wall_time; } rtems_rate_monotonic_period_statistics; +/** + * The following defines the INTERNAL data structure that has the + * statistics kept on each period instance. + */ +typedef struct { + /** This field contains the number of periods executed. */ + uint32_t count; + /** This field contains the number of periods missed. */ + uint32_t missed_count; + + /** This field contains the least amount of CPU time used in a period. */ + Thread_CPU_usage_t min_cpu_time; + /** This field contains the highest amount of CPU time used in a period. */ + Thread_CPU_usage_t max_cpu_time; + /** This field contains the total amount of wall time used in a period. */ + Thread_CPU_usage_t total_cpu_time; + + /** This field contains the least amount of wall time used in a period. */ + Rate_monotonic_Period_time_t min_wall_time; + /** This field contains the highest amount of wall time used in a period. */ + Rate_monotonic_Period_time_t max_wall_time; + /** This field contains the total amount of CPU time used in a period. */ + Rate_monotonic_Period_time_t total_wall_time; +} Rate_monotonic_Statistics; + /** * The following defines the period status structure. */ @@ -197,13 +238,13 @@ typedef struct { * This field contains the total CPU usage used while executing * the body of the loop that is executed each period. */ - rtems_thread_cpu_usage_t owner_executed_at_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. */ - rtems_rate_monotonic_period_time_t time_at_period; + Rate_monotonic_Period_time_t time_at_period; /** * This field contains the length of the next period to be @@ -221,7 +262,7 @@ typedef struct { * This field contains the statistics which are maintained * on each period. */ - rtems_rate_monotonic_period_statistics Statistics; + Rate_monotonic_Statistics Statistics; } Rate_monotonic_Control; /** diff --git a/cpukit/rtems/include/rtems/rtems/types.h b/cpukit/rtems/include/rtems/rtems/types.h index a0633e16a9..6178abf130 100644 --- a/cpukit/rtems/include/rtems/rtems/types.h +++ b/cpukit/rtems/include/rtems/rtems/types.h @@ -101,6 +101,19 @@ typedef Heap_Information_block region_information_block; */ typedef Watchdog_Interval rtems_interval; +/** + * This is the public type used to represent the CPU usage per thread. + * + * @note When using nanosecond granularity timing, RTEMS may internally + * use a variety of represenations. + */ +#ifndef __RTEMS_USE_TICKS_CPU_USAGE_STATISTICS__ + typedef struct timespec rtems_thread_cpu_usage_t; +#else + typedef uint32_t Thread_CPU_usage_t; +#endif + + /** * The following record defines the time of control block. This * control block is used to maintain the current time of day. diff --git a/cpukit/rtems/src/ratemongetstatistics.c b/cpukit/rtems/src/ratemongetstatistics.c index 1738c9c9b9..9b6eb4b173 100644 --- a/cpukit/rtems/src/ratemongetstatistics.c +++ b/cpukit/rtems/src/ratemongetstatistics.c @@ -45,8 +45,10 @@ rtems_status_code rtems_rate_monotonic_get_statistics( rtems_rate_monotonic_period_statistics *statistics ) { - Objects_Locations location; - Rate_monotonic_Control *the_period; + Objects_Locations location; + Rate_monotonic_Control *the_period; + rtems_rate_monotonic_period_statistics *dst; + Rate_monotonic_Statistics *src; if ( !statistics ) return RTEMS_INVALID_ADDRESS; @@ -55,7 +57,30 @@ rtems_status_code rtems_rate_monotonic_get_statistics( switch ( location ) { case OBJECTS_LOCAL: - *statistics = the_period->Statistics; + dst = statistics; + src = &the_period->Statistics; + dst->count = src->count; + dst->missed_count = src->missed_count; + #if defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS) + _Timestamp_To_timespec( &src->min_cpu_time, &dst->min_cpu_time ); + _Timestamp_To_timespec( &src->max_cpu_time, &dst->max_cpu_time ); + _Timestamp_To_timespec( &src->total_cpu_time, &dst->total_cpu_time ); + #else + statistics->min_wall_time = src->min_wall_time; + statistics->max_wall_time = src->max_wall_time; + statistics->total_wall_time = src->total_wall_time; + #endif + + #if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) + _Timestamp_To_timespec( &src->min_wall_time, &dst->min_wall_time ); + _Timestamp_To_timespec( &src->max_wall_time, &dst->max_wall_time ); + _Timestamp_To_timespec( &src->total_wall_time, &dst->total_wall_time ); + #else + dst->min_wall_time = src->min_wall_time; + dst->max_wall_time = src->max_wall_time; + dst->total_wall_time = src->total_wall_time; + #endif + _Thread_Enable_dispatch(); return RTEMS_SUCCESSFUL; diff --git a/cpukit/rtems/src/ratemongetstatus.c b/cpukit/rtems/src/ratemongetstatus.c index 59b39e2917..eb307dad6a 100644 --- a/cpukit/rtems/src/ratemongetstatus.c +++ b/cpukit/rtems/src/ratemongetstatus.c @@ -52,6 +52,11 @@ rtems_status_code rtems_rate_monotonic_get_status( { Objects_Locations location; Rate_monotonic_Control *the_period; + #if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) || \ + defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS) + Timestamp_Control uptime; + Timestamp_Control temp; + #endif if ( !status ) return RTEMS_INVALID_ADDRESS; @@ -65,12 +70,12 @@ rtems_status_code rtems_rate_monotonic_get_status( if ( status->state == RATE_MONOTONIC_INACTIVE ) { #ifdef RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS - _Timestamp_Set_to_zero( &status->since_last_period ); + _Timespec_Set_to_zero( &status->since_last_period ); #else status->since_last_period = 0; #endif #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS - _Timestamp_Set_to_zero( &status->executed_since_last_period ); + _Timespec_Set_to_zero( &status->executed_since_last_period ); #else status->executed_since_last_period = 0; #endif @@ -81,16 +86,12 @@ rtems_status_code rtems_rate_monotonic_get_status( */ #if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) || \ defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS) - Timestamp_Control uptime; _TOD_Get_uptime( &uptime ); #endif #ifdef RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS - _Timestamp_Subtract( - &the_period->time_at_period, - &uptime, - &status->since_last_period - ); + _Timestamp_Subtract( &the_period->time_at_period, &uptime, &temp ); + _Timestamp_To_timespec( &temp, &status->since_last_period ); #else status->since_last_period = _Watchdog_Ticks_since_boot - the_period->time_at_period; @@ -100,8 +101,9 @@ rtems_status_code rtems_rate_monotonic_get_status( _Timestamp_Subtract( &_Thread_Time_of_last_context_switch, &uptime, - &status->executed_since_last_period + &temp ); + _Timestamp_To_timespec( &temp, &status->executed_since_last_period ); #else status->executed_since_last_period = the_period->owner->cpu_time_used - diff --git a/cpukit/rtems/src/ratemonperiod.c b/cpukit/rtems/src/ratemonperiod.c index db3b179e98..3c51ec72ef 100644 --- a/cpukit/rtems/src/ratemonperiod.c +++ b/cpukit/rtems/src/ratemonperiod.c @@ -27,15 +27,12 @@ void _Rate_monotonic_Update_statistics( Rate_monotonic_Control *the_period ) { - rtems_rate_monotonic_period_statistics *stats; - rtems_thread_cpu_usage_t executed; - rtems_rate_monotonic_period_time_t since_last_period; - #ifdef RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS - rtems_rate_monotonic_period_time_t period_start; - #endif + Rate_monotonic_Statistics *stats; + Thread_CPU_usage_t executed; + Rate_monotonic_Period_time_t since_last_period; #if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) || \ defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS) - Timestamp_Control uptime; + Timestamp_Control uptime; /* * Obtain the current time since boot @@ -54,8 +51,11 @@ void _Rate_monotonic_Update_statistics( */ #ifdef RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS - period_start = the_period->time_at_period; - _Timestamp_Subtract( &period_start, &uptime, &since_last_period ); + _Timestamp_Subtract( + &the_period->time_at_period, + &uptime, + &since_last_period + ); the_period->time_at_period = uptime; #else since_last_period = _Watchdog_Ticks_since_boot - the_period->time_at_period; @@ -64,7 +64,7 @@ void _Rate_monotonic_Update_statistics( #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS { - rtems_thread_cpu_usage_t ran, used; + Thread_CPU_usage_t ran, used; /* Grab CPU usage when the thread got switched in */ used = _Thread_Executing->cpu_time_used; @@ -233,7 +233,7 @@ rtems_status_code rtems_rate_monotonic_period( #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS { - rtems_thread_cpu_usage_t ran; + Thread_CPU_usage_t ran; the_period->owner_executed_at_period = _Thread_Executing->cpu_time_used; diff --git a/cpukit/rtems/src/ratemonreportstatistics.c b/cpukit/rtems/src/ratemonreportstatistics.c index 02a0237faa..bd9bbed84c 100644 --- a/cpukit/rtems/src/ratemonreportstatistics.c +++ b/cpukit/rtems/src/ratemonreportstatistics.c @@ -21,11 +21,10 @@ #include #include +#include #if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) || \ defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS) - #include - /* We print to 1/10's of milliseconds */ #define NANOSECONDS_DIVIDER 1000 #define PERCENT_FMT "%04" PRId32 @@ -149,22 +148,22 @@ ididididid NNNN ccccc mmmmmm X */ { #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS - Timestamp_Control cpu_average; - Timestamp_Control *min_cpu = &the_stats.min_cpu_time; - Timestamp_Control *max_cpu = &the_stats.max_cpu_time; - Timestamp_Control *total_cpu = &the_stats.total_cpu_time; + struct timespec cpu_average; + struct timespec *min_cpu = &the_stats.min_cpu_time; + struct timespec *max_cpu = &the_stats.max_cpu_time; + struct timespec *total_cpu = &the_stats.total_cpu_time; - _Timestamp_Divide_by_integer( total_cpu, the_stats.count, &cpu_average ); + _Timespec_Divide_by_integer( total_cpu, the_stats.count, &cpu_average ); (*print)( context, "%" PRId32 "." NANOSECONDS_FMT "/" /* min cpu time */ "%" PRId32 "." NANOSECONDS_FMT "/" /* max cpu time */ "%" PRId32 "." NANOSECONDS_FMT " ", /* avg cpu time */ - _Timestamp_Get_seconds( min_cpu ), - _Timestamp_Get_nanoseconds( min_cpu ) / NANOSECONDS_DIVIDER, - _Timestamp_Get_seconds( max_cpu ), - _Timestamp_Get_nanoseconds( max_cpu ) / NANOSECONDS_DIVIDER, - _Timestamp_Get_seconds( &cpu_average ), - _Timestamp_Get_nanoseconds( &cpu_average ) / NANOSECONDS_DIVIDER + _Timespec_Get_seconds( min_cpu ), + _Timespec_Get_nanoseconds( min_cpu ) / NANOSECONDS_DIVIDER, + _Timespec_Get_seconds( max_cpu ), + _Timespec_Get_nanoseconds( max_cpu ) / NANOSECONDS_DIVIDER, + _Timespec_Get_seconds( &cpu_average ), + _Timespec_Get_nanoseconds( &cpu_average ) / NANOSECONDS_DIVIDER ); #else uint32_t ival_cpu, fval_cpu; @@ -185,22 +184,22 @@ ididididid NNNN ccccc mmmmmm X */ { #ifdef RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS - Timestamp_Control wall_average; - Timestamp_Control *min_wall = &the_stats.min_wall_time; - Timestamp_Control *max_wall = &the_stats.max_wall_time; - Timestamp_Control *total_wall = &the_stats.total_wall_time; + struct timespec wall_average; + struct timespec *min_wall = &the_stats.min_wall_time; + struct timespec *max_wall = &the_stats.max_wall_time; + struct timespec *total_wall = &the_stats.total_wall_time; - _Timestamp_Divide_by_integer(total_wall, the_stats.count, &wall_average); + _Timespec_Divide_by_integer(total_wall, the_stats.count, &wall_average); (*print)( context, "%" PRId32 "." NANOSECONDS_FMT "/" /* min wall time */ "%" PRId32 "." NANOSECONDS_FMT "/" /* max wall time */ "%" PRId32 "." NANOSECONDS_FMT "\n", /* avg wall time */ - _Timestamp_Get_seconds( min_wall ), - _Timestamp_Get_nanoseconds( min_wall ) / NANOSECONDS_DIVIDER, - _Timestamp_Get_seconds( max_wall ), - _Timestamp_Get_nanoseconds( max_wall ) / NANOSECONDS_DIVIDER, - _Timestamp_Get_seconds( &wall_average ), - _Timestamp_Get_nanoseconds( &wall_average ) / NANOSECONDS_DIVIDER + _Timespec_Get_seconds( min_wall ), + _Timespec_Get_nanoseconds( min_wall ) / NANOSECONDS_DIVIDER, + _Timespec_Get_seconds( max_wall ), + _Timespec_Get_nanoseconds( max_wall ) / NANOSECONDS_DIVIDER, + _Timespec_Get_seconds( &wall_average ), + _Timespec_Get_nanoseconds( &wall_average ) / NANOSECONDS_DIVIDER ); #else uint32_t ival_wall, fval_wall; -- cgit v1.2.3