[rtems-central commit] spec: Specify scheduler detail

Sebastian Huber sebh at rtems.org
Thu Jul 7 08:02:37 UTC 2022


Module:    rtems-central
Branch:    master
Commit:    4bae3f03ec895919829d7d1fcdca70f922d194b9
Changeset: http://git.rtems.org/rtems-central/commit/?id=4bae3f03ec895919829d7d1fcdca70f922d194b9

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Jul  4 16:12:53 2022 +0200

spec: Specify scheduler detail

---

 .../sched/smp/req/reconsider-help-keep-ready.yml   |  18 ++++
 spec/score/sched/smp/val/smp.yml                   | 119 ++++++++++++++++++++-
 2 files changed, 135 insertions(+), 2 deletions(-)

diff --git a/spec/score/sched/smp/req/reconsider-help-keep-ready.yml b/spec/score/sched/smp/req/reconsider-help-keep-ready.yml
new file mode 100644
index 00000000..1d8e2ac8
--- /dev/null
+++ b/spec/score/sched/smp/req/reconsider-help-keep-ready.yml
@@ -0,0 +1,18 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2022 embedded brains GmbH (http://www.embedded-brains.de)
+enabled-by: RTEMS_SMP
+links:
+- role: requirement-refinement
+  uid: group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+  While a thread is not a ${/glossary/scheduledtask:/term}, while the thread is
+  in the set of ${/glossary/readytask:/plural} of an
+  ${/glossary/scheduler-eligible:/term}, when a help request is reconsidered
+  for the thread on the scheduler, the thread shall not get removed from the
+  set of ${/glossary/readytask:/plural} of the scheduler.
+type: requirement
diff --git a/spec/score/sched/smp/val/smp.yml b/spec/score/sched/smp/val/smp.yml
index 5588e739..0054e7d4 100644
--- a/spec/score/sched/smp/val/smp.yml
+++ b/spec/score/sched/smp/val/smp.yml
@@ -1,6 +1,6 @@
 SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
 copyrights:
-- Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+- Copyright (C) 2021, 2022 embedded brains GmbH (http://www.embedded-brains.de)
 enabled-by: RTEMS_SMP
 links: []
 test-actions:
@@ -421,6 +421,65 @@ test-actions:
       CleanupOwnerBlocked( ctx );
     links: []
   links: []
+- action-brief: |
+    Create three worker threads and a mutex.  Use the mutex and the worker to
+    check that a not scheduled thread does not get removed from the set of
+    ready threads of a scheduler when a help request is reconsidered.
+  action-code: |
+    Thread_Control *worker_b;
+
+    SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_B_ID, PRIO_NORMAL );
+    SetScheduler( ctx->worker_id[ WORKER_C ], SCHEDULER_B_ID, PRIO_HIGH );
+    SendAndSync( ctx, WORKER_B, EVENT_OBTAIN );
+    SendEvents( ctx->worker_id[ WORKER_A ], EVENT_OBTAIN );
+    SetPriority( ctx->worker_id[ WORKER_A ], PRIO_LOW );
+    MakeBusy( ctx, WORKER_B );
+    WaitForBusy( ctx, WORKER_B );
+    MakeBusy( ctx, WORKER_C );
+    WaitForBusy( ctx, WORKER_C );
+  checks:
+  - brief: |
+      Prevent that worker B can perform a post-switch cleanup.
+    code: |
+      worker_b = GetThread( ctx->worker_id[ WORKER_B ] );
+      _Thread_State_acquire( worker_b, &ctx->lock_context );
+      _ISR_lock_ISR_enable( &ctx->lock_context );
+    links: []
+  - brief: |
+      Give worker C a lower priority than worker B.  Worker B will try to
+      finish the thread dispatch by doing a post-switch cleanup.  The
+      post-switch cleanup cannot progress since the runner owns the thread
+      state lock.  Wait until the other processor waits on the thread state
+      lock of worker B.
+    code: |
+      SetPriority( ctx->worker_id[ WORKER_C ], PRIO_LOW );
+      TicketLockWaitForOthers( &worker_b->Join_queue.Queue.Lock, 1 );
+    links: []
+  - brief: |
+      Give worker C a higher priority than worker B.  Let worker B do its
+      post-switch cleanup which will carry out the reconsider help requests for
+      a not scheduled thread.
+    code: |
+      ctx->counter = 0;
+      T_scheduler_set_event_handler( ReleaseThreadLockB, ctx );
+      SetPriority( ctx->worker_id[ WORKER_C ], PRIO_HIGH );
+      T_scheduler_set_event_handler( NULL, NULL );
+      T_eq_u32( ctx->counter, 4 );
+    links:
+    - role: validation
+      uid: ../req/reconsider-help-keep-ready
+  - brief: |
+      Clean up all used resources.
+    code: |
+      StopBusy( ctx, WORKER_B );
+      StopBusy( ctx, WORKER_C );
+      SendAndSync( ctx, WORKER_B, EVENT_RELEASE );
+      SetPriority( ctx->worker_id[ WORKER_A ], PRIO_HIGH );
+      SendEvents( ctx->worker_id[ WORKER_A ], EVENT_RELEASE );
+      SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_A_ID, PRIO_HIGH );
+      SetScheduler( ctx->worker_id[ WORKER_C ], SCHEDULER_A_ID, PRIO_HIGH );
+    links: []
+  links: []
 test-brief: |
   Tests SMP-specific scheduler behaviour.
 test-context:
