[rtems commit] score: Fix plain priority thread queues (SMP)

Sebastian Huber sebh at rtems.org
Thu Feb 7 07:48:48 UTC 2019


Module:    rtems
Branch:    master
Commit:    fbd08066af13beda4abdb25717f66d0a943fc5c8
Changeset: http://git.rtems.org/rtems/commit/?id=fbd08066af13beda4abdb25717f66d0a943fc5c8

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Thu Feb  7 07:46:38 2019 +0100

score: Fix plain priority thread queues (SMP)

We must add/remove the priority queue to the FIFO of priority queues.

---

 cpukit/score/src/threadqops.c         |  8 +++++
 testsuites/smptests/smpmutex01/init.c | 63 +++++++++++++++++++++++++++++++++++
 2 files changed, 71 insertions(+)

diff --git a/cpukit/score/src/threadqops.c b/cpukit/score/src/threadqops.c
index 445fc4c..dbabf9c 100644
--- a/cpukit/score/src/threadqops.c
+++ b/cpukit/score/src/threadqops.c
@@ -360,6 +360,10 @@ static void _Thread_queue_Priority_priority_actions(
     switch ( priority_action_type ) {
 #if defined(RTEMS_SMP)
       case PRIORITY_ACTION_ADD:
+        if ( _Priority_Is_empty( &priority_queue->Queue ) ) {
+          _Chain_Append_unprotected( &heads->Heads.Fifo, &priority_queue->Node );
+        }
+
         _Priority_Plain_insert(
           &priority_queue->Queue,
           &scheduler_node->Wait.Priority.Node,
@@ -371,6 +375,10 @@ static void _Thread_queue_Priority_priority_actions(
           &priority_queue->Queue,
           &scheduler_node->Wait.Priority.Node
         );
+
+        if ( _Priority_Is_empty( &priority_queue->Queue ) ) {
+          _Chain_Extract_unprotected( &priority_queue->Node );
+        }
         break;
 #endif
       default:
diff --git a/testsuites/smptests/smpmutex01/init.c b/testsuites/smptests/smpmutex01/init.c
index 37f3bf1..09ee496 100644
--- a/testsuites/smptests/smpmutex01/init.c
+++ b/testsuites/smptests/smpmutex01/init.c
@@ -687,6 +687,67 @@ static void test_mixed_queue_two_scheduler_instances_sem_only(test_context *ctx)
   sem_release(ctx);
 }
 
+static void test_two_scheduler_instances_sem_with_inheritance(test_context *ctx)
+{
+  sem_obtain(ctx);
+
+  request(ctx, B_4, REQ_MTX_OBTAIN);
+  check_generations(ctx, B_4, NONE);
+  assert_prio_by_scheduler(ctx, B_4, SCHED_A, PRIO_NONE);
+  assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
+
+  request(ctx, B_4, REQ_SEM_OBTAIN_RELEASE);
+  check_generations(ctx, NONE, NONE);
+
+  request(ctx, A_1, REQ_MTX_OBTAIN);
+  check_generations(ctx, NONE, NONE);
+  assert_prio_by_scheduler(ctx, B_4, SCHED_A, 1);
+  assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
+
+  sem_release(ctx);
+  sync_with_helper(ctx);
+  check_generations(ctx, B_4, NONE);
+
+  request(ctx, B_4, REQ_MTX_RELEASE);
+  check_generations(ctx, B_4, A_1);
+  assert_prio_by_scheduler(ctx, B_4, SCHED_A, PRIO_NONE);
+  assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
+
+  request(ctx, A_1, REQ_MTX_RELEASE);
+  check_generations(ctx, A_1, NONE);
+}
+
+static void test_two_scheduler_instances_sem_with_inheritance_timeout(test_context *ctx)
+{
+  sem_obtain(ctx);
+
+  request(ctx, B_4, REQ_MTX_OBTAIN);
+  check_generations(ctx, B_4, NONE);
+  assert_prio_by_scheduler(ctx, B_4, SCHED_A, PRIO_NONE);
+  assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
+
+  request(ctx, B_4, REQ_SEM_OBTAIN_RELEASE);
+  check_generations(ctx, NONE, NONE);
+
+  request(ctx, A_1, REQ_MTX_OBTAIN_TIMEOUT);
+  check_generations(ctx, NONE, NONE);
+  assert_prio_by_scheduler(ctx, B_4, SCHED_A, 1);
+  assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
+  wait();
+  check_generations(ctx, A_1, NONE);
+  assert_prio_by_scheduler(ctx, B_4, SCHED_A, PRIO_NONE);
+  assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
+
+  sem_release(ctx);
+  sync_with_helper(ctx);
+  check_generations(ctx, B_4, NONE);
+
+  request(ctx, B_4, REQ_MTX_RELEASE);
+  check_generations(ctx, B_4, NONE);
+  assert_prio_by_scheduler(ctx, B_4, SCHED_A, PRIO_NONE);
+  assert_prio_by_scheduler(ctx, B_4, SCHED_B, 4);
+}
+
 static void test_simple_inheritance_two_scheduler_instances(test_context *ctx)
 {
   obtain(ctx);
@@ -1010,6 +1071,8 @@ static void test(test_context *ctx)
     test_dequeue_order_one_scheduler_instance(ctx);
     test_mixed_queue_two_scheduler_instances(ctx);
     test_mixed_queue_two_scheduler_instances_sem_only(ctx);
+    test_two_scheduler_instances_sem_with_inheritance(ctx);
+    test_two_scheduler_instances_sem_with_inheritance_timeout(ctx);
     test_simple_inheritance_two_scheduler_instances(ctx);
     test_nested_inheritance_two_scheduler_instances(ctx);
     test_dequeue_order_two_scheduler_instances(ctx);



More information about the vc mailing list