summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/score/src')
-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
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 )