summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src/threadrestart.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-05-05 13:05:54 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-05-19 12:00:47 +0200
commit900d337f960cb7cc53f5c93c29a503e5ced2c31f (patch)
tree1d1f49724e5cfcef1974d5dc4251486b0fddd2ef /cpukit/score/src/threadrestart.c
parentscore: Fine grained locking for mutexes (diff)
downloadrtems-900d337f960cb7cc53f5c93c29a503e5ced2c31f.tar.bz2
score: Rework _Thread_Change_priority()
Move the writes to Thread_Control::current_priority and Thread_Control::real_priority into _Thread_Change_priority() under the protection of the thread lock. Add a filter function to _Thread_Change_priority() to enable specialized variants. Avoid race conditions during a thread priority restore with the new Thread_Control::priority_restore_hint for an important average case optimizations used by priority inheritance mutexes. Update #2273.
Diffstat (limited to 'cpukit/score/src/threadrestart.c')
-rw-r--r--cpukit/score/src/threadrestart.c46
1 files changed, 34 insertions, 12 deletions
diff --git a/cpukit/score/src/threadrestart.c b/cpukit/score/src/threadrestart.c
index 8dea518e10..b98b6388f8 100644
--- a/cpukit/score/src/threadrestart.c
+++ b/cpukit/score/src/threadrestart.c
@@ -42,6 +42,28 @@ static Thread_Zombie_control _Thread_Zombies = {
.Lock = ISR_LOCK_INITIALIZER( "thread zombies" )
};
+static bool _Thread_Raise_real_priority_filter(
+ Thread_Control *the_thread,
+ Priority_Control *new_priority_ptr,
+ void *arg
+)
+{
+ Priority_Control real_priority;
+ Priority_Control new_priority;
+ Priority_Control current_priority;
+
+ real_priority = the_thread->real_priority;
+ new_priority = *new_priority_ptr;
+ current_priority = the_thread->current_priority;
+
+ new_priority = _Thread_Priority_highest( real_priority, new_priority );
+ *new_priority_ptr = new_priority;
+
+ the_thread->real_priority = new_priority;
+
+ return _Thread_Priority_less_than( current_priority, new_priority );
+}
+
static void _Thread_Make_zombie( Thread_Control *the_thread )
{
ISR_lock_Context lock_context;
@@ -231,12 +253,17 @@ static void _Thread_Start_life_change(
the_thread->is_preemptible = the_thread->Start.is_preemptible;
the_thread->budget_algorithm = the_thread->Start.budget_algorithm;
the_thread->budget_callout = the_thread->Start.budget_callout;
- the_thread->real_priority = priority;
_Thread_Set_state( the_thread, STATES_RESTARTING );
_Thread_queue_Extract_with_proxy( the_thread );
_Watchdog_Remove_ticks( &the_thread->Timer );
- _Scheduler_Set_priority_if_higher( scheduler, the_thread, priority );
+ _Thread_Change_priority(
+ the_thread,
+ priority,
+ NULL,
+ _Thread_Raise_real_priority_filter,
+ false
+ );
_Thread_Add_post_switch_action( the_thread, &the_thread->Life.Action );
_Thread_Ready( the_thread );
}
@@ -260,9 +287,9 @@ static void _Thread_Request_life_change(
scheduler = _Scheduler_Get( the_thread );
if ( the_thread == executing ) {
- executing->real_priority = priority;
+ Priority_Control unused;
- _Scheduler_Set_priority_if_higher( scheduler, the_thread, priority );
+ _Thread_Set_priority( the_thread, priority, &unused, true );
_Thread_Start_life_change_for_executing( executing );
} else if ( previous_life_state == THREAD_LIFE_NORMAL ) {
_Thread_Start_life_change( the_thread, scheduler, priority );
@@ -270,16 +297,11 @@ static void _Thread_Request_life_change(
_Thread_Clear_state( the_thread, STATES_SUSPENDED );
if ( _Thread_Is_life_terminating( additional_life_state ) ) {
- the_thread->real_priority = _Scheduler_Highest_priority_of_two(
- scheduler,
- the_thread->real_priority,
- priority
- );
-
- _Scheduler_Change_priority_if_higher(
- scheduler,
+ _Thread_Change_priority(
the_thread,
priority,
+ NULL,
+ _Thread_Raise_real_priority_filter,
false
);
}