diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-04-22 11:15:46 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2015-05-19 12:00:45 +0200 |
commit | 383cf42217d05a9cf19c6d081d50f92b2262a308 (patch) | |
tree | 0ee3fb9e007b2028a357a14056ed4e337886313b /cpukit/score/src | |
parent | score: Add Thread_queue_Operations (diff) | |
download | rtems-383cf42217d05a9cf19c6d081d50f92b2262a308.tar.bz2 |
score: More thread queue operations
Move thread queue discipline specific operations into
Thread_queue_Operations. Use a separate node in the thread control
block for the thread queue to make it independent of the scheduler data
structures.
Update #2273.
Diffstat (limited to 'cpukit/score/src')
-rw-r--r-- | cpukit/score/src/thread.c | 1 | ||||
-rw-r--r-- | cpukit/score/src/threadq.c | 15 | ||||
-rw-r--r-- | cpukit/score/src/threadqenqueue.c | 58 | ||||
-rw-r--r-- | cpukit/score/src/threadqfirst.c | 19 | ||||
-rw-r--r-- | cpukit/score/src/threadqops.c | 143 | ||||
-rw-r--r-- | cpukit/score/src/threadtimeout.c | 6 |
6 files changed, 160 insertions, 82 deletions
diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c index f4c53079d5..8a34ced684 100644 --- a/cpukit/score/src/thread.c +++ b/cpukit/score/src/thread.c @@ -28,7 +28,6 @@ ) THREAD_OFFSET_ASSERT( Object ); -THREAD_OFFSET_ASSERT( RBNode ); THREAD_OFFSET_ASSERT( current_state ); THREAD_OFFSET_ASSERT( current_priority ); THREAD_OFFSET_ASSERT( real_priority ); diff --git a/cpukit/score/src/threadq.c b/cpukit/score/src/threadq.c index 47c294e968..61832c19a2 100644 --- a/cpukit/score/src/threadq.c +++ b/cpukit/score/src/threadq.c @@ -19,9 +19,7 @@ #endif #include <rtems/score/threadqimpl.h> -#include <rtems/score/chainimpl.h> #include <rtems/score/rbtreeimpl.h> -#include <rtems/score/scheduler.h> #include <rtems/score/threadimpl.h> RBTree_Compare_result _Thread_queue_Compare_priority( @@ -51,15 +49,20 @@ void _Thread_queue_Initialize( uint32_t timeout_status ) { - the_thread_queue->discipline = the_discipline; + const Thread_queue_Operations *operations; + the_thread_queue->timeout_status = timeout_status; the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED; _ISR_lock_Initialize( &the_thread_queue->Lock, "Thread Queue" ); if ( the_discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY ) { - _RBTree_Initialize_empty( &the_thread_queue->Queues.Priority ); - } else { /* must be THREAD_QUEUE_DISCIPLINE_FIFO */ - _Chain_Initialize_empty( &the_thread_queue->Queues.Fifo ); + operations = &_Thread_queue_Operations_priority; + } else { + _Assert( the_discipline == THREAD_QUEUE_DISCIPLINE_FIFO ); + operations = &_Thread_queue_Operations_FIFO; } + + the_thread_queue->operations = operations; + ( *operations->initialize )( the_thread_queue ); } diff --git a/cpukit/score/src/threadqenqueue.c b/cpukit/score/src/threadqenqueue.c index 6cc731e282..be08ffcbf1 100644 --- a/cpukit/score/src/threadqenqueue.c +++ b/cpukit/score/src/threadqenqueue.c @@ -20,7 +20,6 @@ #include <rtems/score/threadqimpl.h> #include <rtems/score/assert.h> -#include <rtems/score/rbtreeimpl.h> #include <rtems/score/threadimpl.h> #include <rtems/score/watchdogimpl.h> @@ -47,6 +46,7 @@ static void _Thread_blocking_operation_Finalize( * The thread is not waiting on anything after this completes. */ _Thread_Wait_set_queue( the_thread, NULL ); + _Thread_Wait_restore_default_operations( the_thread ); _Thread_Lock_restore_default( the_thread ); @@ -127,28 +127,14 @@ void _Thread_queue_Enqueue_critical( the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED; if ( sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) { - /* - * Invoke the discipline specific enqueue method. - */ - if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_FIFO ) { - _Chain_Append_unprotected( - &the_thread_queue->Queues.Fifo, - &the_thread->Object.Node - ); - } else { /* must be THREAD_QUEUE_DISCIPLINE_PRIORITY */ - _Thread_Wait_set_operations( - the_thread, - &_Thread_queue_Operations_priority - ); - _RBTree_Insert( - &the_thread_queue->Queues.Priority, - &the_thread->RBNode, - _Thread_queue_Compare_priority, - false - ); - } + const Thread_queue_Operations *operations; the_thread_queue->sync_state = THREAD_BLOCKING_OPERATION_SYNCHRONIZED; + + operations = the_thread_queue->operations; + _Thread_Wait_set_operations( the_thread, operations ); + ( *operations->enqueue )( the_thread_queue, the_thread ); + _Thread_queue_Release( the_thread_queue, lock_context ); } else { /* Cancel a blocking operation due to ISR */ @@ -181,15 +167,7 @@ void _Thread_queue_Extract_with_return_code( _SMP_Assert( lock == &the_thread_queue->Lock ); - if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_FIFO ) { - _Chain_Extract_unprotected( &the_thread->Object.Node ); - } else { /* must be THREAD_QUEUE_DISCIPLINE_PRIORITY */ - _RBTree_Extract( - &the_thread->Wait.queue->Queues.Priority, - &the_thread->RBNode - ); - _Thread_Wait_restore_default_operations( the_thread ); - } + ( *the_thread_queue->operations->extract )( the_thread_queue, the_thread ); the_thread->Wait.return_code = return_code; @@ -217,27 +195,9 @@ Thread_Control *_Thread_queue_Dequeue( ISR_lock_Context lock_context; Thread_blocking_operation_States sync_state; - the_thread = NULL; _Thread_queue_Acquire( the_thread_queue, &lock_context ); - /* - * Invoke the discipline specific dequeue method. - */ - if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_FIFO ) { - if ( !_Chain_Is_empty( &the_thread_queue->Queues.Fifo ) ) { - the_thread = (Thread_Control *) - _Chain_Get_first_unprotected( &the_thread_queue->Queues.Fifo ); - } - } else { /* must be THREAD_QUEUE_DISCIPLINE_PRIORITY */ - RBTree_Node *first; - - first = _RBTree_Get( &the_thread_queue->Queues.Priority, RBT_LEFT ); - if ( first ) { - the_thread = THREAD_RBTREE_NODE_TO_THREAD( first ); - _Thread_Wait_restore_default_operations( the_thread ); - } - } - + the_thread = ( *the_thread_queue->operations->dequeue )( the_thread_queue ); if ( the_thread == NULL ) { /* * We did not find a thread to unblock in the queue. Maybe the executing diff --git a/cpukit/score/src/threadqfirst.c b/cpukit/score/src/threadqfirst.c index f43b9abbd0..553b28bf62 100644 --- a/cpukit/score/src/threadqfirst.c +++ b/cpukit/score/src/threadqfirst.c @@ -19,29 +19,12 @@ #endif #include <rtems/score/threadqimpl.h> -#include <rtems/score/chainimpl.h> -#include <rtems/score/threadimpl.h> Thread_Control *_Thread_queue_First_locked( Thread_queue_Control *the_thread_queue ) { - Thread_Control *thread; - - thread = NULL; - - if ( the_thread_queue->discipline == THREAD_QUEUE_DISCIPLINE_FIFO ) { - if ( !_Chain_Is_empty( &the_thread_queue->Queues.Fifo ) ) - thread = (Thread_Control *) _Chain_First(&the_thread_queue->Queues.Fifo); - } else { /* must be THREAD_QUEUE_DISCIPLINE_PRIORITY */ - RBTree_Node *first; - - first = _RBTree_First( &the_thread_queue->Queues.Priority, RBT_LEFT ); - if ( first ) - thread = THREAD_RBTREE_NODE_TO_THREAD( first ); - } - - return thread; + return ( *the_thread_queue->operations->first )( the_thread_queue ); } Thread_Control *_Thread_queue_First( diff --git a/cpukit/score/src/threadqops.c b/cpukit/score/src/threadqops.c index 561480130a..9958ed667c 100644 --- a/cpukit/score/src/threadqops.c +++ b/cpukit/score/src/threadqops.c @@ -17,40 +17,167 @@ #endif #include <rtems/score/threadimpl.h> +#include <rtems/score/chainimpl.h> #include <rtems/score/rbtreeimpl.h> static void _Thread_queue_Do_nothing_priority_change( Thread_Control *the_thread, Priority_Control new_priority, - Thread_queue_Control *queue + Thread_queue_Control *the_thread_queue ) { /* Do nothing */ } +static void _Thread_queue_Do_nothing_extract( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread +) +{ + /* Do nothing */ +} + +static void _Thread_queue_FIFO_initialize( + Thread_queue_Control *the_thread_queue +) +{ + _Chain_Initialize_empty( &the_thread_queue->Queues.Fifo ); +} + +static void _Thread_queue_FIFO_enqueue( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread +) +{ + _Chain_Append_unprotected( + &the_thread_queue->Queues.Fifo, + &the_thread->Wait.Node.Chain + ); +} + +static Thread_Control *_Thread_queue_FIFO_dequeue( + Thread_queue_Control *the_thread_queue +) +{ + Chain_Control *fifo = &the_thread_queue->Queues.Fifo; + + return _Chain_Is_empty( fifo ) ? + NULL : THREAD_CHAIN_NODE_TO_THREAD( _Chain_Get_first_unprotected( fifo ) ); +} + +static void _Thread_queue_FIFO_extract( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread +) +{ + _Chain_Extract_unprotected( &the_thread->Wait.Node.Chain ); +} + +static Thread_Control *_Thread_queue_FIFO_first( + Thread_queue_Control *the_thread_queue +) +{ + Chain_Control *fifo = &the_thread_queue->Queues.Fifo; + + return _Chain_Is_empty( fifo ) ? + NULL : THREAD_CHAIN_NODE_TO_THREAD( _Chain_First( fifo ) ); +} + static void _Thread_queue_Priority_priority_change( Thread_Control *the_thread, Priority_Control new_priority, - Thread_queue_Control *queue + Thread_queue_Control *the_thread_queue +) +{ + _RBTree_Extract( + &the_thread_queue->Queues.Priority, + &the_thread->Wait.Node.RBTree + ); + _RBTree_Insert( + &the_thread_queue->Queues.Priority, + &the_thread->Wait.Node.RBTree, + _Thread_queue_Compare_priority, + false + ); +} + +static void _Thread_queue_Priority_initialize( + Thread_queue_Control *the_thread_queue +) +{ + _RBTree_Initialize_empty( &the_thread_queue->Queues.Priority ); +} + +static void _Thread_queue_Priority_enqueue( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread ) { - _RBTree_Extract( &queue->Queues.Priority, &the_thread->RBNode ); _RBTree_Insert( - &queue->Queues.Priority, - &the_thread->RBNode, + &the_thread_queue->Queues.Priority, + &the_thread->Wait.Node.RBTree, _Thread_queue_Compare_priority, false ); } +static Thread_Control *_Thread_queue_Priority_dequeue( + Thread_queue_Control *the_thread_queue +) +{ + RBTree_Node *first; + + first = _RBTree_Get( &the_thread_queue->Queues.Priority, RBT_LEFT ); + + return first != NULL ? THREAD_RBTREE_NODE_TO_THREAD( first ) : NULL; +} + +static void _Thread_queue_Priority_extract( + Thread_queue_Control *the_thread_queue, + Thread_Control *the_thread +) +{ + _RBTree_Extract( + &the_thread_queue->Queues.Priority, + &the_thread->Wait.Node.RBTree + ); +} + +static Thread_Control *_Thread_queue_Priority_first( + Thread_queue_Control *the_thread_queue +) +{ + RBTree_Node *first; + + first = _RBTree_First( &the_thread_queue->Queues.Priority, RBT_LEFT ); + + return first != NULL ? THREAD_RBTREE_NODE_TO_THREAD( first ) : NULL; +} + const Thread_queue_Operations _Thread_queue_Operations_default = { - .priority_change = _Thread_queue_Do_nothing_priority_change + .priority_change = _Thread_queue_Do_nothing_priority_change, + .extract = _Thread_queue_Do_nothing_extract + /* + * The default operations are only used in _Thread_Change_priority() and + * _Thread_Timeout() and don't have a thread queue associated with them, so + * the enqueue and first operations are superfluous. + */ }; const Thread_queue_Operations _Thread_queue_Operations_FIFO = { - .priority_change = _Thread_queue_Do_nothing_priority_change + .priority_change = _Thread_queue_Do_nothing_priority_change, + .initialize = _Thread_queue_FIFO_initialize, + .enqueue = _Thread_queue_FIFO_enqueue, + .dequeue = _Thread_queue_FIFO_dequeue, + .extract = _Thread_queue_FIFO_extract, + .first = _Thread_queue_FIFO_first }; const Thread_queue_Operations _Thread_queue_Operations_priority = { - .priority_change = _Thread_queue_Priority_priority_change + .priority_change = _Thread_queue_Priority_priority_change, + .initialize = _Thread_queue_Priority_initialize, + .enqueue = _Thread_queue_Priority_enqueue, + .dequeue = _Thread_queue_Priority_dequeue, + .extract = _Thread_queue_Priority_extract, + .first = _Thread_queue_Priority_first }; diff --git a/cpukit/score/src/threadtimeout.c b/cpukit/score/src/threadtimeout.c index b6ce2d7362..300beb5219 100644 --- a/cpukit/score/src/threadtimeout.c +++ b/cpukit/score/src/threadtimeout.c @@ -24,6 +24,12 @@ static void _Thread_Do_timeout( Thread_Control *the_thread ) { the_thread->Wait.return_code = the_thread->Wait.timeout_code; + ( *the_thread->Wait.operations->extract )( + the_thread->Wait.queue, + the_thread + ); + _Thread_Wait_set_queue( the_thread, NULL ); + _Thread_Wait_restore_default_operations( the_thread ); _Thread_Lock_restore_default( the_thread ); } |