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 \
( 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
* the inactive chain of free period control blocks.

View File

@@ -404,7 +404,7 @@ typedef union {
* The mutually exclusive wait state flags are
* - @ref THREAD_WAIT_STATE_INTEND_TO_BLOCK,
* - @ref THREAD_WAIT_STATE_BLOCKED, and
* - @ref THREAD_WAIT_STATE_READY_AGAIN.
* - @ref THREAD_WAIT_STATE_READY.
*/
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.
*/
#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.
*
@@ -2240,13 +2244,6 @@ RTEMS_INLINE_ROUTINE void _Thread_Wait_cancel(
*/
#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.
*/

View File

@@ -42,12 +42,10 @@ static bool _Event_Is_blocking_on_event(
)
{
Thread_Wait_flags wait_flags;
Thread_Wait_flags wait_mask;
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(
@@ -88,16 +86,14 @@ rtems_status_code _Event_Surrender(
_Event_Is_blocking_on_event( the_thread, wait_class )
&& _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 );
ready_again = wait_class | THREAD_WAIT_STATE_READY_AGAIN;
success = _Thread_Wait_flags_try_change_release(
the_thread,
wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK,
ready_again
THREAD_WAIT_STATE_READY
);
if ( success ) {
@@ -107,7 +103,7 @@ rtems_status_code _Event_Surrender(
_Thread_Wait_flags_get( the_thread )
== ( 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;
}
} else {

View File

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

View File

@@ -74,13 +74,13 @@ void _Rate_monotonic_Timeout( Watchdog_Control *the_watchdog )
success = _Thread_Wait_flags_try_change_release(
owner,
RATE_MONOTONIC_INTEND_TO_BLOCK,
RATE_MONOTONIC_READY_AGAIN
THREAD_WAIT_STATE_READY
);
if ( success ) {
unblock = false;
} else {
_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;
}

View File

@@ -299,7 +299,7 @@ static bool _Thread_Try_initialize(
the_thread->Wait.operations = &_Thread_queue_Operations_default;
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 */
_RBTree_Initialize_empty( &the_thread->Keys.Key_value_pairs );

View File

@@ -41,9 +41,6 @@
#define THREAD_QUEUE_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)
/*
* 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,
* 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 );
}
@@ -576,13 +573,13 @@ static bool _Thread_queue_Make_ready_again( Thread_Control *the_thread )
success = _Thread_Wait_flags_try_change_release(
the_thread,
THREAD_QUEUE_INTEND_TO_BLOCK,
THREAD_QUEUE_READY_AGAIN
THREAD_WAIT_STATE_READY
);
if ( success ) {
unblock = false;
} else {
_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;
}

View File

@@ -35,9 +35,8 @@ void _Thread_Continue( Thread_Control *the_thread, Status_Control status )
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 ready_again;
bool success;
_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;
wait_class = wait_flags & THREAD_WAIT_CLASS_MASK;
ready_again = wait_class | THREAD_WAIT_STATE_READY_AGAIN;
success = _Thread_Wait_flags_try_change_release(
the_thread,
wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK,
ready_again
THREAD_WAIT_STATE_READY
);
if ( success ) {
@@ -59,7 +57,7 @@ void _Thread_Continue( Thread_Control *the_thread, Status_Control status )
_Thread_Wait_flags_get( the_thread )
== ( 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;
}
} 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( getState( ctx ), RATE_MONOTONIC_ACTIVE );
state = T_INTERRUPT_TEST_DONE;
} else if ( flags == THREAD_WAIT_FLAGS_INITIAL ) {
} else if ( flags == THREAD_WAIT_STATE_READY ) {
T_quiet_true(
previous_period_state == RATE_MONOTONIC_ACTIVE
|| previous_period_state == RATE_MONOTONIC_EXPIRED
@@ -100,8 +100,6 @@ static void prepare( void *arg )
{
test_context *ctx;
rtems_status_code sc;
ISR_Level level;
bool success;
ctx = arg;
@@ -119,15 +117,6 @@ static void prepare( void *arg )
*/
sc = rtems_rate_monotonic_period( ctx->period, 1 );
} 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 )

View File

@@ -32,7 +32,7 @@ static bool is_interrupt_timeout( test_context *ctx )
{
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 )

View File

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

View File

@@ -56,7 +56,7 @@ static T_interrupt_test_state release_semaphore(void *arg)
rtems_test_assert(
_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;
rtems_test_assert(sem->count == 0);