From 94d9beecf41191e96554dd9d12ffdbabe9cc54df Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Fri, 30 Oct 2009 17:54:29 +0000 Subject: 2009-10-30 Glenn Humphrey PR pr1462/cpukit * rtems/include/rtems/rtems/ratemon.h, rtems/src/ratemongetstatus.c, rtems/src/ratemonperiod.c, rtems/src/ratemontimeout.c, score/include/rtems/score/thread.h: Fix bugs in rate monotonic statistics. --- cpukit/ChangeLog | 8 ++ cpukit/rtems/include/rtems/rtems/ratemon.h | 22 ++++- cpukit/rtems/src/ratemongetstatus.c | 4 +- cpukit/rtems/src/ratemonperiod.c | 144 +++++++++++++++-------------- cpukit/rtems/src/ratemontimeout.c | 7 +- cpukit/score/include/rtems/score/thread.h | 6 +- 6 files changed, 113 insertions(+), 78 deletions(-) diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index 2b8cfee4a3..b80eddb59b 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,11 @@ +2009-10-30 Glenn Humphrey + + PR pr1462/cpukit + * rtems/include/rtems/rtems/ratemon.h, rtems/src/ratemongetstatus.c, + rtems/src/ratemonperiod.c, rtems/src/ratemontimeout.c, + score/include/rtems/score/thread.h: Fix bugs in rate monotonic + statistics. + 2009-10-30 Joel Sherrill * rtems/src/semcreate.c: Fix mismatched brace in multiprocessing code. diff --git a/cpukit/rtems/include/rtems/rtems/ratemon.h b/cpukit/rtems/include/rtems/rtems/ratemon.h index 925efda1a9..b3552e639a 100644 --- a/cpukit/rtems/include/rtems/rtems/ratemon.h +++ b/cpukit/rtems/include/rtems/rtems/ratemon.h @@ -3,7 +3,8 @@ * * This include file contains all the constants, structures, and * prototypes associated with the Rate Monotonic Manager. This manager - * provides facilities to implement tasks which execute in a periodic fashion. + * provides facilities to implement threads which execute in a periodic + * fashion. * * Directives provided are: * @@ -14,7 +15,7 @@ * - obtain status information on a period */ -/* COPYRIGHT (c) 1989-2008. +/* COPYRIGHT (c) 1989-2009. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -405,9 +406,9 @@ rtems_status_code rtems_rate_monotonic_period( * @brief _Rate_monotonic_Timeout * * This routine is invoked when the period represented - * by ID expires. If the task which owns this period is blocked + * by ID expires. If the thread which owns this period is blocked * waiting for the period to expire, then it is readied and the - * period is restarted. If the owning task is not waiting for the + * period is restarted. If the owning thread is not waiting for the * period to expire, then the period is placed in the EXPIRED * state and not restarted. */ @@ -416,6 +417,19 @@ void _Rate_monotonic_Timeout( void *ignored ); +/** + * @brief _Rate_monotonic_Initiate_statistics( + * + * This routine is invoked when a period is initiated via an explicit + * call to rtems_rate_monotonic_period for the period's first iteration + * or from _Rate_monotonic_Timeout for period iterations 2-n. + * + * @param[in] the_period points to the period being operated upon. + */ +void _Rate_monotonic_Initiate_statistics( + Rate_monotonic_Control *the_period +); + /** * @brief _Rate_monotonic_Reset_wall_time_statistics * diff --git a/cpukit/rtems/src/ratemongetstatus.c b/cpukit/rtems/src/ratemongetstatus.c index aea428d2d1..8fc003f7e4 100644 --- a/cpukit/rtems/src/ratemongetstatus.c +++ b/cpukit/rtems/src/ratemongetstatus.c @@ -1,7 +1,7 @@ /* * Rate Monotonic Manager -- Get Status * - * COPYRIGHT (c) 1989-2007. + * COPYRIGHT (c) 1989-2009. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -65,7 +65,7 @@ rtems_status_code rtems_rate_monotonic_get_status( switch ( location ) { case OBJECTS_LOCAL: - status->owner = ((the_period->owner) ? the_period->owner->Object.id : 0); + status->owner = the_period->owner->Object.id; status->state = the_period->state; if ( status->state == RATE_MONOTONIC_INACTIVE ) { diff --git a/cpukit/rtems/src/ratemonperiod.c b/cpukit/rtems/src/ratemonperiod.c index 3c51ec72ef..ffa8f397a3 100644 --- a/cpukit/rtems/src/ratemonperiod.c +++ b/cpukit/rtems/src/ratemonperiod.c @@ -1,7 +1,7 @@ /* * Rate Monotonic Manager - Period Blocking and Status * - * COPYRIGHT (c) 1989-2007. + * COPYRIGHT (c) 1989-2009. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -23,6 +23,61 @@ #include #include +void _Rate_monotonic_Initiate_statistics( + Rate_monotonic_Control *the_period +) +{ + Thread_Control *owning_thread = the_period->owner; + + /* + * If any statistics are at nanosecond granularity, we need to + * obtain the uptime. + */ + #if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) || \ + defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS) + + struct timespec uptime; + + _TOD_Get_uptime( &uptime ); + #endif + + /* + * Set the starting point and the CPU time used for the statistics. + */ + #ifdef RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS + the_period->time_at_period = uptime; + #else + the_period->time_at_period = _Watchdog_Ticks_since_boot; + #endif + + the_period->owner_executed_at_period = owning_thread->cpu_time_used; + + /* + * If using nanosecond granularity for CPU Usage 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. + */ + #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_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->owner_executed_at_period, &ran ); + } + #endif +} + void _Rate_monotonic_Update_statistics( Rate_monotonic_Control *the_period ) @@ -47,14 +102,22 @@ void _Rate_monotonic_Update_statistics( */ /* - * Grab basic information + * Update the counts. + */ + + stats = &the_period->Statistics; + stats->count++; + + if ( the_period->state == RATE_MONOTONIC_EXPIRED ) + stats->missed_count++; + + /* + * Grab basic information for time statistics. */ #ifdef RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS _Timestamp_Subtract( - &the_period->time_at_period, - &uptime, - &since_last_period + &the_period->time_at_period, &uptime, &since_last_period ); the_period->time_at_period = uptime; #else @@ -91,17 +154,6 @@ void _Rate_monotonic_Update_statistics( the_period->owner_executed_at_period; #endif - /* - * Now update the statistics - */ - - stats = &the_period->Statistics; - stats->count++; - - - if ( the_period->state == RATE_MONOTONIC_EXPIRED ) - stats->missed_count++; - /* * Update CPU time */ @@ -175,8 +227,8 @@ rtems_status_code rtems_rate_monotonic_period( ISR_Level level; the_period = _Rate_monotonic_Get( id, &location ); - switch ( location ) { + switch ( location ) { case OBJECTS_LOCAL: if ( !_Thread_Is_executing( the_period->owner ) ) { _Thread_Enable_dispatch(); @@ -204,57 +256,13 @@ rtems_status_code rtems_rate_monotonic_period( _ISR_Disable( level ); switch ( the_period->state ) { case RATE_MONOTONIC_INACTIVE: { - #if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) || \ - defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS) - Timestamp_Control uptime; - #endif - - /* - * No need to update statistics -- there are not a period active - */ _ISR_Enable( level ); - - #if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) || \ - defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS) - _TOD_Get_uptime( &uptime ); - #endif - - #ifdef RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS - /* - * Since the statistics didn't update the starting time, - * we do it here. - */ - the_period->time_at_period = uptime; - #else - the_period->time_at_period = _Watchdog_Ticks_since_boot; - #endif - - #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS - { - Thread_CPU_usage_t ran; - - the_period->owner_executed_at_period = - _Thread_Executing->cpu_time_used; - - /* How much time time since last context switch */ - _Timestamp_Subtract( - &_Thread_Time_of_last_context_switch, - &uptime, - &ran - ); - - /* The thread had executed before the last context switch also. - * - * the_period->owner_executed_at_period += ran - */ - _Timestamp_Add_to( &the_period->owner_executed_at_period, &ran ); - } - #else - the_period->owner_executed_at_period = - _Thread_Executing->cpu_time_used; - #endif + /* + * Baseline statistics information for the beginning of a period. + */ + _Rate_monotonic_Initiate_statistics( the_period ); the_period->state = RATE_MONOTONIC_ACTIVE; _Watchdog_Initialize( @@ -273,7 +281,7 @@ rtems_status_code rtems_rate_monotonic_period( case RATE_MONOTONIC_ACTIVE: /* - * Update statistics from the concluding period + * Update statistics from the concluding period. */ _Rate_monotonic_Update_statistics( the_period ); @@ -282,7 +290,6 @@ rtems_status_code rtems_rate_monotonic_period( * in the process of blocking on the period and that we * may be changing the length of the next period. */ - the_period->state = RATE_MONOTONIC_OWNER_IS_BLOCKING; the_period->next_length = length; @@ -295,7 +302,6 @@ rtems_status_code rtems_rate_monotonic_period( * Did the watchdog timer expire while we were actually blocking * on it? */ - _ISR_Disable( level ); local_state = the_period->state; the_period->state = RATE_MONOTONIC_ACTIVE; @@ -305,7 +311,6 @@ rtems_status_code rtems_rate_monotonic_period( * If it did, then we want to unblock ourself and continue as * if nothing happen. The period was reset in the timeout routine. */ - if ( local_state == RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING ) _Thread_Clear_state( _Thread_Executing, STATES_WAITING_FOR_PERIOD ); @@ -314,6 +319,7 @@ rtems_status_code rtems_rate_monotonic_period( break; case RATE_MONOTONIC_EXPIRED: + /* * Update statistics from the concluding period */ diff --git a/cpukit/rtems/src/ratemontimeout.c b/cpukit/rtems/src/ratemontimeout.c index 2e91fd2803..de1674636c 100644 --- a/cpukit/rtems/src/ratemontimeout.c +++ b/cpukit/rtems/src/ratemontimeout.c @@ -1,7 +1,7 @@ /* * Rate Monotonic Manager -- Period End Timeout Handler * - * COPYRIGHT (c) 1989-2007. + * COPYRIGHT (c) 1989-2009. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -51,7 +51,6 @@ void _Rate_monotonic_Timeout( * When we get here, the Timer is already off the chain so we do not * have to worry about that -- hence no _Watchdog_Remove(). */ - the_period = _Rate_monotonic_Get( id, &location ); switch ( location ) { @@ -61,10 +60,14 @@ void _Rate_monotonic_Timeout( the_thread->Wait.id == the_period->Object.id ) { _Thread_Unblock( the_thread ); + _Rate_monotonic_Initiate_statistics( the_period ); + _Watchdog_Insert_ticks( &the_period->Timer, the_period->next_length ); } else if ( the_period->state == RATE_MONOTONIC_OWNER_IS_BLOCKING ) { the_period->state = RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING; + _Rate_monotonic_Initiate_statistics( the_period ); + _Watchdog_Insert_ticks( &the_period->Timer, the_period->next_length ); } else the_period->state = RATE_MONOTONIC_EXPIRED; diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h index ed5b475cd1..d84310a9d2 100644 --- a/cpukit/score/include/rtems/score/thread.h +++ b/cpukit/score/include/rtems/score/thread.h @@ -460,13 +460,17 @@ SCORE_EXTERN Context_Control _Thread_BSP_context; * counter which is used to prevent context switches at inopportune * moments. */ +#if defined(__AVR__) +SCORE_EXTERN volatile uint8_t _Thread_Dispatch_disable_level; +#else SCORE_EXTERN volatile uint32_t _Thread_Dispatch_disable_level; +#endif /** * If this is non-zero, then the post-task switch extension * is run regardless of the state of the per thread flag. */ -SCORE_EXTERN uint32_t _Thread_Do_post_task_switch_extension; +SCORE_EXTERN bool _Thread_Do_post_task_switch_extension; /** * The following holds how many user extensions are in the system. This -- cgit v1.2.3