[rtems-central commit] spec: Specify thread dispatch detail

Sebastian Huber sebh at rtems.org
Tue Nov 21 13:35:41 UTC 2023


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Nov 21 11:13:16 2023 +0100

spec: Specify thread dispatch detail

---

 .../thread/req/thread-dispatch-no-recursion.yml    | 15 ++++
 spec/score/thread/val/thread.yml                   | 86 +++++++++++++++++++++-
 2 files changed, 100 insertions(+), 1 deletion(-)

diff --git a/spec/score/thread/req/thread-dispatch-no-recursion.yml b/spec/score/thread/req/thread-dispatch-no-recursion.yml
new file mode 100644
index 00000000..6d1466d4
--- /dev/null
+++ b/spec/score/thread/req/thread-dispatch-no-recursion.yml
@@ -0,0 +1,15 @@
+SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
+copyrights:
+- Copyright (C) 2023 embedded brains GmbH & Co. KG
+enabled-by: true
+links:
+- role: requirement-refinement
+  uid: ../if/group
+functional-type: function
+rationale: null
+references: []
+requirement-type: functional
+text: |
+  While a thread dispatch is necessary, when a thread context switch returned,
+  the thread dispatch to the heir thread shall be done without recursion.
+type: requirement
diff --git a/spec/score/thread/val/thread.yml b/spec/score/thread/val/thread.yml
index 23ecf414..d6a95f62 100644
--- a/spec/score/thread/val/thread.yml
+++ b/spec/score/thread/val/thread.yml
@@ -1,6 +1,6 @@
 SPDX-License-Identifier: CC-BY-SA-4.0 OR BSD-2-Clause
 copyrights:
-- Copyright (C) 2021 embedded brains GmbH & Co. KG
+- Copyright (C) 2021, 2023 embedded brains GmbH & Co. KG
 enabled-by: true
 links: []
 test-actions:
@@ -144,6 +144,37 @@ test-actions:
     - role: validation
       uid: ../req/global-construction-classic-before-entry
   links: []
+- action-brief: |
+    Validate that thread dispatching does not recurse.  Issue a couple of
+    thread context switches during a thread dispatch.  Record the stack
+    pointers of the heir threads.
+  action-code: |
+    SetSelfPriority( PRIO_NORMAL );
+    ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+    StartTask( ctx->worker_id, WorkerTask, NULL );
+
+    ctx->thread_switch_state = 0;
+    ctx->runner_stack[ 0 ] = 0;
+    ctx->runner_stack[ 1 ] = 1;
+    ctx->worker_stack[ 0 ] = 0;
+    ctx->worker_stack[ 1 ] = 1;
+    SetTaskSwitchExtension( TaskSwitch );
+    ResumeTask( ctx->worker_id );
+
+    SetTaskSwitchExtension( NULL );
+    DeleteTask( ctx->worker_id );
+    RestoreRunnerPriority();
+  checks:
+  - brief: |
+      Check that the thread dispatching did not recurse through the recorded
+      stack pointers.
+    code: |
+      T_eq_uptr( ctx->runner_stack[ 0 ], ctx->runner_stack[ 1 ] );
+      T_eq_uptr( ctx->worker_stack[ 0 ], ctx->worker_stack[ 1 ] );
+    links:
+    - role: validation
+      uid: ../req/thread-dispatch-no-recursion
+  links: []
 test-brief: |
   Tests general thread behaviour.
 test-context:
@@ -162,6 +193,21 @@ test-context:
   description: null
   member: |
     volatile double fp_obj
+- brief: |
+    This member indicates the thread switch state.
+  description: null
+  member: |
+    int thread_switch_state
+- brief: |
+    This member contain the runner stack pointer at the context switch.
+  description: null
+  member: |
+    uintptr_t runner_stack[ 2 ]
+- brief: |
+    This member contain the worker stack pointer at the context switch.
+  description: null
+  member: |
+    uintptr_t worker_stack[ 2 ]
 test-context-support: null
 test-description: null
 test-header: null
@@ -239,6 +285,44 @@ test-support: |
     ctx = (Context *) arg;
     DeleteTask( ctx->worker_id );
   }
+
+  static void TaskSwitch( rtems_tcb *executing, rtems_tcb *heir )
+  {
+    Context  *ctx;
+    rtems_id  worker_id;
+    int       state;
+    uintptr_t heir_stack;
+
+    ctx = T_fixture_context();
+    worker_id = ctx->worker_id;
+    state = ctx->thread_switch_state;
+    ctx->thread_switch_state = state + 1;
+    heir_stack = _CPU_Context_Get_SP( &heir->Registers );
+
+    switch ( state ) {
+      case 0:
+        T_eq_u32( heir->Object.id, worker_id );
+        SuspendTask( worker_id );
+        ctx->worker_stack[ 0 ] = heir_stack;
+        break;
+      case 1:
+        T_eq_u32( executing->Object.id, worker_id );
+        ResumeTask( worker_id );
+        ctx->runner_stack[ 0 ] = heir_stack;
+        break;
+      case 2:
+        T_eq_u32( heir->Object.id, worker_id );
+        SuspendTask( worker_id );
+        ctx->worker_stack[ 1 ] = heir_stack;
+        break;
+      case 3:
+        T_eq_u32( executing->Object.id, worker_id );
+        ctx->runner_stack[ 1 ] = heir_stack;
+        break;
+      default:
+        T_unreachable();
+    }
+  }
 test-target: testsuites/validation/tc-score-thread.c
 test-teardown: null
 type: test-case



More information about the vc mailing list