summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cpukit/sapi/include/confdefs.h20
-rw-r--r--cpukit/score/Makefile.am2
-rw-r--r--cpukit/score/include/rtems/score/scheduler.h9
-rw-r--r--cpukit/score/include/rtems/score/schedulercbs.h4
-rw-r--r--cpukit/score/include/rtems/score/schedulercbsimpl.h52
-rw-r--r--cpukit/score/include/rtems/score/scheduleredf.h9
-rw-r--r--cpukit/score/include/rtems/score/scheduleredfimpl.h13
-rw-r--r--cpukit/score/include/rtems/score/schedulerimpl.h7
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriority.h19
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h15
-rw-r--r--cpukit/score/include/rtems/score/schedulerpriorityimpl.h112
-rw-r--r--cpukit/score/include/rtems/score/schedulerprioritysmp.h29
-rw-r--r--cpukit/score/include/rtems/score/schedulersimplesmp.h7
-rw-r--r--cpukit/score/include/rtems/score/schedulersmp.h66
-rw-r--r--cpukit/score/include/rtems/score/schedulersmpimpl.h66
-rw-r--r--cpukit/score/include/rtems/score/thread.h33
-rw-r--r--cpukit/score/preinstall.am4
-rw-r--r--cpukit/score/src/schedulercbs.c12
-rw-r--r--cpukit/score/src/schedulercbsallocate.c15
-rw-r--r--cpukit/score/src/schedulercbsattachthread.c10
-rw-r--r--cpukit/score/src/schedulercbsdetachthread.c8
-rw-r--r--cpukit/score/src/schedulercbsreleasejob.c10
-rw-r--r--cpukit/score/src/schedulercbsunblock.c11
-rw-r--r--cpukit/score/src/scheduleredf.c4
-rw-r--r--cpukit/score/src/scheduleredfallocate.c13
-rw-r--r--cpukit/score/src/scheduleredfenqueue.c8
-rw-r--r--cpukit/score/src/scheduleredfextract.c8
-rw-r--r--cpukit/score/src/scheduleredfupdate.c14
-rw-r--r--cpukit/score/src/scheduleredfyield.c9
-rw-r--r--cpukit/score/src/schedulerpriorityaffinitysmp.c31
-rw-r--r--cpukit/score/src/schedulerpriorityenqueue.c7
-rw-r--r--cpukit/score/src/schedulerpriorityenqueuefirst.c2
-rw-r--r--cpukit/score/src/schedulerprioritysmp.c72
-rw-r--r--cpukit/score/src/schedulerpriorityunblock.c7
-rw-r--r--cpukit/score/src/schedulerpriorityupdate.c4
-rw-r--r--cpukit/score/src/schedulerpriorityyield.c5
-rw-r--r--cpukit/score/src/schedulersimplesmp.c23
-rw-r--r--cpukit/score/src/schedulersmpvalidstatechanges.c39
-rw-r--r--cpukit/score/src/threadinitialize.c2
-rw-r--r--testsuites/sptests/spsize/size.c2
40 files changed, 553 insertions, 230 deletions
diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h
index ad432ed82c..1c97d153ba 100644
--- a/cpukit/sapi/include/confdefs.h
+++ b/cpukit/sapi/include/confdefs.h
@@ -2474,18 +2474,24 @@ const rtems_libio_helper rtems_fs_init_helper =
void *extensions[ CONFIGURE_MAXIMUM_USER_EXTENSIONS + 1 ];
#endif
union {
+ Scheduler_Node Base;
#ifdef CONFIGURE_SCHEDULER_CBS
- Scheduler_CBS_Per_thread CBS;
+ Scheduler_CBS_Node CBS;
#endif
#ifdef CONFIGURE_SCHEDULER_EDF
- Scheduler_EDF_Per_thread EDF;
+ Scheduler_EDF_Node EDF;
#endif
- #if defined(CONFIGURE_SCHEDULER_PRIORITY) \
- || defined(CONFIGURE_SCHEDULER_PRIORITY_SMP)
- Scheduler_priority_Per_thread Priority;
+ #ifdef CONFIGURE_SCHEDULER_PRIORITY
+ Scheduler_priority_Node Priority;
+ #endif
+ #ifdef CONFIGURE_SCHEDULER_SIMPLE_SMP
+ Scheduler_SMP_Node Simple_SMP;
+ #endif
+ #ifdef CONFIGURE_SCHEDULER_PRIORITY_SMP
+ Scheduler_priority_SMP_Node Priority_SMP;
#endif
#ifdef CONFIGURE_SCHEDULER_PRIORITY_AFFINITY_SMP
- Scheduler_priority_affinity_SMP_Per_thread Priority_affinity;
+ Scheduler_priority_affinity_SMP_Node Priority_affinity_SMP;
#endif
#ifdef CONFIGURE_SCHEDULER_USER_PER_THREAD
CONFIGURE_SCHEDULER_USER_PER_THREAD User;
@@ -2511,7 +2517,7 @@ const rtems_libio_helper rtems_fs_init_helper =
const Thread_Control_add_on _Thread_Control_add_ons[] = {
{
- offsetof( Configuration_Thread_control, Control.scheduler_info ),
+ offsetof( Configuration_Thread_control, Control.scheduler_node ),
offsetof( Configuration_Thread_control, Scheduler )
}, {
offsetof(
diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am
index ae925507d1..8fb11d7bdf 100644
--- a/cpukit/score/Makefile.am
+++ b/cpukit/score/Makefile.am
@@ -52,6 +52,7 @@ include_rtems_score_HEADERS += include/rtems/score/rbtreeimpl.h
include_rtems_score_HEADERS += include/rtems/score/scheduler.h
include_rtems_score_HEADERS += include/rtems/score/schedulerimpl.h
include_rtems_score_HEADERS += include/rtems/score/schedulercbs.h
+include_rtems_score_HEADERS += include/rtems/score/schedulercbsimpl.h
include_rtems_score_HEADERS += include/rtems/score/scheduleredf.h
include_rtems_score_HEADERS += include/rtems/score/scheduleredfimpl.h
include_rtems_score_HEADERS += include/rtems/score/schedulerpriority.h
@@ -126,6 +127,7 @@ endif
if HAS_SMP
libscore_a_SOURCES += src/profilingsmplock.c
+libscore_a_SOURCES += src/schedulersmpvalidstatechanges.c
libscore_a_SOURCES += src/schedulerpriorityaffinitysmp.c
libscore_a_SOURCES += src/schedulerprioritysmp.c
libscore_a_SOURCES += src/schedulersimplesmp.c
diff --git a/cpukit/score/include/rtems/score/scheduler.h b/cpukit/score/include/rtems/score/scheduler.h
index 768576fef9..7f0b43ae52 100644
--- a/cpukit/score/include/rtems/score/scheduler.h
+++ b/cpukit/score/include/rtems/score/scheduler.h
@@ -42,6 +42,8 @@ extern "C" {
typedef struct Scheduler_Control Scheduler_Control;
+typedef struct Scheduler_Node Scheduler_Node;
+
/**
* @brief The scheduler operations.
*/
@@ -157,6 +159,13 @@ struct Scheduler_Control {
};
/**
+ * @brief Scheduler node for per-thread data.
+ */
+struct Scheduler_Node {
+ /* No fields yet */
+};
+
+/**
* @brief Registered schedulers.
*
* Application provided via <rtems/confdefs.h>.
diff --git a/cpukit/score/include/rtems/score/schedulercbs.h b/cpukit/score/include/rtems/score/schedulercbs.h
index e546c8d1e3..6cfdfbe959 100644
--- a/cpukit/score/include/rtems/score/schedulercbs.h
+++ b/cpukit/score/include/rtems/score/schedulercbs.h
@@ -129,10 +129,10 @@ typedef struct {
*/
typedef struct {
/** EDF scheduler specific data of a task. */
- Scheduler_EDF_Per_thread edf_per_thread;
+ Scheduler_EDF_Node Base;
/** CBS server specific data of a task. */
Scheduler_CBS_Server *cbs_server;
-} Scheduler_CBS_Per_thread;
+} Scheduler_CBS_Node;
/**
diff --git a/cpukit/score/include/rtems/score/schedulercbsimpl.h b/cpukit/score/include/rtems/score/schedulercbsimpl.h
new file mode 100644
index 0000000000..f40de0712e
--- /dev/null
+++ b/cpukit/score/include/rtems/score/schedulercbsimpl.h
@@ -0,0 +1,52 @@
+/**
+ * @file
+ *
+ * @brief CBS Scheduler Implementation
+ *
+ * @ingroup ScoreSchedulerCBS
+ */
+
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#ifndef _RTEMS_SCORE_SCHEDULERCBSIMPL_H
+#define _RTEMS_SCORE_SCHEDULERCBSIMPL_H
+
+#include <rtems/score/schedulercbs.h>
+#include <rtems/score/schedulerimpl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/**
+ * @addtogroup ScoreSchedulerCBS
+ *
+ * @{
+ */
+
+RTEMS_INLINE_ROUTINE Scheduler_CBS_Node *_Scheduler_CBS_Node_get(
+ Thread_Control *the_thread
+)
+{
+ return (Scheduler_CBS_Node *) _Scheduler_Node_get( the_thread );
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _RTEMS_SCORE_SCHEDULERCBSIMPL_H */
diff --git a/cpukit/score/include/rtems/score/scheduleredf.h b/cpukit/score/include/rtems/score/scheduleredf.h
index fabce7e288..95be94c802 100644
--- a/cpukit/score/include/rtems/score/scheduleredf.h
+++ b/cpukit/score/include/rtems/score/scheduleredf.h
@@ -91,10 +91,15 @@ typedef enum {
} Scheduler_EDF_Queue_state;
/**
- * This structure handles EDF specific data of a thread.
+ * @brief Scheduler node specialization for EDF schedulers.
*/
typedef struct {
/**
+ * @brief Basic scheduler node.
+ */
+ Scheduler_Node Base;
+
+ /**
* Pointer to corresponding Thread Control Block.
*/
Thread_Control *thread;
@@ -106,7 +111,7 @@ typedef struct {
* State of the thread with respect to ready queue.
*/
Scheduler_EDF_Queue_state queue_state;
-} Scheduler_EDF_Per_thread;
+} Scheduler_EDF_Node;
/**
* @brief Initialize EDF scheduler.
diff --git a/cpukit/score/include/rtems/score/scheduleredfimpl.h b/cpukit/score/include/rtems/score/scheduleredfimpl.h
index d4b197e442..708557f78e 100644
--- a/cpukit/score/include/rtems/score/scheduleredfimpl.h
+++ b/cpukit/score/include/rtems/score/scheduleredfimpl.h
@@ -37,6 +37,13 @@ RTEMS_INLINE_ROUTINE Scheduler_EDF_Context *
return (Scheduler_EDF_Context *) scheduler->context;
}
+RTEMS_INLINE_ROUTINE Scheduler_EDF_Node *_Scheduler_EDF_Node_get(
+ Thread_Control *the_thread
+)
+{
+ return (Scheduler_EDF_Node *) _Scheduler_Node_get( the_thread );
+}
+
RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Schedule_body(
const Scheduler_Control *scheduler,
Thread_Control *the_thread,
@@ -46,9 +53,9 @@ RTEMS_INLINE_ROUTINE void _Scheduler_EDF_Schedule_body(
Scheduler_EDF_Context *context =
_Scheduler_EDF_Get_context( scheduler );
RBTree_Node *first = _RBTree_First( &context->Ready, RBT_LEFT );
- Scheduler_EDF_Per_thread *sched_info =
- _RBTree_Container_of(first, Scheduler_EDF_Per_thread, Node);
- Thread_Control *heir = (Thread_Control *) sched_info->thread;
+ Scheduler_EDF_Node *node =
+ _RBTree_Container_of(first, Scheduler_EDF_Node, Node);
+ Thread_Control *heir = node->thread;
( void ) the_thread;
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
index 42e57303b8..c972ef57bd 100644
--- a/cpukit/score/include/rtems/score/schedulerimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerimpl.h
@@ -623,6 +623,13 @@ RTEMS_INLINE_ROUTINE uint32_t _Scheduler_Get_index(
return (uint32_t) (scheduler - &_Scheduler_Table[ 0 ]);
}
+RTEMS_INLINE_ROUTINE Scheduler_Node *_Scheduler_Node_get(
+ Thread_Control *the_thread
+)
+{
+ return the_thread->scheduler_node;
+}
+
/** @} */
#ifdef __cplusplus
diff --git a/cpukit/score/include/rtems/score/schedulerpriority.h b/cpukit/score/include/rtems/score/schedulerpriority.h
index 4393b7ddb5..134dcd715b 100644
--- a/cpukit/score/include/rtems/score/schedulerpriority.h
+++ b/cpukit/score/include/rtems/score/schedulerpriority.h
@@ -83,7 +83,7 @@ typedef struct {
} Scheduler_priority_Context;
/**
- * Per-thread data related to the _Scheduler_PRIORITY scheduling policy.
+ * @brief Data for ready queue operations.
*/
typedef struct {
/** This field points to the Ready FIFO for this thread's priority. */
@@ -91,7 +91,22 @@ typedef struct {
/** This field contains precalculated priority map indices. */
Priority_bit_map_Information Priority_map;
-} Scheduler_priority_Per_thread;
+} Scheduler_priority_Ready_queue;
+
+/**
+ * @brief Scheduler node specialization for Deterministic Priority schedulers.
+ */
+typedef struct {
+ /**
+ * @brief Basic scheduler node.
+ */
+ Scheduler_Node Base;
+
+ /**
+ * @brief The associated ready queue of this node.
+ */
+ Scheduler_priority_Ready_queue Ready_queue;
+} Scheduler_priority_Node;
/**
* @brief Initializes the priority scheduler.
diff --git a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
index c327fccb6e..e86fd35c6f 100644
--- a/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
+++ b/cpukit/score/include/rtems/score/schedulerpriorityaffinitysmp.h
@@ -118,25 +118,20 @@ bool _Scheduler_priority_affinity_SMP_Set_affinity(
);
/**
- * This structure handles affinity specific data of a thread.
- *
- * @note The attribute priority_sched_info must remain
- * the first element in the structure so that the
- * Scheduler_priority_XXX methods will continue to
- * function.
+ * @brief Scheduler node specialization for Deterministic Priority Affinity SMP
+ * schedulers.
*/
typedef struct {
-
/**
- * Data for the Priority Scheduler.
+ * @brief SMP priority scheduler node.
*/
- Scheduler_priority_Per_thread Priority_sched_info;
+ Scheduler_priority_SMP_Node Base;
/**
* Structure containing affinity set data and size
*/
CPU_set_Control Affinity;
-} Scheduler_priority_affinity_SMP_Per_thread;
+} Scheduler_priority_affinity_SMP_Node;
/** @} */
diff --git a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
index fde06872ca..3fb1e5b622 100644
--- a/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerpriorityimpl.h
@@ -41,6 +41,13 @@ RTEMS_INLINE_ROUTINE Scheduler_priority_Context *
return (Scheduler_priority_Context *) scheduler->context;
}
+RTEMS_INLINE_ROUTINE Scheduler_priority_Node *_Scheduler_priority_Node_get(
+ Thread_Control *the_thread
+)
+{
+ return (Scheduler_priority_Node *) _Scheduler_Node_get( the_thread );
+}
+
/**
* @brief Ready queue initialization.
*
@@ -57,77 +64,72 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_initialize(
_Chain_Initialize_empty( &ready_queues[index] );
}
-RTEMS_INLINE_ROUTINE Scheduler_priority_Per_thread *
+RTEMS_INLINE_ROUTINE Scheduler_priority_Node *
_Scheduler_priority_Get_scheduler_info( Thread_Control *thread )
{
- return ( Scheduler_priority_Per_thread * ) thread->scheduler_info;
+ return ( Scheduler_priority_Node * ) thread->scheduler_node;
}
/**
- * @brief Put a thread to the ready queue.
+ * @brief Enqueues a thread on the specified ready queue.
*
- * This routine puts @a the_thread on to the priority-based ready queue.
+ * The thread is placed as the last element of its priority group.
*
* @param[in] the_thread The thread to enqueue.
+ * @param[in] ready_queue The ready queue.
* @param[in] bit_map The priority bit map of the scheduler instance.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue(
- Thread_Control *the_thread,
- Priority_bit_map_Control *bit_map
+ Thread_Control *the_thread,
+ Scheduler_priority_Ready_queue *ready_queue,
+ Priority_bit_map_Control *bit_map
)
{
- Scheduler_priority_Per_thread *sched_info_of_thread =
- _Scheduler_priority_Get_scheduler_info( the_thread );
- Chain_Control *ready_chain = sched_info_of_thread->ready_chain;
+ Chain_Control *ready_chain = ready_queue->ready_chain;
_Chain_Append_unprotected( ready_chain, &the_thread->Object.Node );
- _Priority_bit_map_Add( bit_map, &sched_info_of_thread->Priority_map );
+ _Priority_bit_map_Add( bit_map, &ready_queue->Priority_map );
}
/**
- * @brief Put a thread to the head of the ready queue.
+ * @brief Enqueues a thread on the specified ready queue as first.
*
- * This routine puts @a the_thread to the head of the ready queue.
- * For priority-based ready queues, the thread will be the first thread
- * at its priority level.
+ * The thread is placed as the first element of its priority group.
*
- * @param[in] the_thread The thread to enqueue.
+ * @param[in] the_thread The thread to enqueue as first.
+ * @param[in] ready_queue The ready queue.
* @param[in] bit_map The priority bit map of the scheduler instance.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_enqueue_first(
- Thread_Control *the_thread,
- Priority_bit_map_Control *bit_map
+ Thread_Control *the_thread,
+ Scheduler_priority_Ready_queue *ready_queue,
+ Priority_bit_map_Control *bit_map
)
{
- Scheduler_priority_Per_thread *sched_info_of_thread =
- _Scheduler_priority_Get_scheduler_info( the_thread );
- Chain_Control *ready_chain = sched_info_of_thread->ready_chain;
+ Chain_Control *ready_chain = ready_queue->ready_chain;
_Chain_Prepend_unprotected( ready_chain, &the_thread->Object.Node );
- _Priority_bit_map_Add( bit_map, &sched_info_of_thread->Priority_map );
+ _Priority_bit_map_Add( bit_map, &ready_queue->Priority_map );
}
/**
- * @brief Remove a specific thread from the ready queue.
- *
- * This routine removes a specific thread from the specified
- * priority-based ready queue.
+ * @brief Extracts a thread from the specified ready queue.
*
* @param[in] the_thread The thread to extract.
+ * @param[in] ready_queue The ready queue.
* @param[in] bit_map The priority bit map of the scheduler instance.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_extract(
- Thread_Control *the_thread,
- Priority_bit_map_Control *bit_map
+ Thread_Control *the_thread,
+ Scheduler_priority_Ready_queue *ready_queue,
+ Priority_bit_map_Control *bit_map
)
{
- Scheduler_priority_Per_thread *sched_info_of_thread =
- _Scheduler_priority_Get_scheduler_info( the_thread );
- Chain_Control *ready_chain = sched_info_of_thread->ready_chain;
+ Chain_Control *ready_chain = ready_queue->ready_chain;
if ( _Chain_Has_only_one_node( ready_chain ) ) {
_Chain_Initialize_empty( ready_chain );
- _Priority_bit_map_Remove( bit_map, &sched_info_of_thread->Priority_map );
+ _Priority_bit_map_Remove( bit_map, &ready_queue->Priority_map );
} else {
_Chain_Extract_unprotected( &the_thread->Object.Node );
}
@@ -140,8 +142,13 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Extract_body(
{
Scheduler_priority_Context *context =
_Scheduler_priority_Get_context( scheduler );
+ Scheduler_priority_Node *node = _Scheduler_priority_Node_get( the_thread );
- _Scheduler_priority_Ready_queue_extract( the_thread, &context->Bit_map );
+ _Scheduler_priority_Ready_queue_extract(
+ the_thread,
+ &node->Ready_queue,
+ &context->Bit_map
+ );
}
/**
@@ -165,20 +172,20 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_priority_Ready_queue_first(
}
/**
- * @brief Requeue a thread on the ready queue.
+ * @brief Requeues a thread on the specified ready queue.
*
* This routine is invoked when a thread changes priority and should be
* moved to a different position on the ready queue.
*
- * @param[in] the_thread is a pointer to the thread
+ * @param[in] the_thread The thread to requeue.
+ * @param[in] ready_queue The ready queue.
*/
RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_requeue(
- Thread_Control *the_thread
+ Thread_Control *the_thread,
+ Scheduler_priority_Ready_queue *ready_queue
)
{
- Scheduler_priority_Per_thread *sched_info_of_thread =
- _Scheduler_priority_Get_scheduler_info( the_thread );
- Chain_Control *ready_chain = sched_info_of_thread->ready_chain;
+ Chain_Control *ready_chain = ready_queue->ready_chain;
if ( !_Chain_Has_only_one_node( ready_chain ) ) {
_Chain_Extract_unprotected( &the_thread->Object.Node );
@@ -210,22 +217,29 @@ RTEMS_INLINE_ROUTINE void _Scheduler_priority_Schedule_body(
_Scheduler_Update_heir( heir, force_dispatch );
}
-RTEMS_INLINE_ROUTINE void _Scheduler_priority_Update_body(
- Thread_Control *thread,
- Priority_bit_map_Control *bit_map,
- Chain_Control *ready_queues
+/**
+ * @brief Updates the specified ready queue data according to the current
+ * priority of the thread.
+ *
+ * @param[in] the_thread The thread.
+ * @param[in] ready_queue The ready queue.
+ * @param[in] bit_map The priority bit map of the scheduler instance.
+ * @param[in] ready_queues The ready queues of the scheduler instance.
+ */
+RTEMS_INLINE_ROUTINE void _Scheduler_priority_Ready_queue_update(
+ Thread_Control *the_thread,
+ Scheduler_priority_Ready_queue *ready_queue,
+ Priority_bit_map_Control *bit_map,
+ Chain_Control *ready_queues
)
{
- Scheduler_priority_Per_thread *sched_info_of_thread =
- _Scheduler_priority_Get_scheduler_info( thread );
-
- sched_info_of_thread->ready_chain =
- &ready_queues[ thread->current_priority ];
+ Priority_Control priority = the_thread->current_priority;
+ ready_queue->ready_chain = &ready_queues[ priority ];
_Priority_bit_map_Initialize_information(
bit_map,
- &sched_info_of_thread->Priority_map,
- thread->current_priority
+ &ready_queue->Priority_map,
+ priority
);
}
diff --git a/cpukit/score/include/rtems/score/schedulerprioritysmp.h b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
index 66de9645bd..3e7d22f81d 100644
--- a/cpukit/score/include/rtems/score/schedulerprioritysmp.h
+++ b/cpukit/score/include/rtems/score/schedulerprioritysmp.h
@@ -47,13 +47,33 @@ extern "C" {
* @{
*/
+/**
+ * @brief Scheduler context specialization for Deterministic Priority SMP
+ * schedulers.
+ */
typedef struct {
Scheduler_SMP_Context Base;
Priority_bit_map_Control Bit_map;
- Chain_Control Ready[ 0 ];
+ Chain_Control Ready[ RTEMS_ZERO_LENGTH_ARRAY ];
} Scheduler_priority_SMP_Context;
/**
+ * @brief Scheduler node specialization for Deterministic Priority SMP
+ * schedulers.
+ */
+typedef struct {
+ /**
+ * @brief SMP scheduler node.
+ */
+ Scheduler_SMP_Node Base;
+
+ /**
+ * @brief The associated ready queue of this node.
+ */
+ Scheduler_priority_Ready_queue Ready_queue;
+} Scheduler_priority_SMP_Node;
+
+/**
* @brief Entry points for the Priority SMP Scheduler.
*/
#define SCHEDULER_PRIORITY_SMP_ENTRY_POINTS \
@@ -63,7 +83,7 @@ typedef struct {
_Scheduler_priority_SMP_Yield, \
_Scheduler_priority_SMP_Block, \
_Scheduler_priority_SMP_Enqueue_fifo, \
- _Scheduler_default_Allocate, \
+ _Scheduler_priority_SMP_Allocate, \
_Scheduler_default_Free, \
_Scheduler_priority_SMP_Update, \
_Scheduler_priority_SMP_Enqueue_fifo, \
@@ -79,6 +99,11 @@ typedef struct {
void _Scheduler_priority_SMP_Initialize( const Scheduler_Control *scheduler );
+bool _Scheduler_priority_SMP_Allocate(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread
+);
+
void _Scheduler_priority_SMP_Schedule(
const Scheduler_Control *scheduler,
Thread_Control *thread
diff --git a/cpukit/score/include/rtems/score/schedulersimplesmp.h b/cpukit/score/include/rtems/score/schedulersimplesmp.h
index 880115faaf..268d88fe8a 100644
--- a/cpukit/score/include/rtems/score/schedulersimplesmp.h
+++ b/cpukit/score/include/rtems/score/schedulersimplesmp.h
@@ -64,7 +64,7 @@ typedef struct {
_Scheduler_simple_smp_Yield, \
_Scheduler_simple_smp_Block, \
_Scheduler_simple_smp_Enqueue_priority_fifo, \
- _Scheduler_default_Allocate, \
+ _Scheduler_simple_smp_Allocate, \
_Scheduler_default_Free, \
_Scheduler_default_Update, \
_Scheduler_simple_smp_Enqueue_priority_fifo, \
@@ -80,6 +80,11 @@ typedef struct {
void _Scheduler_simple_smp_Initialize( const Scheduler_Control *scheduler );
+bool _Scheduler_simple_smp_Allocate(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+);
+
void _Scheduler_simple_smp_Block(
const Scheduler_Control *scheduler,
Thread_Control *thread
diff --git a/cpukit/score/include/rtems/score/schedulersmp.h b/cpukit/score/include/rtems/score/schedulersmp.h
index 778a1fb832..ee1b087ff8 100644
--- a/cpukit/score/include/rtems/score/schedulersmp.h
+++ b/cpukit/score/include/rtems/score/schedulersmp.h
@@ -38,15 +38,81 @@ extern "C" {
* @{
*/
+/**
+ * @brief Scheduler context specialization for SMP schedulers.
+ */
typedef struct {
/**
* @brief Basic scheduler context.
*/
Scheduler_Context Base;
+ /**
+ * @brief The chain of scheduled nodes.
+ */
Chain_Control Scheduled;
} Scheduler_SMP_Context;
+/**
+ * @brief SMP scheduler node states.
+ */
+typedef enum {
+ /**
+ * @brief This scheduler node is blocked.
+ *
+ * A scheduler node is blocked if the corresponding thread is not ready.
+ */
+ SCHEDULER_SMP_NODE_BLOCKED,
+
+ /**
+ * @brief The scheduler node is scheduled.
+ *
+ * A scheduler node is scheduled if the corresponding thread is ready and the
+ * scheduler allocated a processor for it. A scheduled node is assigned to
+ * exactly one processor. The sum of scheduled and in the air nodes equals
+ * the processor count owned by a scheduler instance.
+ */
+ SCHEDULER_SMP_NODE_SCHEDULED,
+
+ /**
+ * @brief This scheduler node is ready.
+ *
+ * A scheduler node is ready if the corresponding thread is ready and the
+ * scheduler did not allocate a processor for it.
+ */
+ SCHEDULER_SMP_NODE_READY,
+
+ /**
+ * @brief This scheduler node is in the air.
+ *
+ * A scheduled node is in the air if it has an allocated processor and the
+ * corresponding thread is in a transient state. Such a node is not an
+ * element of the set of scheduled nodes. The extract operation on a
+ * scheduled node will produce a scheduler node in the air (see also
+ * _Thread_Set_transient()). The next enqueue or schedule operation will
+ * decide what to do based on this state indication. It can either place the
+ * scheduler node back on the set of scheduled nodes and the thread can keep
+ * its allocated processor, or it can take the processor away from the thread
+ * and give the processor to another thread of higher priority.
+ */
+ SCHEDULER_SMP_NODE_IN_THE_AIR
+} Scheduler_SMP_Node_state;
+
+/**
+ * @brief Scheduler node specialization for SMP schedulers.
+ */
+typedef struct {
+ /**
+ * @brief Basic scheduler node.
+ */
+ Scheduler_Node Base;
+
+ /**
+ * @brief The state of this node.
+ */
+ Scheduler_SMP_Node_state state;
+} Scheduler_SMP_Node;
+
/** @} */
#ifdef __cplusplus
diff --git a/cpukit/score/include/rtems/score/schedulersmpimpl.h b/cpukit/score/include/rtems/score/schedulersmpimpl.h
index 69222c28f8..3bbd4bb0a7 100644
--- a/cpukit/score/include/rtems/score/schedulersmpimpl.h
+++ b/cpukit/score/include/rtems/score/schedulersmpimpl.h
@@ -64,6 +64,34 @@ static inline void _Scheduler_SMP_Initialize(
_Chain_Initialize_empty( &self->Scheduled );
}
+static inline Scheduler_SMP_Node *_Scheduler_SMP_Node_get(
+ Thread_Control *thread
+)
+{
+ return (Scheduler_SMP_Node *) _Scheduler_Node_get( thread );
+}
+
+static inline void _Scheduler_SMP_Node_initialize(
+ Scheduler_SMP_Node *node
+)
+{
+ node->state = SCHEDULER_SMP_NODE_BLOCKED;
+}
+
+extern const bool _Scheduler_SMP_Node_valid_state_changes[ 4 ][ 4 ];
+
+static inline void _Scheduler_SMP_Node_change_state(
+ Scheduler_SMP_Node *node,
+ Scheduler_SMP_Node_state new_state
+)
+{
+ _Assert(
+ _Scheduler_SMP_Node_valid_state_changes[ node->state ][ new_state ]
+ );
+
+ node->state = new_state;
+}
+
static inline bool _Scheduler_SMP_Is_processor_owned_by_us(
const Scheduler_SMP_Context *self,
const Per_CPU_Control *cpu
@@ -106,13 +134,16 @@ static inline void _Scheduler_SMP_Allocate_processor(
Thread_Control *victim
)
{
+ Scheduler_SMP_Node *scheduled_node = _Scheduler_SMP_Node_get( scheduled );
Per_CPU_Control *cpu_of_scheduled = _Thread_Get_CPU( scheduled );
Per_CPU_Control *cpu_of_victim = _Thread_Get_CPU( victim );
Per_CPU_Control *cpu_self = _Per_CPU_Get();
Thread_Control *heir;
- scheduled->is_scheduled = true;
- victim->is_scheduled = false;
+ _Scheduler_SMP_Node_change_state(
+ scheduled_node,
+ SCHEDULER_SMP_NODE_SCHEDULED
+ );
_Assert( _ISR_Get_level() != 0 );
@@ -160,10 +191,10 @@ static inline void _Scheduler_SMP_Enqueue_ordered(
Scheduler_SMP_Move move_from_scheduled_to_ready
)
{
- if ( thread->is_in_the_air ) {
- Thread_Control *highest_ready = ( *get_highest_ready )( self );
+ Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
- thread->is_in_the_air = false;
+ if ( node->state == SCHEDULER_SMP_NODE_IN_THE_AIR ) {
+ Thread_Control *highest_ready = ( *get_highest_ready )( self );
/*
* The thread has been extracted from the scheduled chain. We have to
@@ -175,13 +206,12 @@ static inline void _Scheduler_SMP_Enqueue_ordered(
highest_ready != NULL
&& !( *order )( &thread->Object.Node, &highest_ready->Object.Node )
) {
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
_Scheduler_SMP_Allocate_processor( self, highest_ready, thread );
-
( *insert_ready )( self, thread );
( *move_from_ready_to_scheduled )( self, highest_ready );
} else {
- thread->is_scheduled = true;
-
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_SCHEDULED );
( *insert_scheduled )( self, thread );
}
} else {
@@ -195,11 +225,18 @@ static inline void _Scheduler_SMP_Enqueue_ordered(
lowest_scheduled != NULL
&& ( *order )( &thread->Object.Node, &lowest_scheduled->Object.Node )
) {
- _Scheduler_SMP_Allocate_processor( self, thread, lowest_scheduled );
+ Scheduler_SMP_Node *lowest_scheduled_node =
+ _Scheduler_SMP_Node_get( lowest_scheduled );
+ _Scheduler_SMP_Node_change_state(
+ lowest_scheduled_node,
+ SCHEDULER_SMP_NODE_READY
+ );
+ _Scheduler_SMP_Allocate_processor( self, thread, lowest_scheduled );
( *insert_scheduled )( self, thread );
( *move_from_scheduled_to_ready )( self, lowest_scheduled );
} else {
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_READY );
( *insert_ready )( self, thread );
}
}
@@ -226,8 +263,10 @@ static inline void _Scheduler_SMP_Schedule(
Scheduler_SMP_Move move_from_ready_to_scheduled
)
{
- if ( thread->is_in_the_air ) {
- thread->is_in_the_air = false;
+ Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
+
+ if ( node->state == SCHEDULER_SMP_NODE_IN_THE_AIR ) {
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_BLOCKED );
_Scheduler_SMP_Schedule_highest_ready(
self,
@@ -295,7 +334,10 @@ static inline void _Scheduler_SMP_Start_idle(
Per_CPU_Control *cpu
)
{
- thread->is_scheduled = true;
+ Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
+
+ node->state = SCHEDULER_SMP_NODE_SCHEDULED;
+
_Thread_Set_CPU( thread, cpu );
_Chain_Append_unprotected( &self->Scheduled, &thread->Object.Node );
}
diff --git a/cpukit/score/include/rtems/score/thread.h b/cpukit/score/include/rtems/score/thread.h
index 248ae96850..0deeea065f 100644
--- a/cpukit/score/include/rtems/score/thread.h
+++ b/cpukit/score/include/rtems/score/thread.h
@@ -39,6 +39,8 @@
struct Scheduler_Control;
+struct Scheduler_Node;
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -479,31 +481,6 @@ struct Thread_Control_struct {
bool is_preemptible;
#if defined(RTEMS_SMP)
/**
- * @brief This field is true if the thread is scheduled.
- *
- * A thread is scheduled if it is ready and the scheduler allocated a
- * processor for it. A scheduled thread is assigned to exactly one
- * processor. There are exactly processor count scheduled threads in the
- * system.
- */
- bool is_scheduled;
-
- /**
- * @brief This field is true if the thread is in the air.
- *
- * A thread is in the air if it has an allocated processor (it is an
- * executing or heir thread on exactly one processor) and it is not a member
- * of the scheduled chain. The extract operation on a scheduled thread will
- * produce threads in the air (see also _Thread_Set_transient()). The next
- * enqueue or schedule operation will decide what to do based on this state
- * indication. It can either place the thread back on the scheduled chain
- * and the thread can keep its allocated processor, or it can take the
- * processor away from the thread and give the processor to another thread of
- * higher priority.
- */
- bool is_in_the_air;
-
- /**
* @brief The scheduler of this thread.
*/
const struct Scheduler_Control *scheduler;
@@ -530,8 +507,10 @@ struct Thread_Control_struct {
*/
Thread_CPU_usage_t cpu_time_used;
- /** This pointer holds per-thread data for the scheduler and ready queue. */
- void *scheduler_info;
+ /**
+ * @brief The scheduler node of this thread for the real scheduler.
+ */
+ struct Scheduler_Node *scheduler_node;
#ifdef RTEMS_SMP
/**
diff --git a/cpukit/score/preinstall.am b/cpukit/score/preinstall.am
index efbe37dbfc..d00e1374c6 100644
--- a/cpukit/score/preinstall.am
+++ b/cpukit/score/preinstall.am
@@ -191,6 +191,10 @@ $(PROJECT_INCLUDE)/rtems/score/schedulercbs.h: include/rtems/score/schedulercbs.
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulercbs.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulercbs.h
+$(PROJECT_INCLUDE)/rtems/score/schedulercbsimpl.h: include/rtems/score/schedulercbsimpl.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
+ $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/schedulercbsimpl.h
+PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/schedulercbsimpl.h
+
$(PROJECT_INCLUDE)/rtems/score/scheduleredf.h: include/rtems/score/scheduleredf.h $(PROJECT_INCLUDE)/rtems/score/$(dirstamp)
$(INSTALL_DATA) $< $(PROJECT_INCLUDE)/rtems/score/scheduleredf.h
PREINSTALL_FILES += $(PROJECT_INCLUDE)/rtems/score/scheduleredf.h
diff --git a/cpukit/score/src/schedulercbs.c b/cpukit/score/src/schedulercbs.c
index 54312b2ca6..e2f34d4c82 100644
--- a/cpukit/score/src/schedulercbs.c
+++ b/cpukit/score/src/schedulercbs.c
@@ -18,7 +18,7 @@
#include "config.h"
#endif
-#include <rtems/score/schedulercbs.h>
+#include <rtems/score/schedulercbsimpl.h>
#include <rtems/score/threadimpl.h>
#include <rtems/score/wkspace.h>
@@ -27,7 +27,7 @@ void _Scheduler_CBS_Budget_callout(
)
{
Priority_Control new_priority;
- Scheduler_CBS_Per_thread *sched_info;
+ Scheduler_CBS_Node *node;
Scheduler_CBS_Server_id server_id;
/* Put violating task to background until the end of period. */
@@ -38,13 +38,13 @@ void _Scheduler_CBS_Budget_callout(
_Thread_Change_priority(the_thread, new_priority, true);
/* Invoke callback function if any. */
- sched_info = (Scheduler_CBS_Per_thread *) the_thread->scheduler_info;
- if ( sched_info->cbs_server->cbs_budget_overrun ) {
+ node = _Scheduler_CBS_Node_get( the_thread );
+ if ( node->cbs_server->cbs_budget_overrun ) {
_Scheduler_CBS_Get_server_id(
- sched_info->cbs_server->task_id,
+ node->cbs_server->task_id,
&server_id
);
- sched_info->cbs_server->cbs_budget_overrun( server_id );
+ node->cbs_server->cbs_budget_overrun( server_id );
}
}
diff --git a/cpukit/score/src/schedulercbsallocate.c b/cpukit/score/src/schedulercbsallocate.c
index a6f89c35a9..6a29088eb6 100644
--- a/cpukit/score/src/schedulercbsallocate.c
+++ b/cpukit/score/src/schedulercbsallocate.c
@@ -18,25 +18,20 @@
#include "config.h"
#endif
-#include <rtems/system.h>
-#include <rtems/config.h>
-#include <rtems/score/scheduler.h>
-#include <rtems/score/scheduleredf.h>
-#include <rtems/score/schedulercbs.h>
-#include <rtems/score/wkspace.h>
+#include <rtems/score/schedulercbsimpl.h>
bool _Scheduler_CBS_Allocate(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
)
{
- Scheduler_CBS_Per_thread *schinfo = the_thread->scheduler_info;
+ Scheduler_CBS_Node *node = _Scheduler_CBS_Node_get( the_thread );
(void) scheduler;
- schinfo->edf_per_thread.thread = the_thread;
- schinfo->edf_per_thread.queue_state = SCHEDULER_EDF_QUEUE_STATE_NEVER_HAS_BEEN;
- schinfo->cbs_server = NULL;
+ node->Base.thread = the_thread;
+ node->Base.queue_state = SCHEDULER_EDF_QUEUE_STATE_NEVER_HAS_BEEN;
+ node->cbs_server = NULL;
return true;
}
diff --git a/cpukit/score/src/schedulercbsattachthread.c b/cpukit/score/src/schedulercbsattachthread.c
index 43bf92da66..3892e89aae 100644
--- a/cpukit/score/src/schedulercbsattachthread.c
+++ b/cpukit/score/src/schedulercbsattachthread.c
@@ -18,7 +18,7 @@
#include "config.h"
#endif
-#include <rtems/score/schedulercbs.h>
+#include <rtems/score/schedulercbsimpl.h>
#include <rtems/score/threadimpl.h>
int _Scheduler_CBS_Attach_thread (
@@ -43,18 +43,16 @@ int _Scheduler_CBS_Attach_thread (
the_thread = _Thread_Get(task_id, &location);
/* The routine _Thread_Get may disable dispatch and not enable again. */
if ( the_thread ) {
- Scheduler_CBS_Per_thread *sched_info;
-
- sched_info = (Scheduler_CBS_Per_thread *) the_thread->scheduler_info;
+ Scheduler_CBS_Node *node = _Scheduler_CBS_Node_get( the_thread );
/* Thread is already attached to a server. */
- if ( sched_info->cbs_server ) {
+ if ( node->cbs_server ) {
_Objects_Put( &the_thread->Object );
return SCHEDULER_CBS_ERROR_FULL;
}
_Scheduler_CBS_Server_list[server_id].task_id = task_id;
- sched_info->cbs_server = &_Scheduler_CBS_Server_list[server_id];
+ node->cbs_server = &_Scheduler_CBS_Server_list[server_id];
the_thread->budget_callout = _Scheduler_CBS_Budget_callout;
the_thread->budget_algorithm = THREAD_CPU_BUDGET_ALGORITHM_CALLOUT;
diff --git a/cpukit/score/src/schedulercbsdetachthread.c b/cpukit/score/src/schedulercbsdetachthread.c
index 0f77cdf10e..6d634ef59f 100644
--- a/cpukit/score/src/schedulercbsdetachthread.c
+++ b/cpukit/score/src/schedulercbsdetachthread.c
@@ -19,7 +19,7 @@
#include "config.h"
#endif
-#include <rtems/score/schedulercbs.h>
+#include <rtems/score/schedulercbsimpl.h>
#include <rtems/score/threadimpl.h>
int _Scheduler_CBS_Detach_thread (
@@ -29,7 +29,6 @@ int _Scheduler_CBS_Detach_thread (
{
Objects_Locations location;
Thread_Control *the_thread;
- Scheduler_CBS_Per_thread *sched_info;
if ( server_id >= _Scheduler_CBS_Maximum_servers )
return SCHEDULER_CBS_ERROR_INVALID_PARAMETER;
@@ -43,9 +42,10 @@ int _Scheduler_CBS_Detach_thread (
the_thread = _Thread_Get(task_id, &location);
/* The routine _Thread_Get may disable dispatch and not enable again. */
if ( the_thread ) {
+ Scheduler_CBS_Node *node = _Scheduler_CBS_Node_get( the_thread );
+
_Scheduler_CBS_Server_list[server_id].task_id = -1;
- sched_info = (Scheduler_CBS_Per_thread *) the_thread->scheduler_info;
- sched_info->cbs_server = NULL;
+ node->cbs_server = NULL;
the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
the_thread->budget_callout = the_thread->Start.budget_callout;
diff --git a/cpukit/score/src/schedulercbsreleasejob.c b/cpukit/score/src/schedulercbsreleasejob.c
index c5ac572a61..eec930a6c1 100644
--- a/cpukit/score/src/schedulercbsreleasejob.c
+++ b/cpukit/score/src/schedulercbsreleasejob.c
@@ -19,7 +19,7 @@
#include "config.h"
#endif
-#include <rtems/score/schedulercbs.h>
+#include <rtems/score/schedulercbsimpl.h>
#include <rtems/score/threadimpl.h>
#include <rtems/score/watchdogimpl.h>
@@ -29,11 +29,9 @@ void _Scheduler_CBS_Release_job(
uint32_t deadline
)
{
- Priority_Control new_priority;
- Scheduler_CBS_Per_thread *sched_info =
- (Scheduler_CBS_Per_thread *) the_thread->scheduler_info;
- Scheduler_CBS_Server *serv_info =
- (Scheduler_CBS_Server *) sched_info->cbs_server;
+ Scheduler_CBS_Node *node = _Scheduler_CBS_Node_get( the_thread );
+ Scheduler_CBS_Server *serv_info = node->cbs_server;
+ Priority_Control new_priority;
if (deadline) {
/* Initializing or shifting deadline. */
diff --git a/cpukit/score/src/schedulercbsunblock.c b/cpukit/score/src/schedulercbsunblock.c
index 030cc85c68..411e6cef27 100644
--- a/cpukit/score/src/schedulercbsunblock.c
+++ b/cpukit/score/src/schedulercbsunblock.c
@@ -19,7 +19,7 @@
#include "config.h"
#endif
-#include <rtems/score/schedulercbs.h>
+#include <rtems/score/schedulercbsimpl.h>
#include <rtems/score/schedulerimpl.h>
#include <rtems/score/threadimpl.h>
#include <rtems/score/watchdogimpl.h>
@@ -29,16 +29,13 @@ void _Scheduler_CBS_Unblock(
Thread_Control *the_thread
)
{
- Scheduler_CBS_Per_thread *sched_info;
- Scheduler_CBS_Server *serv_info;
- Priority_Control new_priority;
+ Scheduler_CBS_Node *node = _Scheduler_CBS_Node_get( the_thread );
+ Scheduler_CBS_Server *serv_info = node->cbs_server;
+ Priority_Control new_priority;
_Scheduler_EDF_Enqueue( scheduler, the_thread );
/* TODO: flash critical section? */
- sched_info = (Scheduler_CBS_Per_thread *) the_thread->scheduler_info;
- serv_info = (Scheduler_CBS_Server *) sched_info->cbs_server;
-
/*
* Late unblock rule for deadline-driven tasks. The remaining time to
* deadline must be sufficient to serve the remaining computation time
diff --git a/cpukit/score/src/scheduleredf.c b/cpukit/score/src/scheduleredf.c
index 4d1aa62d08..010d053949 100644
--- a/cpukit/score/src/scheduleredf.c
+++ b/cpukit/score/src/scheduleredf.c
@@ -27,9 +27,9 @@ static int _Scheduler_EDF_RBTree_compare_function
)
{
Priority_Control value1 = _RBTree_Container_of
- (n1,Scheduler_EDF_Per_thread,Node)->thread->current_priority;
+ (n1,Scheduler_EDF_Node,Node)->thread->current_priority;
Priority_Control value2 = _RBTree_Container_of
- (n2,Scheduler_EDF_Per_thread,Node)->thread->current_priority;
+ (n2,Scheduler_EDF_Node,Node)->thread->current_priority;
/*
* This function compares only numbers for the red-black tree,
diff --git a/cpukit/score/src/scheduleredfallocate.c b/cpukit/score/src/scheduleredfallocate.c
index 3dc9dd5070..f9aaa57b8a 100644
--- a/cpukit/score/src/scheduleredfallocate.c
+++ b/cpukit/score/src/scheduleredfallocate.c
@@ -18,24 +18,19 @@
#include "config.h"
#endif
-#include <rtems/system.h>
-#include <rtems/config.h>
-#include <rtems/score/scheduler.h>
-#include <rtems/score/scheduleredf.h>
-#include <rtems/score/wkspace.h>
+#include <rtems/score/scheduleredfimpl.h>
bool _Scheduler_EDF_Allocate(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
)
{
- Scheduler_EDF_Per_thread *schinfo = the_thread->scheduler_info;
+ Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread );
(void) scheduler;
- schinfo = (Scheduler_EDF_Per_thread *)(the_thread->scheduler_info);
- schinfo->thread = the_thread;
- schinfo->queue_state = SCHEDULER_EDF_QUEUE_STATE_NEVER_HAS_BEEN;
+ node->thread = the_thread;
+ node->queue_state = SCHEDULER_EDF_QUEUE_STATE_NEVER_HAS_BEEN;
return true;
}
diff --git a/cpukit/score/src/scheduleredfenqueue.c b/cpukit/score/src/scheduleredfenqueue.c
index 38e67eb7a7..8973d8b32c 100644
--- a/cpukit/score/src/scheduleredfenqueue.c
+++ b/cpukit/score/src/scheduleredfenqueue.c
@@ -27,10 +27,8 @@ void _Scheduler_EDF_Enqueue(
{
Scheduler_EDF_Context *context =
_Scheduler_EDF_Get_context( scheduler );
- Scheduler_EDF_Per_thread *sched_info =
- (Scheduler_EDF_Per_thread*) the_thread->scheduler_info;
- RBTree_Node *node = &(sched_info->Node);
+ Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread );
- _RBTree_Insert( &context->Ready, node );
- sched_info->queue_state = SCHEDULER_EDF_QUEUE_STATE_YES;
+ _RBTree_Insert( &context->Ready, &node->Node );
+ node->queue_state = SCHEDULER_EDF_QUEUE_STATE_YES;
}
diff --git a/cpukit/score/src/scheduleredfextract.c b/cpukit/score/src/scheduleredfextract.c
index 02c47afb06..94fde0a05c 100644
--- a/cpukit/score/src/scheduleredfextract.c
+++ b/cpukit/score/src/scheduleredfextract.c
@@ -27,10 +27,8 @@ void _Scheduler_EDF_Extract(
{
Scheduler_EDF_Context *context =
_Scheduler_EDF_Get_context( scheduler );
- Scheduler_EDF_Per_thread *sched_info =
- (Scheduler_EDF_Per_thread*) the_thread->scheduler_info;
- RBTree_Node *node = &(sched_info->Node);
+ Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread );
- _RBTree_Extract( &context->Ready, node );
- sched_info->queue_state = SCHEDULER_EDF_QUEUE_STATE_NOT_PRESENTLY;
+ _RBTree_Extract( &context->Ready, &node->Node );
+ node->queue_state = SCHEDULER_EDF_QUEUE_STATE_NOT_PRESENTLY;
}
diff --git a/cpukit/score/src/scheduleredfupdate.c b/cpukit/score/src/scheduleredfupdate.c
index 88d6d9d7d4..99a3e0e3f6 100644
--- a/cpukit/score/src/scheduleredfupdate.c
+++ b/cpukit/score/src/scheduleredfupdate.c
@@ -18,28 +18,22 @@
#include "config.h"
#endif
-#include <rtems/system.h>
-#include <rtems/config.h>
-#include <rtems/score/priority.h>
-#include <rtems/score/scheduler.h>
-#include <rtems/score/scheduleredf.h>
-#include <rtems/score/thread.h>
+#include <rtems/score/scheduleredfimpl.h>
void _Scheduler_EDF_Update(
const Scheduler_Control *scheduler,
Thread_Control *the_thread
)
{
- Scheduler_EDF_Per_thread *sched_info =
- (Scheduler_EDF_Per_thread*)the_thread->scheduler_info;
+ Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread );
(void) scheduler;
- if (sched_info->queue_state == SCHEDULER_EDF_QUEUE_STATE_NEVER_HAS_BEEN) {
+ if (node->queue_state == SCHEDULER_EDF_QUEUE_STATE_NEVER_HAS_BEEN) {
/* Shifts the priority to the region of background tasks. */
the_thread->Start.initial_priority |= (SCHEDULER_EDF_PRIO_MSB);
the_thread->real_priority = the_thread->Start.initial_priority;
the_thread->current_priority = the_thread->Start.initial_priority;
- sched_info->queue_state = SCHEDULER_EDF_QUEUE_STATE_NOT_PRESENTLY;
+ node->queue_state = SCHEDULER_EDF_QUEUE_STATE_NOT_PRESENTLY;
}
}
diff --git a/cpukit/score/src/scheduleredfyield.c b/cpukit/score/src/scheduleredfyield.c
index 8f8786ad1d..9eb07825fe 100644
--- a/cpukit/score/src/scheduleredfyield.c
+++ b/cpukit/score/src/scheduleredfyield.c
@@ -28,20 +28,17 @@ void _Scheduler_EDF_Yield(
{
Scheduler_EDF_Context *context =
_Scheduler_EDF_Get_context( scheduler );
+ Scheduler_EDF_Node *node = _Scheduler_EDF_Node_get( the_thread );
ISR_Level level;
- Scheduler_EDF_Per_thread *thread_info =
- (Scheduler_EDF_Per_thread *) the_thread->scheduler_info;
- RBTree_Node *thread_node = &(thread_info->Node);
-
_ISR_Disable( level );
/*
* The RBTree has more than one node, enqueue behind the tasks
* with the same priority in case there are such ones.
*/
- _RBTree_Extract( &context->Ready, thread_node );
- _RBTree_Insert( &context->Ready, thread_node );
+ _RBTree_Extract( &context->Ready, &node->Node );
+ _RBTree_Insert( &context->Ready, &node->Node );
_ISR_Flash( level );
diff --git a/cpukit/score/src/schedulerpriorityaffinitysmp.c b/cpukit/score/src/schedulerpriorityaffinitysmp.c
index 0ea4336321..0d9525d894 100644
--- a/cpukit/score/src/schedulerpriorityaffinitysmp.c
+++ b/cpukit/score/src/schedulerpriorityaffinitysmp.c
@@ -25,10 +25,11 @@
#include <rtems/score/wkspace.h>
#include <rtems/score/cpusetimpl.h>
-RTEMS_INLINE_ROUTINE Scheduler_priority_affinity_SMP_Per_thread *
-_Scheduler_priority_affinity_Get_scheduler_info( Thread_Control *thread )
+static Scheduler_priority_affinity_SMP_Node *
+_Scheduler_priority_affinity_Node_get( Thread_Control *thread )
{
- return ( Scheduler_priority_affinity_SMP_Per_thread * ) thread->scheduler_info;
+ return ( Scheduler_priority_affinity_SMP_Node * )
+ _Scheduler_Node_get( thread );
}
bool _Scheduler_priority_affinity_SMP_Allocate(
@@ -36,11 +37,13 @@ bool _Scheduler_priority_affinity_SMP_Allocate(
Thread_Control *the_thread
)
{
- Scheduler_priority_affinity_SMP_Per_thread *info =
- the_thread->scheduler_info;
+ Scheduler_priority_affinity_SMP_Node *node =
+ _Scheduler_priority_affinity_Node_get( the_thread );
- info->Affinity = *_CPU_set_Default();
- info->Affinity.set = &info->Affinity.preallocated;
+ _Scheduler_SMP_Node_initialize( &node->Base.Base );
+
+ node->Affinity = *_CPU_set_Default();
+ node->Affinity.set = &node->Affinity.preallocated;
return true;
}
@@ -52,16 +55,16 @@ bool _Scheduler_priority_affinity_SMP_Get_affinity(
cpu_set_t *cpuset
)
{
- Scheduler_priority_affinity_SMP_Per_thread *info =
- _Scheduler_priority_affinity_Get_scheduler_info(thread);
+ Scheduler_priority_affinity_SMP_Node *node =
+ _Scheduler_priority_affinity_Node_get(thread);
(void) scheduler;
- if ( info->Affinity.setsize != cpusetsize ) {
+ if ( node->Affinity.setsize != cpusetsize ) {
return false;
}
- CPU_COPY( cpuset, info->Affinity.set );
+ CPU_COPY( cpuset, node->Affinity.set );
return true;
}
@@ -72,8 +75,8 @@ bool _Scheduler_priority_affinity_SMP_Set_affinity(
cpu_set_t *cpuset
)
{
- Scheduler_priority_affinity_SMP_Per_thread *info =
- _Scheduler_priority_affinity_Get_scheduler_info(thread);
+ Scheduler_priority_affinity_SMP_Node *node =
+ _Scheduler_priority_affinity_Node_get(thread);
(void) scheduler;
@@ -81,7 +84,7 @@ bool _Scheduler_priority_affinity_SMP_Set_affinity(
return false;
}
- CPU_COPY( info->Affinity.set, cpuset );
+ CPU_COPY( node->Affinity.set, cpuset );
return true;
}
diff --git a/cpukit/score/src/schedulerpriorityenqueue.c b/cpukit/score/src/schedulerpriorityenqueue.c
index e3f2be6061..aa901cc978 100644
--- a/cpukit/score/src/schedulerpriorityenqueue.c
+++ b/cpukit/score/src/schedulerpriorityenqueue.c
@@ -27,6 +27,11 @@ void _Scheduler_priority_Enqueue(
{
Scheduler_priority_Context *context =
_Scheduler_priority_Get_context( scheduler );
+ Scheduler_priority_Node *node = _Scheduler_priority_Node_get( the_thread );
- _Scheduler_priority_Ready_queue_enqueue( the_thread, &context->Bit_map );
+ _Scheduler_priority_Ready_queue_enqueue(
+ the_thread,
+ &node->Ready_queue,
+ &context->Bit_map
+ );
}
diff --git a/cpukit/score/src/schedulerpriorityenqueuefirst.c b/cpukit/score/src/schedulerpriorityenqueuefirst.c
index 0d197065a0..1714fe57f0 100644
--- a/cpukit/score/src/schedulerpriorityenqueuefirst.c
+++ b/cpukit/score/src/schedulerpriorityenqueuefirst.c
@@ -27,9 +27,11 @@ void _Scheduler_priority_Enqueue_first(
{
Scheduler_priority_Context *context =
_Scheduler_priority_Get_context( scheduler );
+ Scheduler_priority_Node *node = _Scheduler_priority_Node_get( the_thread );
_Scheduler_priority_Ready_queue_enqueue_first(
the_thread,
+ &node->Ready_queue,
&context->Bit_map
);
}
diff --git a/cpukit/score/src/schedulerprioritysmp.c b/cpukit/score/src/schedulerprioritysmp.c
index 025d9601fd..263bc8746d 100644
--- a/cpukit/score/src/schedulerprioritysmp.c
+++ b/cpukit/score/src/schedulerprioritysmp.c
@@ -1,9 +1,9 @@
/**
* @file
*
- * @brief Deterministic Priority SMP Scheduler Implementation
+ * @ingroup ScoreSchedulerPrioritySMP
*
- * @ingroup ScoreSchedulerSMP
+ * @brief Deterministic Priority SMP Scheduler Implementation
*/
/*
@@ -43,6 +43,13 @@ _Scheduler_priority_SMP_Self_from_SMP_base( Scheduler_SMP_Context *smp_base )
- offsetof( Scheduler_priority_SMP_Context, Base ) );
}
+static Scheduler_priority_SMP_Node *_Scheduler_priority_SMP_Node_get(
+ Thread_Control *thread
+)
+{
+ return (Scheduler_priority_SMP_Node *) _Scheduler_Node_get( thread );
+}
+
void _Scheduler_priority_SMP_Initialize( const Scheduler_Control *scheduler )
{
Scheduler_priority_SMP_Context *self =
@@ -53,6 +60,18 @@ void _Scheduler_priority_SMP_Initialize( const Scheduler_Control *scheduler )
_Scheduler_priority_Ready_queue_initialize( &self->Ready[ 0 ] );
}
+bool _Scheduler_priority_SMP_Allocate(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread
+)
+{
+ Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
+
+ _Scheduler_SMP_Node_initialize( node );
+
+ return true;
+}
+
void _Scheduler_priority_SMP_Update(
const Scheduler_Control *scheduler,
Thread_Control *thread
@@ -60,9 +79,12 @@ void _Scheduler_priority_SMP_Update(
{
Scheduler_priority_SMP_Context *self =
_Scheduler_priority_SMP_Get_context( scheduler );
+ Scheduler_priority_SMP_Node *node =
+ _Scheduler_priority_SMP_Node_get( thread );
- _Scheduler_priority_Update_body(
+ _Scheduler_priority_Ready_queue_update(
thread,
+ &node->Ready_queue,
&self->Bit_map,
&self->Ready[ 0 ]
);
@@ -93,10 +115,13 @@ static void _Scheduler_priority_SMP_Move_from_scheduled_to_ready(
{
Scheduler_priority_SMP_Context *self =
_Scheduler_priority_SMP_Self_from_SMP_base( smp_base );
+ Scheduler_priority_SMP_Node *node =
+ _Scheduler_priority_SMP_Node_get( scheduled_to_ready );
_Chain_Extract_unprotected( &scheduled_to_ready->Object.Node );
_Scheduler_priority_Ready_queue_enqueue_first(
scheduled_to_ready,
+ &node->Ready_queue,
&self->Bit_map
);
}
@@ -108,9 +133,12 @@ static void _Scheduler_priority_SMP_Move_from_ready_to_scheduled(
{
Scheduler_priority_SMP_Context *self =
_Scheduler_priority_SMP_Self_from_SMP_base( smp_base );
+ Scheduler_priority_SMP_Node *node =
+ _Scheduler_priority_SMP_Node_get( ready_to_scheduled );
_Scheduler_priority_Ready_queue_extract(
ready_to_scheduled,
+ &node->Ready_queue,
&self->Bit_map
);
_Scheduler_simple_Insert_priority_fifo(
@@ -126,8 +154,14 @@ static void _Scheduler_priority_SMP_Insert_ready_lifo(
{
Scheduler_priority_SMP_Context *self =
_Scheduler_priority_SMP_Self_from_SMP_base( smp_base );
+ Scheduler_priority_SMP_Node *node =
+ _Scheduler_priority_SMP_Node_get( thread );
- _Scheduler_priority_Ready_queue_enqueue( thread, &self->Bit_map );
+ _Scheduler_priority_Ready_queue_enqueue(
+ thread,
+ &node->Ready_queue,
+ &self->Bit_map
+ );
}
static void _Scheduler_priority_SMP_Insert_ready_fifo(
@@ -137,8 +171,14 @@ static void _Scheduler_priority_SMP_Insert_ready_fifo(
{
Scheduler_priority_SMP_Context *self =
_Scheduler_priority_SMP_Self_from_SMP_base( smp_base );
+ Scheduler_priority_SMP_Node *node =
+ _Scheduler_priority_SMP_Node_get( thread );
- _Scheduler_priority_Ready_queue_enqueue_first( thread, &self->Bit_map );
+ _Scheduler_priority_Ready_queue_enqueue_first(
+ thread,
+ &node->Ready_queue,
+ &self->Bit_map
+ );
}
static void _Scheduler_priority_SMP_Do_extract(
@@ -148,15 +188,25 @@ static void _Scheduler_priority_SMP_Do_extract(
{
Scheduler_priority_SMP_Context *self =
_Scheduler_priority_SMP_Self_from_SMP_base( smp_base );
- bool is_scheduled = thread->is_scheduled;
-
- thread->is_in_the_air = is_scheduled;
- thread->is_scheduled = false;
+ Scheduler_priority_SMP_Node *node =
+ _Scheduler_priority_SMP_Node_get( thread );
- if ( is_scheduled ) {
+ if ( node->Base.state == SCHEDULER_SMP_NODE_SCHEDULED ) {
+ _Scheduler_SMP_Node_change_state(
+ &node->Base,
+ SCHEDULER_SMP_NODE_IN_THE_AIR
+ );
_Chain_Extract_unprotected( &thread->Object.Node );
} else {
- _Scheduler_priority_Ready_queue_extract( thread, &self->Bit_map );
+ _Scheduler_SMP_Node_change_state(
+ &node->Base,
+ SCHEDULER_SMP_NODE_BLOCKED
+ );
+ _Scheduler_priority_Ready_queue_extract(
+ thread,
+ &node->Ready_queue,
+ &self->Bit_map
+ );
}
}
diff --git a/cpukit/score/src/schedulerpriorityunblock.c b/cpukit/score/src/schedulerpriorityunblock.c
index f5482a8229..e83bff1abf 100644
--- a/cpukit/score/src/schedulerpriorityunblock.c
+++ b/cpukit/score/src/schedulerpriorityunblock.c
@@ -29,8 +29,13 @@ void _Scheduler_priority_Unblock (
{
Scheduler_priority_Context *context =
_Scheduler_priority_Get_context( scheduler );
+ Scheduler_priority_Node *node = _Scheduler_priority_Node_get( the_thread );
- _Scheduler_priority_Ready_queue_enqueue( the_thread, &context->Bit_map );
+ _Scheduler_priority_Ready_queue_enqueue(
+ the_thread,
+ &node->Ready_queue,
+ &context->Bit_map
+ );
/* TODO: flash critical section? */
diff --git a/cpukit/score/src/schedulerpriorityupdate.c b/cpukit/score/src/schedulerpriorityupdate.c
index c906c346b4..8a22ee662d 100644
--- a/cpukit/score/src/schedulerpriorityupdate.c
+++ b/cpukit/score/src/schedulerpriorityupdate.c
@@ -27,9 +27,11 @@ void _Scheduler_priority_Update(
{
Scheduler_priority_Context *context =
_Scheduler_priority_Get_context( scheduler );
+ Scheduler_priority_Node *node = _Scheduler_priority_Node_get( the_thread );
- _Scheduler_priority_Update_body(
+ _Scheduler_priority_Ready_queue_update(
the_thread,
+ &node->Ready_queue,
&context->Bit_map,
&context->Ready[ 0 ]
);
diff --git a/cpukit/score/src/schedulerpriorityyield.c b/cpukit/score/src/schedulerpriorityyield.c
index 63b344ace7..f2aeada660 100644
--- a/cpukit/score/src/schedulerpriorityyield.c
+++ b/cpukit/score/src/schedulerpriorityyield.c
@@ -27,9 +27,8 @@ void _Scheduler_priority_Yield(
Thread_Control *the_thread
)
{
- Scheduler_priority_Per_thread *sched_info_of_thread =
- _Scheduler_priority_Get_scheduler_info( the_thread );
- Chain_Control *ready_chain = sched_info_of_thread->ready_chain;
+ Scheduler_priority_Node *node = _Scheduler_priority_Node_get( the_thread );
+ Chain_Control *ready_chain = node->Ready_queue.ready_chain;
ISR_Level level;
(void) scheduler;
diff --git a/cpukit/score/src/schedulersimplesmp.c b/cpukit/score/src/schedulersimplesmp.c
index 5448d5d3de..7fe2fd7943 100644
--- a/cpukit/score/src/schedulersimplesmp.c
+++ b/cpukit/score/src/schedulersimplesmp.c
@@ -3,7 +3,7 @@
*
* @brief Simple SMP Scheduler Implementation
*
- * @ingroup ScoreSchedulerSMP
+ * @ingroup ScoreSchedulerSMPSimple
*/
/*
@@ -44,6 +44,18 @@ void _Scheduler_simple_smp_Initialize( const Scheduler_Control *scheduler )
_Chain_Initialize_empty( &self->Ready );
}
+bool _Scheduler_simple_smp_Allocate(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread
+)
+{
+ Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( the_thread );
+
+ _Scheduler_SMP_Node_initialize( node );
+
+ return true;
+}
+
static Thread_Control *_Scheduler_simple_smp_Get_highest_ready(
Scheduler_SMP_Context *smp_base
)
@@ -122,10 +134,15 @@ static void _Scheduler_simple_smp_Do_extract(
Thread_Control *thread
)
{
+ Scheduler_SMP_Node *node = _Scheduler_SMP_Node_get( thread );
+
(void) smp_base;
- thread->is_in_the_air = thread->is_scheduled;
- thread->is_scheduled = false;
+ if ( node->state == SCHEDULER_SMP_NODE_SCHEDULED ) {
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_IN_THE_AIR );
+ } else {
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_NODE_BLOCKED );
+ }
_Chain_Extract_unprotected( &thread->Object.Node );
}
diff --git a/cpukit/score/src/schedulersmpvalidstatechanges.c b/cpukit/score/src/schedulersmpvalidstatechanges.c
new file mode 100644
index 0000000000..61f6a7e2d5
--- /dev/null
+++ b/cpukit/score/src/schedulersmpvalidstatechanges.c
@@ -0,0 +1,39 @@
+/**
+ * @file
+ *
+ * @ingroup ScoreSchedulerSMP
+ *
+ * @brief SMP Scheduler Implementation
+ */
+
+/*
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.org/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems/score/schedulerpriorityimpl.h>
+
+/*
+ * Table with all valid state transitions. It is used in
+ * _Scheduler_SMP_Node_change_state() in case RTEMS_DEBUG is defined.
+ */
+const bool _Scheduler_SMP_Node_valid_state_changes[ 4 ][ 4 ] = {
+ /* BLOCKED SCHEDULED READY IN THE AIR */
+ /* BLOCKED */ { false, true, true, false },
+ /* SCHEDULED */ { false, false, true, true },
+ /* READY */ { true, true, false, false },
+ /* IN THE AIR */ { true, true, true, false }
+};
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index 2beaed4563..b65628d1eb 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -181,8 +181,6 @@ bool _Thread_Initialize(
the_thread->Start.isr_level = isr_level;
#if defined(RTEMS_SMP)
- the_thread->is_scheduled = false;
- the_thread->is_in_the_air = false;
the_thread->scheduler = scheduler;
_CPU_Context_Set_is_executing( &the_thread->Registers, false );
#endif
diff --git a/testsuites/sptests/spsize/size.c b/testsuites/sptests/spsize/size.c
index dc1e55b10d..9e4823e1b1 100644
--- a/testsuites/sptests/spsize/size.c
+++ b/testsuites/sptests/spsize/size.c
@@ -87,7 +87,7 @@ void print_formula(void);
/* Priority scheduling per-thread consumption. Gets
* included in the PER_TASK consumption.
*/
-#define SCHEDULER_TASK_WKSP (sizeof(Scheduler_priority_Per_thread))
+#define SCHEDULER_TASK_WKSP (sizeof(Scheduler_priority_Node))
/* Priority scheduling workspace consumption
*