summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2021-11-24 09:24:44 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2021-12-08 17:25:15 +0100
commite4a6eac110b666b3947579f9739737db05717fc7 (patch)
treea5dc45be0434a26799f5acbecded182bfcf7282a
parent4af4e3ab00e82c5f22fd2f344e4ca1066cd7f761 (diff)
testsuites/validation/tc-sched-smp.c
-rw-r--r--testsuites/validation/tc-sched-smp.c159
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 );
}
/** @} */