summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2023-11-21 11:13:16 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2023-11-21 11:15:25 +0100
commit625f1d82a723e64119e596cf2965604a71137057 (patch)
tree676502cb251dd73cbfcc7edc7d6f62d84b28df65 /spec
parent8329e37a2459916c3796e029a7aeba6382dd6824 (diff)
spec: Specify thread dispatch detail
Diffstat (limited to 'spec')
-rw-r--r--spec/score/thread/req/thread-dispatch-no-recursion.yml15
-rw-r--r--spec/score/thread/val/thread.yml86
2 files changed, 100 insertions, 1 deletions
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