score: Move wait flag update to tq extract

This makes it possible to use _Thread_queue_Extract_locked() for barrier
operations which extract all threads on the queue in one critical
section.
This commit is contained in:
Sebastian Huber
2015-07-13 13:49:35 +02:00
parent d7665823b2
commit e709aa8522
3 changed files with 34 additions and 15 deletions

View File

@@ -214,8 +214,16 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Enqueue(
* @param[in] queue The actual thread queue. * @param[in] queue The actual thread queue.
* @param[in] operations The thread queue operations. * @param[in] operations The thread queue operations.
* @param[in] the_thread The thread to extract. * @param[in] the_thread The thread to extract.
*
* @return Returns the unblock indicator for _Thread_queue_Unblock_critical().
* True indicates, that this thread must be unblocked by the scheduler later in
* _Thread_queue_Unblock_critical(), and false otherwise. In case false is
* returned, then the thread queue enqueue procedure was interrupted. Thus it
* will unblock itself and the thread wait information is no longer accessible,
* since this thread may already block on another resource in an SMP
* configuration.
*/ */
void _Thread_queue_Extract_locked( bool _Thread_queue_Extract_locked(
Thread_queue_Queue *queue, Thread_queue_Queue *queue,
const Thread_queue_Operations *operations, const Thread_queue_Operations *operations,
Thread_Control *the_thread Thread_Control *the_thread
@@ -229,11 +237,14 @@ void _Thread_queue_Extract_locked(
* thread queue lock is released and an unblock is necessary. Thread * thread queue lock is released and an unblock is necessary. Thread
* dispatching is enabled once the sequence to unblock the thread is complete. * dispatching is enabled once the sequence to unblock the thread is complete.
* *
* @param[in] unblock The unblock indicator returned by
* _Thread_queue_Extract_locked().
* @param[in] queue The actual thread queue. * @param[in] queue The actual thread queue.
* @param[in] the_thread The thread to extract. * @param[in] the_thread The thread to extract.
* @param[in] lock_context The lock context of the lock acquire. * @param[in] lock_context The lock context of the lock acquire.
*/ */
void _Thread_queue_Unblock_critical( void _Thread_queue_Unblock_critical(
bool unblock,
Thread_queue_Queue *queue, Thread_queue_Queue *queue,
Thread_Control *the_thread, Thread_Control *the_thread,
ISR_lock_Context *lock_context ISR_lock_Context *lock_context

View File

@@ -179,13 +179,15 @@ CORE_mutex_Status _CORE_mutex_Surrender(
* transfer the mutex to that thread. * transfer the mutex to that thread.
*/ */
if ( ( the_thread = _Thread_queue_First_locked( &the_mutex->Wait_queue ) ) ) { if ( ( the_thread = _Thread_queue_First_locked( &the_mutex->Wait_queue ) ) ) {
bool unblock;
/* /*
* We must extract the thread now since this will restore its default * We must extract the thread now since this will restore its default
* thread lock. This is necessary to avoid a deadlock in the * thread lock. This is necessary to avoid a deadlock in the
* _Thread_Change_priority() below due to a recursive thread queue lock * _Thread_Change_priority() below due to a recursive thread queue lock
* acquire. * acquire.
*/ */
_Thread_queue_Extract_locked( unblock = _Thread_queue_Extract_locked(
&the_mutex->Wait_queue.Queue, &the_mutex->Wait_queue.Queue,
the_mutex->Wait_queue.operations, the_mutex->Wait_queue.operations,
the_thread the_thread
@@ -220,6 +222,7 @@ CORE_mutex_Status _CORE_mutex_Surrender(
} }
_Thread_queue_Unblock_critical( _Thread_queue_Unblock_critical(
unblock,
&the_mutex->Wait_queue.Queue, &the_mutex->Wait_queue.Queue,
the_thread, the_thread,
lock_context lock_context

View File

@@ -100,27 +100,20 @@ void _Thread_queue_Enqueue_critical(
_Thread_Dispatch_enable( cpu_self ); _Thread_Dispatch_enable( cpu_self );
} }
void _Thread_queue_Extract_locked( bool _Thread_queue_Extract_locked(
Thread_queue_Queue *queue, Thread_queue_Queue *queue,
const Thread_queue_Operations *operations, const Thread_queue_Operations *operations,
Thread_Control *the_thread Thread_Control *the_thread
) )
{ {
bool success;
bool unblock;
( *operations->extract )( queue, the_thread ); ( *operations->extract )( queue, the_thread );
_Thread_Wait_set_queue( the_thread, NULL ); _Thread_Wait_set_queue( the_thread, NULL );
_Thread_Wait_restore_default_operations( the_thread ); _Thread_Wait_restore_default_operations( the_thread );
_Thread_Lock_restore_default( the_thread ); _Thread_Lock_restore_default( the_thread );
}
void _Thread_queue_Unblock_critical(
Thread_queue_Queue *queue,
Thread_Control *the_thread,
ISR_lock_Context *lock_context
)
{
bool success;
bool unblock;
success = _Thread_Wait_flags_try_change_critical( success = _Thread_Wait_flags_try_change_critical(
the_thread, the_thread,
@@ -135,6 +128,16 @@ void _Thread_queue_Unblock_critical(
unblock = true; unblock = true;
} }
return unblock;
}
void _Thread_queue_Unblock_critical(
bool unblock,
Thread_queue_Queue *queue,
Thread_Control *the_thread,
ISR_lock_Context *lock_context
)
{
if ( unblock ) { if ( unblock ) {
Per_CPU_Control *cpu_self; Per_CPU_Control *cpu_self;
@@ -156,8 +159,10 @@ void _Thread_queue_Extract_critical(
ISR_lock_Context *lock_context ISR_lock_Context *lock_context
) )
{ {
_Thread_queue_Extract_locked( queue, operations, the_thread ); bool unblock;
_Thread_queue_Unblock_critical( queue, the_thread, lock_context );
unblock = _Thread_queue_Extract_locked( queue, operations, the_thread );
_Thread_queue_Unblock_critical( unblock, queue, the_thread, lock_context );
} }
void _Thread_queue_Extract( Thread_Control *the_thread ) void _Thread_queue_Extract( Thread_Control *the_thread )