summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-08 22:22:46 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-06-22 14:44:56 +0200
commit9bfad8cd519f17cbb26a672868169fcd304d5bd5 (patch)
tree3a07add3fb0cdf47fe4d5c9432ad931429c05d65 /cpukit/score/src
parentscore: Move _RBTree_Find() (diff)
downloadrtems-9bfad8cd519f17cbb26a672868169fcd304d5bd5.tar.bz2
score: Add thread priority to scheduler nodes
The thread priority is manifest in two independent areas. One area is the user visible thread priority along with a potential thread queue. The other is the scheduler. Currently, a thread priority update via _Thread_Change_priority() first updates the user visble thread priority and the thread queue, then the scheduler is notified if necessary. The priority is passed to the scheduler via a local variable. A generation counter ensures that the scheduler discards out-of-date priorities. This use of a local variable ties the update in these two areas close together. For later enhancements and the OMIP locking protocol implementation we need more flexibility. Add a thread priority information block to Scheduler_Node and synchronize priority value updates via a sequence lock on SMP configurations. Update #2556.
Diffstat (limited to 'cpukit/score/src')
-rw-r--r--cpukit/score/src/schedulercbsnodeinit.c5
-rw-r--r--cpukit/score/src/schedulercbsunblock.c4
-rw-r--r--cpukit/score/src/schedulerdefaultnodeinit.c5
-rw-r--r--cpukit/score/src/schedulerdefaultupdate.c33
-rw-r--r--cpukit/score/src/scheduleredfchangepriority.c31
-rw-r--r--cpukit/score/src/scheduleredfnodeinit.c5
-rw-r--r--cpukit/score/src/scheduleredfunblock.c14
-rw-r--r--cpukit/score/src/scheduleredfupdate.c38
-rw-r--r--cpukit/score/src/schedulerpriority.c21
-rw-r--r--cpukit/score/src/schedulerpriorityaffinitysmp.c20
-rw-r--r--cpukit/score/src/schedulerprioritychangepriority.c30
-rw-r--r--cpukit/score/src/schedulerprioritysmp.c42
-rw-r--r--cpukit/score/src/schedulerpriorityunblock.c28
-rw-r--r--cpukit/score/src/schedulerpriorityupdate.c39
-rw-r--r--cpukit/score/src/schedulersimplechangepriority.c20
-rw-r--r--cpukit/score/src/schedulersimplesmp.c28
-rw-r--r--cpukit/score/src/schedulerstrongapa.c42
-rw-r--r--cpukit/score/src/thread.c1
-rw-r--r--cpukit/score/src/threadchangepriority.c21
-rw-r--r--cpukit/score/src/threadinitialize.c4
20 files changed, 181 insertions, 250 deletions
diff --git a/cpukit/score/src/schedulercbsnodeinit.c b/cpukit/score/src/schedulercbsnodeinit.c
index df679b6588..3aa825bd12 100644
--- a/cpukit/score/src/schedulercbsnodeinit.c
+++ b/cpukit/score/src/schedulercbsnodeinit.c
@@ -22,12 +22,13 @@
void _Scheduler_CBS_Node_initialize(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread
+ Thread_Control *the_thread,
+ Priority_Control priority
)
{
Scheduler_CBS_Node *node;
- _Scheduler_EDF_Node_initialize( scheduler, the_thread );
+ _Scheduler_EDF_Node_initialize( scheduler, the_thread, priority );
node = _Scheduler_CBS_Thread_get_node( the_thread );
node->cbs_server = NULL;
diff --git a/cpukit/score/src/schedulercbsunblock.c b/cpukit/score/src/schedulercbsunblock.c
index 3f5bd33623..70db651080 100644
--- a/cpukit/score/src/schedulercbsunblock.c
+++ b/cpukit/score/src/schedulercbsunblock.c
@@ -34,11 +34,13 @@ Scheduler_Void_or_thread _Scheduler_CBS_Unblock(
Scheduler_CBS_Node *node;
Scheduler_CBS_Server *serv_info;
Priority_Control priority;
+ bool prepend_it;
context = _Scheduler_EDF_Get_context( scheduler );
node = _Scheduler_CBS_Thread_get_node( the_thread );
serv_info = node->cbs_server;
- priority = node->Base.current_priority;
+ priority = _Scheduler_Node_get_priority( &node->Base.Base, &prepend_it );
+ (void) prepend_it;
/*
* Late unblock rule for deadline-driven tasks. The remaining time to
diff --git a/cpukit/score/src/schedulerdefaultnodeinit.c b/cpukit/score/src/schedulerdefaultnodeinit.c
index a96a528ee4..de2b6c8dd3 100644
--- a/cpukit/score/src/schedulerdefaultnodeinit.c
+++ b/cpukit/score/src/schedulerdefaultnodeinit.c
@@ -23,12 +23,13 @@
void _Scheduler_default_Node_initialize(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread
+ Thread_Control *the_thread,
+ Priority_Control priority
)
{
Scheduler_Node *node = _Scheduler_Thread_get_own_node( the_thread );
(void) scheduler;
- _Scheduler_Node_do_initialize( node, the_thread );
+ _Scheduler_Node_do_initialize( node, the_thread, priority );
}
diff --git a/cpukit/score/src/schedulerdefaultupdate.c b/cpukit/score/src/schedulerdefaultupdate.c
deleted file mode 100644
index fcdc838502..0000000000
--- a/cpukit/score/src/schedulerdefaultupdate.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * @file
- *
- * @brief Scheduler Default Update Operation
- *
- * @ingroup ScoreScheduler
- */
-
-/*
- * COPYRIGHT (c) 2011.
- * On-Line Applications Research Corporation (OAR).
- *
- * 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/scheduler.h>
-
-void _Scheduler_default_Update_priority(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread,
- Priority_Control new_priority
-)
-{
- (void) scheduler;
- (void) the_thread;
- (void) new_priority;
-}
diff --git a/cpukit/score/src/scheduleredfchangepriority.c b/cpukit/score/src/scheduleredfchangepriority.c
index a0f5ec7061..9a73128e4c 100644
--- a/cpukit/score/src/scheduleredfchangepriority.c
+++ b/cpukit/score/src/scheduleredfchangepriority.c
@@ -36,31 +36,42 @@ Priority_Control _Scheduler_EDF_Unmap_priority(
return priority & ~SCHEDULER_EDF_PRIO_MSB;
}
-Scheduler_Void_or_thread _Scheduler_EDF_Change_priority(
+Scheduler_Void_or_thread _Scheduler_EDF_Update_priority(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread,
- Priority_Control new_priority,
- bool prepend_it
+ Thread_Control *the_thread
)
{
Scheduler_EDF_Context *context;
Scheduler_EDF_Node *node;
+ Priority_Control priority;
+ bool prepend_it;
+
+ if ( !_Thread_Is_ready( the_thread ) ) {
+ /* Nothing to do */
+ SCHEDULER_RETURN_VOID_OR_NULL;
+ }
- context = _Scheduler_EDF_Get_context( scheduler );
node = _Scheduler_EDF_Thread_get_node( the_thread );
+ priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
- if ( ( new_priority & SCHEDULER_EDF_PRIO_MSB ) != 0 ) {
- node->background_priority = new_priority;
+ if ( priority == node->current_priority ) {
+ /* Nothing to do */
+ SCHEDULER_RETURN_VOID_OR_NULL;
}
- node->current_priority = new_priority;
+ if ( ( priority & SCHEDULER_EDF_PRIO_MSB ) != 0 ) {
+ node->background_priority = priority;
+ }
+
+ node->current_priority = priority;
+ context = _Scheduler_EDF_Get_context( scheduler );
_Scheduler_EDF_Extract( context, node );
if ( prepend_it ) {
- _Scheduler_EDF_Enqueue_first( context, node, new_priority );
+ _Scheduler_EDF_Enqueue_first( context, node, priority );
} else {
- _Scheduler_EDF_Enqueue( context, node, new_priority );
+ _Scheduler_EDF_Enqueue( context, node, priority );
}
_Scheduler_EDF_Schedule_body( scheduler, the_thread, false );
diff --git a/cpukit/score/src/scheduleredfnodeinit.c b/cpukit/score/src/scheduleredfnodeinit.c
index ec6d9bae7c..6005fa0538 100644
--- a/cpukit/score/src/scheduleredfnodeinit.c
+++ b/cpukit/score/src/scheduleredfnodeinit.c
@@ -22,14 +22,15 @@
void _Scheduler_EDF_Node_initialize(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread
+ Thread_Control *the_thread,
+ Priority_Control priority
)
{
Scheduler_EDF_Node *node = _Scheduler_EDF_Thread_get_node( the_thread );
(void) scheduler;
- _Scheduler_Node_do_initialize( &node->Base, the_thread );
+ _Scheduler_Node_do_initialize( &node->Base, the_thread, priority );
node->thread = the_thread;
}
diff --git a/cpukit/score/src/scheduleredfunblock.c b/cpukit/score/src/scheduleredfunblock.c
index b3acbcd4c2..9f80fa9aea 100644
--- a/cpukit/score/src/scheduleredfunblock.c
+++ b/cpukit/score/src/scheduleredfunblock.c
@@ -29,11 +29,16 @@ Scheduler_Void_or_thread _Scheduler_EDF_Unblock(
{
Scheduler_EDF_Context *context;
Scheduler_EDF_Node *node;
+ Priority_Control priority;
+ bool prepend_it;
context = _Scheduler_EDF_Get_context( scheduler );
node = _Scheduler_EDF_Thread_get_node( the_thread );
+ priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
+ (void) prepend_it;
- _Scheduler_EDF_Enqueue( context, node, node->current_priority );
+ node->current_priority = priority;
+ _Scheduler_EDF_Enqueue( context, node, priority );
/*
* If the thread that was unblocked is more important than the heir,
@@ -47,11 +52,8 @@ Scheduler_Void_or_thread _Scheduler_EDF_Unblock(
* Even if the thread isn't preemptible, if the new heir is
* a pseudo-ISR system task, we need to do a context switch.
*/
- if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
- _Scheduler_Update_heir(
- the_thread,
- the_thread->current_priority == PRIORITY_PSEUDO_ISR
- );
+ if ( priority < _Thread_Heir->current_priority ) {
+ _Scheduler_Update_heir( the_thread, priority == PRIORITY_PSEUDO_ISR );
}
SCHEDULER_RETURN_VOID_OR_NULL;
diff --git a/cpukit/score/src/scheduleredfupdate.c b/cpukit/score/src/scheduleredfupdate.c
deleted file mode 100644
index 5d475fe5f1..0000000000
--- a/cpukit/score/src/scheduleredfupdate.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * @file
- *
- * @brief Scheduler EDF Update
- * @ingroup ScoreScheduler
- */
-
-/*
- * Copyright (C) 2011 Petr Benes.
- * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
- *
- * 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/scheduleredfimpl.h>
-
-void _Scheduler_EDF_Update_priority(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread,
- Priority_Control new_priority
-)
-{
- Scheduler_EDF_Node *node;
-
- node = _Scheduler_EDF_Thread_get_node( the_thread );
-
- if ( ( new_priority & SCHEDULER_EDF_PRIO_MSB ) != 0 ) {
- node->background_priority = new_priority;
- }
-
- node->current_priority = new_priority;
-}
diff --git a/cpukit/score/src/schedulerpriority.c b/cpukit/score/src/schedulerpriority.c
index 61505a4fce..2719697ba3 100644
--- a/cpukit/score/src/schedulerpriority.c
+++ b/cpukit/score/src/schedulerpriority.c
@@ -32,3 +32,24 @@ void _Scheduler_priority_Initialize( const Scheduler_Control *scheduler )
scheduler->maximum_priority
);
}
+
+void _Scheduler_priority_Node_initialize(
+ const Scheduler_Control *scheduler,
+ Thread_Control *the_thread,
+ Priority_Control priority
+)
+{
+ Scheduler_priority_Context *context;
+ Scheduler_priority_Node *node;
+
+ context = _Scheduler_priority_Get_context( scheduler );
+ node = _Scheduler_priority_Thread_get_node( the_thread );
+
+ _Scheduler_Node_do_initialize( &node->Base, the_thread, priority );
+ _Scheduler_priority_Ready_queue_update(
+ &node->Ready_queue,
+ priority,
+ &context->Bit_map,
+ &context->Ready[ 0 ]
+ );
+}
diff --git a/cpukit/score/src/schedulerpriorityaffinitysmp.c b/cpukit/score/src/schedulerpriorityaffinitysmp.c
index fa56e2b1b5..3618f4c901 100644
--- a/cpukit/score/src/schedulerpriorityaffinitysmp.c
+++ b/cpukit/score/src/schedulerpriorityaffinitysmp.c
@@ -96,15 +96,14 @@ _Scheduler_priority_affinity_SMP_Node_downcast(
*/
void _Scheduler_priority_affinity_SMP_Node_initialize(
const Scheduler_Control *scheduler,
- Thread_Control *thread
+ Thread_Control *the_thread,
+ Priority_Control priority
)
{
Scheduler_priority_affinity_SMP_Node *node =
- _Scheduler_priority_affinity_SMP_Thread_get_own_node( thread );
-
- (void) scheduler;
+ _Scheduler_priority_affinity_SMP_Thread_get_own_node( the_thread );
- _Scheduler_SMP_Node_initialize( &node->Base.Base, thread );
+ _Scheduler_priority_SMP_Node_initialize( scheduler, the_thread, priority );
/*
* All we add is affinity information to the basic SMP node.
@@ -409,6 +408,7 @@ Thread_Control *_Scheduler_priority_affinity_SMP_Unblock(
needs_help = _Scheduler_SMP_Unblock(
context,
thread,
+ _Scheduler_priority_SMP_Do_update,
_Scheduler_priority_affinity_SMP_Enqueue_fifo
);
@@ -535,21 +535,17 @@ static Thread_Control *_Scheduler_priority_affinity_SMP_Enqueue_scheduled_fifo(
/*
* This is the public scheduler specific Change Priority operation.
*/
-Thread_Control *_Scheduler_priority_affinity_SMP_Change_priority(
+Thread_Control *_Scheduler_priority_affinity_SMP_Update_priority(
const Scheduler_Control *scheduler,
- Thread_Control *thread,
- Priority_Control new_priority,
- bool prepend_it
+ Thread_Control *thread
)
{
Scheduler_Context *context = _Scheduler_Get_context( scheduler );
Thread_Control *displaced;
- displaced = _Scheduler_SMP_Change_priority(
+ displaced = _Scheduler_SMP_Update_priority(
context,
thread,
- new_priority,
- prepend_it,
_Scheduler_priority_SMP_Extract_from_ready,
_Scheduler_priority_SMP_Do_update,
_Scheduler_priority_affinity_SMP_Enqueue_fifo,
diff --git a/cpukit/score/src/schedulerprioritychangepriority.c b/cpukit/score/src/schedulerprioritychangepriority.c
index f883e02d43..04599f5c74 100644
--- a/cpukit/score/src/schedulerprioritychangepriority.c
+++ b/cpukit/score/src/schedulerprioritychangepriority.c
@@ -21,16 +21,30 @@
#include <rtems/score/schedulerpriorityimpl.h>
-Scheduler_Void_or_thread _Scheduler_priority_Change_priority(
+Scheduler_Void_or_thread _Scheduler_priority_Update_priority(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread,
- Priority_Control new_priority,
- bool prepend_it
+ Thread_Control *the_thread
)
{
- Scheduler_priority_Context *context =
- _Scheduler_priority_Get_context( scheduler );
- Scheduler_priority_Node *node = _Scheduler_priority_Thread_get_node( the_thread );
+ Scheduler_priority_Context *context;
+ Scheduler_priority_Node *node;
+ unsigned int priority;
+ bool prepend_it;
+
+ if ( !_Thread_Is_ready( the_thread ) ) {
+ /* Nothing to do */
+ SCHEDULER_RETURN_VOID_OR_NULL;
+ }
+
+ node = _Scheduler_priority_Thread_get_node( the_thread );
+ priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
+
+ if ( priority == node->Ready_queue.current_priority ) {
+ /* Nothing to do */
+ SCHEDULER_RETURN_VOID_OR_NULL;
+ }
+
+ context = _Scheduler_priority_Get_context( scheduler );
_Scheduler_priority_Ready_queue_extract(
&the_thread->Object.Node,
@@ -40,7 +54,7 @@ Scheduler_Void_or_thread _Scheduler_priority_Change_priority(
_Scheduler_priority_Ready_queue_update(
&node->Ready_queue,
- new_priority,
+ priority,
&context->Bit_map,
&context->Ready[ 0 ]
);
diff --git a/cpukit/score/src/schedulerprioritysmp.c b/cpukit/score/src/schedulerprioritysmp.c
index bd042d2534..aba863e66a 100644
--- a/cpukit/score/src/schedulerprioritysmp.c
+++ b/cpukit/score/src/schedulerprioritysmp.c
@@ -47,24 +47,27 @@ void _Scheduler_priority_SMP_Initialize( const Scheduler_Control *scheduler )
void _Scheduler_priority_SMP_Node_initialize(
const Scheduler_Control *scheduler,
- Thread_Control *thread
+ Thread_Control *the_thread,
+ Priority_Control priority
)
{
- Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_own_node( thread );
-
- _Scheduler_SMP_Node_initialize( node, thread );
-}
+ Scheduler_Context *context;
+ Scheduler_priority_SMP_Context *self;
+ Scheduler_priority_SMP_Node *node;
-void _Scheduler_priority_SMP_Update_priority(
- const Scheduler_Control *scheduler,
- Thread_Control *thread,
- Priority_Control new_priority
-)
-{
- Scheduler_Context *context = _Scheduler_Get_context( scheduler );
- Scheduler_Node *node = _Scheduler_Thread_get_node( thread );
+ context = _Scheduler_Get_context( scheduler );
+ self = _Scheduler_priority_SMP_Get_self( context );
+ node = _Scheduler_priority_SMP_Node_downcast(
+ _Scheduler_Thread_get_own_node( the_thread )
+ );
- _Scheduler_priority_SMP_Do_update( context, node, new_priority );
+ _Scheduler_SMP_Node_initialize( &node->Base, the_thread, priority );
+ _Scheduler_priority_Ready_queue_update(
+ &node->Ready_queue,
+ priority,
+ &self->Bit_map,
+ &self->Ready[ 0 ]
+ );
}
static Scheduler_Node *_Scheduler_priority_SMP_Get_highest_ready(
@@ -213,24 +216,21 @@ Thread_Control *_Scheduler_priority_SMP_Unblock(
return _Scheduler_SMP_Unblock(
context,
thread,
+ _Scheduler_priority_SMP_Do_update,
_Scheduler_priority_SMP_Enqueue_fifo
);
}
-Thread_Control *_Scheduler_priority_SMP_Change_priority(
+Thread_Control *_Scheduler_priority_SMP_Update_priority(
const Scheduler_Control *scheduler,
- Thread_Control *thread,
- Priority_Control new_priority,
- bool prepend_it
+ Thread_Control *thread
)
{
Scheduler_Context *context = _Scheduler_Get_context( scheduler );
- return _Scheduler_SMP_Change_priority(
+ return _Scheduler_SMP_Update_priority(
context,
thread,
- new_priority,
- prepend_it,
_Scheduler_priority_SMP_Extract_from_ready,
_Scheduler_priority_SMP_Do_update,
_Scheduler_priority_SMP_Enqueue_fifo,
diff --git a/cpukit/score/src/schedulerpriorityunblock.c b/cpukit/score/src/schedulerpriorityunblock.c
index a912ebfbe2..ba8501bc50 100644
--- a/cpukit/score/src/schedulerpriorityunblock.c
+++ b/cpukit/score/src/schedulerpriorityunblock.c
@@ -27,9 +27,24 @@ Scheduler_Void_or_thread _Scheduler_priority_Unblock (
Thread_Control *the_thread
)
{
- Scheduler_priority_Context *context =
- _Scheduler_priority_Get_context( scheduler );
- Scheduler_priority_Node *node = _Scheduler_priority_Thread_get_node( the_thread );
+ Scheduler_priority_Context *context;
+ Scheduler_priority_Node *node;
+ unsigned int priority;
+ bool prepend_it;
+
+ context = _Scheduler_priority_Get_context( scheduler );
+ node = _Scheduler_priority_Thread_get_node( the_thread );
+ priority = _Scheduler_Node_get_priority( &node->Base, &prepend_it );
+ (void) prepend_it;
+
+ if ( priority != node->Ready_queue.current_priority ) {
+ _Scheduler_priority_Ready_queue_update(
+ &node->Ready_queue,
+ priority,
+ &context->Bit_map,
+ &context->Ready[ 0 ]
+ );
+ }
_Scheduler_priority_Ready_queue_enqueue(
&the_thread->Object.Node,
@@ -51,11 +66,8 @@ Scheduler_Void_or_thread _Scheduler_priority_Unblock (
* Even if the thread isn't preemptible, if the new heir is
* a pseudo-ISR system task, we need to do a context switch.
*/
- if ( the_thread->current_priority < _Thread_Heir->current_priority ) {
- _Scheduler_Update_heir(
- the_thread,
- the_thread->current_priority == PRIORITY_PSEUDO_ISR
- );
+ if ( priority < _Thread_Heir->current_priority ) {
+ _Scheduler_Update_heir( the_thread, priority == PRIORITY_PSEUDO_ISR );
}
SCHEDULER_RETURN_VOID_OR_NULL;
diff --git a/cpukit/score/src/schedulerpriorityupdate.c b/cpukit/score/src/schedulerpriorityupdate.c
deleted file mode 100644
index d2a7e6ccba..0000000000
--- a/cpukit/score/src/schedulerpriorityupdate.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * @file
- *
- * @brief Update Scheduler Priority
- * @ingroup ScoreScheduler
- */
-
-/*
- * Copyright (C) 2010 Gedare Bloom.
- * Copyright (C) 2011 On-Line Applications Research Corporation (OAR).
- *
- * 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>
-
-void _Scheduler_priority_Update_priority(
- const Scheduler_Control *scheduler,
- Thread_Control *the_thread,
- Priority_Control new_priority
-)
-{
- Scheduler_priority_Context *context =
- _Scheduler_priority_Get_context( scheduler );
- Scheduler_priority_Node *node = _Scheduler_priority_Thread_get_node( the_thread );
-
- _Scheduler_priority_Ready_queue_update(
- &node->Ready_queue,
- new_priority,
- &context->Bit_map,
- &context->Ready[ 0 ]
- );
-}
diff --git a/cpukit/score/src/schedulersimplechangepriority.c b/cpukit/score/src/schedulersimplechangepriority.c
index 9b94b3ab26..9d4a565dbd 100644
--- a/cpukit/score/src/schedulersimplechangepriority.c
+++ b/cpukit/score/src/schedulersimplechangepriority.c
@@ -21,15 +21,23 @@
#include <rtems/score/schedulersimpleimpl.h>
-Scheduler_Void_or_thread _Scheduler_simple_Change_priority(
+Scheduler_Void_or_thread _Scheduler_simple_Update_priority(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread,
- Priority_Control new_priority,
- bool prepend_it
+ Thread_Control *the_thread
)
{
- Scheduler_simple_Context *context =
- _Scheduler_simple_Get_context( scheduler );
+ Scheduler_simple_Context *context;
+ Scheduler_Node *node;
+ bool prepend_it;
+
+ if ( !_Thread_Is_ready( the_thread ) ) {
+ /* Nothing to do */
+ SCHEDULER_RETURN_VOID_OR_NULL;
+ }
+
+ context = _Scheduler_simple_Get_context( scheduler );
+ node = _Scheduler_Thread_get_node( the_thread );
+ _Scheduler_Node_get_priority( node, &prepend_it );
_Scheduler_simple_Extract( scheduler, the_thread );
diff --git a/cpukit/score/src/schedulersimplesmp.c b/cpukit/score/src/schedulersimplesmp.c
index 0f05a7da81..f368ead556 100644
--- a/cpukit/score/src/schedulersimplesmp.c
+++ b/cpukit/score/src/schedulersimplesmp.c
@@ -44,12 +44,13 @@ void _Scheduler_simple_SMP_Initialize( const Scheduler_Control *scheduler )
void _Scheduler_simple_SMP_Node_initialize(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread
+ Thread_Control *the_thread,
+ Priority_Control priority
)
{
Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_own_node( the_thread );
- _Scheduler_SMP_Node_initialize( node, the_thread );
+ _Scheduler_SMP_Node_initialize( node, the_thread, priority );
}
static void _Scheduler_simple_SMP_Do_update(
@@ -65,18 +66,6 @@ static void _Scheduler_simple_SMP_Do_update(
_Scheduler_SMP_Node_update_priority( node, new_priority );
}
-void _Scheduler_simple_SMP_Update_priority(
- const Scheduler_Control *scheduler,
- Thread_Control *thread,
- Priority_Control new_priority
-)
-{
- Scheduler_Context *context = _Scheduler_Get_context( scheduler );
- Scheduler_Node *node = _Scheduler_Thread_get_node( thread );
-
- _Scheduler_simple_SMP_Do_update( context, node, new_priority );
-}
-
static Scheduler_Node *_Scheduler_simple_SMP_Get_highest_ready(
Scheduler_Context *context,
Scheduler_Node *node
@@ -295,24 +284,21 @@ Thread_Control *_Scheduler_simple_SMP_Unblock(
return _Scheduler_SMP_Unblock(
context,
thread,
+ _Scheduler_simple_SMP_Do_update,
_Scheduler_simple_SMP_Enqueue_fifo
);
}
-Thread_Control *_Scheduler_simple_SMP_Change_priority(
+Thread_Control *_Scheduler_simple_SMP_Update_priority(
const Scheduler_Control *scheduler,
- Thread_Control *thread,
- Priority_Control new_priority,
- bool prepend_it
+ Thread_Control *thread
)
{
Scheduler_Context *context = _Scheduler_Get_context( scheduler );
- return _Scheduler_SMP_Change_priority(
+ return _Scheduler_SMP_Update_priority(
context,
thread,
- new_priority,
- prepend_it,
_Scheduler_simple_SMP_Extract_from_ready,
_Scheduler_simple_SMP_Do_update,
_Scheduler_simple_SMP_Enqueue_fifo,
diff --git a/cpukit/score/src/schedulerstrongapa.c b/cpukit/score/src/schedulerstrongapa.c
index dd4409766e..51dac679ed 100644
--- a/cpukit/score/src/schedulerstrongapa.c
+++ b/cpukit/score/src/schedulerstrongapa.c
@@ -173,24 +173,27 @@ void _Scheduler_strong_APA_Initialize( const Scheduler_Control *scheduler )
void _Scheduler_strong_APA_Node_initialize(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread
-)
-{
- Scheduler_SMP_Node *node = _Scheduler_SMP_Thread_get_own_node( the_thread );
-
- _Scheduler_SMP_Node_initialize( node, the_thread );
-}
-
-void _Scheduler_strong_APA_Update_priority(
- const Scheduler_Control *scheduler,
Thread_Control *the_thread,
- Priority_Control new_priority
+ Priority_Control priority
)
{
- Scheduler_Context *context = _Scheduler_Get_context( scheduler );
- Scheduler_Node *node = _Scheduler_Thread_get_node( the_thread );
+ Scheduler_Context *context;
+ Scheduler_strong_APA_Context *self;
+ Scheduler_strong_APA_Node *node;
+
+ context = _Scheduler_Get_context( scheduler );
+ self = _Scheduler_strong_APA_Get_self( context );
+ node = _Scheduler_strong_APA_Node_downcast(
+ _Scheduler_Thread_get_own_node( the_thread )
+ );
- _Scheduler_strong_APA_Do_update( context, node, new_priority );
+ _Scheduler_SMP_Node_initialize( &node->Base, the_thread, priority );
+ _Scheduler_priority_Ready_queue_update(
+ &node->Ready_queue,
+ priority,
+ &self->Bit_map,
+ &self->Ready[ 0 ]
+ );
}
static Scheduler_Node *_Scheduler_strong_APA_Get_highest_ready(
@@ -339,24 +342,21 @@ Thread_Control *_Scheduler_strong_APA_Unblock(
return _Scheduler_SMP_Unblock(
context,
the_thread,
+ _Scheduler_strong_APA_Do_update,
_Scheduler_strong_APA_Enqueue_fifo
);
}
-Thread_Control *_Scheduler_strong_APA_Change_priority(
+Thread_Control *_Scheduler_strong_APA_Update_priority(
const Scheduler_Control *scheduler,
- Thread_Control *the_thread,
- Priority_Control new_priority,
- bool prepend_it
+ Thread_Control *the_thread
)
{
Scheduler_Context *context = _Scheduler_Get_context( scheduler );
- return _Scheduler_SMP_Change_priority(
+ return _Scheduler_SMP_Update_priority(
context,
the_thread,
- new_priority,
- prepend_it,
_Scheduler_strong_APA_Extract_from_ready,
_Scheduler_strong_APA_Do_update,
_Scheduler_strong_APA_Enqueue_fifo,
diff --git a/cpukit/score/src/thread.c b/cpukit/score/src/thread.c
index 2e0bbd91bb..8028540e10 100644
--- a/cpukit/score/src/thread.c
+++ b/cpukit/score/src/thread.c
@@ -34,7 +34,6 @@ THREAD_OFFSET_ASSERT( Join_queue );
THREAD_OFFSET_ASSERT( current_state );
THREAD_OFFSET_ASSERT( current_priority );
THREAD_OFFSET_ASSERT( real_priority );
-THREAD_OFFSET_ASSERT( priority_generation );
THREAD_OFFSET_ASSERT( priority_restore_hint );
THREAD_OFFSET_ASSERT( resource_count );
THREAD_OFFSET_ASSERT( Wait );
diff --git a/cpukit/score/src/threadchangepriority.c b/cpukit/score/src/threadchangepriority.c
index 152646f52f..7b22371326 100644
--- a/cpukit/score/src/threadchangepriority.c
+++ b/cpukit/score/src/threadchangepriority.c
@@ -50,11 +50,12 @@ void _Thread_Change_priority(
* we are not REALLY changing priority.
*/
if ( ( *filter )( the_thread, &new_priority, arg ) ) {
- uint32_t my_generation;
+ Scheduler_Node *own_node;
+
+ own_node = _Scheduler_Thread_get_own_node( the_thread );
+ _Scheduler_Node_set_priority( own_node, new_priority, prepend_it );
- my_generation = the_thread->priority_generation + 1;
the_thread->current_priority = new_priority;
- the_thread->priority_generation = my_generation;
( *the_thread->Wait.operations->priority_change )(
the_thread,
@@ -65,19 +66,7 @@ void _Thread_Change_priority(
_Thread_Lock_release( lock, &lock_context );
_Thread_State_acquire( the_thread, &lock_context );
-
- if ( the_thread->priority_generation == my_generation ) {
- if ( _States_Is_ready( the_thread->current_state ) ) {
- _Scheduler_Change_priority(
- the_thread,
- new_priority,
- prepend_it
- );
- } else {
- _Scheduler_Update_priority( the_thread, new_priority );
- }
- }
-
+ _Scheduler_Update_priority( the_thread );
_Thread_State_release( the_thread, &lock_context );
} else {
_Thread_Lock_release( lock, &lock_context );
diff --git a/cpukit/score/src/threadinitialize.c b/cpukit/score/src/threadinitialize.c
index 229d68bf74..10dbf02dfc 100644
--- a/cpukit/score/src/threadinitialize.c
+++ b/cpukit/score/src/threadinitialize.c
@@ -200,11 +200,9 @@ bool _Thread_Initialize(
RTEMS_STATIC_ASSERT( THREAD_WAIT_FLAGS_INITIAL == 0, Wait_flags );
- _Scheduler_Node_initialize( scheduler, the_thread );
+ _Scheduler_Node_initialize( scheduler, the_thread, priority );
scheduler_node_initialized = true;
- _Scheduler_Update_priority( the_thread, priority );
-
/* POSIX Keys */
_RBTree_Initialize_empty( &the_thread->Keys.Key_value_pairs );
_ISR_lock_Initialize( &the_thread->Keys.Lock, "POSIX Key Value Pairs" );