File indexing completed on 2025-05-11 08:24:53
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051 #ifdef HAVE_CONFIG_H
0052 #include "config.h"
0053 #endif
0054
0055 #include "tr-tq-enqueue-mrsp.h"
0056
0057 #include <rtems/test.h>
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 typedef struct {
0068 uint8_t Skip : 1;
0069 uint8_t Pre_EligibleScheduler_NA : 1;
0070 uint8_t Pre_QueueEligible_NA : 1;
0071 uint8_t Pre_QueueIneligible_NA : 1;
0072 uint8_t Post_Position : 3;
0073 } ScoreTqReqEnqueueMrsp_Entry;
0074
0075
0076
0077
0078 typedef struct {
0079
0080
0081
0082
0083
0084 bool helping;
0085
0086
0087
0088
0089
0090
0091 rtems_task_priority priority;
0092
0093
0094
0095
0096
0097
0098
0099 size_t other_before;
0100
0101
0102
0103
0104
0105
0106
0107 size_t other_after;
0108
0109
0110
0111
0112
0113 TQContext *tq_ctx;
0114
0115 struct {
0116
0117
0118
0119 size_t pcs[ 3 ];
0120
0121
0122
0123
0124 bool in_action_loop;
0125
0126
0127
0128
0129 size_t index;
0130
0131
0132
0133
0134 ScoreTqReqEnqueueMrsp_Entry entry;
0135
0136
0137
0138
0139
0140 bool skip;
0141 } Map;
0142 } ScoreTqReqEnqueueMrsp_Context;
0143
0144 static ScoreTqReqEnqueueMrsp_Context
0145 ScoreTqReqEnqueueMrsp_Instance;
0146
0147 static const char * const ScoreTqReqEnqueueMrsp_PreDesc_EligibleScheduler[] = {
0148 "Home",
0149 "Helping",
0150 "NA"
0151 };
0152
0153 static const char * const ScoreTqReqEnqueueMrsp_PreDesc_QueueEligible[] = {
0154 "None",
0155 "Equal",
0156 "Low",
0157 "NA"
0158 };
0159
0160 static const char * const ScoreTqReqEnqueueMrsp_PreDesc_QueueIneligible[] = {
0161 "None",
0162 "Only",
0163 "Before",
0164 "After",
0165 "NA"
0166 };
0167
0168 static const char * const * const ScoreTqReqEnqueueMrsp_PreDesc[] = {
0169 ScoreTqReqEnqueueMrsp_PreDesc_EligibleScheduler,
0170 ScoreTqReqEnqueueMrsp_PreDesc_QueueEligible,
0171 ScoreTqReqEnqueueMrsp_PreDesc_QueueIneligible,
0172 NULL
0173 };
0174
0175
0176
0177
0178
0179
0180
0181 static bool CanDoFullValidation( void )
0182 {
0183 return rtems_scheduler_get_processor_maximum() >= 4;
0184 }
0185
0186 static void ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_Prepare(
0187 ScoreTqReqEnqueueMrsp_Context *ctx,
0188 ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler state
0189 )
0190 {
0191 switch ( state ) {
0192 case ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_Home: {
0193
0194
0195
0196 ctx->helping = false;
0197 break;
0198 }
0199
0200 case ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_Helping: {
0201
0202
0203
0204 ctx->helping = true;
0205 break;
0206 }
0207
0208 case ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_NA:
0209 break;
0210 }
0211 }
0212
0213 static void ScoreTqReqEnqueueMrsp_Pre_QueueEligible_Prepare(
0214 ScoreTqReqEnqueueMrsp_Context *ctx,
0215 ScoreTqReqEnqueueMrsp_Pre_QueueEligible state
0216 )
0217 {
0218 switch ( state ) {
0219 case ScoreTqReqEnqueueMrsp_Pre_QueueEligible_None: {
0220
0221
0222
0223
0224 ctx->priority = PRIO_PSEUDO_ISR;
0225 break;
0226 }
0227
0228 case ScoreTqReqEnqueueMrsp_Pre_QueueEligible_Equal: {
0229
0230
0231
0232
0233
0234
0235 ctx->priority = PRIO_VERY_HIGH;
0236 break;
0237 }
0238
0239 case ScoreTqReqEnqueueMrsp_Pre_QueueEligible_Low: {
0240
0241
0242
0243
0244
0245
0246 ctx->priority = PRIO_HIGH;
0247 break;
0248 }
0249
0250 case ScoreTqReqEnqueueMrsp_Pre_QueueEligible_NA:
0251 break;
0252 }
0253 }
0254
0255 static void ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_Prepare(
0256 ScoreTqReqEnqueueMrsp_Context *ctx,
0257 ScoreTqReqEnqueueMrsp_Pre_QueueIneligible state
0258 )
0259 {
0260 switch ( state ) {
0261 case ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_None: {
0262
0263
0264
0265
0266 ctx->other_before = false;
0267 ctx->other_after = false;
0268 break;
0269 }
0270
0271 case ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_Only: {
0272
0273
0274
0275
0276 ctx->other_before = true;
0277 ctx->other_after = false;
0278 break;
0279 }
0280
0281 case ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_Before: {
0282
0283
0284
0285
0286
0287
0288 ctx->other_before = true;
0289 ctx->other_after = false;
0290 break;
0291 }
0292
0293 case ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_After: {
0294
0295
0296
0297
0298
0299
0300 ctx->other_before = false;
0301 ctx->other_after = true;
0302 break;
0303 }
0304
0305 case ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_NA:
0306 break;
0307 }
0308 }
0309
0310 static void ScoreTqReqEnqueueMrsp_Post_Position_Check(
0311 ScoreTqReqEnqueueMrsp_Context *ctx,
0312 ScoreTqReqEnqueueMrsp_Post_Position state
0313 )
0314 {
0315 size_t i;
0316
0317 i = 0;
0318
0319
0320 T_null( TQGetNextUnblock( ctx->tq_ctx, &i )->thread );
0321
0322 switch ( state ) {
0323 case ScoreTqReqEnqueueMrsp_Post_Position_InitialFirst: {
0324
0325
0326
0327
0328
0329 T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0330 T_eq_u32( 1, TQGetCounter( ctx->tq_ctx ) );
0331 break;
0332 }
0333
0334 case ScoreTqReqEnqueueMrsp_Post_Position_InitialLast: {
0335
0336
0337
0338
0339
0340 if ( CanDoFullValidation() ) {
0341 T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_C ) );
0342 T_eq_u32( 2, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0343 T_eq_u32( 2, TQGetCounter( ctx->tq_ctx ) );
0344 } else {
0345 T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0346 T_eq_u32( 1, TQGetCounter( ctx->tq_ctx ) );
0347 }
0348 break;
0349 }
0350
0351 case ScoreTqReqEnqueueMrsp_Post_Position_Second: {
0352
0353
0354
0355
0356 if ( CanDoFullValidation() ) {
0357 T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_B ) );
0358 T_eq_u32( 2, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0359 T_eq_u32( 2, TQGetCounter( ctx->tq_ctx ) );
0360 } else {
0361 T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0362 T_eq_u32( 1, TQGetCounter( ctx->tq_ctx ) );
0363 }
0364 break;
0365 }
0366
0367 case ScoreTqReqEnqueueMrsp_Post_Position_SecondFirst: {
0368
0369
0370
0371
0372
0373
0374
0375 if ( CanDoFullValidation() ) {
0376 T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_B ) );
0377 T_eq_u32( 2, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_C ) );
0378 T_eq_u32( 3, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0379 T_eq_u32( 3, TQGetCounter( ctx->tq_ctx ) );
0380 } else {
0381 T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0382 T_eq_u32( 1, TQGetCounter( ctx->tq_ctx ) );
0383 }
0384 break;
0385 }
0386
0387 case ScoreTqReqEnqueueMrsp_Post_Position_SecondLast: {
0388
0389
0390
0391
0392
0393
0394
0395 if ( CanDoFullValidation() ) {
0396 T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_C ) );
0397 T_eq_u32( 2, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_B ) );
0398 T_eq_u32( 3, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0399 T_eq_u32( 3, TQGetCounter( ctx->tq_ctx ) );
0400 } else {
0401 T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
0402 T_eq_u32( 1, TQGetCounter( ctx->tq_ctx ) );
0403 }
0404 break;
0405 }
0406
0407 case ScoreTqReqEnqueueMrsp_Post_Position_NA:
0408 break;
0409 }
0410 }
0411
0412 static void ScoreTqReqEnqueueMrsp_Setup( ScoreTqReqEnqueueMrsp_Context *ctx )
0413 {
0414 if ( CanDoFullValidation() ) {
0415 RemoveProcessor( SCHEDULER_C_ID, 2 );
0416 AddProcessor( SCHEDULER_B_ID, 2 );
0417 TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_C, SCHEDULER_C_ID, PRIO_LOW );
0418 }
0419
0420 TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_A, SCHEDULER_B_ID, PRIO_LOW );
0421 TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_B, SCHEDULER_B_ID, PRIO_LOW );
0422 TQSetScheduler(
0423 ctx->tq_ctx,
0424 TQ_BLOCKER_D,
0425 SCHEDULER_A_ID,
0426 PRIO_ULTRA_HIGH
0427 );
0428 }
0429
0430 static void ScoreTqReqEnqueueMrsp_Setup_Wrap( void *arg )
0431 {
0432 ScoreTqReqEnqueueMrsp_Context *ctx;
0433
0434 ctx = arg;
0435 ctx->Map.in_action_loop = false;
0436 ScoreTqReqEnqueueMrsp_Setup( ctx );
0437 }
0438
0439 static void ScoreTqReqEnqueueMrsp_Teardown(
0440 ScoreTqReqEnqueueMrsp_Context *ctx
0441 )
0442 {
0443 if ( CanDoFullValidation() ) {
0444 RemoveProcessor( SCHEDULER_B_ID, 2 );
0445 AddProcessor( SCHEDULER_C_ID, 2 );
0446 }
0447
0448 TQReset( ctx->tq_ctx );
0449 }
0450
0451 static void ScoreTqReqEnqueueMrsp_Teardown_Wrap( void *arg )
0452 {
0453 ScoreTqReqEnqueueMrsp_Context *ctx;
0454
0455 ctx = arg;
0456 ctx->Map.in_action_loop = false;
0457 ScoreTqReqEnqueueMrsp_Teardown( ctx );
0458 }
0459
0460 static void ScoreTqReqEnqueueMrsp_Action( ScoreTqReqEnqueueMrsp_Context *ctx )
0461 {
0462 Status_Control status;
0463
0464 TQResetCounter( ctx->tq_ctx );
0465 TQClearDone( ctx->tq_ctx, TQ_BLOCKER_A );
0466 TQClearDone( ctx->tq_ctx, TQ_BLOCKER_B );
0467 TQClearDone( ctx->tq_ctx, TQ_BLOCKER_C );
0468
0469 status = TQEnqueue( ctx->tq_ctx, TQ_WAIT_FOREVER );
0470 T_eq_int( status, TQConvertStatus( ctx->tq_ctx, STATUS_SUCCESSFUL ) );
0471
0472 if ( ctx->helping ) {
0473 TQSend(
0474 ctx->tq_ctx,
0475 TQ_BLOCKER_A,
0476 TQ_EVENT_MUTEX_A_OBTAIN | TQ_EVENT_RUNNER_SYNC
0477 );
0478 TQSynchronizeRunner();
0479 TQSend(
0480 ctx->tq_ctx,
0481 TQ_BLOCKER_D,
0482 TQ_EVENT_MUTEX_A_OBTAIN | TQ_EVENT_MUTEX_A_RELEASE |
0483 TQ_EVENT_RUNNER_SYNC_2
0484 );
0485 }
0486
0487 if ( CanDoFullValidation() ) {
0488 if ( ctx->other_before ) {
0489 TQSendAndWaitForIntendToBlock(
0490 ctx->tq_ctx,
0491 TQ_BLOCKER_C,
0492 TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
0493 );
0494 }
0495
0496 if ( ctx->priority != PRIO_PSEUDO_ISR ) {
0497 TQSendAndWaitForIntendToBlock(
0498 ctx->tq_ctx,
0499 TQ_BLOCKER_B,
0500 TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
0501 );
0502 }
0503
0504 if ( ctx->other_after ) {
0505 TQSendAndWaitForIntendToBlock(
0506 ctx->tq_ctx,
0507 TQ_BLOCKER_C,
0508 TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
0509 );
0510 }
0511 }
0512
0513 TQSendAndWaitForIntendToBlock(
0514 ctx->tq_ctx,
0515 TQ_BLOCKER_A,
0516 TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
0517 );
0518
0519 TQSchedulerRecordStart( ctx->tq_ctx );
0520 status = TQSurrender( ctx->tq_ctx );
0521 T_eq_int( status, TQConvertStatus( ctx->tq_ctx, STATUS_SUCCESSFUL ) );
0522 TQWaitForDone( ctx->tq_ctx, TQ_BLOCKER_A );
0523
0524 if ( CanDoFullValidation() ) {
0525 if ( ctx->priority != PRIO_PSEUDO_ISR ) {
0526 TQWaitForDone( ctx->tq_ctx, TQ_BLOCKER_B );
0527 }
0528
0529 if ( ctx->other_before || ctx->other_after ) {
0530 TQWaitForDone( ctx->tq_ctx, TQ_BLOCKER_C );
0531 }
0532 }
0533
0534 TQSchedulerRecordStop( ctx->tq_ctx );
0535
0536 if ( ctx->helping ) {
0537 TQSend(
0538 ctx->tq_ctx,
0539 TQ_BLOCKER_A,
0540 TQ_EVENT_MUTEX_A_RELEASE | TQ_EVENT_RUNNER_SYNC
0541 );
0542 TQSynchronizeRunner2();
0543 }
0544 }
0545
0546 static const ScoreTqReqEnqueueMrsp_Entry
0547 ScoreTqReqEnqueueMrsp_Entries[] = {
0548 { 1, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_NA },
0549 { 0, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_Second },
0550 { 0, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_SecondLast },
0551 { 0, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_SecondFirst },
0552 { 0, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_InitialFirst },
0553 { 0, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_InitialLast }
0554 };
0555
0556 static const uint8_t
0557 ScoreTqReqEnqueueMrsp_Map[] = {
0558 4, 5, 0, 0, 1, 0, 2, 3, 1, 0, 2, 3, 4, 5, 0, 0, 1, 0, 2, 3, 1, 0, 2, 3
0559 };
0560
0561 static size_t ScoreTqReqEnqueueMrsp_Scope( void *arg, char *buf, size_t n )
0562 {
0563 ScoreTqReqEnqueueMrsp_Context *ctx;
0564
0565 ctx = arg;
0566
0567 if ( ctx->Map.in_action_loop ) {
0568 return T_get_scope( ScoreTqReqEnqueueMrsp_PreDesc, buf, n, ctx->Map.pcs );
0569 }
0570
0571 return 0;
0572 }
0573
0574 static T_fixture ScoreTqReqEnqueueMrsp_Fixture = {
0575 .setup = ScoreTqReqEnqueueMrsp_Setup_Wrap,
0576 .stop = NULL,
0577 .teardown = ScoreTqReqEnqueueMrsp_Teardown_Wrap,
0578 .scope = ScoreTqReqEnqueueMrsp_Scope,
0579 .initial_context = &ScoreTqReqEnqueueMrsp_Instance
0580 };
0581
0582 static inline ScoreTqReqEnqueueMrsp_Entry ScoreTqReqEnqueueMrsp_PopEntry(
0583 ScoreTqReqEnqueueMrsp_Context *ctx
0584 )
0585 {
0586 size_t index;
0587
0588 index = ctx->Map.index;
0589 ctx->Map.index = index + 1;
0590 return ScoreTqReqEnqueueMrsp_Entries[
0591 ScoreTqReqEnqueueMrsp_Map[ index ]
0592 ];
0593 }
0594
0595 static void ScoreTqReqEnqueueMrsp_TestVariant(
0596 ScoreTqReqEnqueueMrsp_Context *ctx
0597 )
0598 {
0599 ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_Prepare(
0600 ctx,
0601 ctx->Map.pcs[ 0 ]
0602 );
0603 ScoreTqReqEnqueueMrsp_Pre_QueueEligible_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0604 ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0605 ScoreTqReqEnqueueMrsp_Action( ctx );
0606 ScoreTqReqEnqueueMrsp_Post_Position_Check(
0607 ctx,
0608 ctx->Map.entry.Post_Position
0609 );
0610 }
0611
0612 static T_fixture_node ScoreTqReqEnqueueMrsp_Node;
0613
0614 static T_remark ScoreTqReqEnqueueMrsp_Remark = {
0615 .next = NULL,
0616 .remark = "ScoreTqReqEnqueueMrsp"
0617 };
0618
0619 void ScoreTqReqEnqueueMrsp_Run( TQContext *tq_ctx )
0620 {
0621 ScoreTqReqEnqueueMrsp_Context *ctx;
0622
0623 ctx = &ScoreTqReqEnqueueMrsp_Instance;
0624 ctx->tq_ctx = tq_ctx;
0625
0626 ctx = T_push_fixture(
0627 &ScoreTqReqEnqueueMrsp_Node,
0628 &ScoreTqReqEnqueueMrsp_Fixture
0629 );
0630 ctx->Map.in_action_loop = true;
0631 ctx->Map.index = 0;
0632
0633 for (
0634 ctx->Map.pcs[ 0 ] = ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_Home;
0635 ctx->Map.pcs[ 0 ] < ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_NA;
0636 ++ctx->Map.pcs[ 0 ]
0637 ) {
0638 for (
0639 ctx->Map.pcs[ 1 ] = ScoreTqReqEnqueueMrsp_Pre_QueueEligible_None;
0640 ctx->Map.pcs[ 1 ] < ScoreTqReqEnqueueMrsp_Pre_QueueEligible_NA;
0641 ++ctx->Map.pcs[ 1 ]
0642 ) {
0643 for (
0644 ctx->Map.pcs[ 2 ] = ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_None;
0645 ctx->Map.pcs[ 2 ] < ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_NA;
0646 ++ctx->Map.pcs[ 2 ]
0647 ) {
0648 ctx->Map.entry = ScoreTqReqEnqueueMrsp_PopEntry( ctx );
0649 ScoreTqReqEnqueueMrsp_TestVariant( ctx );
0650 }
0651 }
0652 }
0653
0654 T_add_remark( &ScoreTqReqEnqueueMrsp_Remark );
0655 T_pop_fixture();
0656 }
0657
0658