[PATCH 2/5] score: Introduce scheduler nodes
Sebastian Huber
sebastian.huber at embedded-brains.de
Tue May 13 14:18:30 UTC 2014
Rename scheduler per-thread information into scheduler nodes using
Scheduler_Node as the base type. Use inheritance for specialized
schedulers.
Move the scheduler specific states from the thread control block into
the scheduler node structure.
Validate the SMP scheduler node state transitions in case RTEMS_DEBUG is
defined.
---
cpukit/sapi/include/confdefs.h | 17 ++--
cpukit/score/Makefile.am | 2 +
cpukit/score/include/rtems/score/scheduler.h | 9 ++
cpukit/score/include/rtems/score/schedulercbs.h | 4 +-
.../score/include/rtems/score/schedulercbsimpl.h | 52 +++++++++
cpukit/score/include/rtems/score/scheduleredf.h | 9 ++-
.../score/include/rtems/score/scheduleredfimpl.h | 13 ++-
cpukit/score/include/rtems/score/schedulerimpl.h | 7 ++
.../score/include/rtems/score/schedulerpriority.h | 19 +++-
.../rtems/score/schedulerpriorityaffinitysmp.h | 15 +--
.../include/rtems/score/schedulerpriorityimpl.h | 112 +++++++++++---------
.../include/rtems/score/schedulerprioritysmp.h | 29 +++++-
.../score/include/rtems/score/schedulersimplesmp.h | 7 +-
cpukit/score/include/rtems/score/schedulersmp.h | 66 ++++++++++++
.../score/include/rtems/score/schedulersmpimpl.h | 63 +++++++++--
cpukit/score/include/rtems/score/thread.h | 33 +-----
cpukit/score/preinstall.am | 4 +
cpukit/score/src/schedulercbs.c | 12 +-
cpukit/score/src/schedulercbsallocate.c | 15 +--
cpukit/score/src/schedulercbsattachthread.c | 10 +-
cpukit/score/src/schedulercbsdetachthread.c | 8 +-
cpukit/score/src/schedulercbsreleasejob.c | 10 +-
cpukit/score/src/schedulercbsunblock.c | 11 +--
cpukit/score/src/scheduleredf.c | 4 +-
cpukit/score/src/scheduleredfallocate.c | 13 +--
cpukit/score/src/scheduleredfenqueue.c | 8 +-
cpukit/score/src/scheduleredfextract.c | 8 +-
cpukit/score/src/scheduleredfupdate.c | 14 +--
cpukit/score/src/scheduleredfyield.c | 9 +-
cpukit/score/src/schedulerpriorityaffinitysmp.c | 31 +++---
cpukit/score/src/schedulerpriorityenqueue.c | 7 +-
cpukit/score/src/schedulerpriorityenqueuefirst.c | 2 +
cpukit/score/src/schedulerprioritysmp.c | 66 ++++++++++--
cpukit/score/src/schedulerpriorityunblock.c | 7 +-
cpukit/score/src/schedulerpriorityupdate.c | 4 +-
cpukit/score/src/schedulerpriorityyield.c | 5 +-
cpukit/score/src/schedulersimplesmp.c | 23 ++++-
cpukit/score/src/schedulersmpvalidstatechanges.c | 35 ++++++
cpukit/score/src/threadinitialize.c | 2 -
testsuites/sptests/spsize/size.c | 2 +-
40 files changed, 537 insertions(+), 230 deletions(-)
create mode 100644 cpukit/score/include/rtems/score/schedulercbsimpl.h
create mode 100644 cpukit/score/src/schedulersmpvalidstatechanges.c
diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h
index ad432ed..68a2c7d 100644
--- a/cpukit/sapi/include/confdefs.h
+++ b/cpukit/sapi/include/confdefs.h
@@ -2474,18 +2474,21 @@ 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_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 +2514,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 ae92550..8fb11d7 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 768576f..7f0b43a 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 e546c8d..6cfdfbe 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 0000000..f40de07
--- /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 at 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 fabce7e..95be94c 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 d4b197e..708557f 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 42e5730..c972ef5 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 4393b7d..134dcd7 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 c327fcc..e86fd35 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 fde0687..3fb1e5b 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 66de964..3e7d22f 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 880115f..268d88f 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 778a1fb..172cd11 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_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_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_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_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 69222c2..b00804d 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_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,13 @@ 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_SCHEDULED );
_Assert( _ISR_Get_level() != 0 );
@@ -160,10 +188,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_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 +203,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_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_SCHEDULED );
( *insert_scheduled )( self, thread );
}
} else {
@@ -195,11 +222,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_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_READY );
( *insert_ready )( self, thread );
}
}
@@ -226,8 +260,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_IN_THE_AIR ) {
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_BLOCKED );
_Scheduler_SMP_Schedule_highest_ready(
self,
@@ -295,7 +331,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_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 7b5a30f..10c7ddc 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
@@ -495,31 +497,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;
@@ -546,8 +523,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 efbe37d..d00e137 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 54312b2..e2f34d4 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 a6f89c3..6a29088 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 43bf92d..3892e89 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 0f77cdf..6d634ef 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 c5ac572..eec930a 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 030cc85..411e6ce 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 4d1aa62..010d053 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 3dc9dd5..f9aaa57 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 38e67eb..8973d8b 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 02c47af..94fde0a 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 88d6d9d..99a3e0e 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 8f8786a..9eb0782 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 0ea4336..0d9525d 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 e3f2be6..aa901cc 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 0d19706..1714fe5 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 025d960..65a847c 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,19 @@ 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_SCHEDULED ) {
+ _Scheduler_SMP_Node_change_state( &node->Base, SCHEDULER_SMP_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_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 f5482a8..e83bff1 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 c906c34..8a22ee6 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 63b344a..f2aeada 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 5448d5d..4aaab7e 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_SCHEDULED ) {
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_IN_THE_AIR );
+ } else {
+ _Scheduler_SMP_Node_change_state( node, SCHEDULER_SMP_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 0000000..d5c43ef
--- /dev/null
+++ b/cpukit/score/src/schedulersmpvalidstatechanges.c
@@ -0,0 +1,35 @@
+/**
+ * @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 at 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>
+
+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 2beaed4..b65628d 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 dc1e55b..9e4823e 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
*
--
1.7.7
More information about the devel
mailing list