summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-05-13 16:03:05 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-05-14 14:46:19 +0200
commitbeab7329fca655c93743fbb590d00bb4ea5a6d78 (patch)
treefbeb6b27f887b46a41f84acc64aecfce18686540 /cpukit/score/src
parentscore: Scheduler documentation (diff)
downloadrtems-beab7329fca655c93743fbb590d00bb4ea5a6d78.tar.bz2
score: Introduce scheduler nodes
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.
Diffstat (limited to 'cpukit/score/src')
-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
22 files changed, 202 insertions, 112 deletions
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