From 11ab74ef980467db8b0e7a88862cfb08744b2481 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Tue, 5 Dec 1995 15:27:51 +0000 Subject: new states added and _Rate_monotonic_Set_State removed. --- c/src/exec/rtems/headers/ratemon.h | 24 ++--- c/src/exec/rtems/include/rtems/rtems/ratemon.h | 24 ++--- c/src/exec/rtems/src/ratemon.c | 130 ++++++++++--------------- cpukit/rtems/include/rtems/rtems/ratemon.h | 24 ++--- cpukit/rtems/src/ratemon.c | 130 ++++++++++--------------- 5 files changed, 127 insertions(+), 205 deletions(-) diff --git a/c/src/exec/rtems/headers/ratemon.h b/c/src/exec/rtems/headers/ratemon.h index 4e85ab1ac2..3c6c6695ca 100644 --- a/c/src/exec/rtems/headers/ratemon.h +++ b/c/src/exec/rtems/headers/ratemon.h @@ -39,9 +39,13 @@ extern "C" { */ typedef enum { - RATE_MONOTONIC_INACTIVE, /* off chain, never initialized */ - RATE_MONOTONIC_ACTIVE, /* on chain, running continuously */ - RATE_MONOTONIC_EXPIRED /* off chain, will be reset by next rm_period */ + RATE_MONOTONIC_INACTIVE, /* off chain, never initialized */ + RATE_MONOTONIC_OWNER_IS_BLOCKING, /* on chain, owner is blocking on it */ + RATE_MONOTONIC_ACTIVE, /* on chain, running continuously */ + RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING, /* on chain, expired while owner was */ + /* was blocking on it */ + RATE_MONOTONIC_EXPIRED /* off chain, will be reset by next */ + /* rtems_rate_monotonic_period */ } Rate_Monotonic_Period_states; /* @@ -192,20 +196,6 @@ STATIC INLINE Rate_monotonic_Control *_Rate_monotonic_Get ( Objects_Locations *location ); -/* - * _Rate_monotonic_Set_state - * - * DESCRIPTION: - * - * This function blocks the calling task so that it is waiting for - * a period to expire. It returns TRUE if the task was successfully - * blocked, and FALSE otherwise. - */ - -boolean _Rate_monotonic_Set_state( - Rate_monotonic_Control *the_period -); - /* * _Rate_monotonic_Timeout * diff --git a/c/src/exec/rtems/include/rtems/rtems/ratemon.h b/c/src/exec/rtems/include/rtems/rtems/ratemon.h index 4e85ab1ac2..3c6c6695ca 100644 --- a/c/src/exec/rtems/include/rtems/rtems/ratemon.h +++ b/c/src/exec/rtems/include/rtems/rtems/ratemon.h @@ -39,9 +39,13 @@ extern "C" { */ typedef enum { - RATE_MONOTONIC_INACTIVE, /* off chain, never initialized */ - RATE_MONOTONIC_ACTIVE, /* on chain, running continuously */ - RATE_MONOTONIC_EXPIRED /* off chain, will be reset by next rm_period */ + RATE_MONOTONIC_INACTIVE, /* off chain, never initialized */ + RATE_MONOTONIC_OWNER_IS_BLOCKING, /* on chain, owner is blocking on it */ + RATE_MONOTONIC_ACTIVE, /* on chain, running continuously */ + RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING, /* on chain, expired while owner was */ + /* was blocking on it */ + RATE_MONOTONIC_EXPIRED /* off chain, will be reset by next */ + /* rtems_rate_monotonic_period */ } Rate_Monotonic_Period_states; /* @@ -192,20 +196,6 @@ STATIC INLINE Rate_monotonic_Control *_Rate_monotonic_Get ( Objects_Locations *location ); -/* - * _Rate_monotonic_Set_state - * - * DESCRIPTION: - * - * This function blocks the calling task so that it is waiting for - * a period to expire. It returns TRUE if the task was successfully - * blocked, and FALSE otherwise. - */ - -boolean _Rate_monotonic_Set_state( - Rate_monotonic_Control *the_period -); - /* * _Rate_monotonic_Timeout * diff --git a/c/src/exec/rtems/src/ratemon.c b/c/src/exec/rtems/src/ratemon.c index 9733620e06..d3524b02d6 100644 --- a/c/src/exec/rtems/src/ratemon.c +++ b/c/src/exec/rtems/src/ratemon.c @@ -233,9 +233,11 @@ rtems_status_code rtems_rate_monotonic_period( rtems_interval length ) { - Rate_monotonic_Control *the_period; - Objects_Locations location; - rtems_status_code return_value; + Rate_monotonic_Control *the_period; + Objects_Locations location; + rtems_status_code return_value; + Rate_Monotonic_Period_states local_state; + ISR_Level level; the_period = _Rate_monotonic_Get( id, &location ); switch ( location ) { @@ -268,8 +270,10 @@ rtems_status_code rtems_rate_monotonic_period( return( return_value ); } + _ISR_Disable( level ); switch ( the_period->state ) { case RATE_MONOTONIC_INACTIVE: + _ISR_Enable( level ); the_period->state = RATE_MONOTONIC_ACTIVE; _Watchdog_Initialize( &the_period->Timer, @@ -282,88 +286,58 @@ rtems_status_code rtems_rate_monotonic_period( return RTEMS_SUCCESSFUL; case RATE_MONOTONIC_ACTIVE: -/* following is and could be a critical section problem */ - _Thread_Executing->Wait.id = the_period->Object.id; - if ( _Rate_monotonic_Set_state( the_period ) ) { - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - /* has expired -- fall into next case */ + /* + * This tells the _Rate_monotonic_Timeout that this task is + * in the process of blocking on the period. + */ + + the_period->state = RATE_MONOTONIC_OWNER_IS_BLOCKING; + _ISR_Enable( level ); + + _Thread_Executing->Wait.id = the_period->Object.id; + _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_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; + _ISR_Enable( level ); + + /* + * 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 ); + + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + break; + case RATE_MONOTONIC_EXPIRED: + _ISR_Enable( level ); the_period->state = RATE_MONOTONIC_ACTIVE; _Watchdog_Insert_ticks( &the_period->Timer, length ); _Thread_Enable_dispatch(); return RTEMS_TIMEOUT; + + case RATE_MONOTONIC_OWNER_IS_BLOCKING: + case RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING: + /* + * These should never happen. + */ + break; } } return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ } -/*PAGE - * - * _Rate_monotonic_Set_state - * - * This kernel routine sets the STATES_WAITING_FOR_PERIOD state in - * the running thread's tcb if the specified period has not expired. - * The ready chain is adjusted if necessary. - * - * Input parameters: - * the_period - pointer to period control block - * - * Output parameters: - * TRUE - if blocked successfully for period - * FALSE - if period has expired - * - * INTERRUPT LATENCY: - * delete node - * priority map - * select heir - */ - -boolean _Rate_monotonic_Set_state( -Rate_monotonic_Control *the_period -) -{ - Thread_Control *executing; - Chain_Control *ready; - ISR_Level level; - States_Control old_state; - - executing = _Thread_Executing; - ready = executing->ready; - _ISR_Disable( level ); - - old_state = executing->current_state; - - if ( _Rate_monotonic_Is_expired( the_period ) ) { - _ISR_Enable( level ); - return( FALSE ); - } - - executing->current_state = - _States_Set( STATES_WAITING_FOR_PERIOD, old_state ); - - if ( _States_Is_ready( old_state ) ) { - if ( _Chain_Has_only_one_node( ready ) ) { - _Chain_Initialize_empty( ready ); - _Priority_Remove_from_bit_map( &executing->Priority_map ); - _ISR_Flash( level ); - } else { - _Chain_Extract_unprotected( &executing->Object.Node ); - _ISR_Flash( level ); - } - - if ( _Thread_Is_heir( executing ) ) - _Thread_Calculate_heir(); - - _Context_Switch_necessary = TRUE; - } - - _ISR_Enable( level ); - return( TRUE ); -} - /*PAGE * * _Rate_monotonic_Timeout @@ -385,7 +359,7 @@ void _Rate_monotonic_Timeout( ) { Rate_monotonic_Control *the_period; - Objects_Locations location; + Objects_Locations location; Thread_Control *the_thread; the_period = _Rate_monotonic_Get( id, &location ); @@ -399,8 +373,10 @@ void _Rate_monotonic_Timeout( the_thread->Wait.id == the_period->Object.id ) { _Thread_Unblock( the_thread ); _Watchdog_Reset( &the_period->Timer ); - } - else + } else if ( the_period->state == RATE_MONOTONIC_OWNER_IS_BLOCKING ) { + the_period->state = RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING; + _Watchdog_Reset( &the_period->Timer ); + } else the_period->state = RATE_MONOTONIC_EXPIRED; _Thread_Unnest_dispatch(); break; diff --git a/cpukit/rtems/include/rtems/rtems/ratemon.h b/cpukit/rtems/include/rtems/rtems/ratemon.h index 4e85ab1ac2..3c6c6695ca 100644 --- a/cpukit/rtems/include/rtems/rtems/ratemon.h +++ b/cpukit/rtems/include/rtems/rtems/ratemon.h @@ -39,9 +39,13 @@ extern "C" { */ typedef enum { - RATE_MONOTONIC_INACTIVE, /* off chain, never initialized */ - RATE_MONOTONIC_ACTIVE, /* on chain, running continuously */ - RATE_MONOTONIC_EXPIRED /* off chain, will be reset by next rm_period */ + RATE_MONOTONIC_INACTIVE, /* off chain, never initialized */ + RATE_MONOTONIC_OWNER_IS_BLOCKING, /* on chain, owner is blocking on it */ + RATE_MONOTONIC_ACTIVE, /* on chain, running continuously */ + RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING, /* on chain, expired while owner was */ + /* was blocking on it */ + RATE_MONOTONIC_EXPIRED /* off chain, will be reset by next */ + /* rtems_rate_monotonic_period */ } Rate_Monotonic_Period_states; /* @@ -192,20 +196,6 @@ STATIC INLINE Rate_monotonic_Control *_Rate_monotonic_Get ( Objects_Locations *location ); -/* - * _Rate_monotonic_Set_state - * - * DESCRIPTION: - * - * This function blocks the calling task so that it is waiting for - * a period to expire. It returns TRUE if the task was successfully - * blocked, and FALSE otherwise. - */ - -boolean _Rate_monotonic_Set_state( - Rate_monotonic_Control *the_period -); - /* * _Rate_monotonic_Timeout * diff --git a/cpukit/rtems/src/ratemon.c b/cpukit/rtems/src/ratemon.c index 9733620e06..d3524b02d6 100644 --- a/cpukit/rtems/src/ratemon.c +++ b/cpukit/rtems/src/ratemon.c @@ -233,9 +233,11 @@ rtems_status_code rtems_rate_monotonic_period( rtems_interval length ) { - Rate_monotonic_Control *the_period; - Objects_Locations location; - rtems_status_code return_value; + Rate_monotonic_Control *the_period; + Objects_Locations location; + rtems_status_code return_value; + Rate_Monotonic_Period_states local_state; + ISR_Level level; the_period = _Rate_monotonic_Get( id, &location ); switch ( location ) { @@ -268,8 +270,10 @@ rtems_status_code rtems_rate_monotonic_period( return( return_value ); } + _ISR_Disable( level ); switch ( the_period->state ) { case RATE_MONOTONIC_INACTIVE: + _ISR_Enable( level ); the_period->state = RATE_MONOTONIC_ACTIVE; _Watchdog_Initialize( &the_period->Timer, @@ -282,88 +286,58 @@ rtems_status_code rtems_rate_monotonic_period( return RTEMS_SUCCESSFUL; case RATE_MONOTONIC_ACTIVE: -/* following is and could be a critical section problem */ - _Thread_Executing->Wait.id = the_period->Object.id; - if ( _Rate_monotonic_Set_state( the_period ) ) { - _Thread_Enable_dispatch(); - return RTEMS_SUCCESSFUL; - } - /* has expired -- fall into next case */ + /* + * This tells the _Rate_monotonic_Timeout that this task is + * in the process of blocking on the period. + */ + + the_period->state = RATE_MONOTONIC_OWNER_IS_BLOCKING; + _ISR_Enable( level ); + + _Thread_Executing->Wait.id = the_period->Object.id; + _Thread_Set_state( _Thread_Executing, STATES_WAITING_FOR_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; + _ISR_Enable( level ); + + /* + * 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 ); + + _Thread_Enable_dispatch(); + return RTEMS_SUCCESSFUL; + break; + case RATE_MONOTONIC_EXPIRED: + _ISR_Enable( level ); the_period->state = RATE_MONOTONIC_ACTIVE; _Watchdog_Insert_ticks( &the_period->Timer, length ); _Thread_Enable_dispatch(); return RTEMS_TIMEOUT; + + case RATE_MONOTONIC_OWNER_IS_BLOCKING: + case RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING: + /* + * These should never happen. + */ + break; } } return RTEMS_INTERNAL_ERROR; /* unreached - only to remove warnings */ } -/*PAGE - * - * _Rate_monotonic_Set_state - * - * This kernel routine sets the STATES_WAITING_FOR_PERIOD state in - * the running thread's tcb if the specified period has not expired. - * The ready chain is adjusted if necessary. - * - * Input parameters: - * the_period - pointer to period control block - * - * Output parameters: - * TRUE - if blocked successfully for period - * FALSE - if period has expired - * - * INTERRUPT LATENCY: - * delete node - * priority map - * select heir - */ - -boolean _Rate_monotonic_Set_state( -Rate_monotonic_Control *the_period -) -{ - Thread_Control *executing; - Chain_Control *ready; - ISR_Level level; - States_Control old_state; - - executing = _Thread_Executing; - ready = executing->ready; - _ISR_Disable( level ); - - old_state = executing->current_state; - - if ( _Rate_monotonic_Is_expired( the_period ) ) { - _ISR_Enable( level ); - return( FALSE ); - } - - executing->current_state = - _States_Set( STATES_WAITING_FOR_PERIOD, old_state ); - - if ( _States_Is_ready( old_state ) ) { - if ( _Chain_Has_only_one_node( ready ) ) { - _Chain_Initialize_empty( ready ); - _Priority_Remove_from_bit_map( &executing->Priority_map ); - _ISR_Flash( level ); - } else { - _Chain_Extract_unprotected( &executing->Object.Node ); - _ISR_Flash( level ); - } - - if ( _Thread_Is_heir( executing ) ) - _Thread_Calculate_heir(); - - _Context_Switch_necessary = TRUE; - } - - _ISR_Enable( level ); - return( TRUE ); -} - /*PAGE * * _Rate_monotonic_Timeout @@ -385,7 +359,7 @@ void _Rate_monotonic_Timeout( ) { Rate_monotonic_Control *the_period; - Objects_Locations location; + Objects_Locations location; Thread_Control *the_thread; the_period = _Rate_monotonic_Get( id, &location ); @@ -399,8 +373,10 @@ void _Rate_monotonic_Timeout( the_thread->Wait.id == the_period->Object.id ) { _Thread_Unblock( the_thread ); _Watchdog_Reset( &the_period->Timer ); - } - else + } else if ( the_period->state == RATE_MONOTONIC_OWNER_IS_BLOCKING ) { + the_period->state = RATE_MONOTONIC_EXPIRED_WHILE_BLOCKING; + _Watchdog_Reset( &the_period->Timer ); + } else the_period->state = RATE_MONOTONIC_EXPIRED; _Thread_Unnest_dispatch(); break; -- cgit v1.2.3