summaryrefslogtreecommitdiffstats
path: root/cpukit/score/include/rtems/score/schedulerimpl.h
diff options
context:
space:
mode:
authorLuca Bonato <lohathe@gmail.com>2014-11-21 11:01:34 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-11-24 08:01:15 +0100
commitcceb19f4e50d7b52e02b39141a433cab75b90423 (patch)
treee10c484498d70192ebb9dd101459750eeb9e9c1d /cpukit/score/include/rtems/score/schedulerimpl.h
parenttermio05: Remove unreferenced files (diff)
downloadrtems-cceb19f4e50d7b52e02b39141a433cab75b90423.tar.bz2
smp: Fix scheduler helping protocol
New test case for smptests/smpmrsp01. Fix _Scheduler_Block_node() in case the node is in the SCHEDULER_HELP_ACTIVE_RIVAL helping state. For example a rtems_task_suspend() on a task waiting for a MrsP semaphore. Fix _Scheduler_Unblock_node() in case the node is in the SCHEDULER_SMP_NODE_READY state. For example a rtems_task_resume() on a task owning or waiting for a MrsP semaphore.
Diffstat (limited to 'cpukit/score/include/rtems/score/schedulerimpl.h')
-rw-r--r--cpukit/score/include/rtems/score/schedulerimpl.h28
1 files changed, 14 insertions, 14 deletions
diff --git a/cpukit/score/include/rtems/score/schedulerimpl.h b/cpukit/score/include/rtems/score/schedulerimpl.h
index 45a2f8da9d..b262b91f84 100644
--- a/cpukit/score/include/rtems/score/schedulerimpl.h
+++ b/cpukit/score/include/rtems/score/schedulerimpl.h
@@ -1081,6 +1081,7 @@ RTEMS_INLINE_ROUTINE Thread_Control *_Scheduler_Release_idle_thread(
*/
RTEMS_INLINE_ROUTINE bool _Scheduler_Block_node(
Scheduler_Context *context,
+ Thread_Control *thread,
Scheduler_Node *node,
bool is_scheduled,
Scheduler_Get_idle_thread get_idle_thread
@@ -1088,25 +1089,24 @@ RTEMS_INLINE_ROUTINE bool _Scheduler_Block_node(
{
bool block;
Thread_Control *old_user = _Scheduler_Node_get_user( node );
- Thread_Control *new_user;
+ Thread_Control *new_user = NULL;
_Scheduler_Thread_change_state( old_user, THREAD_SCHEDULER_BLOCKED );
- if ( node->help_state == SCHEDULER_HELP_ACTIVE_RIVAL ) {
- new_user = _Scheduler_Node_get_owner( node );
-
- _Assert( new_user != old_user );
- _Scheduler_Node_set_user( node, new_user );
- } else if (
- node->help_state == SCHEDULER_HELP_ACTIVE_OWNER
- && is_scheduled
- ) {
- new_user = _Scheduler_Use_idle_thread( context, node, get_idle_thread );
- } else {
- new_user = NULL;
+ if ( is_scheduled ) {
+ if ( node->help_state == SCHEDULER_HELP_ACTIVE_OWNER ) {
+ new_user = _Scheduler_Use_idle_thread( context, node, get_idle_thread );
+ } else if ( node->help_state == SCHEDULER_HELP_ACTIVE_RIVAL ) {
+ Thread_Control *owner = _Scheduler_Node_get_owner( node );
+
+ if ( thread == old_user && owner != old_user ) {
+ new_user = owner;
+ _Scheduler_Node_set_user( node, new_user );
+ }
+ }
}
- if ( new_user != NULL && is_scheduled ) {
+ if ( new_user != NULL ) {
Per_CPU_Control *cpu = _Thread_Get_CPU( old_user );
_Scheduler_Thread_change_state( new_user, THREAD_SCHEDULER_SCHEDULED );