summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cpukit/libcsupport/src/resource_snapshot.c4
-rw-r--r--cpukit/libmisc/monitor/mon-object.c4
-rw-r--r--cpukit/posix/include/rtems/posix/pthreadimpl.h6
-rw-r--r--cpukit/posix/src/killinfo.c47
-rw-r--r--cpukit/posix/src/pthread.c6
-rw-r--r--cpukit/rtems/include/rtems/rtems/tasksimpl.h4
-rw-r--r--cpukit/rtems/src/taskcreate.c2
-rw-r--r--cpukit/rtems/src/taskdelete.c5
-rw-r--r--cpukit/rtems/src/taskident.c7
-rw-r--r--cpukit/rtems/src/taskmp.c7
-rw-r--r--cpukit/rtems/src/tasks.c6
-rw-r--r--cpukit/sapi/include/confdefs.h2
-rw-r--r--cpukit/score/include/rtems/score/objectimpl.h7
-rw-r--r--cpukit/score/include/rtems/score/thread.h2
-rw-r--r--cpukit/score/include/rtems/score/threadimpl.h26
-rw-r--r--cpukit/score/include/rtems/score/threadq.h30
-rw-r--r--cpukit/score/include/rtems/score/threadqimpl.h40
-rw-r--r--cpukit/score/src/thread.c43
-rw-r--r--cpukit/score/src/threadinitialize.c24
-rw-r--r--cpukit/score/src/threadq.c5
-rw-r--r--cpukit/score/src/threadqops.c147
-rw-r--r--cpukit/score/src/threadrestart.c13
-rw-r--r--testsuites/sptests/spobjgetnext/init.c2
-rw-r--r--testsuites/sptests/sptask_err04/task1.c2
-rw-r--r--testsuites/sptests/spthreadq01/init.c4
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,
&notepad_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
);