diff options
25 files changed, 317 insertions, 128 deletions
diff --git a/cpukit/libcsupport/src/resource_snapshot.c b/cpukit/libcsupport/src/resource_snapshot.c index 6bba22671b..5475139535 100644 --- a/cpukit/libcsupport/src/resource_snapshot.c +++ b/cpukit/libcsupport/src/resource_snapshot.c @@ -63,7 +63,7 @@ static const Objects_Information *const objects_info_table[] = { &_Dual_ported_memory_Information, &_Region_Information, &_Semaphore_Information, - &_RTEMS_tasks_Information, + &_RTEMS_tasks_Information.Objects, &_Timer_Information #ifdef RTEMS_POSIX_API , @@ -75,7 +75,7 @@ static const Objects_Information *const objects_info_table[] = { &_POSIX_RWLock_Information, &_POSIX_Semaphore_Information, &_POSIX_Spinlock_Information, - &_POSIX_Threads_Information, + &_POSIX_Threads_Information.Objects, &_POSIX_Timer_Information #endif }; diff --git a/cpukit/libmisc/monitor/mon-object.c b/cpukit/libmisc/monitor/mon-object.c index 1e54c22cf9..72e9f1ee45 100644 --- a/cpukit/libmisc/monitor/mon-object.c +++ b/cpukit/libmisc/monitor/mon-object.c @@ -75,7 +75,7 @@ static const rtems_monitor_object_info_t rtems_monitor_object_info[] = (rtems_monitor_object_dump_fn) rtems_monitor_init_task_dump, }, { RTEMS_MONITOR_OBJECT_TASK, - (void *) &_RTEMS_tasks_Information, + (void *) &_RTEMS_tasks_Information.Objects, sizeof(rtems_monitor_task_t), (rtems_monitor_object_next_fn) rtems_monitor_manager_next, (rtems_monitor_object_canonical_fn) rtems_monitor_task_canonical, @@ -132,7 +132,7 @@ static const rtems_monitor_object_info_t rtems_monitor_object_info[] = }, #if defined(RTEMS_POSIX_API) { RTEMS_MONITOR_OBJECT_PTHREAD, - (void *) &_POSIX_Threads_Information, + (void *) &_POSIX_Threads_Information.Objects, sizeof(rtems_monitor_task_t), (rtems_monitor_object_next_fn) rtems_monitor_manager_next, (rtems_monitor_object_canonical_fn) rtems_monitor_task_canonical, diff --git a/cpukit/posix/include/rtems/posix/pthreadimpl.h b/cpukit/posix/include/rtems/posix/pthreadimpl.h index d0dc330643..f95ac9cf94 100644 --- a/cpukit/posix/include/rtems/posix/pthreadimpl.h +++ b/cpukit/posix/include/rtems/posix/pthreadimpl.h @@ -44,7 +44,7 @@ extern "C" { * The following defines the information control block used to manage * this class of objects. */ -POSIX_EXTERN Objects_Information _POSIX_Threads_Information; +POSIX_EXTERN Thread_Information _POSIX_Threads_Information; /** * This variable contains the default POSIX Thread attributes. @@ -171,7 +171,7 @@ RTEMS_INLINE_ROUTINE Thread_Control *_POSIX_Threads_Allocate(void) _Thread_Kill_zombies(); return (Thread_Control *) - _Objects_Allocate_unprotected( &_POSIX_Threads_Information ); + _Objects_Allocate_unprotected( &_POSIX_Threads_Information.Objects ); } /* @@ -200,7 +200,7 @@ RTEMS_INLINE_ROUTINE void _POSIX_Threads_Free ( Thread_Control *the_pthread ) { - _Objects_Free( &_POSIX_Threads_Information, &the_pthread->Object ); + _Objects_Free( &_POSIX_Threads_Information.Objects, &the_pthread->Object ); } /* diff --git a/cpukit/posix/src/killinfo.c b/cpukit/posix/src/killinfo.c index d08e68684b..a90f4b1221 100644 --- a/cpukit/posix/src/killinfo.c +++ b/cpukit/posix/src/killinfo.c @@ -70,11 +70,11 @@ int killinfo( Thread_Control *the_thread; Thread_Control *interested; Priority_Control interested_priority; - Chain_Control *the_chain; Chain_Node *the_node; siginfo_t siginfo_struct; siginfo_t *siginfo; POSIX_signals_Siginfo_node *psiginfo; + Thread_queue_Heads *heads; /* * Only supported for the "calling process" (i.e. this node). @@ -140,32 +140,35 @@ int killinfo( /* XXX violation of visibility -- need to define thread queue support */ - the_chain = &_POSIX_signals_Wait_queue.Queue.Heads.Fifo; + heads = _POSIX_signals_Wait_queue.Queue.heads; + if ( heads != NULL ) { + Chain_Control *the_chain = &heads->Heads.Fifo; - for ( the_node = _Chain_First( the_chain ); - !_Chain_Is_tail( the_chain, the_node ) ; - the_node = the_node->next ) { + for ( the_node = _Chain_First( the_chain ); + !_Chain_Is_tail( the_chain, the_node ) ; + the_node = the_node->next ) { - the_thread = THREAD_CHAIN_NODE_TO_THREAD( the_node ); - api = the_thread->API_Extensions[ THREAD_API_POSIX ]; + the_thread = THREAD_CHAIN_NODE_TO_THREAD( the_node ); + api = the_thread->API_Extensions[ THREAD_API_POSIX ]; - #if defined(DEBUG_SIGNAL_PROCESSING) - printk( "Waiting Thread=%p option=0x%08x mask=0x%08x blocked=0x%08x\n", - the_thread, the_thread->Wait.option, mask, api->signals_blocked); - #endif + #if defined(DEBUG_SIGNAL_PROCESSING) + printk( "Waiting Thread=%p option=0x%08x mask=0x%08x blocked=0x%08x\n", + the_thread, the_thread->Wait.option, mask, api->signals_blocked); + #endif - /* - * Is this thread is actually blocked waiting for the signal? - */ - if (the_thread->Wait.option & mask) - goto process_it; + /* + * Is this thread is actually blocked waiting for the signal? + */ + if (the_thread->Wait.option & mask) + goto process_it; - /* - * Is this thread is blocked waiting for another signal but has - * not blocked this one? - */ - if (~api->signals_blocked & mask) - goto process_it; + /* + * Is this thread is blocked waiting for another signal but has + * not blocked this one? + */ + if (~api->signals_blocked & mask) + goto process_it; + } } /* diff --git a/cpukit/posix/src/pthread.c b/cpukit/posix/src/pthread.c index 02d86b5536..dc31449d82 100644 --- a/cpukit/posix/src/pthread.c +++ b/cpukit/posix/src/pthread.c @@ -370,19 +370,17 @@ void _POSIX_Threads_Manager_initialization(void) CPU_COPY( attr->affinityset, affinity->set ); #endif - _Objects_Initialize_information( + _Thread_Initialize_information( &_POSIX_Threads_Information, /* object information table */ OBJECTS_POSIX_API, /* object API */ OBJECTS_POSIX_THREADS, /* object class */ Configuration_POSIX_API.maximum_threads, /* maximum objects of this class */ - _Thread_Control_size, /* size of this object's control block */ true, /* true if names for this object are strings */ _POSIX_PATH_MAX /* 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/rtems/include/rtems/rtems/tasksimpl.h b/cpukit/rtems/include/rtems/rtems/tasksimpl.h index b8f91d3607..d35f6816c9 100644 --- a/cpukit/rtems/include/rtems/rtems/tasksimpl.h +++ b/cpukit/rtems/include/rtems/rtems/tasksimpl.h @@ -49,7 +49,7 @@ extern "C" { * The following instantiates the information control block used to * manage this class of objects. */ -RTEMS_TASKS_EXTERN Objects_Information _RTEMS_tasks_Information; +RTEMS_TASKS_EXTERN Thread_Information _RTEMS_tasks_Information; /** * @brief RTEMS Task Manager Initialization @@ -88,7 +88,7 @@ RTEMS_INLINE_ROUTINE Thread_Control *_RTEMS_tasks_Allocate(void) _Thread_Kill_zombies(); return (Thread_Control *) - _Objects_Allocate_unprotected( &_RTEMS_tasks_Information ); + _Objects_Allocate_unprotected( &_RTEMS_tasks_Information.Objects ); } /** diff --git a/cpukit/rtems/src/taskcreate.c b/cpukit/rtems/src/taskcreate.c index 65a8d33ff1..f8107beb30 100644 --- a/cpukit/rtems/src/taskcreate.c +++ b/cpukit/rtems/src/taskcreate.c @@ -177,7 +177,7 @@ rtems_status_code rtems_task_create( if ( is_global ) { _Objects_MP_Open( - &_RTEMS_tasks_Information, + &_RTEMS_tasks_Information.Objects, the_global_object, name, the_thread->Object.id diff --git a/cpukit/rtems/src/taskdelete.c b/cpukit/rtems/src/taskdelete.c index dc9a2a1961..7a06c51eac 100644 --- a/cpukit/rtems/src/taskdelete.c +++ b/cpukit/rtems/src/taskdelete.c @@ -38,7 +38,10 @@ rtems_status_code rtems_task_delete( case OBJECTS_LOCAL: #if defined(RTEMS_MULTIPROCESSING) if ( the_thread->is_global ) { - _Objects_MP_Close( &_RTEMS_tasks_Information, the_thread->Object.id ); + _Objects_MP_Close( + &_RTEMS_tasks_Information.Objects, + the_thread->Object.id + ); _RTEMS_tasks_MP_Send_process_packet( RTEMS_TASKS_MP_ANNOUNCE_DELETE, the_thread->Object.id, diff --git a/cpukit/rtems/src/taskident.c b/cpukit/rtems/src/taskident.c index 28b7406c39..c4f1770b10 100644 --- a/cpukit/rtems/src/taskident.c +++ b/cpukit/rtems/src/taskident.c @@ -44,7 +44,12 @@ rtems_status_code rtems_task_ident( return RTEMS_SUCCESSFUL; } - status = _Objects_Name_to_id_u32( &_RTEMS_tasks_Information, name, node, id ); + status = _Objects_Name_to_id_u32( + &_RTEMS_tasks_Information.Objects, + name, + node, + id + ); return _Status_Object_name_errors_to_status[ status ]; } diff --git a/cpukit/rtems/src/taskmp.c b/cpukit/rtems/src/taskmp.c index 339544cdc4..a1386d9bbb 100644 --- a/cpukit/rtems/src/taskmp.c +++ b/cpukit/rtems/src/taskmp.c @@ -198,7 +198,7 @@ void _RTEMS_tasks_MP_Process_packet ( case RTEMS_TASKS_MP_ANNOUNCE_CREATE: ignored = _Objects_MP_Allocate_and_open( - &_RTEMS_tasks_Information, + &_RTEMS_tasks_Information.Objects, the_packet->name, the_packet->Prefix.id, true @@ -209,7 +209,10 @@ void _RTEMS_tasks_MP_Process_packet ( case RTEMS_TASKS_MP_ANNOUNCE_DELETE: - _Objects_MP_Close( &_RTEMS_tasks_Information, the_packet->Prefix.id ); + _Objects_MP_Close( + &_RTEMS_tasks_Information.Objects, + the_packet->Prefix.id + ); _MPCI_Return_packet( the_packet_prefix ); break; diff --git a/cpukit/rtems/src/tasks.c b/cpukit/rtems/src/tasks.c index 5ed891522e..e5a80ee5b8 100644 --- a/cpukit/rtems/src/tasks.c +++ b/cpukit/rtems/src/tasks.c @@ -204,19 +204,17 @@ User_extensions_Control _RTEMS_tasks_User_extensions = { void _RTEMS_tasks_Manager_initialization(void) { - _Objects_Initialize_information( + _Thread_Initialize_information( &_RTEMS_tasks_Information, /* object information table */ OBJECTS_CLASSIC_API, /* object API */ OBJECTS_RTEMS_TASKS, /* object class */ Configuration_RTEMS_API.maximum_tasks, /* maximum objects of this class */ - _Thread_Control_size, /* size of this object's control block */ false, /* true if the name is a string */ RTEMS_MAXIMUM_NAME_LENGTH /* maximum length of an object name */ #if defined(RTEMS_MULTIPROCESSING) , - true, /* true if this is a global object class */ - NULL /* Proxy extraction support callout */ + true /* true if this is a global object class */ #endif ); diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h index 8115a85724..4b438ff540 100644 --- a/cpukit/sapi/include/confdefs.h +++ b/cpukit/sapi/include/confdefs.h @@ -2969,6 +2969,8 @@ const rtems_libio_helper rtems_fs_init_helper = #define CONFIGURE_MEMORY_FOR_TASKS(_tasks, _number_FP_tasks) \ ( \ _Configure_Object_RAM(_tasks, sizeof(Configuration_Thread_control)) \ + + _Configure_From_workspace(_Configure_Max_Objects(_tasks) \ + * sizeof(Thread_queue_Heads)) \ + _Configure_Max_Objects(_number_FP_tasks) \ * _Configure_From_workspace(CONTEXT_FP_SIZE) \ ) diff --git a/cpukit/score/include/rtems/score/objectimpl.h b/cpukit/score/include/rtems/score/objectimpl.h index a5a3b7ef5f..1919cd1d64 100644 --- a/cpukit/score/include/rtems/score/objectimpl.h +++ b/cpukit/score/include/rtems/score/objectimpl.h @@ -718,6 +718,13 @@ Objects_Maximum _Objects_Active_count( const Objects_Information *information ); +RTEMS_INLINE_ROUTINE Objects_Maximum _Objects_Extend_size( + const Objects_Information *information +) +{ + return information->auto_extend ? information->allocation_size : 0; +} + /** * This function returns true if the api is valid. * diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h index f9ba3a030e..2f0b35e1a8 100644 --- a/cpukit/score/include/rtems/score/thread.h +++ b/cpukit/score/include/rtems/score/thread.h @@ -349,6 +349,8 @@ typedef struct { * @see _Thread_Lock_set() and _Thread_Wait_set_operations(). */ const Thread_queue_Operations *operations; + + Thread_queue_Heads *spare_heads; } Thread_Wait_information; /** diff --git a/cpukit/score/include/rtems/score/threadimpl.h b/cpukit/score/include/rtems/score/threadimpl.h index 4dcef0b7d8..7b8f89c346 100644 --- a/cpukit/score/include/rtems/score/threadimpl.h +++ b/cpukit/score/include/rtems/score/threadimpl.h @@ -32,6 +32,7 @@ #include <rtems/score/sysstate.h> #include <rtems/score/threadqimpl.h> #include <rtems/score/todimpl.h> +#include <rtems/score/freechain.h> #include <rtems/config.h> #ifdef __cplusplus @@ -54,11 +55,17 @@ extern "C" { */ SCORE_EXTERN void *rtems_ada_self; +typedef struct { + Objects_Information Objects; + + Freechain_Control Free_thread_queue_heads; +} Thread_Information; + /** * The following defines the information control block used to * manage this class of objects. */ -SCORE_EXTERN Objects_Information _Thread_Internal_information; +SCORE_EXTERN Thread_Information _Thread_Internal_information; /** * The following points to the thread whose floating point @@ -89,6 +96,19 @@ SCORE_EXTERN struct _reent **_Thread_libc_reent; RTEMS_CONTAINER_OF( node, Thread_Control, Resource_node ) #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 +); + /** * @brief Initialize thread handler. * @@ -154,7 +174,7 @@ void _Thread_Stack_Free( * guaranteed to be of at least minimum size. */ bool _Thread_Initialize( - Objects_Information *information, + Thread_Information *information, Thread_Control *the_thread, const struct Scheduler_Control *scheduler, void *stack_area, @@ -736,7 +756,7 @@ RTEMS_INLINE_ROUTINE uint32_t _Thread_Get_maximum_internal_threads(void) RTEMS_INLINE_ROUTINE Thread_Control *_Thread_Internal_allocate( void ) { return (Thread_Control *) - _Objects_Allocate_unprotected( &_Thread_Internal_information ); + _Objects_Allocate_unprotected( &_Thread_Internal_information.Objects ); } /** diff --git a/cpukit/score/include/rtems/score/threadq.h b/cpukit/score/include/rtems/score/threadq.h index 599a81c23c..e3aee5869a 100644 --- a/cpukit/score/include/rtems/score/threadq.h +++ b/cpukit/score/include/rtems/score/threadq.h @@ -52,6 +52,14 @@ typedef struct { RBTree_Control Priority; } Heads; + Chain_Control Free_chain; + + Chain_Node Free_node; +} Thread_queue_Heads; + +typedef struct { + Thread_queue_Heads *heads; + /** * @brief Lock to protect this thread queue. * @@ -80,17 +88,6 @@ typedef void ( *Thread_queue_Priority_change_operation )( ); /** - * @brief Thread queue initialize operation. - * - * @param[in] queue The actual thread queue. - * - * @see _Thread_Wait_set_operations(). - */ -typedef void ( *Thread_queue_Initialize_operation )( - Thread_queue_Queue *queue -); - -/** * @brief Thread queue enqueue operation. * * @param[in] queue The actual thread queue. @@ -119,7 +116,7 @@ typedef void ( *Thread_queue_Extract_operation )( /** * @brief Thread queue first operation. * - * @param[in] queue The actual thread queue. + * @param[in] heads The thread queue heads. * * @retval NULL No thread is present on the thread queue. * @retval first The first thread of the thread queue according to the insert @@ -128,7 +125,7 @@ typedef void ( *Thread_queue_Extract_operation )( * @see _Thread_Wait_set_operations(). */ typedef Thread_Control *( *Thread_queue_First_operation )( - Thread_queue_Queue *queue + Thread_queue_Heads *heads ); /** @@ -150,13 +147,6 @@ typedef struct { Thread_queue_Priority_change_operation priority_change; /** - * @brief Thread queue initialize operation. - * - * Called by object initialization routines. - */ - Thread_queue_Initialize_operation initialize; - - /** * @brief Thread queue enqueue operation. * * Called by object routines to enqueue the thread. diff --git a/cpukit/score/include/rtems/score/threadqimpl.h b/cpukit/score/include/rtems/score/threadqimpl.h index 330b18c5bf..e1060e4e82 100644 --- a/cpukit/score/include/rtems/score/threadqimpl.h +++ b/cpukit/score/include/rtems/score/threadqimpl.h @@ -33,6 +33,14 @@ extern "C" { */ /**@{*/ +RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_initialize( + Thread_queue_Queue *queue +) +{ + queue->heads = NULL; + _ISR_lock_Initialize( &queue->Lock, "Thread Queue" ); +} + RTEMS_INLINE_ROUTINE void _Thread_queue_Queue_acquire_critical( Thread_queue_Queue *queue, ISR_lock_Context *lock_context @@ -322,7 +330,13 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Thread_queue_First_locked( Thread_queue_Control *the_thread_queue ) { - return ( *the_thread_queue->operations->first )( &the_thread_queue->Queue ); + Thread_queue_Heads *heads = the_thread_queue->Queue.heads; + + if ( heads != NULL ) { + return ( *the_thread_queue->operations->first )( heads ); + } else { + return NULL; + } } /** @@ -375,9 +389,7 @@ void _Thread_queue_Initialize( #if defined(RTEMS_SMP) #define THREAD_QUEUE_FIFO_INITIALIZER( designator, name ) { \ .Queue = { \ - .Heads = { \ - .Fifo = CHAIN_INITIALIZER_EMPTY( designator.Queue.Heads.Fifo ) \ - }, \ + .heads = NULL, \ .Lock = ISR_LOCK_INITIALIZER( name ), \ }, \ .operations = &_Thread_queue_Operations_FIFO \ @@ -385,33 +397,19 @@ void _Thread_queue_Initialize( #define THREAD_QUEUE_PRIORITY_INITIALIZER( designator, name ) { \ .Queue = { \ - .Heads = { \ - .Priority = RBTREE_INITIALIZER_EMPTY( \ - designator.Queue.Heads.Priority \ - ) \ - }, \ + .heads = NULL, \ .Lock = ISR_LOCK_INITIALIZER( name ), \ }, \ .operations = &_Thread_queue_Operations_priority \ } #else #define THREAD_QUEUE_FIFO_INITIALIZER( designator, name ) { \ - .Queue = { \ - .Heads = { \ - .Fifo = CHAIN_INITIALIZER_EMPTY( designator.Queue.Heads.Fifo ) \ - } \ - }, \ + .Queue = { .heads = NULL }, \ .operations = &_Thread_queue_Operations_FIFO \ } #define THREAD_QUEUE_PRIORITY_INITIALIZER( designator, name ) { \ - .Queue = { \ - .Heads = { \ - .Priority = RBTREE_INITIALIZER_EMPTY( \ - designator.Queue.Heads.Priority \ - ) \ - } \ - }, \ + .Queue = { .heads = NULL }, \ .operations = &_Thread_queue_Operations_priority \ } #endif 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 ) diff --git a/testsuites/sptests/spobjgetnext/init.c b/testsuites/sptests/spobjgetnext/init.c index 2695190239..924d65e6e8 100644 --- a/testsuites/sptests/spobjgetnext/init.c +++ b/testsuites/sptests/spobjgetnext/init.c @@ -75,7 +75,7 @@ rtems_task Init( TEST_BEGIN(); - info = &_RTEMS_tasks_Information; + info = &_RTEMS_tasks_Information.Objects; main_task = rtems_task_self(); puts( "Init - _Objects_Get_next - NULL object information" ); diff --git a/testsuites/sptests/sptask_err04/task1.c b/testsuites/sptests/sptask_err04/task1.c index 92ddb6d7ab..f7bd98b979 100644 --- a/testsuites/sptests/sptask_err04/task1.c +++ b/testsuites/sptests/sptask_err04/task1.c @@ -99,7 +99,7 @@ rtems_task Task_1( puts( "TA1 - rtems_task_get_note - RTEMS_INVALID_ID" ); status = rtems_task_get_note( - _RTEMS_tasks_Information.minimum_id + (3L<<OBJECTS_API_START_BIT), + _RTEMS_tasks_Information.Objects.minimum_id + (3L<<OBJECTS_API_START_BIT), RTEMS_NOTEPAD_LAST, ¬epad_value ); diff --git a/testsuites/sptests/spthreadq01/init.c b/testsuites/sptests/spthreadq01/init.c index 2c27057a56..b0a342057a 100644 --- a/testsuites/sptests/spthreadq01/init.c +++ b/testsuites/sptests/spthreadq01/init.c @@ -36,10 +36,10 @@ static rtems_task Init( _Thread_Enable_dispatch(); /* is there more to check? */ - rtems_test_assert( _Chain_Is_empty( &fifo_queue.Queue.Heads.Fifo ) ); + rtems_test_assert( fifo_queue.Queue.heads == NULL ); rtems_test_assert( fifo_queue.operations == &_Thread_queue_Operations_FIFO ); - rtems_test_assert( _RBTree_Is_empty( &fifo_queue.Queue.Heads.Priority ) ); + rtems_test_assert( prio_queue.Queue.heads == NULL ); rtems_test_assert( prio_queue.operations == &_Thread_queue_Operations_priority ); |