score: Simplify thread wait state handling

Remove the THREAD_WAIT_STATE_READY_AGAIN and simply use the initial value to
indicate that a thread does not wait on something.  Rename
THREAD_WAIT_FLAGS_INITIAL to THREAD_WAIT_STATE_READY.  This change is necessary
so that _Thread_Continue() can be called for threads which never waited on
something (for example dormant threads).

Update #4546.
This commit is contained in:
Sebastian Huber
2021-11-11 10:34:31 +01:00
parent 50aef135a4
commit e429e9742a
13 changed files with 30 additions and 59 deletions

View File

@@ -48,9 +48,6 @@ extern "C" {
#define RATE_MONOTONIC_BLOCKED \ #define RATE_MONOTONIC_BLOCKED \
( THREAD_WAIT_CLASS_PERIOD | THREAD_WAIT_STATE_BLOCKED ) ( THREAD_WAIT_CLASS_PERIOD | THREAD_WAIT_STATE_BLOCKED )
#define RATE_MONOTONIC_READY_AGAIN \
( THREAD_WAIT_CLASS_PERIOD | THREAD_WAIT_STATE_READY_AGAIN )
/** /**
* @brief Allocates a period control block from * @brief Allocates a period control block from
* the inactive chain of free period control blocks. * the inactive chain of free period control blocks.

View File

@@ -404,7 +404,7 @@ typedef union {
* The mutually exclusive wait state flags are * The mutually exclusive wait state flags are
* - @ref THREAD_WAIT_STATE_INTEND_TO_BLOCK, * - @ref THREAD_WAIT_STATE_INTEND_TO_BLOCK,
* - @ref THREAD_WAIT_STATE_BLOCKED, and * - @ref THREAD_WAIT_STATE_BLOCKED, and
* - @ref THREAD_WAIT_STATE_READY_AGAIN. * - @ref THREAD_WAIT_STATE_READY.
*/ */
typedef unsigned int Thread_Wait_flags; typedef unsigned int Thread_Wait_flags;

View File

@@ -2216,16 +2216,20 @@ RTEMS_INLINE_ROUTINE void _Thread_Wait_cancel(
} }
} }
/**
* @brief The initial thread wait flags value set by _Thread_Initialize().
*/
#define THREAD_WAIT_FLAGS_INITIAL 0x0U
/** /**
* @brief Mask to get the thread wait state flags. * @brief Mask to get the thread wait state flags.
*/ */
#define THREAD_WAIT_STATE_MASK 0xffU #define THREAD_WAIT_STATE_MASK 0xffU
/**
* @brief Indicates that the thread does not wait on something.
*
* In this wait state, the wait class is zero. This wait state is set
* initially by _Thread_Initialize() and after each wait operation once the
* thread is ready again.
*/
#define THREAD_WAIT_STATE_READY 0x0U
/** /**
* @brief Indicates that the thread begins with the blocking operation. * @brief Indicates that the thread begins with the blocking operation.
* *
@@ -2240,13 +2244,6 @@ RTEMS_INLINE_ROUTINE void _Thread_Wait_cancel(
*/ */
#define THREAD_WAIT_STATE_BLOCKED 0x2U #define THREAD_WAIT_STATE_BLOCKED 0x2U
/**
* @brief Indicates that a condition to end the thread wait occurred.
*
* This could be a timeout, a signal, an event or a resource availability.
*/
#define THREAD_WAIT_STATE_READY_AGAIN 0x4U
/** /**
* @brief Mask to get the thread wait class flags. * @brief Mask to get the thread wait class flags.
*/ */

View File

