From adbedd10cfe5259018b1682d903ab40f6005b3f0 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 15 Apr 2016 21:18:26 +0200 Subject: score: Introduce _Thread_queue_Flush_critical() Replace _Thread_queue_Flush() with _Thread_queue_Flush_critical() and add a filter function for customization of the thread queue flush operation. Update #2555. --- cpukit/score/src/threadqflush.c | 94 ++++++++++++++++++++++++++++------------- 1 file changed, 65 insertions(+), 29 deletions(-) (limited to 'cpukit/score/src/threadqflush.c') diff --git a/cpukit/score/src/threadqflush.c b/cpukit/score/src/threadqflush.c index c50831466d..0ce639eb68 100644 --- a/cpukit/score/src/threadqflush.c +++ b/cpukit/score/src/threadqflush.c @@ -18,46 +18,82 @@ #include "config.h" #endif -#include -#include +#include -void _Thread_queue_Do_flush( - Thread_queue_Control *the_thread_queue, +size_t _Thread_queue_Do_flush_critical( + Thread_queue_Queue *queue, const Thread_queue_Operations *operations, - uint32_t status + Thread_queue_Flush_filter filter, #if defined(RTEMS_MULTIPROCESSING) - , Thread_queue_MP_callout mp_callout, - Objects_Id mp_id + Objects_Id mp_id, #endif + ISR_lock_Context *lock_context ) { - ISR_lock_Context lock_context; - Thread_Control *the_thread; - - _Thread_queue_Acquire( the_thread_queue, &lock_context ); - - while ( - ( - the_thread = _Thread_queue_First_locked( - the_thread_queue, - operations - ) - ) - ) { - the_thread->Wait.return_code = status; - - _Thread_queue_Extract_critical( - &the_thread_queue->Queue, + size_t flushed; + Chain_Control unblock; + Chain_Node *node; + Chain_Node *tail; + + flushed = 0; + _Chain_Initialize_empty( &unblock ); + + while ( true ) { + Thread_queue_Heads *heads; + Thread_Control *first; + bool do_unblock; + + heads = queue->heads; + if ( heads == NULL ) { + break; + } + + first = ( *operations->first )( heads ); + first = ( *filter )( first, queue, lock_context ); + if ( first == NULL ) { + break; + } + + do_unblock = _Thread_queue_Extract_locked( + queue, operations, - the_thread, + first, mp_callout, - mp_id, - &lock_context + mp_id ); + if ( do_unblock ) { + _Chain_Append_unprotected( &unblock, &first->Wait.Node.Chain ); + } + + ++flushed; + } + + node = _Chain_First( &unblock ); + tail = _Chain_Tail( &unblock ); + + if ( node != tail ) { + Per_CPU_Control *cpu_self; + + cpu_self = _Thread_Dispatch_disable_critical( lock_context ); + _Thread_queue_Queue_release( queue, lock_context ); + + do { + Thread_Control *the_thread; + Chain_Node *next; + + next = _Chain_Next( node ); + the_thread = THREAD_CHAIN_NODE_TO_THREAD( node ); + _Thread_Timer_remove( the_thread ); + _Thread_Unblock( the_thread ); + + node = next; + } while ( node != tail ); - _Thread_queue_Acquire( the_thread_queue, &lock_context ); + _Thread_Dispatch_enable( cpu_self ); + } else { + _Thread_queue_Queue_release( queue, lock_context ); } - _Thread_queue_Release( the_thread_queue, &lock_context ); + return flushed; } -- cgit v1.2.3