diff options
Diffstat (limited to '')
-rw-r--r-- | cpukit/score/include/rtems/score/threadqimpl.h | 13 | ||||
-rw-r--r-- | cpukit/score/src/coremutexsurrender.c | 5 | ||||
-rw-r--r-- | cpukit/score/src/threadqenqueue.c | 31 |
3 files changed, 34 insertions, 15 deletions
diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h index e1060e4e82..cf3aeed053 100644 --- a/cpukit/score/include/rtems/score/threadqimpl.h +++ b/cpukit/score/include/rtems/score/threadqimpl.h @@ -214,8 +214,16 @@ RTEMS_INLINE_ROUTINE void _Thread_queue_Enqueue( * @param[in] queue The actual thread queue. * @param[in] operations The thread queue operations. * @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, const Thread_queue_Operations *operations, Thread_Control *the_thread @@ -229,11 +237,14 @@ void _Thread_queue_Extract_locked( * thread queue lock is released and an unblock is necessary. Thread * 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] the_thread The thread to extract. * @param[in] lock_context The lock context of the lock acquire. */ void _Thread_queue_Unblock_critical( + bool unblock, Thread_queue_Queue *queue, Thread_Control *the_thread, ISR_lock_Context *lock_context diff --git a/cpukit/score/src/coremutexsurrender.c b/cpukit/score/src/coremutexsurrender.c index e3f0d6f2e4..d3f965d55d 100644 --- a/cpukit/score/src/coremutexsurrender.c +++ b/cpukit/score/src/coremutexsurrender.c @@ -179,13 +179,15 @@ CORE_mutex_Status _CORE_mutex_Surrender( * transfer the mutex to that thread. */ 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 * thread lock. This is necessary to avoid a deadlock in the * _Thread_Change_priority() below due to a recursive thread queue lock * acquire. */ - _Thread_queue_Extract_locked( + unblock = _Thread_queue_Extract_locked( &the_mutex->Wait_queue.Queue, the_mutex->Wait_queue.operations, the_thread @@ -220,6 +222,7 @@ CORE_mutex_Status _CORE_mutex_Surrender( } _Thread_queue_Unblock_critical( + unblock, &the_mutex->Wait_queue.Queue, the_thread, lock_context diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c index 5ed01b7a95..1d1581a2fb 100644 --- a/cpukit/score/src/threadqenqueue.c +++ b/cpukit/score/src/threadqenqueue.c @@ -100,27 +100,20 @@ void _Thread_queue_Enqueue_critical( _Thread_Dispatch_enable( cpu_self ); } -void _Thread_queue_Extract_locked( +bool _Thread_queue_Extract_locked( Thread_queue_Queue *queue, const Thread_queue_Operations *operations, Thread_Control *the_thread ) { + bool success; + bool unblock; + ( *operations->extract )( queue, the_thread ); _Thread_Wait_set_queue( the_thread, NULL ); _Thread_Wait_restore_default_operations( 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( the_thread, @@ -135,6 +128,16 @@ void _Thread_queue_Unblock_critical( 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 ) { Per_CPU_Control *cpu_self; @@ -156,8 +159,10 @@ void _Thread_queue_Extract_critical( ISR_lock_Context *lock_context ) { - _Thread_queue_Extract_locked( queue, operations, the_thread ); - _Thread_queue_Unblock_critical( queue, the_thread, lock_context ); + bool unblock; + + 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 ) |