@@ -42,12 +42,10 @@ static bool _Event_Is_blocking_on_event(
) )
{ {
Thread_Wait_flags wait_flags; Thread_Wait_flags wait_flags;
Thread_Wait_flags wait_mask;
wait_flags = _Thread_Wait_flags_get( the_thread ); wait_flags = _Thread_Wait_flags_get( the_thread );
wait_mask = THREAD_WAIT_CLASS_MASK | THREAD_WAIT_STATE_READY_AGAIN;
return ( wait_flags & wait_mask ) == wait_class; return ( wait_flags & THREAD_WAIT_CLASS_MASK ) == wait_class;
} }
static bool _Event_Is_satisfied( static bool _Event_Is_satisfied(
@@ -88,16 +86,14 @@ rtems_status_code _Event_Surrender(
_Event_Is_blocking_on_event( the_thread, wait_class ) _Event_Is_blocking_on_event( the_thread, wait_class )
&& _Event_Is_satisfied( the_thread, pending_events, &seized_events ) && _Event_Is_satisfied( the_thread, pending_events, &seized_events )
) { ) {
Thread_Wait_flags ready_again;
bool success; bool success;
_Event_Satisfy( the_thread, event, pending_events, seized_events ); _Event_Satisfy( the_thread, event, pending_events, seized_events );
ready_again = wait_class | THREAD_WAIT_STATE_READY_AGAIN;
success = _Thread_Wait_flags_try_change_release( success = _Thread_Wait_flags_try_change_release(
the_thread, the_thread,
wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK, wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK,
ready_again THREAD_WAIT_STATE_READY
); );
if ( success ) { if ( success ) {
@@ -107,7 +103,7 @@ rtems_status_code _Event_Surrender(
_Thread_Wait_flags_get( the_thread ) _Thread_Wait_flags_get( the_thread )
== ( wait_class | THREAD_WAIT_STATE_BLOCKED ) == ( wait_class | THREAD_WAIT_STATE_BLOCKED )
); );
_Thread_Wait_flags_set( the_thread, ready_again ); _Thread_Wait_flags_set( the_thread, THREAD_WAIT_STATE_READY );
unblock = true; unblock = true;
} }
} else { } else {

View File

@@ -247,7 +247,7 @@ static rtems_status_code _Rate_monotonic_Block_while_active(
); );
if ( !success ) { if ( !success ) {
_Assert( _Assert(
_Thread_Wait_flags_get( executing ) == RATE_MONOTONIC_READY_AGAIN _Thread_Wait_flags_get( executing ) == THREAD_WAIT_STATE_READY
); );
_Thread_Unblock( executing ); _Thread_Unblock( executing );
} }

View File

@@ -74,13 +74,13 @@ void _Rate_monotonic_Timeout( Watchdog_Control *the_watchdog )
success = _Thread_Wait_flags_try_change_release( success = _Thread_Wait_flags_try_change_release(
owner, owner,
RATE_MONOTONIC_INTEND_TO_BLOCK, RATE_MONOTONIC_INTEND_TO_BLOCK,
RATE_MONOTONIC_READY_AGAIN THREAD_WAIT_STATE_READY
); );
if ( success ) { if ( success ) {
unblock = false; unblock = false;
} else { } else {
_Assert( _Thread_Wait_flags_get( owner ) == RATE_MONOTONIC_BLOCKED ); _Assert( _Thread_Wait_flags_get( owner ) == RATE_MONOTONIC_BLOCKED );
_Thread_Wait_flags_set( owner, RATE_MONOTONIC_READY_AGAIN ); _Thread_Wait_flags_set( owner, THREAD_WAIT_STATE_READY );
unblock = true; unblock = true;
} }

View File

@@ -299,7 +299,7 @@ static bool _Thread_Try_initialize(
the_thread->Wait.operations = &_Thread_queue_Operations_default; the_thread->Wait.operations = &_Thread_queue_Operations_default;
the_thread->Start.initial_priority = config->priority; the_thread->Start.initial_priority = config->priority;
RTEMS_STATIC_ASSERT( THREAD_WAIT_FLAGS_INITIAL == 0, Wait_flags ); RTEMS_STATIC_ASSERT( THREAD_WAIT_STATE_READY == 0, Wait_flags );
/* POSIX Keys */ /* POSIX Keys */
_RBTree_Initialize_empty( &the_thread->Keys.Key_value_pairs ); _RBTree_Initialize_empty( &the_thread->Keys.Key_value_pairs );

View File

@@ -41,9 +41,6 @@
#define THREAD_QUEUE_BLOCKED \ #define THREAD_QUEUE_BLOCKED \
(THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_BLOCKED) (THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_BLOCKED)
#define THREAD_QUEUE_READY_AGAIN \
(THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_READY_AGAIN)
#if defined(RTEMS_SMP) #if defined(RTEMS_SMP)
/* /*
* A global registry of active thread queue links is used to provide deadlock * A global registry of active thread queue links is used to provide deadlock
@@ -560,7 +557,7 @@ static void _Thread_queue_Force_ready_again( Thread_Control *the_thread )
* We must set the wait flags under protection of the current thread lock, * We must set the wait flags under protection of the current thread lock,
* otherwise a _Thread_Timeout() running on another processor may interfere. * otherwise a _Thread_Timeout() running on another processor may interfere.
*/ */
_Thread_Wait_flags_set( the_thread, THREAD_QUEUE_READY_AGAIN ); _Thread_Wait_flags_set( the_thread, THREAD_WAIT_STATE_READY );
_Thread_Wait_restore_default( the_thread ); _Thread_Wait_restore_default( the_thread );
} }
@@ -576,13 +573,13 @@ static bool _Thread_queue_Make_ready_again( Thread_Control *the_thread )
success = _Thread_Wait_flags_try_change_release( success = _Thread_Wait_flags_try_change_release(
the_thread, the_thread,
THREAD_QUEUE_INTEND_TO_BLOCK, THREAD_QUEUE_INTEND_TO_BLOCK,
THREAD_QUEUE_READY_AGAIN THREAD_WAIT_STATE_READY
); );
if ( success ) { if ( success ) {
unblock = false; unblock = false;
} else { } else {
_Assert( _Thread_Wait_flags_get( the_thread ) == THREAD_QUEUE_BLOCKED ); _Assert( _Thread_Wait_flags_get( the_thread ) == THREAD_QUEUE_BLOCKED );
_Thread_Wait_flags_set( the_thread, THREAD_QUEUE_READY_AGAIN ); _Thread_Wait_flags_set( the_thread, THREAD_WAIT_STATE_READY );
unblock = true; unblock = true;
} }

