diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-11-24 09:24:44 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2021-11-24 09:58:12 +0100 |
commit | d39944a7fb77acab86997f4e984635b42a9c2502 (patch) | |
tree | 40237c4db32ee1ad1505511376b95fb2a2de076b | |
parent | b23f46b7d461078f746951ea78f377faad4cbfa5 (diff) |
testsuites/validation/tc-sched-smp.c
-rw-r--r-- | testsuites/validation/tc-sched-smp.c | 159 |
1 files changed, 144 insertions, 15 deletions
diff --git a/testsuites/validation/tc-sched-smp.c b/testsuites/validation/tc-sched-smp.c index 483a5d475f..957a978980 100644 --- a/testsuites/validation/tc-sched-smp.c +++ b/testsuites/validation/tc-sched-smp.c @@ -70,6 +70,22 @@ * * This test case performs the following actions: * + * - Construct a system state in which a sticky thread is blocked while an idle + * thread executes on behalf of the thread. + * + * - Block the sticky worker A while it uses an idle thread in the home + * scheduler. + * + * - Clean up all used resources. + * + * - Construct a system state in which a thread is preempted while it is + * blocked. + * + * - Block worker A and preempt it before the withdraw node operations are + * performed for worker A. + * + * - Clean up all used resources. + * * - Construct a system state in which a thread is rescheduled while it is not * scheduled on another scheduler. * @@ -581,6 +597,50 @@ static void ReadyToScheduled( void *arg ) ResumeTask( ctx->runner_id ); } +static void BlockAndReuseIdle( void *arg ) +{ + Context *ctx; + + ctx = arg; + SuspendTask( ctx->runner_id ); + SuspendTask( ctx->worker_id[ WORKER_A ] ); + ResumeTask( ctx->worker_id[ WORKER_A ] ); + SetPriority( ctx->runner_id, PRIO_HIGH ); + 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 ); @@ -754,10 +814,77 @@ static T_fixture ScoreSchedSmpValSmp_Fixture = { }; /** + * @brief Construct a system state in which a sticky thread is blocked while an + * idle thread executes on behalf of the thread. + */ +static void ScoreSchedSmpValSmp_Action_0( ScoreSchedSmpValSmp_Context *ctx ) +{ + 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 ); + SetPriority( ctx->worker_id[ WORKER_A ], PRIO_NORMAL ); + SendEvents( ctx->worker_id[ WORKER_A ], EVENT_STICKY_OBTAIN ); + MakeBusy( ctx, WORKER_A ); + WaitForBusy( ctx, WORKER_A ); + + /* + * Block the sticky worker A while it uses an idle thread in the home + * scheduler. + */ + CallWithinISR( BlockAndReuseIdle, ctx ); + + /* + * Clean up all used resources. + */ + StopBusy( ctx, WORKER_A ); + SendAndSync( ctx, WORKER_A, EVENT_STICKY_RELEASE ); + 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 ); +} + +/** + * @brief Construct a system state in which a thread is preempted while it is + * blocked. + */ +static void ScoreSchedSmpValSmp_Action_1( ScoreSchedSmpValSmp_Context *ctx ) +{ + 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 ); + + /* + * Block worker A and preempt it before the withdraw node operations are + * performed for worker A. + */ + T_scheduler_set_event_handler( BlockAndPreempt, ctx ); + SuspendTask( ctx->worker_id[ WORKER_A ] ); + + /* + * Clean up all used resources. + */ + 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 ); +} + +/** * @brief Construct a system state in which a thread is rescheduled while it * is not scheduled on another scheduler. */ -static void ScoreSchedSmpValSmp_Action_0( ScoreSchedSmpValSmp_Context *ctx ) +static void ScoreSchedSmpValSmp_Action_2( ScoreSchedSmpValSmp_Context *ctx ) { SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_B_ID, PRIO_NORMAL ); SendEvents( ctx->worker_id[ WORKER_A ], EVENT_OBTAIN ); @@ -792,7 +919,7 @@ static void ScoreSchedSmpValSmp_Action_0( ScoreSchedSmpValSmp_Context *ctx ) * @brief Construct a system state in which an ask for help request is * cancelled while it is processed on another processor. */ -static void ScoreSchedSmpValSmp_Action_1( ScoreSchedSmpValSmp_Context *ctx ) +static void ScoreSchedSmpValSmp_Action_3( ScoreSchedSmpValSmp_Context *ctx ) { PrepareOwnerScheduled( ctx ); @@ -818,7 +945,7 @@ static void ScoreSchedSmpValSmp_Action_1( ScoreSchedSmpValSmp_Context *ctx ) * @brief Construct a system state in which a scheduler tries to schedule a * node those owner thread is already scheduled during a block operation. */ -static void ScoreSchedSmpValSmp_Action_2( ScoreSchedSmpValSmp_Context *ctx ) +static void ScoreSchedSmpValSmp_Action_4( ScoreSchedSmpValSmp_Context *ctx ) { PrepareOwnerScheduled( ctx ); @@ -839,7 +966,7 @@ static void ScoreSchedSmpValSmp_Action_2( ScoreSchedSmpValSmp_Context *ctx ) * @brief Construct a system state in which a scheduler tries to schedule a * node those owner thread is blocked during a block operation. */ -static void ScoreSchedSmpValSmp_Action_3( ScoreSchedSmpValSmp_Context *ctx ) +static void ScoreSchedSmpValSmp_Action_5( ScoreSchedSmpValSmp_Context *ctx ) { PrepareOwnerBlocked( ctx ); @@ -861,7 +988,7 @@ static void ScoreSchedSmpValSmp_Action_3( ScoreSchedSmpValSmp_Context *ctx ) * node those owner thread is already scheduled during a set affinity * operation. */ -static void ScoreSchedSmpValSmp_Action_4( ScoreSchedSmpValSmp_Context *ctx ) +static void ScoreSchedSmpValSmp_Action_6( ScoreSchedSmpValSmp_Context *ctx ) { PrepareOwnerScheduled( ctx ); @@ -883,7 +1010,7 @@ static void ScoreSchedSmpValSmp_Action_4( ScoreSchedSmpValSmp_Context *ctx ) * node those owner thread is already scheduled during a set affinity * operation while a sticky node is involved. */ -static void ScoreSchedSmpValSmp_Action_5( ScoreSchedSmpValSmp_Context *ctx ) +static void ScoreSchedSmpValSmp_Action_7( ScoreSchedSmpValSmp_Context *ctx ) { PrepareOwnerScheduled( ctx ); @@ -906,7 +1033,7 @@ static void ScoreSchedSmpValSmp_Action_5( ScoreSchedSmpValSmp_Context *ctx ) * @brief Construct a system state in which a scheduler tries to schedule a * node those owner thread is blocked during a set affinity operation. */ -static void ScoreSchedSmpValSmp_Action_6( ScoreSchedSmpValSmp_Context *ctx ) +static void ScoreSchedSmpValSmp_Action_8( ScoreSchedSmpValSmp_Context *ctx ) { PrepareOwnerBlocked( ctx ); @@ -928,7 +1055,7 @@ static void ScoreSchedSmpValSmp_Action_6( ScoreSchedSmpValSmp_Context *ctx ) * node those owner thread is blocked during a set affinity operation while a * sticky node is involved. */ -static void ScoreSchedSmpValSmp_Action_7( ScoreSchedSmpValSmp_Context *ctx ) +static void ScoreSchedSmpValSmp_Action_9( ScoreSchedSmpValSmp_Context *ctx ) { PrepareOwnerBlocked( ctx ); @@ -952,7 +1079,7 @@ static void ScoreSchedSmpValSmp_Action_7( ScoreSchedSmpValSmp_Context *ctx ) * node those owner thread is already scheduled during a set priority * operation. */ -static void ScoreSchedSmpValSmp_Action_8( ScoreSchedSmpValSmp_Context *ctx ) +static void ScoreSchedSmpValSmp_Action_10( ScoreSchedSmpValSmp_Context *ctx ) { PrepareOwnerScheduled( ctx ); @@ -975,7 +1102,7 @@ static void ScoreSchedSmpValSmp_Action_8( ScoreSchedSmpValSmp_Context *ctx ) * node those owner thread is already scheduled during a set priority * operation while a sticky node is involved. */ -static void ScoreSchedSmpValSmp_Action_9( ScoreSchedSmpValSmp_Context *ctx ) +static void ScoreSchedSmpValSmp_Action_11( ScoreSchedSmpValSmp_Context *ctx ) { PrepareOwnerScheduled( ctx ); @@ -997,7 +1124,7 @@ static void ScoreSchedSmpValSmp_Action_9( ScoreSchedSmpValSmp_Context *ctx ) * @brief Construct a system state in which a scheduler tries to schedule a * node those owner thread is blocked during a set priority operation. */ -static void ScoreSchedSmpValSmp_Action_10( ScoreSchedSmpValSmp_Context *ctx ) +static void ScoreSchedSmpValSmp_Action_12( ScoreSchedSmpValSmp_Context *ctx ) { PrepareOwnerBlocked( ctx ); @@ -1019,7 +1146,7 @@ static void ScoreSchedSmpValSmp_Action_10( ScoreSchedSmpValSmp_Context *ctx ) * @brief Construct a system state in which a scheduler tries to schedule a * node those owner thread is already scheduled during a yield operation. */ -static void ScoreSchedSmpValSmp_Action_11( ScoreSchedSmpValSmp_Context *ctx ) +static void ScoreSchedSmpValSmp_Action_13( ScoreSchedSmpValSmp_Context *ctx ) { PrepareOwnerScheduled( ctx ); @@ -1041,7 +1168,7 @@ static void ScoreSchedSmpValSmp_Action_11( ScoreSchedSmpValSmp_Context *ctx ) * node those owner thread is already scheduled during a yield operation * while a sticky node is involved. */ -static void ScoreSchedSmpValSmp_Action_12( ScoreSchedSmpValSmp_Context *ctx ) +static void ScoreSchedSmpValSmp_Action_14( ScoreSchedSmpValSmp_Context *ctx ) { PrepareOwnerScheduled( ctx ); @@ -1064,7 +1191,7 @@ static void ScoreSchedSmpValSmp_Action_12( ScoreSchedSmpValSmp_Context *ctx ) * @brief Construct a system state in which a scheduler tries to schedule a * node those owner thread is blocked during a yield operation. */ -static void ScoreSchedSmpValSmp_Action_13( ScoreSchedSmpValSmp_Context *ctx ) +static void ScoreSchedSmpValSmp_Action_15( ScoreSchedSmpValSmp_Context *ctx ) { PrepareOwnerBlocked( ctx ); @@ -1086,7 +1213,7 @@ static void ScoreSchedSmpValSmp_Action_13( ScoreSchedSmpValSmp_Context *ctx ) * node those owner thread is blocked during a yield operation while a sticky * node is involved. */ -static void ScoreSchedSmpValSmp_Action_14( ScoreSchedSmpValSmp_Context *ctx ) +static void ScoreSchedSmpValSmp_Action_16( ScoreSchedSmpValSmp_Context *ctx ) { PrepareOwnerBlocked( ctx ); @@ -1129,6 +1256,8 @@ T_TEST_CASE_FIXTURE( ScoreSchedSmpValSmp, &ScoreSchedSmpValSmp_Fixture ) ScoreSchedSmpValSmp_Action_12( ctx ); ScoreSchedSmpValSmp_Action_13( ctx ); ScoreSchedSmpValSmp_Action_14( ctx ); + ScoreSchedSmpValSmp_Action_15( ctx ); + ScoreSchedSmpValSmp_Action_16( ctx ); } /** @} */ |