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-sem-surrender.h"
0056 #include "tr-tq-surrender.h"
0057
0058 #include <rtems/test.h>
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 typedef struct {
0069 uint16_t Skip : 1;
0070 uint16_t Pre_Variant_NA : 1;
0071 uint16_t Pre_Discipline_NA : 1;
0072 uint16_t Pre_Count_NA : 1;
0073 uint16_t Post_Status : 2;
0074 uint16_t Post_Surrender : 2;
0075 uint16_t Post_Count : 3;
0076 } ScoreSemReqSurrender_Entry;
0077
0078
0079
0080
0081 typedef struct {
0082
0083
0084
0085
0086 uint32_t count_before;
0087
0088
0089
0090
0091 Status_Control status;
0092
0093
0094
0095
0096 uint32_t count_after;
0097
0098
0099
0100
0101
0102 bool blocked;
0103
0104
0105
0106
0107
0108 TQSemContext *tq_ctx;
0109
0110 struct {
0111
0112
0113
0114 size_t pcs[ 3 ];
0115
0116
0117
0118
0119 bool in_action_loop;
0120
0121
0122
0123
0124 size_t index;
0125
0126
0127
0128
0129 ScoreSemReqSurrender_Entry entry;
0130
0131
0132
0133
0134
0135 bool skip;
0136 } Map;
0137 } ScoreSemReqSurrender_Context;
0138
0139 static ScoreSemReqSurrender_Context
0140 ScoreSemReqSurrender_Instance;
0141
0142 static const char * const ScoreSemReqSurrender_PreDesc_Variant[] = {
0143 "Binary",
0144 "Counting",
0145 "NA"
0146 };
0147
0148 static const char * const ScoreSemReqSurrender_PreDesc_Discipline[] = {
0149 "FIFO",
0150 "Priority",
0151 "NA"
0152 };
0153
0154 static const char * const ScoreSemReqSurrender_PreDesc_Count[] = {
0155 "LessMax",
0156 "Max",
0157 "Blocked",
0158 "NA"
0159 };
0160
0161 static const char * const * const ScoreSemReqSurrender_PreDesc[] = {
0162 ScoreSemReqSurrender_PreDesc_Variant,
0163 ScoreSemReqSurrender_PreDesc_Discipline,
0164 ScoreSemReqSurrender_PreDesc_Count,
0165 NULL
0166 };
0167
0168 typedef ScoreSemReqSurrender_Context Context;
0169
0170 static Status_Control Status( const Context *ctx, Status_Control status )
0171 {
0172 return TQConvertStatus( &ctx->tq_ctx->base, status );
0173 }
0174
0175 static void ScoreSemReqSurrender_Pre_Variant_Prepare(
0176 ScoreSemReqSurrender_Context *ctx,
0177 ScoreSemReqSurrender_Pre_Variant state
0178 )
0179 {
0180 switch ( state ) {
0181 case ScoreSemReqSurrender_Pre_Variant_Binary: {
0182
0183
0184
0185 if ( ctx->tq_ctx->variant != TQ_SEM_BINARY ) {
0186 ctx->Map.skip = true;
0187 }
0188 break;
0189 }
0190
0191 case ScoreSemReqSurrender_Pre_Variant_Counting: {
0192
0193
0194
0195 if ( ctx->tq_ctx->variant != TQ_SEM_COUNTING ) {
0196 ctx->Map.skip = true;
0197 }
0198 break;
0199 }
0200
0201 case ScoreSemReqSurrender_Pre_Variant_NA:
0202 break;
0203 }
0204 }
0205
0206 static void ScoreSemReqSurrender_Pre_Discipline_Prepare(
0207 ScoreSemReqSurrender_Context *ctx,
0208 ScoreSemReqSurrender_Pre_Discipline state
0209 )
0210 {
0211 switch ( state ) {
0212 case ScoreSemReqSurrender_Pre_Discipline_FIFO: {
0213
0214
0215
0216 if ( ctx->tq_ctx->base.discipline != TQ_FIFO ) {
0217 ctx->Map.skip = true;
0218 }
0219 break;
0220 }
0221
0222 case ScoreSemReqSurrender_Pre_Discipline_Priority: {
0223
0224
0225
0226 if ( ctx->tq_ctx->base.discipline != TQ_PRIORITY ) {
0227 ctx->Map.skip = true;
0228 }
0229 break;
0230 }
0231
0232 case ScoreSemReqSurrender_Pre_Discipline_NA:
0233 break;
0234 }
0235 }
0236
0237 static void ScoreSemReqSurrender_Pre_Count_Prepare(
0238 ScoreSemReqSurrender_Context *ctx,
0239 ScoreSemReqSurrender_Pre_Count state
0240 )
0241 {
0242 switch ( state ) {
0243 case ScoreSemReqSurrender_Pre_Count_LessMax: {
0244
0245
0246
0247 ctx->blocked = false;
0248
0249 if ( ctx->tq_ctx->variant == TQ_SEM_BINARY ) {
0250 ctx->count_before = 0;
0251 } else {
0252 ctx->count_before = UINT32_MAX - 1;
0253 }
0254 break;
0255 }
0256
0257 case ScoreSemReqSurrender_Pre_Count_Max: {
0258
0259
0260
0261 ctx->blocked = false;
0262
0263 if ( ctx->tq_ctx->variant == TQ_SEM_BINARY ) {
0264 ctx->count_before = 1;
0265 } else {
0266 ctx->count_before = UINT32_MAX;
0267 }
0268 break;
0269 }
0270
0271 case ScoreSemReqSurrender_Pre_Count_Blocked: {
0272
0273
0274
0275 ctx->blocked = true;
0276 ctx->count_before = 0;
0277 break;
0278 }
0279
0280 case ScoreSemReqSurrender_Pre_Count_NA:
0281 break;
0282 }
0283 }
0284
0285 static void ScoreSemReqSurrender_Post_Status_Check(
0286 ScoreSemReqSurrender_Context *ctx,
0287 ScoreSemReqSurrender_Post_Status state
0288 )
0289 {
0290 switch ( state ) {
0291 case ScoreSemReqSurrender_Post_Status_Ok: {
0292
0293
0294
0295
0296 T_eq_int( ctx->status, Status( ctx, STATUS_SUCCESSFUL ) );
0297 break;
0298 }
0299
0300 case ScoreSemReqSurrender_Post_Status_MaxCountExceeded: {
0301
0302
0303
0304
0305 T_eq_int( ctx->status, Status( ctx, STATUS_MAXIMUM_COUNT_EXCEEDED ) );
0306 break;
0307 }
0308
0309 case ScoreSemReqSurrender_Post_Status_NA:
0310 break;
0311 }
0312 }
0313
0314 static void ScoreSemReqSurrender_Post_Surrender_Check(
0315 ScoreSemReqSurrender_Context *ctx,
0316 ScoreSemReqSurrender_Post_Surrender state
0317 )
0318 {
0319 switch ( state ) {
0320 case ScoreSemReqSurrender_Post_Surrender_FIFO: {
0321
0322
0323
0324 ScoreTqReqSurrender_Run( &ctx->tq_ctx->base );
0325 break;
0326 }
0327
0328 case ScoreSemReqSurrender_Post_Surrender_Priority: {
0329
0330
0331
0332
0333 ScoreTqReqSurrender_Run( &ctx->tq_ctx->base );
0334 break;
0335 }
0336
0337 case ScoreSemReqSurrender_Post_Surrender_NA:
0338 break;
0339 }
0340 }
0341
0342 static void ScoreSemReqSurrender_Post_Count_Check(
0343 ScoreSemReqSurrender_Context *ctx,
0344 ScoreSemReqSurrender_Post_Count state
0345 )
0346 {
0347 switch ( state ) {
0348 case ScoreSemReqSurrender_Post_Count_Zero: {
0349
0350
0351
0352 T_eq_u32( ctx->count_after, 0 );
0353 break;
0354 }
0355
0356 case ScoreSemReqSurrender_Post_Count_One: {
0357
0358
0359
0360 T_eq_u32( ctx->count_after, 1 );
0361 break;
0362 }
0363
0364 case ScoreSemReqSurrender_Post_Count_PlusOne: {
0365
0366
0367
0368 T_eq_u32( ctx->count_after, ctx->count_before + 1 );
0369 break;
0370 }
0371
0372 case ScoreSemReqSurrender_Post_Count_Nop: {
0373
0374
0375
0376 T_eq_u32( ctx->count_after, ctx->count_before );
0377 break;
0378 }
0379
0380 case ScoreSemReqSurrender_Post_Count_NA:
0381 break;
0382 }
0383 }
0384
0385 static void ScoreSemReqSurrender_Setup( ScoreSemReqSurrender_Context *ctx )
0386 {
0387 ctx->tq_ctx->base.wait = TQ_WAIT_FOREVER;
0388 TQReset( &ctx->tq_ctx->base );
0389 }
0390
0391 static void ScoreSemReqSurrender_Setup_Wrap( void *arg )
0392 {
0393 ScoreSemReqSurrender_Context *ctx;
0394
0395 ctx = arg;
0396 ctx->Map.in_action_loop = false;
0397 ScoreSemReqSurrender_Setup( ctx );
0398 }
0399
0400 static void ScoreSemReqSurrender_Action( ScoreSemReqSurrender_Context *ctx )
0401 {
0402 TQSemSetCount( ctx->tq_ctx, ctx->count_before );
0403
0404 if ( ctx->blocked ) {
0405 TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
0406 }
0407
0408 ctx->status = TQSurrender( &ctx->tq_ctx->base );
0409 ctx->count_after = TQSemGetCount( ctx->tq_ctx );
0410 TQSemSetCount( ctx->tq_ctx, 1 );
0411 }
0412
0413 static const ScoreSemReqSurrender_Entry
0414 ScoreSemReqSurrender_Entries[] = {
0415 { 0, 0, 0, 0, ScoreSemReqSurrender_Post_Status_Ok,
0416 ScoreSemReqSurrender_Post_Surrender_NA, ScoreSemReqSurrender_Post_Count_One },
0417 { 0, 0, 0, 0, ScoreSemReqSurrender_Post_Status_Ok,
0418 ScoreSemReqSurrender_Post_Surrender_FIFO,
0419 ScoreSemReqSurrender_Post_Count_Zero },
0420 { 0, 0, 0, 0, ScoreSemReqSurrender_Post_Status_Ok,
0421 ScoreSemReqSurrender_Post_Surrender_Priority,
0422 ScoreSemReqSurrender_Post_Count_Zero },
0423 { 0, 0, 0, 0, ScoreSemReqSurrender_Post_Status_Ok,
0424 ScoreSemReqSurrender_Post_Surrender_NA,
0425 ScoreSemReqSurrender_Post_Count_PlusOne },
0426 { 0, 0, 0, 0, ScoreSemReqSurrender_Post_Status_MaxCountExceeded,
0427 ScoreSemReqSurrender_Post_Surrender_NA, ScoreSemReqSurrender_Post_Count_Nop }
0428 };
0429
0430 static const uint8_t
0431 ScoreSemReqSurrender_Map[] = {
0432 0, 0, 1, 0, 0, 2, 3, 4, 1, 3, 4, 2
0433 };
0434
0435 static size_t ScoreSemReqSurrender_Scope( void *arg, char *buf, size_t n )
0436 {
0437 ScoreSemReqSurrender_Context *ctx;
0438
0439 ctx = arg;
0440
0441 if ( ctx->Map.in_action_loop ) {
0442 return T_get_scope( ScoreSemReqSurrender_PreDesc, buf, n, ctx->Map.pcs );
0443 }
0444
0445 return 0;
0446 }
0447
0448 static T_fixture ScoreSemReqSurrender_Fixture = {
0449 .setup = ScoreSemReqSurrender_Setup_Wrap,
0450 .stop = NULL,
0451 .teardown = NULL,
0452 .scope = ScoreSemReqSurrender_Scope,
0453 .initial_context = &ScoreSemReqSurrender_Instance
0454 };
0455
0456 static const uint8_t ScoreSemReqSurrender_Weights[] = {
0457 6, 3, 1
0458 };
0459
0460 static void ScoreSemReqSurrender_Skip(
0461 ScoreSemReqSurrender_Context *ctx,
0462 size_t index
0463 )
0464 {
0465 switch ( index + 1 ) {
0466 case 1:
0467 ctx->Map.pcs[ 1 ] = ScoreSemReqSurrender_Pre_Discipline_NA - 1;
0468
0469 case 2:
0470 ctx->Map.pcs[ 2 ] = ScoreSemReqSurrender_Pre_Count_NA - 1;
0471 break;
0472 }
0473 }
0474
0475 static inline ScoreSemReqSurrender_Entry ScoreSemReqSurrender_PopEntry(
0476 ScoreSemReqSurrender_Context *ctx
0477 )
0478 {
0479 size_t index;
0480
0481 if ( ctx->Map.skip ) {
0482 size_t i;
0483
0484 ctx->Map.skip = false;
0485 index = 0;
0486
0487 for ( i = 0; i < 3; ++i ) {
0488 index += ScoreSemReqSurrender_Weights[ i ] * ctx->Map.pcs[ i ];
0489 }
0490 } else {
0491 index = ctx->Map.index;
0492 }
0493
0494 ctx->Map.index = index + 1;
0495
0496 return ScoreSemReqSurrender_Entries[
0497 ScoreSemReqSurrender_Map[ index ]
0498 ];
0499 }
0500
0501 static void ScoreSemReqSurrender_TestVariant(
0502 ScoreSemReqSurrender_Context *ctx
0503 )
0504 {
0505 ScoreSemReqSurrender_Pre_Variant_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0506
0507 if ( ctx->Map.skip ) {
0508 ScoreSemReqSurrender_Skip( ctx, 0 );
0509 return;
0510 }
0511
0512 ScoreSemReqSurrender_Pre_Discipline_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0513
0514 if ( ctx->Map.skip ) {
0515 ScoreSemReqSurrender_Skip( ctx, 1 );
0516 return;
0517 }
0518
0519 ScoreSemReqSurrender_Pre_Count_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0520 ScoreSemReqSurrender_Action( ctx );
0521 ScoreSemReqSurrender_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
0522 ScoreSemReqSurrender_Post_Surrender_Check(
0523 ctx,
0524 ctx->Map.entry.Post_Surrender
0525 );
0526 ScoreSemReqSurrender_Post_Count_Check( ctx, ctx->Map.entry.Post_Count );
0527 }
0528
0529 static T_fixture_node ScoreSemReqSurrender_Node;
0530
0531 static T_remark ScoreSemReqSurrender_Remark = {
0532 .next = NULL,
0533 .remark = "ScoreSemReqSurrender"
0534 };
0535
0536 void ScoreSemReqSurrender_Run( TQSemContext *tq_ctx )
0537 {
0538 ScoreSemReqSurrender_Context *ctx;
0539
0540 ctx = &ScoreSemReqSurrender_Instance;
0541 ctx->tq_ctx = tq_ctx;
0542
0543 ctx = T_push_fixture(
0544 &ScoreSemReqSurrender_Node,
0545 &ScoreSemReqSurrender_Fixture
0546 );
0547 ctx->Map.in_action_loop = true;
0548 ctx->Map.index = 0;
0549 ctx->Map.skip = false;
0550
0551 for (
0552 ctx->Map.pcs[ 0 ] = ScoreSemReqSurrender_Pre_Variant_Binary;
0553 ctx->Map.pcs[ 0 ] < ScoreSemReqSurrender_Pre_Variant_NA;
0554 ++ctx->Map.pcs[ 0 ]
0555 ) {
0556 for (
0557 ctx->Map.pcs[ 1 ] = ScoreSemReqSurrender_Pre_Discipline_FIFO;
0558 ctx->Map.pcs[ 1 ] < ScoreSemReqSurrender_Pre_Discipline_NA;
0559 ++ctx->Map.pcs[ 1 ]
0560 ) {
0561 for (
0562 ctx->Map.pcs[ 2 ] = ScoreSemReqSurrender_Pre_Count_LessMax;
0563 ctx->Map.pcs[ 2 ] < ScoreSemReqSurrender_Pre_Count_NA;
0564 ++ctx->Map.pcs[ 2 ]
0565 ) {
0566 ctx->Map.entry = ScoreSemReqSurrender_PopEntry( ctx );
0567 ScoreSemReqSurrender_TestVariant( ctx );
0568 }
0569 }
0570 }
0571
0572 T_add_remark( &ScoreSemReqSurrender_Remark );
0573 T_pop_fixture();
0574 }
0575
0576