View File

@@ -35,9 +35,8 @@ void _Thread_Continue( Thread_Control *the_thread, Status_Control status )
wait_flags = _Thread_Wait_flags_get( the_thread ); wait_flags = _Thread_Wait_flags_get( the_thread );
if ( ( wait_flags & THREAD_WAIT_STATE_READY_AGAIN ) == 0 ) { if ( wait_flags != THREAD_WAIT_STATE_READY ) {
Thread_Wait_flags wait_class; Thread_Wait_flags wait_class;
Thread_Wait_flags ready_again;
bool success; bool success;
_Thread_Wait_cancel( the_thread, &queue_context ); _Thread_Wait_cancel( the_thread, &queue_context );
@@ -45,11 +44,10 @@ void _Thread_Continue( Thread_Control *the_thread, Status_Control status )
the_thread->Wait.return_code = status; the_thread->Wait.return_code = status;
wait_class = wait_flags & THREAD_WAIT_CLASS_MASK; wait_class = wait_flags & THREAD_WAIT_CLASS_MASK;
ready_again = wait_class | THREAD_WAIT_STATE_READY_AGAIN;
success = _Thread_Wait_flags_try_change_release( success = _Thread_Wait_flags_try_change_release(
the_thread, the_thread,
wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK, wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK,
ready_again THREAD_WAIT_STATE_READY
); );
if ( success ) { if ( success ) {
@@ -59,7 +57,7 @@ void _Thread_Continue( Thread_Control *the_thread, Status_Control status )
_Thread_Wait_flags_get( the_thread ) _Thread_Wait_flags_get( the_thread )
== ( wait_class | THREAD_WAIT_STATE_BLOCKED ) == ( wait_class | THREAD_WAIT_STATE_BLOCKED )
); );
_Thread_Wait_flags_set( the_thread, ready_again ); _Thread_Wait_flags_set( the_thread, THREAD_WAIT_STATE_READY );
unblock = true; unblock = true;
} }
} else { } else {

View File

@@ -78,7 +78,7 @@ static T_interrupt_test_state interrupt( void *arg )
T_quiet_eq_int( previous_period_state, RATE_MONOTONIC_ACTIVE ); T_quiet_eq_int( previous_period_state, RATE_MONOTONIC_ACTIVE );
T_quiet_eq_int( getState( ctx ), RATE_MONOTONIC_ACTIVE ); T_quiet_eq_int( getState( ctx ), RATE_MONOTONIC_ACTIVE );
state = T_INTERRUPT_TEST_DONE; state = T_INTERRUPT_TEST_DONE;
} else if ( flags == THREAD_WAIT_FLAGS_INITIAL ) { } else if ( flags == THREAD_WAIT_STATE_READY ) {
T_quiet_true( T_quiet_true(
previous_period_state == RATE_MONOTONIC_ACTIVE previous_period_state == RATE_MONOTONIC_ACTIVE
|| previous_period_state == RATE_MONOTONIC_EXPIRED || previous_period_state == RATE_MONOTONIC_EXPIRED
@@ -100,8 +100,6 @@ static void prepare( void *arg )
{ {
test_context *ctx; test_context *ctx;
rtems_status_code sc; rtems_status_code sc;
ISR_Level level;
bool success;
ctx = arg; ctx = arg;
@@ -119,15 +117,6 @@ static void prepare( void *arg )
*/ */
sc = rtems_rate_monotonic_period( ctx->period, 1 ); sc = rtems_rate_monotonic_period( ctx->period, 1 );
} while ( sc != RTEMS_SUCCESSFUL ); } while ( sc != RTEMS_SUCCESSFUL );
_ISR_Local_disable( level );
success = _Thread_Wait_flags_try_change_release(
ctx->thread,
RATE_MONOTONIC_READY_AGAIN,
THREAD_WAIT_FLAGS_INITIAL
);
_ISR_Local_enable( level );
T_quiet_true( success );
} }
static void action( void *arg ) static void action( void *arg )

View File

@@ -32,7 +32,7 @@ static bool is_interrupt_timeout( test_context *ctx )
{ {
Thread_Wait_flags flags = _Thread_Wait_flags_get( ctx->thread ); Thread_Wait_flags flags = _Thread_Wait_flags_get( ctx->thread );
return flags == ( THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_READY_AGAIN ); return flags == THREAD_WAIT_STATE_READY;
} }
static T_interrupt_test_state interrupt( void *arg ) static T_interrupt_test_state interrupt( void *arg )

View File

@@ -92,8 +92,7 @@ static T_interrupt_test_state any_satisfy_before_timeout_interrupt(void *arg)
if (state == T_INTERRUPT_TEST_DONE) { if (state == T_INTERRUPT_TEST_DONE) {
rtems_test_assert( rtems_test_assert(
_Thread_Wait_flags_get(thread) _Thread_Wait_flags_get(thread) == THREAD_WAIT_STATE_READY
== (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_READY_AGAIN)
); );
} }
@@ -184,8 +183,7 @@ static T_interrupt_test_state all_satisfy_before_timeout_interrupt(void *arg)
if (state == T_INTERRUPT_TEST_DONE) { if (state == T_INTERRUPT_TEST_DONE) {
rtems_test_assert( rtems_test_assert(
_Thread_Wait_flags_get(thread) _Thread_Wait_flags_get(thread) == THREAD_WAIT_STATE_READY
== (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_READY_AGAIN)
); );
} }
@@ -261,8 +259,7 @@ static T_interrupt_test_state timeout_before_satisfied_interrupt(void *arg)
if (state == T_INTERRUPT_TEST_DONE) { if (state == T_INTERRUPT_TEST_DONE) {
rtems_test_assert( rtems_test_assert(
_Thread_Wait_flags_get(thread) _Thread_Wait_flags_get(thread) == THREAD_WAIT_STATE_READY
== (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_READY_AGAIN)
); );
} }

View File

@@ -56,7 +56,7 @@ static T_interrupt_test_state release_semaphore(void *arg)
rtems_test_assert( rtems_test_assert(
_Thread_Wait_flags_get(ctx->main_task_control) _Thread_Wait_flags_get(ctx->main_task_control)
== (THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_READY_AGAIN) == THREAD_WAIT_STATE_READY
); );
sem = &ctx->semaphore_control->Core_control.Semaphore; sem = &ctx->semaphore_control->Core_control.Semaphore;
rtems_test_assert(sem->count == 0); rtems_test_assert(sem->count == 0);