diff options
Diffstat (limited to 'cpukit/score/src')
-rw-r--r-- | cpukit/score/src/thread.c | 43 | ||||
-rw-r--r-- | cpukit/score/src/threadinitialize.c | 24 | ||||
-rw-r--r-- | cpukit/score/src/threadq.c | 5 | ||||
-rw-r--r-- | cpukit/score/src/threadqops.c | 147 | ||||
-rw-r--r-- | cpukit/score/src/threadrestart.c | 13 |
5 files changed, 196 insertions, 36 deletions
diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c index ef9788ca41..e1d6d5c231 100644 --- a/cpukit/score/src/thread.c +++ b/cpukit/score/src/thread.c @@ -20,6 +20,7 @@ #include <rtems/score/threadimpl.h> #include <rtems/score/interr.h> +#include <rtems/score/wkspace.h> #define THREAD_OFFSET_ASSERT( field ) \ RTEMS_STATIC_ASSERT( \ @@ -40,6 +41,42 @@ THREAD_OFFSET_ASSERT( Timer ); THREAD_OFFSET_ASSERT( receive_packet ); #endif +void _Thread_Initialize_information( + Thread_Information *information, + Objects_APIs the_api, + uint16_t the_class, + uint32_t maximum, + bool is_string, + uint32_t maximum_name_length +#if defined(RTEMS_MULTIPROCESSING) + , + bool supports_global +#endif +) +{ + _Objects_Initialize_information( + &information->Objects, + the_api, + the_class, + maximum, + _Thread_Control_size, + is_string, + maximum_name_length + #if defined(RTEMS_MULTIPROCESSING) + , + supports_global, + NULL + #endif + ); + + _Freechain_Initialize( + &information->Free_thread_queue_heads, + _Workspace_Allocate_or_fatal_error, + _Objects_Maximum_per_allocation( maximum ), + sizeof( Thread_queue_Heads ) + ); +} + void _Thread_Handler_initialization(void) { rtems_stack_allocate_init_hook stack_allocate_init_hook = @@ -69,18 +106,16 @@ void _Thread_Handler_initialization(void) * per CPU in an SMP system. In addition, if this is a loosely * coupled multiprocessing system, account for the MPCI Server Thread. */ - _Objects_Initialize_information( + _Thread_Initialize_information( &_Thread_Internal_information, OBJECTS_INTERNAL_API, OBJECTS_INTERNAL_THREADS, _Thread_Get_maximum_internal_threads(), - _Thread_Control_size, /* size of this object's control block */ false, /* true if names for this object are strings */ 8 /* maximum length of each object's name */ #if defined(RTEMS_MULTIPROCESSING) , - false, /* true if this is a global object class */ - NULL /* Proxy extraction support callout */ + false /* true if this is a global object class */ #endif ); diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c index c6985f013b..9019e1fd30 100644 --- a/cpukit/score/src/threadinitialize.c +++ b/cpukit/score/src/threadinitialize.c @@ -30,7 +30,7 @@ #include <rtems/config.h> bool _Thread_Initialize( - Objects_Information *information, + Thread_Information *information, Thread_Control *the_thread, const Scheduler_Control *scheduler, void *stack_area, @@ -76,6 +76,7 @@ bool _Thread_Initialize( #endif the_thread->Start.tls_area = NULL; + the_thread->Wait.spare_heads = NULL; /* * Allocate and Initialize the stack for this thread. @@ -135,6 +136,20 @@ bool _Thread_Initialize( #endif /* + * Get thread queue heads + */ + the_thread->Wait.spare_heads = _Freechain_Get( + &information->Free_thread_queue_heads, + _Workspace_Allocate, + _Objects_Extend_size( &information->Objects ), + sizeof( *the_thread->Wait.spare_heads ) + ); + if ( the_thread->Wait.spare_heads == NULL ) { + goto failed; + } + _Chain_Initialize_empty( &the_thread->Wait.spare_heads->Free_chain ); + + /* * Initialize the thread timer */ _Watchdog_Preinitialize( &the_thread->Timer ); @@ -239,7 +254,7 @@ bool _Thread_Initialize( /* * Open the object */ - _Objects_Open( information, &the_thread->Object, name ); + _Objects_Open( &information->Objects, &the_thread->Object, name ); /* * We assume the Allocator Mutex is locked and dispatching is @@ -260,6 +275,11 @@ failed: _Workspace_Free( the_thread->Start.tls_area ); + _Freechain_Put( + &information->Free_thread_queue_heads, + the_thread->Wait.spare_heads + ); + #if ( CPU_HARDWARE_FP == TRUE ) || ( CPU_SOFTWARE_FP == TRUE ) _Workspace_Free( fp_area ); #endif diff --git a/cpukit/score/src/threadq.c b/cpukit/score/src/threadq.c index fc5060119b..27d4d5860e 100644 --- a/cpukit/score/src/threadq.c +++ b/cpukit/score/src/threadq.c @@ -50,8 +50,6 @@ void _Thread_queue_Initialize( { const Thread_queue_Operations *operations; - _ISR_lock_Initialize( &the_thread_queue->Queue.Lock, "Thread Queue" ); - if ( the_discipline == THREAD_QUEUE_DISCIPLINE_PRIORITY ) { operations = &_Thread_queue_Operations_priority; } else { @@ -60,5 +58,6 @@ void _Thread_queue_Initialize( } the_thread_queue->operations = operations; - ( *operations->initialize )( &the_thread_queue->Queue ); + + _Thread_queue_Queue_initialize( &the_thread_queue->Queue ); } diff --git a/cpukit/score/src/threadqops.c b/cpukit/score/src/threadqops.c index e0be4918b6..d19067fab1 100644 --- a/cpukit/score/src/threadqops.c +++ b/cpukit/score/src/threadqops.c @@ -17,6 +17,7 @@ #endif #include <rtems/score/threadimpl.h> +#include <rtems/score/assert.h> #include <rtems/score/chainimpl.h> #include <rtems/score/rbtreeimpl.h> @@ -37,37 +38,110 @@ static void _Thread_queue_Do_nothing_extract( /* Do nothing */ } -static void _Thread_queue_FIFO_initialize( - Thread_queue_Queue *queue +static void _Thread_queue_Queue_enqueue( + Thread_queue_Queue *queue, + Thread_Control *the_thread, + void ( *initialize )( Thread_queue_Heads * ), + void ( *enqueue )( Thread_queue_Heads *, Thread_Control * ) ) { - _Chain_Initialize_empty( &queue->Heads.Fifo ); + Thread_queue_Heads *heads = queue->heads; + Thread_queue_Heads *spare_heads = the_thread->Wait.spare_heads; + + the_thread->Wait.spare_heads = NULL; + + if ( heads == NULL ) { + _Assert( spare_heads != NULL ); + _Assert( _Chain_Is_empty( &spare_heads->Free_chain ) ); + heads = spare_heads; + queue->heads = heads; + ( *initialize )( heads ); + } + + _Chain_Prepend_unprotected( &heads->Free_chain, &spare_heads->Free_node ); + + ( *enqueue )( heads, the_thread ); } -static void _Thread_queue_FIFO_enqueue( +static void _Thread_queue_Queue_extract( Thread_queue_Queue *queue, + Thread_Control *the_thread, + void ( *extract )( Thread_queue_Heads *, Thread_Control * ) +) +{ + Thread_queue_Heads *heads = queue->heads; + + _Assert( heads != NULL ); + + the_thread->Wait.spare_heads = RTEMS_CONTAINER_OF( + _Chain_Get_first_unprotected( &heads->Free_chain ), + Thread_queue_Heads, + Free_node + ); + + if ( _Chain_Is_empty( &heads->Free_chain ) ) { + queue->heads = NULL; + } + + ( *extract )( heads, the_thread ); +} + +static void _Thread_queue_FIFO_do_initialize( + Thread_queue_Heads *heads +) +{ + _Chain_Initialize_empty( &heads->Heads.Fifo ); +} + +static void _Thread_queue_FIFO_do_enqueue( + Thread_queue_Heads *heads, Thread_Control *the_thread ) { _Chain_Append_unprotected( - &queue->Heads.Fifo, + &heads->Heads.Fifo, &the_thread->Wait.Node.Chain ); } +static void _Thread_queue_FIFO_do_extract( + Thread_queue_Heads *heads, + Thread_Control *the_thread +) +{ + _Chain_Extract_unprotected( &the_thread->Wait.Node.Chain ); +} + +static void _Thread_queue_FIFO_enqueue( + Thread_queue_Queue *queue, + Thread_Control *the_thread +) +{ + _Thread_queue_Queue_enqueue( + queue, + the_thread, + _Thread_queue_FIFO_do_initialize, + _Thread_queue_FIFO_do_enqueue + ); +} + static void _Thread_queue_FIFO_extract( Thread_queue_Queue *queue, Thread_Control *the_thread ) { - _Chain_Extract_unprotected( &the_thread->Wait.Node.Chain ); + _Thread_queue_Queue_extract( + queue, + the_thread, + _Thread_queue_FIFO_do_extract + ); } static Thread_Control *_Thread_queue_FIFO_first( - Thread_queue_Queue *queue + Thread_queue_Heads *heads ) { - Chain_Control *fifo = &queue->Heads.Fifo; + Chain_Control *fifo = &heads->Heads.Fifo; return _Chain_Is_empty( fifo ) ? NULL : THREAD_CHAIN_NODE_TO_THREAD( _Chain_First( fifo ) ); @@ -79,56 +153,85 @@ static void _Thread_queue_Priority_priority_change( Thread_queue_Queue *queue ) { + Thread_queue_Heads *heads = queue->heads; + + _Assert( heads != NULL ); + _RBTree_Extract( - &queue->Heads.Priority, + &heads->Heads.Priority, &the_thread->Wait.Node.RBTree ); _RBTree_Insert( - &queue->Heads.Priority, + &heads->Heads.Priority, &the_thread->Wait.Node.RBTree, _Thread_queue_Compare_priority, false ); } -static void _Thread_queue_Priority_initialize( - Thread_queue_Queue *queue +static void _Thread_queue_Priority_do_initialize( + Thread_queue_Heads *heads ) { - _RBTree_Initialize_empty( &queue->Heads.Priority ); + _RBTree_Initialize_empty( &heads->Heads.Priority ); } -static void _Thread_queue_Priority_enqueue( - Thread_queue_Queue *queue, +static void _Thread_queue_Priority_do_enqueue( + Thread_queue_Heads *heads, Thread_Control *the_thread ) { _RBTree_Insert( - &queue->Heads.Priority, + &heads->Heads.Priority, &the_thread->Wait.Node.RBTree, _Thread_queue_Compare_priority, false ); } -static void _Thread_queue_Priority_extract( - Thread_queue_Queue *queue, +static void _Thread_queue_Priority_do_extract( + Thread_queue_Heads *heads, Thread_Control *the_thread ) { _RBTree_Extract( - &queue->Heads.Priority, + &heads->Heads.Priority, &the_thread->Wait.Node.RBTree ); } +static void _Thread_queue_Priority_enqueue( + Thread_queue_Queue *queue, + Thread_Control *the_thread +) +{ + _Thread_queue_Queue_enqueue( + queue, + the_thread, + _Thread_queue_Priority_do_initialize, + _Thread_queue_Priority_do_enqueue + ); +} + +static void _Thread_queue_Priority_extract( + Thread_queue_Queue *queue, + Thread_Control *the_thread +) +{ + _Thread_queue_Queue_extract( + queue, + the_thread, + _Thread_queue_Priority_do_extract + ); +} + static Thread_Control *_Thread_queue_Priority_first( - Thread_queue_Queue *queue + Thread_queue_Heads *heads ) { RBTree_Node *first; - first = _RBTree_First( &queue->Heads.Priority, RBT_LEFT ); + first = _RBTree_First( &heads->Heads.Priority, RBT_LEFT ); return first != NULL ? THREAD_RBTREE_NODE_TO_THREAD( first ) : NULL; } @@ -145,7 +248,6 @@ const Thread_queue_Operations _Thread_queue_Operations_default = { const Thread_queue_Operations _Thread_queue_Operations_FIFO = { .priority_change = _Thread_queue_Do_nothing_priority_change, - .initialize = _Thread_queue_FIFO_initialize, .enqueue = _Thread_queue_FIFO_enqueue, .extract = _Thread_queue_FIFO_extract, .first = _Thread_queue_FIFO_first @@ -153,7 +255,6 @@ const Thread_queue_Operations _Thread_queue_Operations_FIFO = { const Thread_queue_Operations _Thread_queue_Operations_priority = { .priority_change = _Thread_queue_Priority_priority_change, - .initialize = _Thread_queue_Priority_initialize, .enqueue = _Thread_queue_Priority_enqueue, .extract = _Thread_queue_Priority_extract, .first = _Thread_queue_Priority_first diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c index b98b6388f8..abd809de70 100644 --- a/cpukit/score/src/threadrestart.c +++ b/cpukit/score/src/threadrestart.c @@ -93,6 +93,9 @@ static void _Thread_Make_zombie( Thread_Control *the_thread ) static void _Thread_Free( Thread_Control *the_thread ) { + Thread_Information *information = (Thread_Information *) + _Objects_Get_information_id( the_thread->Object.id ); + _User_extensions_Thread_delete( the_thread ); /* @@ -112,6 +115,11 @@ static void _Thread_Free( Thread_Control *the_thread ) _Workspace_Free( the_thread->Start.fp_context ); #endif + _Freechain_Put( + &information->Free_thread_queue_heads, + the_thread->Wait.spare_heads + ); + /* * Free the rest of the memory associated with this task * and set the associated pointers to NULL for safety. @@ -124,10 +132,7 @@ static void _Thread_Free( Thread_Control *the_thread ) _ISR_lock_Destroy( &the_thread->Lock.Default ); #endif - _Objects_Free( - _Objects_Get_information_id( the_thread->Object.id ), - &the_thread->Object - ); + _Objects_Free( &information->Objects, &the_thread->Object ); } static void _Thread_Wait_for_execution_stop( Thread_Control *the_thread ) |