mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-06 07:33:17 +00:00
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:
@@ -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.
|
||||||
|
|||||||
@@ -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
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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 ) {
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user