diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2023-11-21 11:13:16 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2023-11-21 11:15:25 +0100 |
commit | 625f1d82a723e64119e596cf2965604a71137057 (patch) | |
tree | 676502cb251dd73cbfcc7edc7d6f62d84b28df65 /spec | |
parent | 8329e37a2459916c3796e029a7aeba6382dd6824 (diff) |
spec: Specify thread dispatch detail
Diffstat (limited to 'spec')
-rw-r--r-- | spec/score/thread/req/thread-dispatch-no-recursion.yml | 15 | ||||
-rw-r--r-- | spec/score/thread/val/thread.yml | 86 |
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 |