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 <rtems/test-scheduler.h>
0057
0058 #include "tx-support.h"
0059
0060 #include <rtems/test.h>
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 typedef enum {
0072 RtemsTaskReqSetAffinity_Pre_Id_Invalid,
0073 RtemsTaskReqSetAffinity_Pre_Id_Task,
0074 RtemsTaskReqSetAffinity_Pre_Id_NA
0075 } RtemsTaskReqSetAffinity_Pre_Id;
0076
0077 typedef enum {
0078 RtemsTaskReqSetAffinity_Pre_CPUSetSize_Askew,
0079 RtemsTaskReqSetAffinity_Pre_CPUSetSize_Normal,
0080 RtemsTaskReqSetAffinity_Pre_CPUSetSize_Huge,
0081 RtemsTaskReqSetAffinity_Pre_CPUSetSize_NA
0082 } RtemsTaskReqSetAffinity_Pre_CPUSetSize;
0083
0084 typedef enum {
0085 RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Supported,
0086 RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Unsupported,
0087 RtemsTaskReqSetAffinity_Pre_CPUSetOnline_NA
0088 } RtemsTaskReqSetAffinity_Pre_CPUSetOnline;
0089
0090 typedef enum {
0091 RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NotZero,
0092 RtemsTaskReqSetAffinity_Pre_CPUSetHuge_Zero,
0093 RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NA
0094 } RtemsTaskReqSetAffinity_Pre_CPUSetHuge;
0095
0096 typedef enum {
0097 RtemsTaskReqSetAffinity_Pre_CPUSet_Valid,
0098 RtemsTaskReqSetAffinity_Pre_CPUSet_Null,
0099 RtemsTaskReqSetAffinity_Pre_CPUSet_NA
0100 } RtemsTaskReqSetAffinity_Pre_CPUSet;
0101
0102 typedef enum {
0103 RtemsTaskReqSetAffinity_Post_Status_Ok,
0104 RtemsTaskReqSetAffinity_Post_Status_InvAddr,
0105 RtemsTaskReqSetAffinity_Post_Status_InvId,
0106 RtemsTaskReqSetAffinity_Post_Status_InvNum,
0107 RtemsTaskReqSetAffinity_Post_Status_NA
0108 } RtemsTaskReqSetAffinity_Post_Status;
0109
0110 typedef enum {
0111 RtemsTaskReqSetAffinity_Post_SetAffinity_Set,
0112 RtemsTaskReqSetAffinity_Post_SetAffinity_Nop,
0113 RtemsTaskReqSetAffinity_Post_SetAffinity_NA
0114 } RtemsTaskReqSetAffinity_Post_SetAffinity;
0115
0116 typedef struct {
0117 uint16_t Skip : 1;
0118 uint16_t Pre_Id_NA : 1;
0119 uint16_t Pre_CPUSetSize_NA : 1;
0120 uint16_t Pre_CPUSetOnline_NA : 1;
0121 uint16_t Pre_CPUSetHuge_NA : 1;
0122 uint16_t Pre_CPUSet_NA : 1;
0123 uint16_t Post_Status : 3;
0124 uint16_t Post_SetAffinity : 2;
0125 } RtemsTaskReqSetAffinity_Entry;
0126
0127
0128
0129
0130 typedef struct {
0131
0132
0133
0134 T_scheduler_log_2 scheduler_log;
0135
0136
0137
0138
0139
0140 cpu_set_t cpuset_obj[ 2 ];
0141
0142
0143
0144
0145
0146 rtems_status_code status;
0147
0148
0149
0150
0151 rtems_id id;
0152
0153
0154
0155
0156 size_t cpusetsize;
0157
0158
0159
0160
0161 cpu_set_t *cpuset;
0162
0163 struct {
0164
0165
0166
0167
0168 size_t pci[ 5 ];
0169
0170
0171
0172
0173 size_t pcs[ 5 ];
0174
0175
0176
0177
0178 bool in_action_loop;
0179
0180
0181
0182
0183 size_t index;
0184
0185
0186
0187
0188 RtemsTaskReqSetAffinity_Entry entry;
0189
0190
0191
0192
0193
0194 bool skip;
0195 } Map;
0196 } RtemsTaskReqSetAffinity_Context;
0197
0198 static RtemsTaskReqSetAffinity_Context
0199 RtemsTaskReqSetAffinity_Instance;
0200
0201 static const char * const RtemsTaskReqSetAffinity_PreDesc_Id[] = {
0202 "Invalid",
0203 "Task",
0204 "NA"
0205 };
0206
0207 static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSetSize[] = {
0208 "Askew",
0209 "Normal",
0210 "Huge",
0211 "NA"
0212 };
0213
0214 static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSetOnline[] = {
0215 "Supported",
0216 "Unsupported",
0217 "NA"
0218 };
0219
0220 static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSetHuge[] = {
0221 "NotZero",
0222 "Zero",
0223 "NA"
0224 };
0225
0226 static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSet[] = {
0227 "Valid",
0228 "Null",
0229 "NA"
0230 };
0231
0232 static const char * const * const RtemsTaskReqSetAffinity_PreDesc[] = {
0233 RtemsTaskReqSetAffinity_PreDesc_Id,
0234 RtemsTaskReqSetAffinity_PreDesc_CPUSetSize,
0235 RtemsTaskReqSetAffinity_PreDesc_CPUSetOnline,
0236 RtemsTaskReqSetAffinity_PreDesc_CPUSetHuge,
0237 RtemsTaskReqSetAffinity_PreDesc_CPUSet,
0238 NULL
0239 };
0240
0241 static void RtemsTaskReqSetAffinity_Pre_Id_Prepare(
0242 RtemsTaskReqSetAffinity_Context *ctx,
0243 RtemsTaskReqSetAffinity_Pre_Id state
0244 )
0245 {
0246 switch ( state ) {
0247 case RtemsTaskReqSetAffinity_Pre_Id_Invalid: {
0248
0249
0250
0251 ctx->id = INVALID_ID;
0252 break;
0253 }
0254
0255 case RtemsTaskReqSetAffinity_Pre_Id_Task: {
0256
0257
0258
0259 ctx->id = RTEMS_SELF;
0260 break;
0261 }
0262
0263 case RtemsTaskReqSetAffinity_Pre_Id_NA:
0264 break;
0265 }
0266 }
0267
0268 static void RtemsTaskReqSetAffinity_Pre_CPUSetSize_Prepare(
0269 RtemsTaskReqSetAffinity_Context *ctx,
0270 RtemsTaskReqSetAffinity_Pre_CPUSetSize state
0271 )
0272 {
0273 switch ( state ) {
0274 case RtemsTaskReqSetAffinity_Pre_CPUSetSize_Askew: {
0275
0276
0277
0278
0279 ctx->cpusetsize = SIZE_MAX;
0280 break;
0281 }
0282
0283 case RtemsTaskReqSetAffinity_Pre_CPUSetSize_Normal: {
0284
0285
0286
0287
0288
0289 ctx->cpusetsize = sizeof( ctx->cpuset_obj[ 0 ] );
0290 break;
0291 }
0292
0293 case RtemsTaskReqSetAffinity_Pre_CPUSetSize_Huge: {
0294
0295
0296
0297
0298
0299 ctx->cpusetsize = sizeof( ctx->cpuset_obj );
0300 break;
0301 }
0302
0303 case RtemsTaskReqSetAffinity_Pre_CPUSetSize_NA:
0304 break;
0305 }
0306 }
0307
0308 static void RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Prepare(
0309 RtemsTaskReqSetAffinity_Context *ctx,
0310 RtemsTaskReqSetAffinity_Pre_CPUSetOnline state
0311 )
0312 {
0313 switch ( state ) {
0314 case RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Supported: {
0315
0316
0317
0318
0319
0320
0321
0322
0323 break;
0324 }
0325
0326 case RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Unsupported: {
0327
0328
0329
0330
0331
0332
0333
0334 CPU_CLR( 0, &ctx->cpuset_obj[ 0 ] );
0335 break;
0336 }
0337
0338 case RtemsTaskReqSetAffinity_Pre_CPUSetOnline_NA:
0339 break;
0340 }
0341 }
0342
0343 static void RtemsTaskReqSetAffinity_Pre_CPUSetHuge_Prepare(
0344 RtemsTaskReqSetAffinity_Context *ctx,
0345 RtemsTaskReqSetAffinity_Pre_CPUSetHuge state
0346 )
0347 {
0348 switch ( state ) {
0349 case RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NotZero: {
0350
0351
0352
0353
0354
0355
0356 break;
0357 }
0358
0359 case RtemsTaskReqSetAffinity_Pre_CPUSetHuge_Zero: {
0360
0361
0362
0363
0364
0365 CPU_ZERO( &ctx->cpuset_obj[ 1 ] );
0366 break;
0367 }
0368
0369 case RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NA:
0370 break;
0371 }
0372 }
0373
0374 static void RtemsTaskReqSetAffinity_Pre_CPUSet_Prepare(
0375 RtemsTaskReqSetAffinity_Context *ctx,
0376 RtemsTaskReqSetAffinity_Pre_CPUSet state
0377 )
0378 {
0379 switch ( state ) {
0380 case RtemsTaskReqSetAffinity_Pre_CPUSet_Valid: {
0381
0382
0383
0384 ctx->cpuset = &ctx->cpuset_obj[ 0 ];
0385 break;
0386 }
0387
0388 case RtemsTaskReqSetAffinity_Pre_CPUSet_Null: {
0389
0390
0391
0392 ctx->cpuset = NULL;
0393 break;
0394 }
0395
0396 case RtemsTaskReqSetAffinity_Pre_CPUSet_NA:
0397 break;
0398 }
0399 }
0400
0401 static void RtemsTaskReqSetAffinity_Post_Status_Check(
0402 RtemsTaskReqSetAffinity_Context *ctx,
0403 RtemsTaskReqSetAffinity_Post_Status state
0404 )
0405 {
0406 switch ( state ) {
0407 case RtemsTaskReqSetAffinity_Post_Status_Ok: {
0408
0409
0410
0411
0412 T_rsc_success( ctx->status );
0413 break;
0414 }
0415
0416 case RtemsTaskReqSetAffinity_Post_Status_InvAddr: {
0417
0418
0419
0420
0421 T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
0422 break;
0423 }
0424
0425 case RtemsTaskReqSetAffinity_Post_Status_InvId: {
0426
0427
0428
0429
0430 T_rsc( ctx->status, RTEMS_INVALID_ID );
0431 break;
0432 }
0433
0434 case RtemsTaskReqSetAffinity_Post_Status_InvNum: {
0435
0436
0437
0438
0439 T_rsc( ctx->status, RTEMS_INVALID_NUMBER );
0440 break;
0441 }
0442
0443 case RtemsTaskReqSetAffinity_Post_Status_NA:
0444 break;
0445 }
0446 }
0447
0448 static void RtemsTaskReqSetAffinity_Post_SetAffinity_Check(
0449 RtemsTaskReqSetAffinity_Context *ctx,
0450 RtemsTaskReqSetAffinity_Post_SetAffinity state
0451 )
0452 {
0453 switch ( state ) {
0454 case RtemsTaskReqSetAffinity_Post_SetAffinity_Set: {
0455
0456
0457
0458
0459
0460 #if defined(RTEMS_SMP)
0461 T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
0462 T_eq_int(
0463 ctx->scheduler_log.events[ 0 ].operation,
0464 T_SCHEDULER_SET_AFFINITY
0465 );
0466 T_eq_int(
0467 ctx->scheduler_log.events[ 0 ].set_affinity.status,
0468 STATUS_SUCCESSFUL
0469 );
0470 #else
0471 T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
0472 #endif
0473 break;
0474 }
0475
0476 case RtemsTaskReqSetAffinity_Post_SetAffinity_Nop: {
0477
0478
0479
0480
0481 #if defined(RTEMS_SMP)
0482 if ( ctx->scheduler_log.header.recorded == 1 ) {
0483 T_eq_int(
0484 ctx->scheduler_log.events[ 0 ].operation,
0485 T_SCHEDULER_SET_AFFINITY
0486 );
0487 T_eq_int(
0488 ctx->scheduler_log.events[ 0 ].set_affinity.status,
0489 STATUS_INVALID_NUMBER
0490 );
0491 } else {
0492 T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
0493 }
0494 #else
0495 T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
0496 #endif
0497 break;
0498 }
0499
0500 case RtemsTaskReqSetAffinity_Post_SetAffinity_NA:
0501 break;
0502 }
0503 }
0504
0505 static void RtemsTaskReqSetAffinity_Prepare(
0506 RtemsTaskReqSetAffinity_Context *ctx
0507 )
0508 {
0509 CPU_FILL_S( sizeof( ctx->cpuset_obj ), &ctx->cpuset_obj[ 0 ] );
0510 }
0511
0512 static void RtemsTaskReqSetAffinity_Action(
0513 RtemsTaskReqSetAffinity_Context *ctx
0514 )
0515 {
0516 T_scheduler_log *log;
0517
0518 log = T_scheduler_record_2( &ctx->scheduler_log );
0519 T_null( log );
0520
0521 ctx->status = rtems_task_set_affinity(
0522 ctx->id,
0523 ctx->cpusetsize,
0524 ctx->cpuset
0525 );
0526
0527 log = T_scheduler_record( NULL );
0528 T_eq_ptr( &log->header, &ctx->scheduler_log.header );
0529 }
0530
0531 static const RtemsTaskReqSetAffinity_Entry
0532 RtemsTaskReqSetAffinity_Entries[] = {
0533 { 0, 0, 0, 1, 1, 0, RtemsTaskReqSetAffinity_Post_Status_InvAddr,
0534 RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
0535 { 0, 0, 0, 1, 1, 0, RtemsTaskReqSetAffinity_Post_Status_InvId,
0536 RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
0537 { 0, 0, 0, 0, 1, 0, RtemsTaskReqSetAffinity_Post_Status_InvNum,
0538 RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
0539 { 0, 0, 0, 1, 0, 0, RtemsTaskReqSetAffinity_Post_Status_InvId,
0540 RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
0541 { 0, 0, 0, 0, 1, 0, RtemsTaskReqSetAffinity_Post_Status_Ok,
0542 RtemsTaskReqSetAffinity_Post_SetAffinity_Set },
0543 { 0, 0, 0, 0, 0, 0, RtemsTaskReqSetAffinity_Post_Status_Ok,
0544 RtemsTaskReqSetAffinity_Post_SetAffinity_Set },
0545 { 0, 0, 0, 0, 0, 0, RtemsTaskReqSetAffinity_Post_Status_InvNum,
0546 RtemsTaskReqSetAffinity_Post_SetAffinity_Nop }
0547 };
0548
0549 static const uint8_t
0550 RtemsTaskReqSetAffinity_Map[] = {
0551 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 0, 3, 0, 3, 0, 3, 0, 2, 0,
0552 2, 0, 2, 0, 2, 0, 4, 0, 4, 0, 2, 0, 2, 0, 5, 0, 5, 0, 6, 0, 6, 0
0553 };
0554
0555 static size_t RtemsTaskReqSetAffinity_Scope( void *arg, char *buf, size_t n )
0556 {
0557 RtemsTaskReqSetAffinity_Context *ctx;
0558
0559 ctx = arg;
0560
0561 if ( ctx->Map.in_action_loop ) {
0562 return T_get_scope(
0563 RtemsTaskReqSetAffinity_PreDesc,
0564 buf,
0565 n,
0566 ctx->Map.pcs
0567 );
0568 }
0569
0570 return 0;
0571 }
0572
0573 static T_fixture RtemsTaskReqSetAffinity_Fixture = {
0574 .setup = NULL,
0575 .stop = NULL,
0576 .teardown = NULL,
0577 .scope = RtemsTaskReqSetAffinity_Scope,
0578 .initial_context = &RtemsTaskReqSetAffinity_Instance
0579 };
0580
0581 static inline RtemsTaskReqSetAffinity_Entry RtemsTaskReqSetAffinity_PopEntry(
0582 RtemsTaskReqSetAffinity_Context *ctx
0583 )
0584 {
0585 size_t index;
0586
0587 index = ctx->Map.index;
0588 ctx->Map.index = index + 1;
0589 return RtemsTaskReqSetAffinity_Entries[
0590 RtemsTaskReqSetAffinity_Map[ index ]
0591 ];
0592 }
0593
0594 static void RtemsTaskReqSetAffinity_SetPreConditionStates(
0595 RtemsTaskReqSetAffinity_Context *ctx
0596 )
0597 {
0598 ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
0599 ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
0600
0601 if ( ctx->Map.entry.Pre_CPUSetOnline_NA ) {
0602 ctx->Map.pcs[ 2 ] = RtemsTaskReqSetAffinity_Pre_CPUSetOnline_NA;
0603 } else {
0604 ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
0605 }
0606
0607 if ( ctx->Map.entry.Pre_CPUSetHuge_NA ) {
0608 ctx->Map.pcs[ 3 ] = RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NA;
0609 } else {
0610 ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
0611 }
0612
0613 ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
0614 }
0615
0616 static void RtemsTaskReqSetAffinity_TestVariant(
0617 RtemsTaskReqSetAffinity_Context *ctx
0618 )
0619 {
0620 RtemsTaskReqSetAffinity_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0621 RtemsTaskReqSetAffinity_Pre_CPUSetSize_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0622 RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0623 RtemsTaskReqSetAffinity_Pre_CPUSetHuge_Prepare( ctx, ctx->Map.pcs[ 3 ] );
0624 RtemsTaskReqSetAffinity_Pre_CPUSet_Prepare( ctx, ctx->Map.pcs[ 4 ] );
0625 RtemsTaskReqSetAffinity_Action( ctx );
0626 RtemsTaskReqSetAffinity_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
0627 RtemsTaskReqSetAffinity_Post_SetAffinity_Check(
0628 ctx,
0629 ctx->Map.entry.Post_SetAffinity
0630 );
0631 }
0632
0633
0634
0635
0636 T_TEST_CASE_FIXTURE(
0637 RtemsTaskReqSetAffinity,
0638 &RtemsTaskReqSetAffinity_Fixture
0639 )
0640 {
0641 RtemsTaskReqSetAffinity_Context *ctx;
0642
0643 ctx = T_fixture_context();
0644 ctx->Map.in_action_loop = true;
0645 ctx->Map.index = 0;
0646
0647 for (
0648 ctx->Map.pci[ 0 ] = RtemsTaskReqSetAffinity_Pre_Id_Invalid;
0649 ctx->Map.pci[ 0 ] < RtemsTaskReqSetAffinity_Pre_Id_NA;
0650 ++ctx->Map.pci[ 0 ]
0651 ) {
0652 for (
0653 ctx->Map.pci[ 1 ] = RtemsTaskReqSetAffinity_Pre_CPUSetSize_Askew;
0654 ctx->Map.pci[ 1 ] < RtemsTaskReqSetAffinity_Pre_CPUSetSize_NA;
0655 ++ctx->Map.pci[ 1 ]
0656 ) {
0657 for (
0658 ctx->Map.pci[ 2 ] = RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Supported;
0659 ctx->Map.pci[ 2 ] < RtemsTaskReqSetAffinity_Pre_CPUSetOnline_NA;
0660 ++ctx->Map.pci[ 2 ]
0661 ) {
0662 for (
0663 ctx->Map.pci[ 3 ] = RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NotZero;
0664 ctx->Map.pci[ 3 ] < RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NA;
0665 ++ctx->Map.pci[ 3 ]
0666 ) {
0667 for (
0668 ctx->Map.pci[ 4 ] = RtemsTaskReqSetAffinity_Pre_CPUSet_Valid;
0669 ctx->Map.pci[ 4 ] < RtemsTaskReqSetAffinity_Pre_CPUSet_NA;
0670 ++ctx->Map.pci[ 4 ]
0671 ) {
0672 ctx->Map.entry = RtemsTaskReqSetAffinity_PopEntry( ctx );
0673 RtemsTaskReqSetAffinity_SetPreConditionStates( ctx );
0674 RtemsTaskReqSetAffinity_Prepare( ctx );
0675 RtemsTaskReqSetAffinity_TestVariant( ctx );
0676 }
0677 }
0678 }
0679 }
0680 }
0681 }
0682
0683