File indexing completed on 2025-05-11 08:24:52
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 <rtems.h>
0056 #include <string.h>
0057
0058 #include "tr-tq-flush-fifo.h"
0059 #include "tr-tq-flush-priority-inherit.h"
0060 #include "tr-tq-flush-priority.h"
0061 #include "tx-support.h"
0062 #include "tx-thread-queue.h"
0063
0064 #include <rtems/test.h>
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074 typedef enum {
0075 RtemsSemReqFlush_Pre_Class_Counting,
0076 RtemsSemReqFlush_Pre_Class_Simple,
0077 RtemsSemReqFlush_Pre_Class_Binary,
0078 RtemsSemReqFlush_Pre_Class_PrioCeiling,
0079 RtemsSemReqFlush_Pre_Class_PrioInherit,
0080 RtemsSemReqFlush_Pre_Class_MrsP,
0081 RtemsSemReqFlush_Pre_Class_NA
0082 } RtemsSemReqFlush_Pre_Class;
0083
0084 typedef enum {
0085 RtemsSemReqFlush_Pre_Discipline_FIFO,
0086 RtemsSemReqFlush_Pre_Discipline_Priority,
0087 RtemsSemReqFlush_Pre_Discipline_NA
0088 } RtemsSemReqFlush_Pre_Discipline;
0089
0090 typedef enum {
0091 RtemsSemReqFlush_Pre_Id_Valid,
0092 RtemsSemReqFlush_Pre_Id_Invalid,
0093 RtemsSemReqFlush_Pre_Id_NA
0094 } RtemsSemReqFlush_Pre_Id;
0095
0096 typedef enum {
0097 RtemsSemReqFlush_Post_Action_InvId,
0098 RtemsSemReqFlush_Post_Action_NotDef,
0099 RtemsSemReqFlush_Post_Action_FlushFIFO,
0100 RtemsSemReqFlush_Post_Action_FlushPriority,
0101 RtemsSemReqFlush_Post_Action_FlushPriorityCeiling,
0102 RtemsSemReqFlush_Post_Action_FlushPriorityInherit,
0103 RtemsSemReqFlush_Post_Action_NA
0104 } RtemsSemReqFlush_Post_Action;
0105
0106 typedef struct {
0107 uint8_t Skip : 1;
0108 uint8_t Pre_Class_NA : 1;
0109 uint8_t Pre_Discipline_NA : 1;
0110 uint8_t Pre_Id_NA : 1;
0111 uint8_t Post_Action : 3;
0112 } RtemsSemReqFlush_Entry;
0113
0114
0115
0116
0117 typedef struct {
0118
0119
0120
0121 TQContext tq_ctx;
0122
0123
0124
0125
0126 rtems_attribute attribute_set;
0127
0128
0129
0130
0131 uint32_t initial_count;
0132
0133 struct {
0134
0135
0136
0137
0138 size_t pci[ 3 ];
0139
0140
0141
0142
0143 size_t pcs[ 3 ];
0144
0145
0146
0147
0148 bool in_action_loop;
0149
0150
0151
0152
0153 size_t index;
0154
0155
0156
0157
0158 RtemsSemReqFlush_Entry entry;
0159
0160
0161
0162
0163
0164 bool skip;
0165 } Map;
0166 } RtemsSemReqFlush_Context;
0167
0168 static RtemsSemReqFlush_Context
0169 RtemsSemReqFlush_Instance;
0170
0171 static const char * const RtemsSemReqFlush_PreDesc_Class[] = {
0172 "Counting",
0173 "Simple",
0174 "Binary",
0175 "PrioCeiling",
0176 "PrioInherit",
0177 "MrsP",
0178 "NA"
0179 };
0180
0181 static const char * const RtemsSemReqFlush_PreDesc_Discipline[] = {
0182 "FIFO",
0183 "Priority",
0184 "NA"
0185 };
0186
0187 static const char * const RtemsSemReqFlush_PreDesc_Id[] = {
0188 "Valid",
0189 "Invalid",
0190 "NA"
0191 };
0192
0193 static const char * const * const RtemsSemReqFlush_PreDesc[] = {
0194 RtemsSemReqFlush_PreDesc_Class,
0195 RtemsSemReqFlush_PreDesc_Discipline,
0196 RtemsSemReqFlush_PreDesc_Id,
0197 NULL
0198 };
0199
0200 #define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
0201
0202 typedef RtemsSemReqFlush_Context Context;
0203
0204 static void EnqueuePrepare( TQContext *tq_ctx )
0205 {
0206 rtems_status_code sc;
0207
0208 sc = rtems_semaphore_obtain(
0209 tq_ctx->thread_queue_id,
0210 RTEMS_WAIT,
0211 RTEMS_NO_TIMEOUT
0212 );
0213 T_rsc_success( sc );
0214 }
0215
0216 static Status_Control Enqueue( TQContext *tq_ctx, TQWait wait )
0217 {
0218 rtems_status_code sc;
0219
0220 (void) wait;
0221 sc = rtems_semaphore_obtain(
0222 tq_ctx->thread_queue_id,
0223 RTEMS_WAIT,
0224 RTEMS_NO_TIMEOUT
0225 );
0226 T_rsc( sc, RTEMS_UNSATISFIED );
0227
0228 return STATUS_BUILD( STATUS_SUCCESSFUL, 0 );
0229 }
0230
0231 static uint32_t Flush( TQContext *tq_ctx, uint32_t thread_count, bool all )
0232 {
0233 rtems_status_code sc;
0234
0235 (void) all;
0236
0237 sc = rtems_semaphore_flush( tq_ctx->thread_queue_id );
0238 T_rsc_success( sc );
0239
0240 return thread_count;
0241 }
0242
0243 static void RtemsSemReqFlush_Pre_Class_Prepare(
0244 RtemsSemReqFlush_Context *ctx,
0245 RtemsSemReqFlush_Pre_Class state
0246 )
0247 {
0248 switch ( state ) {
0249 case RtemsSemReqFlush_Pre_Class_Counting: {
0250
0251
0252
0253 ctx->attribute_set |= RTEMS_COUNTING_SEMAPHORE;
0254 ctx->initial_count = 0;
0255 ctx->tq_ctx.enqueue_prepare = TQDoNothing;
0256 ctx->tq_ctx.enqueue_done = TQDoNothing;
0257 break;
0258 }
0259
0260 case RtemsSemReqFlush_Pre_Class_Simple: {
0261
0262
0263
0264 ctx->attribute_set |= RTEMS_SIMPLE_BINARY_SEMAPHORE;
0265 ctx->initial_count = 0;
0266 ctx->tq_ctx.enqueue_prepare = TQDoNothing;
0267 ctx->tq_ctx.enqueue_done = TQDoNothing;
0268 break;
0269 }
0270
0271 case RtemsSemReqFlush_Pre_Class_Binary: {
0272
0273
0274
0275 ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE;
0276 ctx->initial_count = 1;
0277 ctx->tq_ctx.enqueue_prepare = EnqueuePrepare;
0278 ctx->tq_ctx.enqueue_done = TQEnqueueDoneDefault;
0279 break;
0280 }
0281
0282 case RtemsSemReqFlush_Pre_Class_PrioCeiling: {
0283
0284
0285
0286 ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY_CEILING;
0287 ctx->initial_count = 1;
0288 ctx->tq_ctx.enqueue_prepare = EnqueuePrepare;
0289 ctx->tq_ctx.enqueue_done = TQEnqueueDoneDefault;
0290 break;
0291 }
0292
0293 case RtemsSemReqFlush_Pre_Class_PrioInherit: {
0294
0295
0296
0297 ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY;
0298 ctx->initial_count = 1;
0299 ctx->tq_ctx.enqueue_prepare = EnqueuePrepare;
0300 ctx->tq_ctx.enqueue_done = TQEnqueueDoneDefault;
0301 break;
0302 }
0303
0304 case RtemsSemReqFlush_Pre_Class_MrsP: {
0305
0306
0307
0308 ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE |
0309 RTEMS_MULTIPROCESSOR_RESOURCE_SHARING;
0310 ctx->initial_count = 1;
0311 ctx->tq_ctx.enqueue_prepare = EnqueuePrepare;
0312 ctx->tq_ctx.enqueue_done = TQEnqueueDoneDefault;
0313 break;
0314 }
0315
0316 case RtemsSemReqFlush_Pre_Class_NA:
0317 break;
0318 }
0319 }
0320
0321 static void RtemsSemReqFlush_Pre_Discipline_Prepare(
0322 RtemsSemReqFlush_Context *ctx,
0323 RtemsSemReqFlush_Pre_Discipline state
0324 )
0325 {
0326 switch ( state ) {
0327 case RtemsSemReqFlush_Pre_Discipline_FIFO: {
0328
0329
0330
0331 ctx->attribute_set |= RTEMS_FIFO;
0332 ctx->tq_ctx.discipline = TQ_FIFO;
0333 break;
0334 }
0335
0336 case RtemsSemReqFlush_Pre_Discipline_Priority: {
0337
0338
0339
0340 ctx->attribute_set |= RTEMS_PRIORITY;
0341 ctx->tq_ctx.discipline = TQ_PRIORITY;
0342 break;
0343 }
0344
0345 case RtemsSemReqFlush_Pre_Discipline_NA:
0346 break;
0347 }
0348 }
0349
0350 static void RtemsSemReqFlush_Pre_Id_Prepare(
0351 RtemsSemReqFlush_Context *ctx,
0352 RtemsSemReqFlush_Pre_Id state
0353 )
0354 {
0355 switch ( state ) {
0356 case RtemsSemReqFlush_Pre_Id_Valid: {
0357
0358
0359
0360
0361 break;
0362 }
0363
0364 case RtemsSemReqFlush_Pre_Id_Invalid: {
0365
0366
0367
0368
0369 break;
0370 }
0371
0372 case RtemsSemReqFlush_Pre_Id_NA:
0373 break;
0374 }
0375 }
0376
0377 static void RtemsSemReqFlush_Post_Action_Check(
0378 RtemsSemReqFlush_Context *ctx,
0379 RtemsSemReqFlush_Post_Action state
0380 )
0381 {
0382 rtems_status_code sc;
0383
0384 switch ( state ) {
0385 case RtemsSemReqFlush_Post_Action_InvId: {
0386
0387
0388
0389
0390 sc = rtems_semaphore_flush( 0xffffffff );
0391 T_rsc( sc, RTEMS_INVALID_ID );
0392 break;
0393 }
0394
0395 case RtemsSemReqFlush_Post_Action_NotDef: {
0396
0397
0398
0399
0400 sc = rtems_semaphore_flush( ctx->tq_ctx.thread_queue_id );
0401 T_rsc( sc, RTEMS_NOT_DEFINED );
0402 break;
0403 }
0404
0405 case RtemsSemReqFlush_Post_Action_FlushFIFO: {
0406
0407
0408
0409
0410 ScoreTqReqFlushFifo_Run( &ctx->tq_ctx, false );
0411 break;
0412 }
0413
0414 case RtemsSemReqFlush_Post_Action_FlushPriority: {
0415
0416
0417
0418
0419 ScoreTqReqFlushPriority_Run( &ctx->tq_ctx, true );
0420 break;
0421 }
0422
0423 case RtemsSemReqFlush_Post_Action_FlushPriorityCeiling: {
0424
0425
0426
0427
0428 ScoreTqReqFlushPriority_Run( &ctx->tq_ctx, false );
0429 break;
0430 }
0431
0432 case RtemsSemReqFlush_Post_Action_FlushPriorityInherit: {
0433
0434
0435
0436
0437 ScoreTqReqFlushPriorityInherit_Run( &ctx->tq_ctx );
0438 break;
0439 }
0440
0441 case RtemsSemReqFlush_Post_Action_NA:
0442 break;
0443 }
0444 }
0445
0446 static void RtemsSemReqFlush_Setup( RtemsSemReqFlush_Context *ctx )
0447 {
0448 memset( ctx, 0, sizeof( *ctx ) );
0449 ctx->tq_ctx.enqueue = Enqueue;
0450 ctx->tq_ctx.flush = Flush;
0451 ctx->tq_ctx.surrender = TQSurrenderClassicSem;
0452 ctx->tq_ctx.convert_status = TQConvertStatusClassic;
0453 TQInitialize( &ctx->tq_ctx );
0454 }
0455
0456 static void RtemsSemReqFlush_Setup_Wrap( void *arg )
0457 {
0458 RtemsSemReqFlush_Context *ctx;
0459
0460 ctx = arg;
0461 ctx->Map.in_action_loop = false;
0462 RtemsSemReqFlush_Setup( ctx );
0463 }
0464
0465 static void RtemsSemReqFlush_Teardown( RtemsSemReqFlush_Context *ctx )
0466 {
0467 TQDestroy( &ctx->tq_ctx );
0468 }
0469
0470 static void RtemsSemReqFlush_Teardown_Wrap( void *arg )
0471 {
0472 RtemsSemReqFlush_Context *ctx;
0473
0474 ctx = arg;
0475 ctx->Map.in_action_loop = false;
0476 RtemsSemReqFlush_Teardown( ctx );
0477 }
0478
0479 static void RtemsSemReqFlush_Prepare( RtemsSemReqFlush_Context *ctx )
0480 {
0481 ctx->attribute_set = RTEMS_DEFAULT_ATTRIBUTES;
0482 }
0483
0484 static void RtemsSemReqFlush_Action( RtemsSemReqFlush_Context *ctx )
0485 {
0486 rtems_status_code sc;
0487
0488 sc = rtems_semaphore_create(
0489 NAME,
0490 ctx->initial_count,
0491 ctx->attribute_set,
0492 PRIO_ULTRA_HIGH,
0493 &ctx->tq_ctx.thread_queue_id
0494 );
0495 T_rsc_success( sc );
0496 }
0497
0498 static void RtemsSemReqFlush_Cleanup( RtemsSemReqFlush_Context *ctx )
0499 {
0500 rtems_status_code sc;
0501
0502 sc = rtems_semaphore_delete( ctx->tq_ctx.thread_queue_id );
0503 T_rsc_success( sc );
0504 }
0505
0506 static const RtemsSemReqFlush_Entry
0507 RtemsSemReqFlush_Entries[] = {
0508 { 0, 1, 1, 0, RtemsSemReqFlush_Post_Action_InvId },
0509 { 0, 0, 0, 0, RtemsSemReqFlush_Post_Action_FlushFIFO },
0510 { 0, 0, 0, 0, RtemsSemReqFlush_Post_Action_FlushPriority },
0511 { 1, 0, 0, 0, RtemsSemReqFlush_Post_Action_NA },
0512 { 0, 0, 0, 0, RtemsSemReqFlush_Post_Action_FlushPriorityCeiling },
0513 { 0, 0, 0, 0, RtemsSemReqFlush_Post_Action_FlushPriorityInherit },
0514 #if defined(RTEMS_SMP)
0515 { 0, 0, 0, 0, RtemsSemReqFlush_Post_Action_NotDef }
0516 #else
0517 { 1, 0, 0, 0, RtemsSemReqFlush_Post_Action_NA }
0518 #endif
0519 };
0520
0521 static const uint8_t
0522 RtemsSemReqFlush_Map[] = {
0523 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 3, 0, 4, 0, 3, 0, 5, 0, 3, 0, 6, 0
0524 };
0525
0526 static size_t RtemsSemReqFlush_Scope( void *arg, char *buf, size_t n )
0527 {
0528 RtemsSemReqFlush_Context *ctx;
0529
0530 ctx = arg;
0531
0532 if ( ctx->Map.in_action_loop ) {
0533 return T_get_scope( RtemsSemReqFlush_PreDesc, buf, n, ctx->Map.pcs );
0534 }
0535
0536 return 0;
0537 }
0538
0539 static T_fixture RtemsSemReqFlush_Fixture = {
0540 .setup = RtemsSemReqFlush_Setup_Wrap,
0541 .stop = NULL,
0542 .teardown = RtemsSemReqFlush_Teardown_Wrap,
0543 .scope = RtemsSemReqFlush_Scope,
0544 .initial_context = &RtemsSemReqFlush_Instance
0545 };
0546
0547 static inline RtemsSemReqFlush_Entry RtemsSemReqFlush_PopEntry(
0548 RtemsSemReqFlush_Context *ctx
0549 )
0550 {
0551 size_t index;
0552
0553 index = ctx->Map.index;
0554 ctx->Map.index = index + 1;
0555 return RtemsSemReqFlush_Entries[
0556 RtemsSemReqFlush_Map[ index ]
0557 ];
0558 }
0559
0560 static void RtemsSemReqFlush_SetPreConditionStates(
0561 RtemsSemReqFlush_Context *ctx
0562 )
0563 {
0564 if ( ctx->Map.entry.Pre_Class_NA ) {
0565 ctx->Map.pcs[ 0 ] = RtemsSemReqFlush_Pre_Class_NA;
0566 } else {
0567 ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
0568 }
0569
0570 if ( ctx->Map.entry.Pre_Discipline_NA ) {
0571 ctx->Map.pcs[ 1 ] = RtemsSemReqFlush_Pre_Discipline_NA;
0572 } else {
0573 ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
0574 }
0575
0576 ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
0577 }
0578
0579 static void RtemsSemReqFlush_TestVariant( RtemsSemReqFlush_Context *ctx )
0580 {
0581 RtemsSemReqFlush_Pre_Class_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0582 RtemsSemReqFlush_Pre_Discipline_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0583 RtemsSemReqFlush_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0584 RtemsSemReqFlush_Action( ctx );
0585 RtemsSemReqFlush_Post_Action_Check( ctx, ctx->Map.entry.Post_Action );
0586 }
0587
0588
0589
0590
0591 T_TEST_CASE_FIXTURE( RtemsSemReqFlush, &RtemsSemReqFlush_Fixture )
0592 {
0593 RtemsSemReqFlush_Context *ctx;
0594
0595 ctx = T_fixture_context();
0596 ctx->Map.in_action_loop = true;
0597 ctx->Map.index = 0;
0598
0599 for (
0600 ctx->Map.pci[ 0 ] = RtemsSemReqFlush_Pre_Class_Counting;
0601 ctx->Map.pci[ 0 ] < RtemsSemReqFlush_Pre_Class_NA;
0602 ++ctx->Map.pci[ 0 ]
0603 ) {
0604 for (
0605 ctx->Map.pci[ 1 ] = RtemsSemReqFlush_Pre_Discipline_FIFO;
0606 ctx->Map.pci[ 1 ] < RtemsSemReqFlush_Pre_Discipline_NA;
0607 ++ctx->Map.pci[ 1 ]
0608 ) {
0609 for (
0610 ctx->Map.pci[ 2 ] = RtemsSemReqFlush_Pre_Id_Valid;
0611 ctx->Map.pci[ 2 ] < RtemsSemReqFlush_Pre_Id_NA;
0612 ++ctx->Map.pci[ 2 ]
0613 ) {
0614 ctx->Map.entry = RtemsSemReqFlush_PopEntry( ctx );
0615
0616 if ( ctx->Map.entry.Skip ) {
0617 continue;
0618 }
0619
0620 RtemsSemReqFlush_SetPreConditionStates( ctx );
0621 RtemsSemReqFlush_Prepare( ctx );
0622 RtemsSemReqFlush_TestVariant( ctx );
0623 RtemsSemReqFlush_Cleanup( ctx );
0624 }
0625 }
0626 }
0627 }
0628
0629