diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-11-24 09:23:09 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-11-24 09:58:44 +0100 |
commit | 3d51ce69a90db1a85ab4bcb88dbcf7e41276beb8 (patch) | |
tree | d12bf98c7bc831df7d50d5b33b7f7f4da09e8b06 | |
parent | spec: Fix text and improve test action (diff) | |
download | rtems-central-3d51ce69a90db1a85ab4bcb88dbcf7e41276beb8.tar.bz2 |
spec: Specify SMP scheduler detail
-rw-r--r-- | spec/score/sched/smp/req/preempt-blocked.yml | 16 | ||||
-rw-r--r-- | spec/score/sched/smp/val/smp.yml | 67 |
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 ); |