[rtems commit] score: Move wait flag update to tq extract

Sebastian Huber sebh at rtems.org
Thu Jul 23 07:12:05 UTC 2015


Module:    rtems
Branch:    master
Commit:    e709aa8522788a45adc0adf22daac82c574fcae4
Changeset: http://git.rtems.org/rtems/commit/?id=e709aa8522788a45adc0adf22daac82c574fcae4

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Jul 13 13:49:35 2015 +0200

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.

---

 cpukit/score/include/rtems/score/threadqimpl.h | 13 ++++++++++-
 cpukit/score/src/coremutexsurrender.c          |  5 ++++-
 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 e1060e4..cf3aeed 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 e3f0d6f..d3f965d 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 5ed01b7..1d1581a 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 )



More information about the vc mailing list