@@ -448,7 +507,17 @@ test-context:
     This member contains the worker busy status.
   description: null
   member: |
-    volatile bool busy[ WORKER_COUNT ];
+    volatile bool busy[ WORKER_COUNT ]
+- brief: |
+    This member contains an ISR lock context.
+  description: null
+  member: |
+    ISR_lock_Context lock_context
+- brief: |
+    This member contains a counter.
+  description: null
+  member: |
+    uint32_t counter
 - brief: |
     If this member is true, then the worker shall be in the busy loop.
   description: null
@@ -482,6 +551,7 @@ test-includes:
 - rtems.h
 - rtems/test-scheduler.h
 - rtems/score/percpu.h
+- rtems/score/schedulersmp.h
 - rtems/score/threadimpl.h
 test-local-includes:
 - tx-support.h
@@ -932,6 +1002,51 @@ test-support: |
     SetScheduler( ctx->worker_id[ WORKER_C ], SCHEDULER_A_ID, PRIO_HIGH );
   }
 
+  static void ReconsiderHelpRequestB(
+    void                    *arg,
+    const T_scheduler_event *event,
+    T_scheduler_when         when
+  )
+  {
+    Context *ctx;
+
+    (void) when;
+    ctx = arg;
+
+    if ( event->operation == T_SCHEDULER_RECONSIDER_HELP_REQUEST ) {
+      Scheduler_SMP_Node *node;
+
+      node = (Scheduler_SMP_Node *) event->node;
+      T_eq_int( node->state, SCHEDULER_SMP_NODE_READY );
+      ++ctx->counter;
+    }
+  }
+
+  static void ReleaseThreadLockB(
+    void                    *arg,
+    const T_scheduler_event *event,
+    T_scheduler_when         when
+  )
+  {
+    Context *ctx;
+
+    ctx = arg;
+
+    if (
+      when == T_SCHEDULER_AFTER &&
+      event->operation == T_SCHEDULER_UPDATE_PRIORITY
+    ) {
+      Thread_Control *worker_b;
+
+      T_scheduler_set_event_handler( ReconsiderHelpRequestB, ctx );
+
+      worker_b = GetThread( ctx->worker_id[ WORKER_B ] );
+      T_eq_int( worker_b->Scheduler.state, THREAD_SCHEDULER_READY );
+
+      _Thread_State_release_critical( worker_b, &ctx->lock_context );
+    }
+  }
+
   static void Worker( rtems_task_argument arg, WorkerIndex worker )
   {
     Context *ctx;



More information about the vc mailing list