2009-10-30 Glenn Humphrey <glenn.humphrey@oarcorp.com>

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.
This commit is contained in:
Joel Sherrill
2009-10-30 17:54:29 +00:00
parent 7bf6612bf2
commit 94d9beecf4
6 changed files with 113 additions and 78 deletions

View File

@@ -1,3 +1,11 @@
2009-10-30 Glenn Humphrey <glenn.humphrey@oarcorp.com>
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 <joel.sherrill@oarcorp.com> 2009-10-30 Joel Sherrill <joel.sherrill@oarcorp.com>
* rtems/src/semcreate.c: Fix mismatched brace in multiprocessing code. * rtems/src/semcreate.c: Fix mismatched brace in multiprocessing code.

View File

@@ -3,7 +3,8 @@
* *
* This include file contains all the constants, structures, and * This include file contains all the constants, structures, and
* prototypes associated with the Rate Monotonic Manager. This manager * 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: * Directives provided are:
* *
@@ -14,7 +15,7 @@
* - obtain status information on a period * - obtain status information on a period
*/ */
/* COPYRIGHT (c) 1989-2008. /* COPYRIGHT (c) 1989-2009.
* On-Line Applications Research Corporation (OAR). * On-Line Applications Research Corporation (OAR).
* *
* The license and distribution terms for this file may be * 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 * @brief _Rate_monotonic_Timeout
* *
* This routine is invoked when the period represented * 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 * 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 * period to expire, then the period is placed in the EXPIRED
* state and not restarted. * state and not restarted.
*/ */
@@ -416,6 +417,19 @@ void _Rate_monotonic_Timeout(
void *ignored 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 * @brief _Rate_monotonic_Reset_wall_time_statistics
* *

View File

@@ -1,7 +1,7 @@
/* /*
* Rate Monotonic Manager -- Get Status * Rate Monotonic Manager -- Get Status
* *
* COPYRIGHT (c) 1989-2007. * COPYRIGHT (c) 1989-2009.
* On-Line Applications Research Corporation (OAR). * On-Line Applications Research Corporation (OAR).
* *
* The license and distribution terms for this file may be * The license and distribution terms for this file may be
@@ -65,7 +65,7 @@ rtems_status_code rtems_rate_monotonic_get_status(
switch ( location ) { switch ( location ) {
case OBJECTS_LOCAL: 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; status->state = the_period->state;
if ( status->state == RATE_MONOTONIC_INACTIVE ) { if ( status->state == RATE_MONOTONIC_INACTIVE ) {

View File

@@ -1,7 +1,7 @@
/* /*
* Rate Monotonic Manager - Period Blocking and Status * Rate Monotonic Manager - Period Blocking and Status
* *
* COPYRIGHT (c) 1989-2007. * COPYRIGHT (c) 1989-2009.
* On-Line Applications Research Corporation (OAR). * On-Line Applications Research Corporation (OAR).
* *
* The license and distribution terms for this file may be * The license and distribution terms for this file may be
@@ -23,6 +23,61 @@
#include <rtems/rtems/ratemon.h> #include <rtems/rtems/ratemon.h>
#include <rtems/score/thread.h> #include <rtems/score/thread.h>
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( void _Rate_monotonic_Update_statistics(
Rate_monotonic_Control *the_period 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 #ifdef RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS
_Timestamp_Subtract( _Timestamp_Subtract(
&the_period->time_at_period, &the_period->time_at_period, &uptime, &since_last_period
&uptime,
&since_last_period
); );
the_period->time_at_period = uptime; the_period->time_at_period = uptime;
#else #else
@@ -91,17 +154,6 @@ void _Rate_monotonic_Update_statistics(
the_period->owner_executed_at_period; the_period->owner_executed_at_period;
#endif #endif
/*
* Now update the statistics
*/
stats = &the_period->Statistics;
stats->count++;
if ( the_period->state == RATE_MONOTONIC_EXPIRED )
stats->missed_count++;
/* /*
* Update CPU time * Update CPU time
*/ */
@@ -175,8 +227,8 @@ rtems_status_code rtems_rate_monotonic_period(
ISR_Level level; ISR_Level level;
the_period = _Rate_monotonic_Get( id, &location ); the_period = _Rate_monotonic_Get( id, &location );
switch ( location ) {
switch ( location ) {
case OBJECTS_LOCAL: case OBJECTS_LOCAL:
if ( !_Thread_Is_executing( the_period->owner ) ) { if ( !_Thread_Is_executing( the_period->owner ) ) {
_Thread_Enable_dispatch(); _Thread_Enable_dispatch();
@@ -204,57 +256,13 @@ rtems_status_code rtems_rate_monotonic_period(
_ISR_Disable( level ); _ISR_Disable( level );
switch ( the_period->state ) { switch ( the_period->state ) {
case RATE_MONOTONIC_INACTIVE: { 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 ); _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, * Baseline statistics information for the beginning of a period.
* we do it here.
*/ */
the_period->time_at_period = uptime; _Rate_monotonic_Initiate_statistics( the_period );
#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
the_period->state = RATE_MONOTONIC_ACTIVE; the_period->state = RATE_MONOTONIC_ACTIVE;
_Watchdog_Initialize( _Watchdog_Initialize(
@@ -273,7 +281,7 @@ rtems_status_code rtems_rate_monotonic_period(
case RATE_MONOTONIC_ACTIVE: case RATE_MONOTONIC_ACTIVE:
/* /*
* Update statistics from the concluding period * Update statistics from the concluding period.
*/ */
_Rate_monotonic_Update_statistics( the_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 * in the process of blocking on the period and that we
* may be changing the length of the next period. * may be changing the length of the next period.
*/ */
the_period->state = RATE_MONOTONIC_OWNER_IS_BLOCKING; the_period->state = RATE_MONOTONIC_OWNER_IS_BLOCKING;
the_period->next_length = length; 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 * Did the watchdog timer expire while we were actually blocking
* on it? * on it?
*/ */
_ISR_Disable( level ); _ISR_Disable( level );
local_state = the_period->state; local_state = the_period->state;
the_period->state = RATE_MONOTONIC_ACTIVE; 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 it did, then we want to unblock ourself and continue as
* if nothing happen. The period was reset in the timeout routine. * if nothing happen. The period was reset in the timeout routine.
*/ */
if ( local_state == RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING ) if ( local_state == RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING )
_Thread_Clear_state( _Thread_Executing, STATES_WAITING_FOR_PERIOD ); _Thread_Clear_state( _Thread_Executing, STATES_WAITING_FOR_PERIOD );
@@ -314,6 +319,7 @@ rtems_status_code rtems_rate_monotonic_period(
break; break;
case RATE_MONOTONIC_EXPIRED: case RATE_MONOTONIC_EXPIRED:
/* /*
* Update statistics from the concluding period * Update statistics from the concluding period
*/ */

View File

@@ -1,7 +1,7 @@
/* /*
* Rate Monotonic Manager -- Period End Timeout Handler * Rate Monotonic Manager -- Period End Timeout Handler
* *
* COPYRIGHT (c) 1989-2007. * COPYRIGHT (c) 1989-2009.
* On-Line Applications Research Corporation (OAR). * On-Line Applications Research Corporation (OAR).
* *
* The license and distribution terms for this file may be * 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 * When we get here, the Timer is already off the chain so we do not
* have to worry about that -- hence no _Watchdog_Remove(). * have to worry about that -- hence no _Watchdog_Remove().
*/ */
the_period = _Rate_monotonic_Get( id, &location ); the_period = _Rate_monotonic_Get( id, &location );
switch ( location ) { switch ( location ) {
@@ -61,10 +60,14 @@ void _Rate_monotonic_Timeout(
the_thread->Wait.id == the_period->Object.id ) { the_thread->Wait.id == the_period->Object.id ) {
_Thread_Unblock( the_thread ); _Thread_Unblock( the_thread );
_Rate_monotonic_Initiate_statistics( the_period );
_Watchdog_Insert_ticks( &the_period->Timer, the_period->next_length ); _Watchdog_Insert_ticks( &the_period->Timer, the_period->next_length );
} else if ( the_period->state == RATE_MONOTONIC_OWNER_IS_BLOCKING ) { } else if ( the_period->state == RATE_MONOTONIC_OWNER_IS_BLOCKING ) {
the_period->state = RATE_MONOTONIC_EXPIRED_WHILE_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 ); _Watchdog_Insert_ticks( &the_period->Timer, the_period->next_length );
} else } else
the_period->state = RATE_MONOTONIC_EXPIRED; the_period->state = RATE_MONOTONIC_EXPIRED;

View File

@@ -460,13 +460,17 @@ SCORE_EXTERN Context_Control _Thread_BSP_context;
* counter which is used to prevent context switches at inopportune * counter which is used to prevent context switches at inopportune
* moments. * moments.
*/ */
#if defined(__AVR__)
SCORE_EXTERN volatile uint8_t _Thread_Dispatch_disable_level;
#else
SCORE_EXTERN volatile uint32_t _Thread_Dispatch_disable_level; SCORE_EXTERN volatile uint32_t _Thread_Dispatch_disable_level;
#endif
/** /**
* If this is non-zero, then the post-task switch extension * If this is non-zero, then the post-task switch extension
* is run regardless of the state of the per thread flag. * 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 * The following holds how many user extensions are in the system. This