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-mtx-seize-wait.h"
0056 #include "tr-tq-enqueue-ceiling.h"
0057 #include "tr-tq-enqueue-deadlock.h"
0058 #include "tr-tq-enqueue-fifo.h"
0059 #include "tr-tq-enqueue-priority-inherit.h"
0060 #include "tr-tq-enqueue-priority.h"
0061
0062 #include <rtems/test.h>
0063
0064
0065
0066
0067
0068
0069
0070
0071
0072 typedef struct {
0073 uint32_t Skip : 1;
0074 uint32_t Pre_Protocol_NA : 1;
0075 uint32_t Pre_Discipline_NA : 1;
0076 uint32_t Pre_DeadlockResult_NA : 1;
0077 uint32_t Pre_Recursive_NA : 1;
0078 uint32_t Pre_Owner_NA : 1;
0079 uint32_t Pre_Priority_NA : 1;
0080 uint32_t Post_Status : 3;
0081 uint32_t Post_Enqueued : 3;
0082 uint32_t Post_Owner : 2;
0083 uint32_t Post_Priority : 2;
0084 } ScoreMtxReqSeizeWait_Entry;
0085
0086
0087
0088
0089 typedef struct {
0090
0091
0092
0093
0094 bool owner_caller;
0095
0096
0097
0098
0099
0100 bool owner_other;
0101
0102
0103
0104
0105 bool deadlock;
0106
0107
0108
0109
0110
0111 rtems_task_priority priority_before;
0112
0113
0114
0115
0116
0117 const rtems_tcb *owner_after;
0118
0119
0120
0121
0122
0123 rtems_task_priority priority_after;
0124
0125
0126
0127
0128
0129 TQMtxContext *tq_ctx;
0130
0131 struct {
0132
0133
0134
0135
0136 size_t pci[ 6 ];
0137
0138
0139
0140
0141 size_t pcs[ 6 ];
0142
0143
0144
0145
0146 bool in_action_loop;
0147
0148
0149
0150
0151 size_t index;
0152
0153
0154
0155
0156 ScoreMtxReqSeizeWait_Entry entry;
0157
0158
0159
0160
0161
0162 bool skip;
0163 } Map;
0164 } ScoreMtxReqSeizeWait_Context;
0165
0166 static ScoreMtxReqSeizeWait_Context
0167 ScoreMtxReqSeizeWait_Instance;
0168
0169 static const char * const ScoreMtxReqSeizeWait_PreDesc_Protocol[] = {
0170 "None",
0171 "Inherit",
0172 "Ceiling",
0173 "MrsP",
0174 "NA"
0175 };
0176
0177 static const char * const ScoreMtxReqSeizeWait_PreDesc_Discipline[] = {
0178 "FIFO",
0179 "Priority",
0180 "NA"
0181 };
0182
0183 static const char * const ScoreMtxReqSeizeWait_PreDesc_DeadlockResult[] = {
0184 "Status",
0185 "Fatal",
0186 "NA"
0187 };
0188
0189 static const char * const ScoreMtxReqSeizeWait_PreDesc_Recursive[] = {
0190 "Allowed",
0191 "Deadlock",
0192 "NA"
0193 };
0194
0195 static const char * const ScoreMtxReqSeizeWait_PreDesc_Owner[] = {
0196 "None",
0197 "Caller",
0198 "Other",
0199 "Deadlock",
0200 "NA"
0201 };
0202
0203 static const char * const ScoreMtxReqSeizeWait_PreDesc_Priority[] = {
0204 "High",
0205 "Equal",
0206 "Low",
0207 "NA"
0208 };
0209
0210 static const char * const * const ScoreMtxReqSeizeWait_PreDesc[] = {
0211 ScoreMtxReqSeizeWait_PreDesc_Protocol,
0212 ScoreMtxReqSeizeWait_PreDesc_Discipline,
0213 ScoreMtxReqSeizeWait_PreDesc_DeadlockResult,
0214 ScoreMtxReqSeizeWait_PreDesc_Recursive,
0215 ScoreMtxReqSeizeWait_PreDesc_Owner,
0216 ScoreMtxReqSeizeWait_PreDesc_Priority,
0217 NULL
0218 };
0219
0220 #if defined(RTEMS_SMP)
0221 #include "tr-tq-enqueue-mrsp.h"
0222 #endif
0223
0224 typedef ScoreMtxReqSeizeWait_Context Context;
0225
0226 static Status_Control Status( const Context *ctx, Status_Control status )
0227 {
0228 return TQConvertStatus( &ctx->tq_ctx->base, status );
0229 }
0230
0231 static bool IsEnqueueStatus( const Context *ctx, Status_Control expected )
0232 {
0233 return ctx->tq_ctx->base.status[ TQ_BLOCKER_A ] == Status( ctx, expected );
0234 }
0235
0236 static void Action( Context *ctx )
0237 {
0238 TQEvent enqueue;
0239
0240 TQSetScheduler(
0241 &ctx->tq_ctx->base,
0242 TQ_BLOCKER_A,
0243 SCHEDULER_A_ID,
0244 PRIO_VERY_HIGH
0245 );
0246
0247 if ( ctx->owner_caller ) {
0248 TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
0249 } else if ( ctx->owner_other ) {
0250 if ( ctx->deadlock ) {
0251 TQSend(
0252 &ctx->tq_ctx->base,
0253 TQ_BLOCKER_A,
0254 TQ_EVENT_MUTEX_NO_PROTOCOL_OBTAIN
0255 );
0256 }
0257
0258 TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_B, TQ_EVENT_ENQUEUE );
0259
0260 if ( ctx->deadlock ) {
0261 TQSend(
0262 &ctx->tq_ctx->base,
0263 TQ_BLOCKER_B,
0264 TQ_EVENT_MUTEX_NO_PROTOCOL_OBTAIN
0265 );
0266 }
0267 }
0268
0269 TQSetPriority( &ctx->tq_ctx->base, TQ_BLOCKER_A, ctx->priority_before );
0270
0271 if ( ctx->tq_ctx->base.deadlock == TQ_DEADLOCK_FATAL ) {
0272 enqueue = TQ_EVENT_ENQUEUE_FATAL;
0273 } else {
0274 enqueue = TQ_EVENT_ENQUEUE;
0275 }
0276
0277 TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, enqueue );
0278 ctx->owner_after = TQGetOwner( &ctx->tq_ctx->base );
0279 ctx->priority_after = TQGetPriority( &ctx->tq_ctx->base, TQ_BLOCKER_A );
0280
0281 if ( ctx->owner_caller ) {
0282 TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_SURRENDER );
0283 } else if ( ctx->owner_other ) {
0284 if ( ctx->deadlock ) {
0285 TQSend(
0286 &ctx->tq_ctx->base,
0287 TQ_BLOCKER_A,
0288 TQ_EVENT_MUTEX_NO_PROTOCOL_RELEASE
0289 );
0290 }
0291
0292 TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_B, TQ_EVENT_SURRENDER );
0293
0294 if ( ctx->deadlock ) {
0295 TQSend(
0296 &ctx->tq_ctx->base,
0297 TQ_BLOCKER_B,
0298 TQ_EVENT_MUTEX_NO_PROTOCOL_RELEASE
0299 );
0300 }
0301 }
0302
0303 if ( IsEnqueueStatus( ctx, STATUS_SUCCESSFUL ) ) {
0304 TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_SURRENDER );
0305 }
0306 }
0307
0308 static void ActionSticky( Context *ctx )
0309 {
0310 TQSetScheduler(
0311 &ctx->tq_ctx->base,
0312 TQ_BLOCKER_A,
0313 SCHEDULER_B_ID,
0314 PRIO_VERY_HIGH
0315 );
0316
0317 if ( ctx->owner_caller ) {
0318 TQSendAndSynchronizeRunner(
0319 &ctx->tq_ctx->base,
0320 TQ_BLOCKER_A,
0321 TQ_EVENT_ENQUEUE
0322 );
0323 } else if ( ctx->owner_other ) {
0324 if ( ctx->deadlock ) {
0325 TQSendAndSynchronizeRunner(
0326 &ctx->tq_ctx->base,
0327 TQ_BLOCKER_A,
0328 TQ_EVENT_MUTEX_NO_PROTOCOL_OBTAIN
0329 );
0330 }
0331
0332 SetSelfScheduler( SCHEDULER_B_ID, PRIO_ULTRA_HIGH );
0333 TQSendAndSynchronizeRunner(
0334 &ctx->tq_ctx->base,
0335 TQ_BLOCKER_B,
0336 TQ_EVENT_ENQUEUE
0337 );
0338
0339 if ( ctx->deadlock ) {
0340 TQSendAndWaitForExecutionStop(
0341 &ctx->tq_ctx->base,
0342 TQ_BLOCKER_B,
0343 TQ_EVENT_MUTEX_NO_PROTOCOL_OBTAIN
0344 );
0345 }
0346
0347 SetSelfScheduler( SCHEDULER_A_ID, PRIO_ULTRA_HIGH );
0348 }
0349
0350 TQSetPriority( &ctx->tq_ctx->base, TQ_BLOCKER_A, ctx->priority_before );
0351 TQClearDone( &ctx->tq_ctx->base, TQ_BLOCKER_A );
0352 TQSendAndWaitForExecutionStopOrIntendToBlock(
0353 &ctx->tq_ctx->base,
0354 TQ_BLOCKER_A,
0355 TQ_EVENT_ENQUEUE
0356 );
0357 ctx->owner_after = TQGetOwner( &ctx->tq_ctx->base );
0358 ctx->priority_after = TQGetPriority( &ctx->tq_ctx->base, TQ_BLOCKER_A );
0359
0360 if ( ctx->owner_caller ) {
0361 TQSendAndSynchronizeRunner(
0362 &ctx->tq_ctx->base,
0363 TQ_BLOCKER_A,
0364 TQ_EVENT_SURRENDER
0365 );
0366 } else if ( ctx->owner_other ) {
0367 if ( ctx->deadlock ) {
0368 TQSendAndSynchronizeRunner(
0369 &ctx->tq_ctx->base,
0370 TQ_BLOCKER_A,
0371 TQ_EVENT_MUTEX_NO_PROTOCOL_RELEASE
0372 );
0373 }
0374
0375 SetSelfScheduler( SCHEDULER_B_ID, PRIO_ULTRA_HIGH );
0376 TQSendAndSynchronizeRunner(
0377 &ctx->tq_ctx->base,
0378 TQ_BLOCKER_B,
0379 TQ_EVENT_SURRENDER
0380 );
0381
0382 if ( ctx->deadlock ) {
0383 TQSendAndSynchronizeRunner(
0384 &ctx->tq_ctx->base,
0385 TQ_BLOCKER_B,
0386 TQ_EVENT_MUTEX_NO_PROTOCOL_RELEASE
0387 );
0388 }
0389
0390 SetSelfScheduler( SCHEDULER_A_ID, PRIO_NORMAL );
0391 }
0392
0393 TQWaitForDone( &ctx->tq_ctx->base, TQ_BLOCKER_A );
0394
0395 if ( IsEnqueueStatus( ctx, STATUS_SUCCESSFUL ) ) {
0396 TQSendAndSynchronizeRunner(
0397 &ctx->tq_ctx->base,
0398 TQ_BLOCKER_A,
0399 TQ_EVENT_SURRENDER
0400 );
0401 }
0402 }
0403
0404 static void ScoreMtxReqSeizeWait_Pre_Protocol_Prepare(
0405 ScoreMtxReqSeizeWait_Context *ctx,
0406 ScoreMtxReqSeizeWait_Pre_Protocol state
0407 )
0408 {
0409 switch ( state ) {
0410 case ScoreMtxReqSeizeWait_Pre_Protocol_None: {
0411
0412
0413
0414 if ( ctx->tq_ctx->protocol != TQ_MTX_NO_PROTOCOL ) {
0415 ctx->Map.skip = true;
0416 }
0417 break;
0418 }
0419
0420 case ScoreMtxReqSeizeWait_Pre_Protocol_Inherit: {
0421
0422
0423
0424 if ( ctx->tq_ctx->protocol != TQ_MTX_PRIORITY_INHERIT ) {
0425 ctx->Map.skip = true;
0426 }
0427 break;
0428 }
0429
0430 case ScoreMtxReqSeizeWait_Pre_Protocol_Ceiling: {
0431
0432
0433
0434 if ( ctx->tq_ctx->protocol != TQ_MTX_PRIORITY_CEILING ) {
0435 ctx->Map.skip = true;
0436 }
0437 break;
0438 }
0439
0440 case ScoreMtxReqSeizeWait_Pre_Protocol_MrsP: {
0441
0442
0443
0444 if ( ctx->tq_ctx->protocol != TQ_MTX_MRSP ) {
0445 ctx->Map.skip = true;
0446 }
0447 break;
0448 }
0449
0450 case ScoreMtxReqSeizeWait_Pre_Protocol_NA:
0451 break;
0452 }
0453 }
0454
0455 static void ScoreMtxReqSeizeWait_Pre_Discipline_Prepare(
0456 ScoreMtxReqSeizeWait_Context *ctx,
0457 ScoreMtxReqSeizeWait_Pre_Discipline state
0458 )
0459 {
0460 switch ( state ) {
0461 case ScoreMtxReqSeizeWait_Pre_Discipline_FIFO: {
0462
0463
0464
0465 if ( ctx->tq_ctx->base.discipline != TQ_FIFO ) {
0466 ctx->Map.skip = true;
0467 }
0468 break;
0469 }
0470
0471 case ScoreMtxReqSeizeWait_Pre_Discipline_Priority: {
0472
0473
0474
0475 if ( ctx->tq_ctx->base.discipline != TQ_PRIORITY ) {
0476 ctx->Map.skip = true;
0477 }
0478 break;
0479 }
0480
0481 case ScoreMtxReqSeizeWait_Pre_Discipline_NA:
0482 break;
0483 }
0484 }
0485
0486 static void ScoreMtxReqSeizeWait_Pre_DeadlockResult_Prepare(
0487 ScoreMtxReqSeizeWait_Context *ctx,
0488 ScoreMtxReqSeizeWait_Pre_DeadlockResult state
0489 )
0490 {
0491 switch ( state ) {
0492 case ScoreMtxReqSeizeWait_Pre_DeadlockResult_Status: {
0493
0494
0495
0496 if ( ctx->tq_ctx->base.deadlock != TQ_DEADLOCK_STATUS ) {
0497 ctx->Map.skip = true;
0498 }
0499 break;
0500 }
0501
0502 case ScoreMtxReqSeizeWait_Pre_DeadlockResult_Fatal: {
0503
0504
0505
0506 if ( ctx->tq_ctx->base.deadlock != TQ_DEADLOCK_FATAL ) {
0507 ctx->Map.skip = true;
0508 }
0509 break;
0510 }
0511
0512 case ScoreMtxReqSeizeWait_Pre_DeadlockResult_NA:
0513 break;
0514 }
0515 }
0516
0517 static void ScoreMtxReqSeizeWait_Pre_Recursive_Prepare(
0518 ScoreMtxReqSeizeWait_Context *ctx,
0519 ScoreMtxReqSeizeWait_Pre_Recursive state
0520 )
0521 {
0522 switch ( state ) {
0523 case ScoreMtxReqSeizeWait_Pre_Recursive_Allowed: {
0524
0525
0526
0527 if ( ctx->tq_ctx->recursive != TQ_MTX_RECURSIVE_ALLOWED ) {
0528 ctx->Map.skip = true;
0529 }
0530 break;
0531 }
0532
0533 case ScoreMtxReqSeizeWait_Pre_Recursive_Deadlock: {
0534
0535
0536
0537 if ( ctx->tq_ctx->recursive != TQ_MTX_RECURSIVE_DEADLOCK ) {
0538 ctx->Map.skip = true;
0539 }
0540 break;
0541 }
0542
0543 case ScoreMtxReqSeizeWait_Pre_Recursive_NA:
0544 break;
0545 }
0546 }
0547
0548 static void ScoreMtxReqSeizeWait_Pre_Owner_Prepare(
0549 ScoreMtxReqSeizeWait_Context *ctx,
0550 ScoreMtxReqSeizeWait_Pre_Owner state
0551 )
0552 {
0553 switch ( state ) {
0554 case ScoreMtxReqSeizeWait_Pre_Owner_None: {
0555
0556
0557
0558
0559 break;
0560 }
0561
0562 case ScoreMtxReqSeizeWait_Pre_Owner_Caller: {
0563
0564
0565
0566 ctx->owner_caller = true;
0567 break;
0568 }
0569
0570 case ScoreMtxReqSeizeWait_Pre_Owner_Other: {
0571
0572
0573
0574
0575 ctx->owner_other = true;
0576 break;
0577 }
0578
0579 case ScoreMtxReqSeizeWait_Pre_Owner_Deadlock: {
0580
0581
0582
0583 ctx->owner_other = true;
0584 ctx->deadlock = true;
0585 break;
0586 }
0587
0588 case ScoreMtxReqSeizeWait_Pre_Owner_NA:
0589 break;
0590 }
0591 }
0592
0593 static void ScoreMtxReqSeizeWait_Pre_Priority_Prepare(
0594 ScoreMtxReqSeizeWait_Context *ctx,
0595 ScoreMtxReqSeizeWait_Pre_Priority state
0596 )
0597 {
0598 switch ( state ) {
0599 case ScoreMtxReqSeizeWait_Pre_Priority_High: {
0600
0601
0602
0603
0604 ctx->priority_before = ctx->tq_ctx->priority_ceiling - 1;
0605 break;
0606 }
0607
0608 case ScoreMtxReqSeizeWait_Pre_Priority_Equal: {
0609
0610
0611
0612
0613 ctx->priority_before = ctx->tq_ctx->priority_ceiling;
0614 break;
0615 }
0616
0617 case ScoreMtxReqSeizeWait_Pre_Priority_Low: {
0618
0619
0620
0621
0622 ctx->priority_before = ctx->tq_ctx->priority_ceiling + 1;
0623 break;
0624 }
0625
0626 case ScoreMtxReqSeizeWait_Pre_Priority_NA:
0627 break;
0628 }
0629 }
0630
0631 static void ScoreMtxReqSeizeWait_Post_Status_Check(
0632 ScoreMtxReqSeizeWait_Context *ctx,
0633 ScoreMtxReqSeizeWait_Post_Status state
0634 )
0635 {
0636 switch ( state ) {
0637 case ScoreMtxReqSeizeWait_Post_Status_Ok: {
0638
0639
0640
0641
0642 T_true( IsEnqueueStatus( ctx, STATUS_SUCCESSFUL ) );
0643 break;
0644 }
0645
0646 case ScoreMtxReqSeizeWait_Post_Status_MutexCeilingViolated: {
0647
0648
0649
0650
0651 T_true( IsEnqueueStatus( ctx, STATUS_MUTEX_CEILING_VIOLATED ) );
0652 break;
0653 }
0654
0655 case ScoreMtxReqSeizeWait_Post_Status_DeadlockStatus: {
0656
0657
0658
0659
0660 T_true( IsEnqueueStatus( ctx, STATUS_DEADLOCK ) );
0661 ScoreTqReqEnqueueDeadlock_Run( &ctx->tq_ctx->base );
0662 break;
0663 }
0664
0665 case ScoreMtxReqSeizeWait_Post_Status_DeadlockFatal: {
0666
0667
0668
0669
0670 T_eq_int( ctx->tq_ctx->base.status[ TQ_BLOCKER_A ], STATUS_DEADLOCK );
0671 ScoreTqReqEnqueueDeadlock_Run( &ctx->tq_ctx->base );
0672 break;
0673 }
0674
0675 case ScoreMtxReqSeizeWait_Post_Status_NA:
0676 break;
0677 }
0678 }
0679
0680 static void ScoreMtxReqSeizeWait_Post_Enqueued_Check(
0681 ScoreMtxReqSeizeWait_Context *ctx,
0682 ScoreMtxReqSeizeWait_Post_Enqueued state
0683 )
0684 {
0685 switch ( state ) {
0686 case ScoreMtxReqSeizeWait_Post_Enqueued_No: {
0687
0688
0689
0690
0691
0692 break;
0693 }
0694
0695 case ScoreMtxReqSeizeWait_Post_Enqueued_FIFO: {
0696
0697
0698
0699 ScoreTqReqEnqueueFifo_Run( &ctx->tq_ctx->base );
0700 break;
0701 }
0702
0703 case ScoreMtxReqSeizeWait_Post_Enqueued_Priority: {
0704
0705
0706
0707 ScoreTqReqEnqueuePriority_Run( &ctx->tq_ctx->base );
0708 break;
0709 }
0710
0711 case ScoreMtxReqSeizeWait_Post_Enqueued_PriorityInherit: {
0712
0713
0714
0715
0716 ScoreTqReqEnqueuePriorityInherit_Run( &ctx->tq_ctx->base );
0717 break;
0718 }
0719
0720 case ScoreMtxReqSeizeWait_Post_Enqueued_PriorityCeiling: {
0721
0722
0723
0724
0725 ScoreTqReqEnqueueCeiling_Run( &ctx->tq_ctx->base );
0726 break;
0727 }
0728
0729 case ScoreMtxReqSeizeWait_Post_Enqueued_PriorityMrsP: {
0730
0731
0732
0733
0734 #if defined(RTEMS_SMP)
0735 ScoreTqReqEnqueueMrsp_Run( &ctx->tq_ctx->base );
0736 #else
0737 T_unreachable();
0738 #endif
0739 break;
0740 }
0741
0742 case ScoreMtxReqSeizeWait_Post_Enqueued_NA:
0743 break;
0744 }
0745 }
0746
0747 static void ScoreMtxReqSeizeWait_Post_Owner_Check(
0748 ScoreMtxReqSeizeWait_Context *ctx,
0749 ScoreMtxReqSeizeWait_Post_Owner state
0750 )
0751 {
0752 switch ( state ) {
0753 case ScoreMtxReqSeizeWait_Post_Owner_Other: {
0754
0755
0756
0757 T_eq_ptr(
0758 ctx->owner_after,
0759 ctx->tq_ctx->base.worker_tcb[ TQ_BLOCKER_B ]
0760 );
0761 break;
0762 }
0763
0764 case ScoreMtxReqSeizeWait_Post_Owner_Caller: {
0765
0766
0767
0768 T_eq_ptr(
0769 ctx->owner_after,
0770 ctx->tq_ctx->base.worker_tcb[ TQ_BLOCKER_A ]
0771 );
0772 break;
0773 }
0774
0775 case ScoreMtxReqSeizeWait_Post_Owner_None: {
0776
0777
0778
0779 T_null( ctx->owner_after );
0780 break;
0781 }
0782
0783 case ScoreMtxReqSeizeWait_Post_Owner_NA:
0784 break;
0785 }
0786 }
0787
0788 static void ScoreMtxReqSeizeWait_Post_Priority_Check(
0789 ScoreMtxReqSeizeWait_Context *ctx,
0790 ScoreMtxReqSeizeWait_Post_Priority state
0791 )
0792 {
0793 switch ( state ) {
0794 case ScoreMtxReqSeizeWait_Post_Priority_Nop: {
0795
0796
0797
0798 T_eq_u32( ctx->priority_after, ctx->priority_before );
0799 break;
0800 }
0801
0802 case ScoreMtxReqSeizeWait_Post_Priority_Ceiling: {
0803
0804
0805
0806 T_eq_u32( ctx->priority_after, ctx->tq_ctx->priority_ceiling );
0807 break;
0808 }
0809
0810 case ScoreMtxReqSeizeWait_Post_Priority_NA:
0811 break;
0812 }
0813 }
0814
0815 static void ScoreMtxReqSeizeWait_Prepare( ScoreMtxReqSeizeWait_Context *ctx )
0816 {
0817 ctx->owner_caller = false;
0818 ctx->owner_other = false;
0819 ctx->deadlock = false;
0820 ctx->priority_before = PRIO_VERY_HIGH;
0821 }
0822
0823 static void ScoreMtxReqSeizeWait_Action( ScoreMtxReqSeizeWait_Context *ctx )
0824 {
0825 TQSetScheduler(
0826 &ctx->tq_ctx->base,
0827 TQ_BLOCKER_B,
0828 SCHEDULER_A_ID,
0829 PRIO_VERY_HIGH
0830 );
0831
0832 if ( ctx->tq_ctx->base.enqueue_variant == TQ_ENQUEUE_STICKY ) {
0833 ActionSticky( ctx );
0834 } else {
0835 Action( ctx );
0836 }
0837 }
0838
0839 static const ScoreMtxReqSeizeWait_Entry
0840 ScoreMtxReqSeizeWait_Entries[] = {
0841 { 1, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_NA,
0842 ScoreMtxReqSeizeWait_Post_Enqueued_NA, ScoreMtxReqSeizeWait_Post_Owner_NA,
0843 ScoreMtxReqSeizeWait_Post_Priority_NA },
0844 { 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeWait_Post_Status_Ok,
0845 ScoreMtxReqSeizeWait_Post_Enqueued_No,
0846 ScoreMtxReqSeizeWait_Post_Owner_Caller,
0847 ScoreMtxReqSeizeWait_Post_Priority_Nop },
0848 { 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeWait_Post_Status_DeadlockStatus,
0849 ScoreMtxReqSeizeWait_Post_Enqueued_No,
0850 ScoreMtxReqSeizeWait_Post_Owner_Other,
0851 ScoreMtxReqSeizeWait_Post_Priority_Nop },
0852 { 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeWait_Post_Status_DeadlockFatal,
0853 ScoreMtxReqSeizeWait_Post_Enqueued_No,
0854 ScoreMtxReqSeizeWait_Post_Owner_Other,
0855 ScoreMtxReqSeizeWait_Post_Priority_Nop },
0856 { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_Ok,
0857 ScoreMtxReqSeizeWait_Post_Enqueued_No,
0858 ScoreMtxReqSeizeWait_Post_Owner_Caller,
0859 ScoreMtxReqSeizeWait_Post_Priority_Ceiling },
0860 { 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeWait_Post_Status_NA,
0861 ScoreMtxReqSeizeWait_Post_Enqueued_FIFO,
0862 ScoreMtxReqSeizeWait_Post_Owner_Other,
0863 ScoreMtxReqSeizeWait_Post_Priority_Nop },
0864 { 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeWait_Post_Status_NA,
0865 ScoreMtxReqSeizeWait_Post_Enqueued_Priority,
0866 ScoreMtxReqSeizeWait_Post_Owner_Other,
0867 ScoreMtxReqSeizeWait_Post_Priority_Nop },
0868 { 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeWait_Post_Status_NA,
0869 ScoreMtxReqSeizeWait_Post_Enqueued_PriorityInherit,
0870 ScoreMtxReqSeizeWait_Post_Owner_Other,
0871 ScoreMtxReqSeizeWait_Post_Priority_Nop },
0872 { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_NA,
0873 ScoreMtxReqSeizeWait_Post_Enqueued_PriorityCeiling,
0874 ScoreMtxReqSeizeWait_Post_Owner_Other,
0875 ScoreMtxReqSeizeWait_Post_Priority_Nop },
0876 { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_DeadlockStatus,
0877 ScoreMtxReqSeizeWait_Post_Enqueued_No,
0878 ScoreMtxReqSeizeWait_Post_Owner_Other,
0879 ScoreMtxReqSeizeWait_Post_Priority_Nop },
0880 { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_DeadlockFatal,
0881 ScoreMtxReqSeizeWait_Post_Enqueued_No,
0882 ScoreMtxReqSeizeWait_Post_Owner_Other,
0883 ScoreMtxReqSeizeWait_Post_Priority_Nop },
0884 { 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeWait_Post_Status_DeadlockStatus,
0885 ScoreMtxReqSeizeWait_Post_Enqueued_No,
0886 ScoreMtxReqSeizeWait_Post_Owner_Caller,
0887 ScoreMtxReqSeizeWait_Post_Priority_Nop },
0888 { 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeWait_Post_Status_DeadlockFatal,
0889 ScoreMtxReqSeizeWait_Post_Enqueued_No,
0890 ScoreMtxReqSeizeWait_Post_Owner_Caller,
0891 ScoreMtxReqSeizeWait_Post_Priority_Nop },
0892 { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_MutexCeilingViolated,
0893 ScoreMtxReqSeizeWait_Post_Enqueued_No,
0894 ScoreMtxReqSeizeWait_Post_Owner_None,
0895 ScoreMtxReqSeizeWait_Post_Priority_Nop },
0896 { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_Ok,
0897 ScoreMtxReqSeizeWait_Post_Enqueued_No,
0898 ScoreMtxReqSeizeWait_Post_Owner_Caller,
0899 ScoreMtxReqSeizeWait_Post_Priority_Nop },
0900 { 1, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_NA,
0901 ScoreMtxReqSeizeWait_Post_Enqueued_NA, ScoreMtxReqSeizeWait_Post_Owner_NA,
0902 ScoreMtxReqSeizeWait_Post_Priority_NA },
0903 { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_MutexCeilingViolated,
0904 ScoreMtxReqSeizeWait_Post_Enqueued_No,
0905 ScoreMtxReqSeizeWait_Post_Owner_Other,
0906 ScoreMtxReqSeizeWait_Post_Priority_Nop },
0907 { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_NA,
0908 ScoreMtxReqSeizeWait_Post_Enqueued_PriorityMrsP,
0909 ScoreMtxReqSeizeWait_Post_Owner_Other,
0910 ScoreMtxReqSeizeWait_Post_Priority_Ceiling },
0911 { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_DeadlockStatus,
0912 ScoreMtxReqSeizeWait_Post_Enqueued_No,
0913 ScoreMtxReqSeizeWait_Post_Owner_Caller,
0914 ScoreMtxReqSeizeWait_Post_Priority_Nop },
0915 { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_DeadlockFatal,
0916 ScoreMtxReqSeizeWait_Post_Enqueued_No,
0917 ScoreMtxReqSeizeWait_Post_Owner_Caller,
0918 ScoreMtxReqSeizeWait_Post_Priority_Nop }
0919 };
0920
0921 static const uint8_t
0922 ScoreMtxReqSeizeWait_Map[] = {
0923 1, 1, 1, 1, 1, 1, 5, 5, 5, 2, 2, 2, 1, 1, 1, 11, 11, 11, 5, 5, 5, 2, 2, 2, 1,
0924 1, 1, 1, 1, 1, 5, 5, 5, 3, 3, 3, 1, 1, 1, 12, 12, 12, 5, 5, 5, 3, 3, 3, 1, 1,
0925 1, 1, 1, 1, 6, 6, 6, 2, 2, 2, 1, 1, 1, 11, 11, 11, 6, 6, 6, 2, 2, 2, 1, 1, 1,
0926 1, 1, 1, 6, 6, 6, 3, 3, 3, 1, 1, 1, 12, 12, 12, 6, 6, 6, 3, 3, 3, 0, 0, 0, 0,
0927 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0928 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 7, 7,
0929 7, 2, 2, 2, 1, 1, 1, 11, 11, 11, 7, 7, 7, 2, 2, 2, 1, 1, 1, 1, 1, 1, 7, 7, 7,
0930 3, 3, 3, 1, 1, 1, 12, 12, 12, 7, 7, 7, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0931 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0932 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 14, 14, 15, 8, 8, 8, 9, 9, 9,
0933 13, 4, 4, 18, 18, 15, 8, 8, 8, 9, 9, 9, 13, 4, 4, 14, 14, 15, 8, 8, 8, 10,
0934 10, 10, 13, 4, 4, 19, 19, 15, 8, 8, 8, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0935 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0936 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 14, 14, 15, 16, 17, 17, 16,
0937 9, 9, 13, 4, 4, 18, 18, 15, 16, 17, 17, 16, 9, 9, 13, 4, 4, 14, 14, 15, 16,
0938 17, 17, 16, 10, 10, 13, 4, 4, 19, 19, 15, 16, 17, 17, 16, 10, 10
0939 };
0940
0941 static size_t ScoreMtxReqSeizeWait_Scope( void *arg, char *buf, size_t n )
0942 {
0943 ScoreMtxReqSeizeWait_Context *ctx;
0944
0945 ctx = arg;
0946
0947 if ( ctx->Map.in_action_loop ) {
0948 return T_get_scope( ScoreMtxReqSeizeWait_PreDesc, buf, n, ctx->Map.pcs );
0949 }
0950
0951 return 0;
0952 }
0953
0954 static T_fixture ScoreMtxReqSeizeWait_Fixture = {
0955 .setup = NULL,
0956 .stop = NULL,
0957 .teardown = NULL,
0958 .scope = ScoreMtxReqSeizeWait_Scope,
0959 .initial_context = &ScoreMtxReqSeizeWait_Instance
0960 };
0961
0962 static const uint8_t ScoreMtxReqSeizeWait_Weights[] = {
0963 96, 48, 24, 12, 3, 1
0964 };
0965
0966 static void ScoreMtxReqSeizeWait_Skip(
0967 ScoreMtxReqSeizeWait_Context *ctx,
0968 size_t index
0969 )
0970 {
0971 switch ( index + 1 ) {
0972 case 1:
0973 ctx->Map.pci[ 1 ] = ScoreMtxReqSeizeWait_Pre_Discipline_NA - 1;
0974
0975 case 2:
0976 ctx->Map.pci[ 2 ] = ScoreMtxReqSeizeWait_Pre_DeadlockResult_NA - 1;
0977
0978 case 3:
0979 ctx->Map.pci[ 3 ] = ScoreMtxReqSeizeWait_Pre_Recursive_NA - 1;
0980
0981 case 4:
0982 ctx->Map.pci[ 4 ] = ScoreMtxReqSeizeWait_Pre_Owner_NA - 1;
0983
0984 case 5:
0985 ctx->Map.pci[ 5 ] = ScoreMtxReqSeizeWait_Pre_Priority_NA - 1;
0986 break;
0987 }
0988 }
0989
0990 static inline ScoreMtxReqSeizeWait_Entry ScoreMtxReqSeizeWait_PopEntry(
0991 ScoreMtxReqSeizeWait_Context *ctx
0992 )
0993 {
0994 size_t index;
0995
0996 if ( ctx->Map.skip ) {
0997 size_t i;
0998
0999 ctx->Map.skip = false;
1000 index = 0;
1001
1002 for ( i = 0; i < 6; ++i ) {
1003 index += ScoreMtxReqSeizeWait_Weights[ i ] * ctx->Map.pci[ i ];
1004 }
1005 } else {
1006 index = ctx->Map.index;
1007 }
1008
1009 ctx->Map.index = index + 1;
1010
1011 return ScoreMtxReqSeizeWait_Entries[
1012 ScoreMtxReqSeizeWait_Map[ index ]
1013 ];
1014 }
1015
1016 static void ScoreMtxReqSeizeWait_SetPreConditionStates(
1017 ScoreMtxReqSeizeWait_Context *ctx
1018 )
1019 {
1020 ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
1021 ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
1022 ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
1023 ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
1024 ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
1025
1026 if ( ctx->Map.entry.Pre_Priority_NA ) {
1027 ctx->Map.pcs[ 5 ] = ScoreMtxReqSeizeWait_Pre_Priority_NA;
1028 } else {
1029 ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
1030 }
1031 }
1032
1033 static void ScoreMtxReqSeizeWait_TestVariant(
1034 ScoreMtxReqSeizeWait_Context *ctx
1035 )
1036 {
1037 ScoreMtxReqSeizeWait_Pre_Protocol_Prepare( ctx, ctx->Map.pcs[ 0 ] );
1038
1039 if ( ctx->Map.skip ) {
1040 ScoreMtxReqSeizeWait_Skip( ctx, 0 );
1041 return;
1042 }
1043
1044 ScoreMtxReqSeizeWait_Pre_Discipline_Prepare( ctx, ctx->Map.pcs[ 1 ] );
1045
1046 if ( ctx->Map.skip ) {
1047 ScoreMtxReqSeizeWait_Skip( ctx, 1 );
1048 return;
1049 }
1050
1051 ScoreMtxReqSeizeWait_Pre_DeadlockResult_Prepare( ctx, ctx->Map.pcs[ 2 ] );
1052
1053 if ( ctx->Map.skip ) {
1054 ScoreMtxReqSeizeWait_Skip( ctx, 2 );
1055 return;
1056 }
1057
1058 ScoreMtxReqSeizeWait_Pre_Recursive_Prepare( ctx, ctx->Map.pcs[ 3 ] );
1059
1060 if ( ctx->Map.skip ) {
1061 ScoreMtxReqSeizeWait_Skip( ctx, 3 );
1062 return;
1063 }
1064
1065 ScoreMtxReqSeizeWait_Pre_Owner_Prepare( ctx, ctx->Map.pcs[ 4 ] );
1066 ScoreMtxReqSeizeWait_Pre_Priority_Prepare( ctx, ctx->Map.pcs[ 5 ] );
1067 ScoreMtxReqSeizeWait_Action( ctx );
1068 ScoreMtxReqSeizeWait_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
1069 ScoreMtxReqSeizeWait_Post_Enqueued_Check(
1070 ctx,
1071 ctx->Map.entry.Post_Enqueued
1072 );
1073 ScoreMtxReqSeizeWait_Post_Owner_Check( ctx, ctx->Map.entry.Post_Owner );
1074 ScoreMtxReqSeizeWait_Post_Priority_Check(
1075 ctx,
1076 ctx->Map.entry.Post_Priority
1077 );
1078 }
1079
1080 static T_fixture_node ScoreMtxReqSeizeWait_Node;
1081
1082 static T_remark ScoreMtxReqSeizeWait_Remark = {
1083 .next = NULL,
1084 .remark = "ScoreMtxReqSeizeWait"
1085 };
1086
1087 void ScoreMtxReqSeizeWait_Run( TQMtxContext *tq_ctx )
1088 {
1089 ScoreMtxReqSeizeWait_Context *ctx;
1090
1091 ctx = &ScoreMtxReqSeizeWait_Instance;
1092 ctx->tq_ctx = tq_ctx;
1093
1094 ctx = T_push_fixture(
1095 &ScoreMtxReqSeizeWait_Node,
1096 &ScoreMtxReqSeizeWait_Fixture
1097 );
1098 ctx->Map.in_action_loop = true;
1099 ctx->Map.index = 0;
1100 ctx->Map.skip = false;
1101
1102 for (
1103 ctx->Map.pci[ 0 ] = ScoreMtxReqSeizeWait_Pre_Protocol_None;
1104 ctx->Map.pci[ 0 ] < ScoreMtxReqSeizeWait_Pre_Protocol_NA;
1105 ++ctx->Map.pci[ 0 ]
1106 ) {
1107 for (
1108 ctx->Map.pci[ 1 ] = ScoreMtxReqSeizeWait_Pre_Discipline_FIFO;
1109 ctx->Map.pci[ 1 ] < ScoreMtxReqSeizeWait_Pre_Discipline_NA;
1110 ++ctx->Map.pci[ 1 ]
1111 ) {
1112 for (
1113 ctx->Map.pci[ 2 ] = ScoreMtxReqSeizeWait_Pre_DeadlockResult_Status;
1114 ctx->Map.pci[ 2 ] < ScoreMtxReqSeizeWait_Pre_DeadlockResult_NA;
1115 ++ctx->Map.pci[ 2 ]
1116 ) {
1117 for (
1118 ctx->Map.pci[ 3 ] = ScoreMtxReqSeizeWait_Pre_Recursive_Allowed;
1119 ctx->Map.pci[ 3 ] < ScoreMtxReqSeizeWait_Pre_Recursive_NA;
1120 ++ctx->Map.pci[ 3 ]
1121 ) {
1122 for (
1123 ctx->Map.pci[ 4 ] = ScoreMtxReqSeizeWait_Pre_Owner_None;
1124 ctx->Map.pci[ 4 ] < ScoreMtxReqSeizeWait_Pre_Owner_NA;
1125 ++ctx->Map.pci[ 4 ]
1126 ) {
1127 for (
1128 ctx->Map.pci[ 5 ] = ScoreMtxReqSeizeWait_Pre_Priority_High;
1129 ctx->Map.pci[ 5 ] < ScoreMtxReqSeizeWait_Pre_Priority_NA;
1130 ++ctx->Map.pci[ 5 ]
1131 ) {
1132 ctx->Map.entry = ScoreMtxReqSeizeWait_PopEntry( ctx );
1133
1134 if ( ctx->Map.entry.Skip ) {
1135 continue;
1136 }
1137
1138 ScoreMtxReqSeizeWait_SetPreConditionStates( ctx );
1139 ScoreMtxReqSeizeWait_Prepare( ctx );
1140 ScoreMtxReqSeizeWait_TestVariant( ctx );
1141 }
1142 }
1143 }
1144 }
1145 }
1146 }
1147
1148 T_add_remark( &ScoreMtxReqSeizeWait_Remark );
1149 T_pop_fixture();
1150 }
1151
1152