[PATCH 06/10] score: Use _Thread_queue_Flush_critical() for cond

Sebastian Huber sebastian.huber at embedded-brains.de
Thu Apr 21 07:20:10 UTC 2016


---
 cpukit/score/src/condition.c | 108 ++++++++++++++++---------------------------
 1 file changed, 41 insertions(+), 67 deletions(-)

diff --git a/cpukit/score/src/condition.c b/cpukit/score/src/condition.c
index da3d133..ba255fc 100644
--- a/cpukit/score/src/condition.c
+++ b/cpukit/score/src/condition.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 embedded brains GmbH.  All rights reserved.
+ * Copyright (c) 2015, 2016 embedded brains GmbH.  All rights reserved.
  *
  *  embedded brains GmbH
  *  Dornierstr. 4
@@ -219,83 +219,57 @@ int _Condition_Wait_recursive_timed(
   return eno;
 }
 
-static int _Condition_Wake( struct _Condition_Control *_condition, int count )
+typedef struct {
+  ISR_lock_Context Base;
+  int              count;
+} Condition_Lock_context;
+
+static Thread_Control *_Condition_Flush_filter(
+  Thread_Control     *the_thread,
+  Thread_queue_Queue *queue,
+  ISR_lock_Context   *lock_context
+)
 {
-  Condition_Control  *condition;
-  ISR_lock_Context    lock_context;
-  Thread_queue_Heads *heads;
-  Chain_Control       unblock;
-  Chain_Node         *node;
-  Chain_Node         *tail;
-  int                 woken;
-
-  condition = _Condition_Get( _condition );
-  _ISR_lock_ISR_disable( &lock_context );
-  _Condition_Queue_acquire_critical( condition, &lock_context );
+  Condition_Lock_context *condition_lock_context;
 
-  /*
-   * In common uses cases of condition variables there are normally no threads
-   * on the queue, so check this condition early.
-   */
-  heads = condition->Queue.Queue.heads;
-  if ( __predict_true( heads == NULL ) ) {
-    _Condition_Queue_release( condition, &lock_context );
-
-    return 0;
-  }
+  condition_lock_context = (Condition_Lock_context *) lock_context;
 
-  woken = 0;
-  _Chain_Initialize_empty( &unblock );
-  while ( count > 0 && heads != NULL ) {
-    const Thread_queue_Operations *operations;
-    Thread_Control                *first;
-    bool                           do_unblock;
-
-    operations = CONDITION_TQ_OPERATIONS;
-    first = ( *operations->first )( heads );
-
-    do_unblock = _Thread_queue_Extract_locked(
-      &condition->Queue.Queue,
-      operations,
-      first,
-      NULL,
-      0
-    );
-    if (do_unblock) {
-      _Chain_Append_unprotected( &unblock, &first->Wait.Node.Chain );
-    }
-
-    ++woken;
-    --count;
-    heads = condition->Queue.Queue.heads;
+  if ( condition_lock_context->count <= 0 ) {
+    return NULL;
   }
 
-  node = _Chain_First( &unblock );
-  tail = _Chain_Tail( &unblock );
-  if ( node != tail ) {
-    Per_CPU_Control *cpu_self;
+  --condition_lock_context->count;
 
-    cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
-    _Condition_Queue_release( condition, &lock_context );
-
-    do {
-      Thread_Control *thread;
-      Chain_Node     *next;
+  return the_thread;
+}
 
-      next = _Chain_Next( node );
-      thread = THREAD_CHAIN_NODE_TO_THREAD( node );
-      _Thread_Timer_remove( thread );
-      _Thread_Unblock( thread );
+static void _Condition_Wake( struct _Condition_Control *_condition, int count )
+{
+  Condition_Control      *condition;
+  Condition_Lock_context  lock_context;
 
-      node = next;
-    } while ( node != tail );
+  condition = _Condition_Get( _condition );
+  _ISR_lock_ISR_disable( &lock_context.Base );
+  _Condition_Queue_acquire_critical( condition, &lock_context.Base );
 
-    _Thread_Dispatch_enable( cpu_self );
-  } else {
-    _Condition_Queue_release( condition, &lock_context );
+  /*
+   * In common uses cases of condition variables there are normally no threads
+   * on the queue, so check this condition early.
+   */
+  if ( __predict_true( _Thread_queue_Is_empty( &condition->Queue.Queue ) ) ) {
+    _Condition_Queue_release( condition, &lock_context.Base );
+    return;
   }
 
-  return woken;
+  lock_context.count = count;
+  _Thread_queue_Flush_critical(
+    &condition->Queue.Queue,
+    CONDITION_TQ_OPERATIONS,
+    _Condition_Flush_filter,
+    NULL,
+    0,
+    &lock_context.Base
+  );
 }
 
 void _Condition_Signal( struct _Condition_Control *_condition )
-- 
1.8.4.5




More information about the devel mailing list