summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-11-24 09:23:09 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-11-24 09:58:44 +0100
commit3d51ce69a90db1a85ab4bcb88dbcf7e41276beb8 (patch)
treed12bf98c7bc831df7d50d5b33b7f7f4da09e8b06
parentspec: Fix text and improve test action (diff)
downloadrtems-central-3d51ce69a90db1a85ab4bcb88dbcf7e41276beb8.tar.bz2
spec: Specify SMP scheduler detail
-rw-r--r--spec/score/sched/smp/req/preempt-blocked.yml16
-rw-r--r--spec/score/sched/smp/val/smp.yml67
2 files changed, 83 insertions, 0 deletions
diff --git a/spec/score/sched/smp/req/preempt-blocked.yml b/spec/score/sched/smp/req/preempt-blocked.yml
new file mode 100644
index 00000000..ecc95f12
--- /dev/null
+++ b/spec/score/sched/smp/req/preempt-blocked.yml
@@ -0,0 +1,16 @@
+SPDX-License-Identifier: CC-BY-SA-4.0
+copyrights:
+- Copyright (C) 2021 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 scheduled by a ${/glossary/scheduler-helping:/term}, while
+ the thread is blocked, when the thread is preempted by the helping scheduler,
+ the thread shall be blocked by the helping scheduler.
+type: requirement
diff --git a/spec/score/sched/smp/val/smp.yml b/spec/score/sched/smp/val/smp.yml
index 36b9c0a3..28963f0d 100644
--- a/spec/score/sched/smp/val/smp.yml
+++ b/spec/score/sched/smp/val/smp.yml
@@ -5,6 +5,41 @@ enabled-by: RTEMS_SMP
links: []
test-actions:
- action-brief: |
+ Construct a system state in which a thread is preempted while it is
+ blocked.
+ action-code: |
+ SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_B_ID, PRIO_NORMAL );
+ SendEvents( ctx->worker_id[ WORKER_A ], EVENT_OBTAIN );
+ SendAndSync( ctx, WORKER_B, EVENT_OBTAIN );
+ SetScheduler( ctx->worker_id[ WORKER_C ], SCHEDULER_B_ID, PRIO_HIGH );
+ SetPriority( ctx->worker_id[ WORKER_A ], PRIO_NORMAL );
+ MakeBusy( ctx, WORKER_A );
+ WaitForBusy( ctx, WORKER_A );
+ checks:
+ - brief: |
+ Block worker A and preempt it before the withdraw node operations are
+ performed for worker A.
+ code: |
+ T_scheduler_set_event_handler( BlockAndPreempt, ctx );
+ SuspendTask( ctx->worker_id[ WORKER_A ] );
+ links:
+ - role: validation
+ uid: ../req/preempt-blocked
+ - brief: |
+ Clean up all used resources.
+ code: |
+ ResumeTask( ctx->worker_id[ WORKER_A ] );
+ StopBusy( ctx, WORKER_C );
+ StopBusy( ctx, WORKER_A );
+ SetPriority( ctx->worker_id[ WORKER_A ], PRIO_HIGH );
+ SetSelfPriority( PRIO_NORMAL );
+ SendEvents( ctx->worker_id[ WORKER_A ], EVENT_RELEASE );
+ SendAndSync( ctx, WORKER_B, 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: []
+- action-brief: |
Construct a system state in which a thread is rescheduled while it is not
scheduled on another scheduler.
action-code: |
@@ -776,6 +811,38 @@ test-support: |
ResumeTask( ctx->runner_id );
}
+ static void Preempt( void *arg )
+ {
+ Context *ctx;
+
+ ctx = arg;
+ MakeBusy( ctx, WORKER_C );
+ }
+
+ static void BlockAndPreempt(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+ )
+ {
+ Context *ctx;
+
+ ctx = arg;
+
+ if ( when == T_SCHEDULER_AFTER && event->operation == T_SCHEDULER_BLOCK ) {
+ Thread_Control *thread;
+
+ T_scheduler_set_event_handler( NULL, NULL );
+
+ thread = GetThread( ctx->worker_id[ WORKER_A ] );
+ T_eq_int( thread->Scheduler.state, THREAD_SCHEDULER_BLOCKED );
+
+ ctx->job_context[ 0 ].handler = Preempt;
+ _Per_CPU_Submit_job( _Per_CPU_Get_by_index( 1 ), &ctx->job[ 0 ] );
+ _Per_CPU_Wait_for_job( _Per_CPU_Get_by_index( 1 ), &ctx->job[ 0 ] );
+ }
+ }
+
static void PrepareOwnerScheduled( Context *ctx )
{
SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_B_ID, PRIO_NORMAL );