File indexing completed on 2025-05-11 08:24:51
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 "tx-support.h"
0059
0060 #include <rtems/test.h>
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 typedef enum {
0071 RtemsBarrierReqRelease_Pre_Id_NoObj,
0072 RtemsBarrierReqRelease_Pre_Id_Manual,
0073 RtemsBarrierReqRelease_Pre_Id_Auto,
0074 RtemsBarrierReqRelease_Pre_Id_NA
0075 } RtemsBarrierReqRelease_Pre_Id;
0076
0077 typedef enum {
0078 RtemsBarrierReqRelease_Pre_Released_Valid,
0079 RtemsBarrierReqRelease_Pre_Released_Null,
0080 RtemsBarrierReqRelease_Pre_Released_NA
0081 } RtemsBarrierReqRelease_Pre_Released;
0082
0083 typedef enum {
0084 RtemsBarrierReqRelease_Pre_Waiting_Zero,
0085 RtemsBarrierReqRelease_Pre_Waiting_Positive,
0086 RtemsBarrierReqRelease_Pre_Waiting_NA
0087 } RtemsBarrierReqRelease_Pre_Waiting;
0088
0089 typedef enum {
0090 RtemsBarrierReqRelease_Post_Status_Ok,
0091 RtemsBarrierReqRelease_Post_Status_InvId,
0092 RtemsBarrierReqRelease_Post_Status_InvAddr,
0093 RtemsBarrierReqRelease_Post_Status_NA
0094 } RtemsBarrierReqRelease_Post_Status;
0095
0096 typedef enum {
0097 RtemsBarrierReqRelease_Post_ReleasedVar_Set,
0098 RtemsBarrierReqRelease_Post_ReleasedVar_Nop,
0099 RtemsBarrierReqRelease_Post_ReleasedVar_NA
0100 } RtemsBarrierReqRelease_Post_ReleasedVar;
0101
0102 typedef struct {
0103 uint8_t Skip : 1;
0104 uint8_t Pre_Id_NA : 1;
0105 uint8_t Pre_Released_NA : 1;
0106 uint8_t Pre_Waiting_NA : 1;
0107 uint8_t Post_Status : 2;
0108 uint8_t Post_ReleasedVar : 2;
0109 } RtemsBarrierReqRelease_Entry;
0110
0111
0112
0113
0114 typedef struct {
0115 rtems_id worker_id;
0116
0117 rtems_id manual_release_id;
0118
0119 rtems_id auto_release_id;
0120
0121 uint32_t waiting_tasks;
0122
0123 uint32_t released_value;
0124
0125 rtems_id id;
0126
0127 uint32_t *released;
0128
0129 rtems_status_code status;
0130
0131 struct {
0132
0133
0134
0135
0136 size_t pci[ 3 ];
0137
0138
0139
0140
0141 size_t pcs[ 3 ];
0142
0143
0144
0145
0146 bool in_action_loop;
0147
0148
0149
0150
0151 size_t index;
0152
0153
0154
0155
0156 RtemsBarrierReqRelease_Entry entry;
0157
0158
0159
0160
0161
0162 bool skip;
0163 } Map;
0164 } RtemsBarrierReqRelease_Context;
0165
0166 static RtemsBarrierReqRelease_Context
0167 RtemsBarrierReqRelease_Instance;
0168
0169 static const char * const RtemsBarrierReqRelease_PreDesc_Id[] = {
0170 "NoObj",
0171 "Manual",
0172 "Auto",
0173 "NA"
0174 };
0175
0176 static const char * const RtemsBarrierReqRelease_PreDesc_Released[] = {
0177 "Valid",
0178 "Null",
0179 "NA"
0180 };
0181
0182 static const char * const RtemsBarrierReqRelease_PreDesc_Waiting[] = {
0183 "Zero",
0184 "Positive",
0185 "NA"
0186 };
0187
0188 static const char * const * const RtemsBarrierReqRelease_PreDesc[] = {
0189 RtemsBarrierReqRelease_PreDesc_Id,
0190 RtemsBarrierReqRelease_PreDesc_Released,
0191 RtemsBarrierReqRelease_PreDesc_Waiting,
0192 NULL
0193 };
0194
0195 #define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
0196
0197 #define EVENT_WAIT RTEMS_EVENT_0
0198
0199 #define RELEASED_INVALID_VALUE 0xffffffff
0200
0201 typedef RtemsBarrierReqRelease_Context Context;
0202
0203 static void Worker( rtems_task_argument arg )
0204 {
0205 Context *ctx;
0206
0207 ctx = (Context *) arg;
0208
0209 while ( true ) {
0210 rtems_event_set events;
0211
0212 events = ReceiveAnyEvents();
0213
0214 if ( ( events & EVENT_WAIT ) != 0 ) {
0215 rtems_status_code sc;
0216
0217 sc = rtems_barrier_wait( ctx->id, RTEMS_NO_TIMEOUT );
0218 T_rsc_success( sc );
0219 }
0220 }
0221 }
0222
0223 static void RtemsBarrierReqRelease_Pre_Id_Prepare(
0224 RtemsBarrierReqRelease_Context *ctx,
0225 RtemsBarrierReqRelease_Pre_Id state
0226 )
0227 {
0228 switch ( state ) {
0229 case RtemsBarrierReqRelease_Pre_Id_NoObj: {
0230
0231
0232
0233 ctx->id = 0xffffffff;
0234 break;
0235 }
0236
0237 case RtemsBarrierReqRelease_Pre_Id_Manual: {
0238
0239
0240
0241
0242 ctx->id = ctx->manual_release_id;
0243 break;
0244 }
0245
0246 case RtemsBarrierReqRelease_Pre_Id_Auto: {
0247
0248
0249
0250
0251 ctx->id = ctx->auto_release_id;
0252 break;
0253 }
0254
0255 case RtemsBarrierReqRelease_Pre_Id_NA:
0256 break;
0257 }
0258 }
0259
0260 static void RtemsBarrierReqRelease_Pre_Released_Prepare(
0261 RtemsBarrierReqRelease_Context *ctx,
0262 RtemsBarrierReqRelease_Pre_Released state
0263 )
0264 {
0265 ctx->released_value = RELEASED_INVALID_VALUE;
0266
0267 switch ( state ) {
0268 case RtemsBarrierReqRelease_Pre_Released_Valid: {
0269
0270
0271
0272
0273 ctx->released = &ctx->released_value;
0274 break;
0275 }
0276
0277 case RtemsBarrierReqRelease_Pre_Released_Null: {
0278
0279
0280
0281 ctx->released = NULL;
0282 break;
0283 }
0284
0285 case RtemsBarrierReqRelease_Pre_Released_NA:
0286 break;
0287 }
0288 }
0289
0290 static void RtemsBarrierReqRelease_Pre_Waiting_Prepare(
0291 RtemsBarrierReqRelease_Context *ctx,
0292 RtemsBarrierReqRelease_Pre_Waiting state
0293 )
0294 {
0295 switch ( state ) {
0296 case RtemsBarrierReqRelease_Pre_Waiting_Zero: {
0297
0298
0299
0300 ctx->waiting_tasks = 0;
0301 break;
0302 }
0303
0304 case RtemsBarrierReqRelease_Pre_Waiting_Positive: {
0305
0306
0307
0308 ctx->waiting_tasks = 1;
0309 SendEvents( ctx->worker_id, EVENT_WAIT );
0310 break;
0311 }
0312
0313 case RtemsBarrierReqRelease_Pre_Waiting_NA:
0314 break;
0315 }
0316 }
0317
0318 static void RtemsBarrierReqRelease_Post_Status_Check(
0319 RtemsBarrierReqRelease_Context *ctx,
0320 RtemsBarrierReqRelease_Post_Status state
0321 )
0322 {
0323 switch ( state ) {
0324 case RtemsBarrierReqRelease_Post_Status_Ok: {
0325
0326
0327
0328
0329 T_rsc_success( ctx->status );
0330 break;
0331 }
0332
0333 case RtemsBarrierReqRelease_Post_Status_InvId: {
0334
0335
0336
0337
0338 T_rsc( ctx->status, RTEMS_INVALID_ID );
0339 break;
0340 }
0341
0342 case RtemsBarrierReqRelease_Post_Status_InvAddr: {
0343
0344
0345
0346
0347 T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
0348 break;
0349 }
0350
0351 case RtemsBarrierReqRelease_Post_Status_NA:
0352 break;
0353 }
0354 }
0355
0356 static void RtemsBarrierReqRelease_Post_ReleasedVar_Check(
0357 RtemsBarrierReqRelease_Context *ctx,
0358 RtemsBarrierReqRelease_Post_ReleasedVar state
0359 )
0360 {
0361 switch ( state ) {
0362 case RtemsBarrierReqRelease_Post_ReleasedVar_Set: {
0363
0364
0365
0366
0367
0368 T_eq_u32( ctx->released_value, ctx->waiting_tasks );
0369 break;
0370 }
0371
0372 case RtemsBarrierReqRelease_Post_ReleasedVar_Nop: {
0373
0374
0375
0376
0377
0378 T_eq_u32( ctx->released_value, RELEASED_INVALID_VALUE );
0379 break;
0380 }
0381
0382 case RtemsBarrierReqRelease_Post_ReleasedVar_NA:
0383 break;
0384 }
0385 }
0386
0387 static void RtemsBarrierReqRelease_Setup( RtemsBarrierReqRelease_Context *ctx )
0388 {
0389 rtems_status_code sc;
0390
0391 memset( ctx, 0, sizeof( *ctx ) );
0392 SetSelfPriority( PRIO_NORMAL );
0393 ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
0394 StartTask( ctx->worker_id, Worker, ctx );
0395
0396 sc = rtems_barrier_create(
0397 NAME,
0398 RTEMS_BARRIER_MANUAL_RELEASE,
0399 0,
0400 &ctx->manual_release_id
0401 );
0402 T_assert_rsc_success( sc );
0403
0404 sc = rtems_barrier_create(
0405 NAME,
0406 RTEMS_BARRIER_AUTOMATIC_RELEASE,
0407 2,
0408 &ctx->auto_release_id
0409 );
0410 T_assert_rsc_success( sc );
0411 }
0412
0413 static void RtemsBarrierReqRelease_Setup_Wrap( void *arg )
0414 {
0415 RtemsBarrierReqRelease_Context *ctx;
0416
0417 ctx = arg;
0418 ctx->Map.in_action_loop = false;
0419 RtemsBarrierReqRelease_Setup( ctx );
0420 }
0421
0422 static void RtemsBarrierReqRelease_Teardown(
0423 RtemsBarrierReqRelease_Context *ctx
0424 )
0425 {
0426 rtems_status_code sc;
0427
0428 DeleteTask( ctx->worker_id );
0429
0430 if ( ctx->manual_release_id != 0 ) {
0431 sc = rtems_barrier_delete( ctx->manual_release_id );
0432 T_rsc_success( sc );
0433 }
0434
0435 if ( ctx->auto_release_id != 0 ) {
0436 sc = rtems_barrier_delete( ctx->auto_release_id );
0437 T_rsc_success( sc );
0438 }
0439
0440 RestoreRunnerPriority();
0441 }
0442
0443 static void RtemsBarrierReqRelease_Teardown_Wrap( void *arg )
0444 {
0445 RtemsBarrierReqRelease_Context *ctx;
0446
0447 ctx = arg;
0448 ctx->Map.in_action_loop = false;
0449 RtemsBarrierReqRelease_Teardown( ctx );
0450 }
0451
0452 static void RtemsBarrierReqRelease_Action(
0453 RtemsBarrierReqRelease_Context *ctx
0454 )
0455 {
0456 ctx->status = rtems_barrier_release( ctx->id, ctx->released );
0457 }
0458
0459 static const RtemsBarrierReqRelease_Entry
0460 RtemsBarrierReqRelease_Entries[] = {
0461 { 0, 0, 0, 1, RtemsBarrierReqRelease_Post_Status_InvAddr,
0462 RtemsBarrierReqRelease_Post_ReleasedVar_Nop },
0463 { 0, 0, 0, 0, RtemsBarrierReqRelease_Post_Status_Ok,
0464 RtemsBarrierReqRelease_Post_ReleasedVar_Set },
0465 { 0, 0, 0, 1, RtemsBarrierReqRelease_Post_Status_InvId,
0466 RtemsBarrierReqRelease_Post_ReleasedVar_Nop }
0467 };
0468
0469 static const uint8_t
0470 RtemsBarrierReqRelease_Map[] = {
0471 2, 2, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0
0472 };
0473
0474 static size_t RtemsBarrierReqRelease_Scope( void *arg, char *buf, size_t n )
0475 {
0476 RtemsBarrierReqRelease_Context *ctx;
0477
0478 ctx = arg;
0479
0480 if ( ctx->Map.in_action_loop ) {
0481 return T_get_scope( RtemsBarrierReqRelease_PreDesc, buf, n, ctx->Map.pcs );
0482 }
0483
0484 return 0;
0485 }
0486
0487 static T_fixture RtemsBarrierReqRelease_Fixture = {
0488 .setup = RtemsBarrierReqRelease_Setup_Wrap,
0489 .stop = NULL,
0490 .teardown = RtemsBarrierReqRelease_Teardown_Wrap,
0491 .scope = RtemsBarrierReqRelease_Scope,
0492 .initial_context = &RtemsBarrierReqRelease_Instance
0493 };
0494
0495 static inline RtemsBarrierReqRelease_Entry RtemsBarrierReqRelease_PopEntry(
0496 RtemsBarrierReqRelease_Context *ctx
0497 )
0498 {
0499 size_t index;
0500
0501 index = ctx->Map.index;
0502 ctx->Map.index = index + 1;
0503 return RtemsBarrierReqRelease_Entries[
0504 RtemsBarrierReqRelease_Map[ index ]
0505 ];
0506 }
0507
0508 static void RtemsBarrierReqRelease_SetPreConditionStates(
0509 RtemsBarrierReqRelease_Context *ctx
0510 )
0511 {
0512 ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
0513 ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
0514
0515 if ( ctx->Map.entry.Pre_Waiting_NA ) {
0516 ctx->Map.pcs[ 2 ] = RtemsBarrierReqRelease_Pre_Waiting_NA;
0517 } else {
0518 ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
0519 }
0520 }
0521
0522 static void RtemsBarrierReqRelease_TestVariant(
0523 RtemsBarrierReqRelease_Context *ctx
0524 )
0525 {
0526 RtemsBarrierReqRelease_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0527 RtemsBarrierReqRelease_Pre_Released_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0528 RtemsBarrierReqRelease_Pre_Waiting_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0529 RtemsBarrierReqRelease_Action( ctx );
0530 RtemsBarrierReqRelease_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
0531 RtemsBarrierReqRelease_Post_ReleasedVar_Check(
0532 ctx,
0533 ctx->Map.entry.Post_ReleasedVar
0534 );
0535 }
0536
0537
0538
0539
0540 T_TEST_CASE_FIXTURE( RtemsBarrierReqRelease, &RtemsBarrierReqRelease_Fixture )
0541 {
0542 RtemsBarrierReqRelease_Context *ctx;
0543
0544 ctx = T_fixture_context();
0545 ctx->Map.in_action_loop = true;
0546 ctx->Map.index = 0;
0547
0548 for (
0549 ctx->Map.pci[ 0 ] = RtemsBarrierReqRelease_Pre_Id_NoObj;
0550 ctx->Map.pci[ 0 ] < RtemsBarrierReqRelease_Pre_Id_NA;
0551 ++ctx->Map.pci[ 0 ]
0552 ) {
0553 for (
0554 ctx->Map.pci[ 1 ] = RtemsBarrierReqRelease_Pre_Released_Valid;
0555 ctx->Map.pci[ 1 ] < RtemsBarrierReqRelease_Pre_Released_NA;
0556 ++ctx->Map.pci[ 1 ]
0557 ) {
0558 for (
0559 ctx->Map.pci[ 2 ] = RtemsBarrierReqRelease_Pre_Waiting_Zero;
0560 ctx->Map.pci[ 2 ] < RtemsBarrierReqRelease_Pre_Waiting_NA;
0561 ++ctx->Map.pci[ 2 ]
0562 ) {
0563 ctx->Map.entry = RtemsBarrierReqRelease_PopEntry( ctx );
0564 RtemsBarrierReqRelease_SetPreConditionStates( ctx );
0565 RtemsBarrierReqRelease_TestVariant( ctx );
0566 }
0567 }
0568 }
0569 }
0570
0571