diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-11-09 16:11:12 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-11-11 16:51:34 +0100 |
commit | 214d7d372eb0d2466fb7e6107a44698f75d42861 (patch) | |
tree | a2df9a78949ca6181cdce346fa1b58265661a3de | |
parent | spec: Improve processor removal specification (diff) | |
download | rtems-central-214d7d372eb0d2466fb7e6107a44698f75d42861.tar.bz2 |
spec: Specify ask for help request
-rw-r--r-- | spec/score/sched/smp/req/ask-for-help-request.yml | 15 | ||||
-rw-r--r-- | spec/score/sched/smp/val/smp.yml | 79 |
2 files changed, 93 insertions, 1 deletions
diff --git a/spec/score/sched/smp/req/ask-for-help-request.yml b/spec/score/sched/smp/req/ask-for-help-request.yml new file mode 100644 index 00000000..0f11f6e5 --- /dev/null +++ b/spec/score/sched/smp/req/ask-for-help-request.yml @@ -0,0 +1,15 @@ +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: | + When a need for help is detected for a thread, the ask for help request shall + be registered on the current processor. +type: requirement diff --git a/spec/score/sched/smp/val/smp.yml b/spec/score/sched/smp/val/smp.yml index 1e596184..c6a8b0d7 100644 --- a/spec/score/sched/smp/val/smp.yml +++ b/spec/score/sched/smp/val/smp.yml @@ -5,6 +5,30 @@ enabled-by: RTEMS_SMP links: [] test-actions: - action-brief: | + Construct a system state in which an ask for help request is cancelled + while it is processed on another processor. + action-code: | + PrepareOwnerScheduled( ctx ); + checks: + - brief: | + Block the runner thread while the owner thread of the highest priority + ready node is already scheduled. + code: | + SuspendTask( ctx->worker_id[ WORKER_A ] ); + T_scheduler_set_event_handler( UnblockAskForHelp, ctx ); + ResumeTask( ctx->worker_id[ WORKER_A ] ); + links: + - role: validation + uid: ../req/ask-for-help-request + - brief: | + Clean up all used resources. + code: | + ResumeTask( ctx->worker_id[ WORKER_A ] ); + StopBusy( ctx, WORKER_C ); + CleanupOwnerScheduled( ctx ); + links: [] + links: [] +- action-brief: | Construct a system state in which a scheduler tries to schedule a node those owner thread is already scheduled during a block operation. action-code: | @@ -308,6 +332,11 @@ test-context: description: null member: | Per_CPU_Job_context job_context +- brief: | + This member contains the call within ISR request. + description: null + member: | + CallWithinISRRequest request; test-context-support: | typedef enum { WORKER_A, @@ -321,7 +350,7 @@ test-includes: - rtems.h - rtems/test-scheduler.h - rtems/score/percpu.h -- rtems/score/thread.h +- rtems/score/threadimpl.h test-local-includes: - tx-support.h test-setup: @@ -527,6 +556,54 @@ test-support: | OperationSuspendA( arg, event, when, T_SCHEDULER_YIELD ); } + static void InterceptAskForHelp( void *arg ) + { + Context *ctx; + Per_CPU_Control *cpu_self; + ISR_lock_Context lock_context; + Chain_Node *node; + Thread_Control *thread; + + ctx = arg; + cpu_self = _Per_CPU_Get(); + + _ISR_lock_ISR_disable( &lock_context ); + _Per_CPU_Acquire( cpu_self, &lock_context ); + ctx->job_context.handler = SuspendA; + _Per_CPU_Submit_job( _Per_CPU_Get_by_index( 1 ), &ctx->job ); + ISRLockWaitForOthers( &cpu_self->Lock, 1 ); + + /* See _Thread_Preemption_intervention() */ + node = _Chain_Get_first_unprotected( &cpu_self->Threads_in_need_for_help ); + thread = THREAD_OF_SCHEDULER_HELP_NODE( node ); + T_assert_eq_ptr( thread, GetThread( ctx->worker_id[ WORKER_A ] ) ); + thread->Scheduler.ask_for_help_cpu = NULL; + + _Per_CPU_Release( cpu_self, &lock_context ); + _ISR_lock_ISR_enable( &lock_context ); + } + + static void UnblockAskForHelp( + void *arg, + const T_scheduler_event *event, + T_scheduler_when when + ) + { + Context *ctx; + + ctx = arg; + + if ( + when == T_SCHEDULER_BEFORE && + event->operation == T_SCHEDULER_UNBLOCK + ) { + T_scheduler_set_event_handler( NULL, NULL ); + ctx->request.handler = InterceptAskForHelp; + ctx->request.arg = ctx; + CallWithinISRSubmit( &ctx->request ); + } + } + static void PrepareOwnerScheduled( Context *ctx ) { SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_B_ID, PRIO_NORMAL ); |