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 #include <rtems/score/apimutex.h>
0058 #include <rtems/score/statesimpl.h>
0059 #include <rtems/score/threaddispatch.h>
0060
0061 #include "tx-support.h"
0062
0063 #include <rtems/test.h>
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073 typedef enum {
0074 RtemsTaskReqExit_Pre_Restarting_Yes,
0075 RtemsTaskReqExit_Pre_Restarting_No,
0076 RtemsTaskReqExit_Pre_Restarting_NA
0077 } RtemsTaskReqExit_Pre_Restarting;
0078
0079 typedef enum {
0080 RtemsTaskReqExit_Pre_Terminating_Yes,
0081 RtemsTaskReqExit_Pre_Terminating_No,
0082 RtemsTaskReqExit_Pre_Terminating_NA
0083 } RtemsTaskReqExit_Pre_Terminating;
0084
0085 typedef enum {
0086 RtemsTaskReqExit_Pre_Protected_Yes,
0087 RtemsTaskReqExit_Pre_Protected_No,
0088 RtemsTaskReqExit_Pre_Protected_NA
0089 } RtemsTaskReqExit_Pre_Protected;
0090
0091 typedef enum {
0092 RtemsTaskReqExit_Pre_ThreadDispatch_Enabled,
0093 RtemsTaskReqExit_Pre_ThreadDispatch_Disabled,
0094 RtemsTaskReqExit_Pre_ThreadDispatch_NA
0095 } RtemsTaskReqExit_Pre_ThreadDispatch;
0096
0097 typedef enum {
0098 RtemsTaskReqExit_Post_FatalError_Yes,
0099 RtemsTaskReqExit_Post_FatalError_Nop,
0100 RtemsTaskReqExit_Post_FatalError_NA
0101 } RtemsTaskReqExit_Post_FatalError;
0102
0103 typedef enum {
0104 RtemsTaskReqExit_Post_DeleteExtensions_Nop,
0105 RtemsTaskReqExit_Post_DeleteExtensions_NA
0106 } RtemsTaskReqExit_Post_DeleteExtensions;
0107
0108 typedef enum {
0109 RtemsTaskReqExit_Post_RestartExtensions_Nop,
0110 RtemsTaskReqExit_Post_RestartExtensions_NA
0111 } RtemsTaskReqExit_Post_RestartExtensions;
0112
0113 typedef enum {
0114 RtemsTaskReqExit_Post_TerminateExtensions_Yes,
0115 RtemsTaskReqExit_Post_TerminateExtensions_Nop,
0116 RtemsTaskReqExit_Post_TerminateExtensions_NA
0117 } RtemsTaskReqExit_Post_TerminateExtensions;
0118
0119 typedef enum {
0120 RtemsTaskReqExit_Post_Zombie_Yes,
0121 RtemsTaskReqExit_Post_Zombie_No,
0122 RtemsTaskReqExit_Post_Zombie_NA
0123 } RtemsTaskReqExit_Post_Zombie;
0124
0125 typedef enum {
0126 RtemsTaskReqExit_Post_ID_Valid,
0127 RtemsTaskReqExit_Post_ID_Invalid,
0128 RtemsTaskReqExit_Post_ID_NA
0129 } RtemsTaskReqExit_Post_ID;
0130
0131 typedef enum {
0132 RtemsTaskReqExit_Post_Delete_NextAllocate,
0133 RtemsTaskReqExit_Post_Delete_Nop,
0134 RtemsTaskReqExit_Post_Delete_NA
0135 } RtemsTaskReqExit_Post_Delete;
0136
0137 typedef struct {
0138 uint32_t Skip : 1;
0139 uint32_t Pre_Restarting_NA : 1;
0140 uint32_t Pre_Terminating_NA : 1;
0141 uint32_t Pre_Protected_NA : 1;
0142 uint32_t Pre_ThreadDispatch_NA : 1;
0143 uint32_t Post_FatalError : 2;
0144 uint32_t Post_DeleteExtensions : 1;
0145 uint32_t Post_RestartExtensions : 1;
0146 uint32_t Post_TerminateExtensions : 2;
0147 uint32_t Post_Zombie : 2;
0148 uint32_t Post_ID : 2;
0149 uint32_t Post_Delete : 2;
0150 } RtemsTaskReqExit_Entry;
0151
0152
0153
0154
0155 typedef struct {
0156
0157
0158
0159 T_scheduler_log_4 scheduler_log;
0160
0161
0162
0163
0164 rtems_id runner_id;
0165
0166
0167
0168
0169 rtems_id worker_id;
0170
0171
0172
0173
0174 rtems_id deleter_id;
0175
0176
0177
0178
0179 rtems_id extension_id;
0180
0181
0182
0183
0184 uint32_t fatal_extension_calls;
0185
0186
0187
0188
0189 uint32_t delete_extension_calls;
0190
0191
0192
0193
0194 uint32_t restart_extension_calls;
0195
0196
0197
0198
0199 uint32_t terminate_extension_calls;
0200
0201
0202
0203
0204
0205 bool protected;
0206
0207
0208
0209
0210 bool allocator_locked;
0211
0212
0213
0214
0215
0216 bool restarting;
0217
0218
0219
0220
0221
0222 bool terminating;
0223
0224
0225
0226
0227
0228 bool dispatch_disabled;
0229
0230
0231
0232
0233 bool delete_worker_expected;
0234
0235 struct {
0236
0237
0238
0239 size_t pcs[ 4 ];
0240
0241
0242
0243
0244 bool in_action_loop;
0245
0246
0247
0248
0249 size_t index;
0250
0251
0252
0253
0254 RtemsTaskReqExit_Entry entry;
0255
0256
0257
0258
0259
0260 bool skip;
0261 } Map;
0262 } RtemsTaskReqExit_Context;
0263
0264 static RtemsTaskReqExit_Context
0265 RtemsTaskReqExit_Instance;
0266
0267 static const char * const RtemsTaskReqExit_PreDesc_Restarting[] = {
0268 "Yes",
0269 "No",
0270 "NA"
0271 };
0272
0273 static const char * const RtemsTaskReqExit_PreDesc_Terminating[] = {
0274 "Yes",
0275 "No",
0276 "NA"
0277 };
0278
0279 static const char * const RtemsTaskReqExit_PreDesc_Protected[] = {
0280 "Yes",
0281 "No",
0282 "NA"
0283 };
0284
0285 static const char * const RtemsTaskReqExit_PreDesc_ThreadDispatch[] = {
0286 "Enabled",
0287 "Disabled",
0288 "NA"
0289 };
0290
0291 static const char * const * const RtemsTaskReqExit_PreDesc[] = {
0292 RtemsTaskReqExit_PreDesc_Restarting,
0293 RtemsTaskReqExit_PreDesc_Terminating,
0294 RtemsTaskReqExit_PreDesc_Protected,
0295 RtemsTaskReqExit_PreDesc_ThreadDispatch,
0296 NULL
0297 };
0298
0299 typedef RtemsTaskReqExit_Context Context;
0300
0301 static void Signal( rtems_signal_set signals )
0302 {
0303 Context *ctx;
0304 T_scheduler_log *log;
0305 Thread_Life_state life_state;
0306
0307 (void) signals;
0308 ctx = T_fixture_context();
0309
0310 if ( ctx->dispatch_disabled ) {
0311 _Thread_Dispatch_disable();
0312 }
0313
0314
0315 life_state = GetExecuting()->Life.state;
0316 T_eq( ctx->protected, ( life_state & THREAD_LIFE_PROTECTED ) != 0 );
0317 T_eq( ctx->restarting, ( life_state & THREAD_LIFE_RESTARTING ) != 0 );
0318 T_eq( ctx->terminating, ( life_state & THREAD_LIFE_TERMINATING ) != 0 );
0319
0320 log = T_scheduler_record_4( &ctx->scheduler_log );
0321 T_null( log );
0322
0323 ctx->delete_extension_calls = 0;
0324 ctx->fatal_extension_calls = 0;
0325 ctx->restart_extension_calls = 0;
0326 ctx->terminate_extension_calls = 0;
0327
0328 rtems_task_exit();
0329 }
0330
0331 static void Deleter( rtems_task_argument arg )
0332 {
0333 Context *ctx;
0334
0335 ctx = (Context *) arg;
0336
0337 if ( ctx != NULL ) {
0338 DeleteTask( ctx->worker_id );
0339 }
0340
0341 SuspendSelf();
0342 }
0343
0344 static void Worker( rtems_task_argument arg )
0345 {
0346 Context *ctx;
0347 rtems_status_code sc;
0348
0349 ctx = (Context *) arg;
0350
0351 sc = rtems_signal_catch( Signal, RTEMS_NO_ASR );
0352 T_rsc_success( sc );
0353
0354 if ( ctx->protected ) {
0355 _RTEMS_Lock_allocator();
0356 ctx->allocator_locked = true;
0357 }
0358
0359 Yield();
0360 }
0361
0362 static void UnlockAllocator( Context *ctx )
0363 {
0364 if ( ctx->allocator_locked ) {
0365 ctx->allocator_locked = false;
0366 _RTEMS_Unlock_allocator();
0367 }
0368 }
0369
0370 static void Fatal(
0371 rtems_fatal_source source,
0372 rtems_fatal_code code,
0373 void *arg
0374 )
0375 {
0376 Context *ctx;
0377 T_scheduler_log *log;
0378 Per_CPU_Control *cpu_self;
0379
0380 ctx = arg;
0381 ++ctx->fatal_extension_calls;
0382
0383 T_eq_int( source, INTERNAL_ERROR_CORE );
0384 T_eq_ulong( code, INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL );
0385 T_assert_eq_int( ctx->fatal_extension_calls, 1 );
0386
0387 log = T_scheduler_record( NULL );
0388 T_eq_ptr( &log->header, &ctx->scheduler_log.header );
0389
0390 UnlockAllocator( ctx );
0391 SuspendSelf();
0392
0393 _ISR_Set_level( 0 );
0394 cpu_self = _Per_CPU_Get();
0395 _Thread_Dispatch_unnest( cpu_self );
0396 _Thread_Dispatch_direct_no_return( cpu_self );
0397 }
0398
0399 static void ThreadDelete( rtems_tcb *executing, rtems_tcb *deleted )
0400 {
0401 Context *ctx;
0402
0403 ctx = T_fixture_context();
0404 ++ctx->delete_extension_calls;
0405
0406 T_eq_u32( executing->Object.id, ctx->runner_id );
0407
0408 if ( ctx->delete_worker_expected ) {
0409 T_eq_u32( deleted->Object.id, ctx->worker_id );
0410 }
0411 }
0412
0413 static void ThreadRestart( rtems_tcb *executing, rtems_tcb *restarted )
0414 {
0415 Context *ctx;
0416
0417 ctx = T_fixture_context();
0418 ++ctx->restart_extension_calls;
0419 }
0420
0421 static void ThreadTerminate( rtems_tcb *executing )
0422 {
0423 Context *ctx;
0424
0425 ctx = T_fixture_context();
0426 ++ctx->terminate_extension_calls;
0427
0428 T_eq_u32( executing->Object.id, ctx->worker_id );
0429
0430 UnlockAllocator( ctx );
0431 }
0432
0433 static const rtems_extensions_table extensions = {
0434 .thread_delete = ThreadDelete,
0435 .thread_restart = ThreadRestart,
0436 .thread_terminate = ThreadTerminate
0437 };
0438
0439 static void RtemsTaskReqExit_Pre_Restarting_Prepare(
0440 RtemsTaskReqExit_Context *ctx,
0441 RtemsTaskReqExit_Pre_Restarting state
0442 )
0443 {
0444 switch ( state ) {
0445 case RtemsTaskReqExit_Pre_Restarting_Yes: {
0446
0447
0448
0449 ctx->restarting = true;
0450 break;
0451 }
0452
0453 case RtemsTaskReqExit_Pre_Restarting_No: {
0454
0455
0456
0457 ctx->restarting = false;
0458 break;
0459 }
0460
0461 case RtemsTaskReqExit_Pre_Restarting_NA:
0462 break;
0463 }
0464 }
0465
0466 static void RtemsTaskReqExit_Pre_Terminating_Prepare(
0467 RtemsTaskReqExit_Context *ctx,
0468 RtemsTaskReqExit_Pre_Terminating state
0469 )
0470 {
0471 switch ( state ) {
0472 case RtemsTaskReqExit_Pre_Terminating_Yes: {
0473
0474
0475
0476 ctx->terminating = true;
0477 break;
0478 }
0479
0480 case RtemsTaskReqExit_Pre_Terminating_No: {
0481
0482
0483
0484 ctx->terminating = false;
0485 break;
0486 }
0487
0488 case RtemsTaskReqExit_Pre_Terminating_NA:
0489 break;
0490 }
0491 }
0492
0493 static void RtemsTaskReqExit_Pre_Protected_Prepare(
0494 RtemsTaskReqExit_Context *ctx,
0495 RtemsTaskReqExit_Pre_Protected state
0496 )
0497 {
0498 switch ( state ) {
0499 case RtemsTaskReqExit_Pre_Protected_Yes: {
0500
0501
0502
0503 ctx->protected = true;
0504 break;
0505 }
0506
0507 case RtemsTaskReqExit_Pre_Protected_No: {
0508
0509
0510
0511 ctx->protected = false;
0512 break;
0513 }
0514
0515 case RtemsTaskReqExit_Pre_Protected_NA:
0516 break;
0517 }
0518 }
0519
0520 static void RtemsTaskReqExit_Pre_ThreadDispatch_Prepare(
0521 RtemsTaskReqExit_Context *ctx,
0522 RtemsTaskReqExit_Pre_ThreadDispatch state
0523 )
0524 {
0525 switch ( state ) {
0526 case RtemsTaskReqExit_Pre_ThreadDispatch_Enabled: {
0527
0528
0529
0530 ctx->dispatch_disabled = false;
0531 break;
0532 }
0533
0534 case RtemsTaskReqExit_Pre_ThreadDispatch_Disabled: {
0535
0536
0537
0538 ctx->dispatch_disabled = true;
0539 break;
0540 }
0541
0542 case RtemsTaskReqExit_Pre_ThreadDispatch_NA:
0543 break;
0544 }
0545 }
0546
0547 static void RtemsTaskReqExit_Post_FatalError_Check(
0548 RtemsTaskReqExit_Context *ctx,
0549 RtemsTaskReqExit_Post_FatalError state
0550 )
0551 {
0552 switch ( state ) {
0553 case RtemsTaskReqExit_Post_FatalError_Yes: {
0554
0555
0556
0557
0558
0559 T_eq_u32( ctx->fatal_extension_calls, 1 );
0560 break;
0561 }
0562
0563 case RtemsTaskReqExit_Post_FatalError_Nop: {
0564
0565
0566
0567 T_eq_u32( ctx->fatal_extension_calls, 0 );
0568 break;
0569 }
0570
0571 case RtemsTaskReqExit_Post_FatalError_NA:
0572 break;
0573 }
0574 }
0575
0576 static void RtemsTaskReqExit_Post_DeleteExtensions_Check(
0577 RtemsTaskReqExit_Context *ctx,
0578 RtemsTaskReqExit_Post_DeleteExtensions state
0579 )
0580 {
0581 switch ( state ) {
0582 case RtemsTaskReqExit_Post_DeleteExtensions_Nop: {
0583
0584
0585
0586
0587 T_eq_u32( ctx->delete_extension_calls, 0 );
0588 break;
0589 }
0590
0591 case RtemsTaskReqExit_Post_DeleteExtensions_NA:
0592 break;
0593 }
0594 }
0595
0596 static void RtemsTaskReqExit_Post_RestartExtensions_Check(
0597 RtemsTaskReqExit_Context *ctx,
0598 RtemsTaskReqExit_Post_RestartExtensions state
0599 )
0600 {
0601 switch ( state ) {
0602 case RtemsTaskReqExit_Post_RestartExtensions_Nop: {
0603
0604
0605
0606
0607 T_eq_u32( ctx->restart_extension_calls, 0 );
0608 break;
0609 }
0610
0611 case RtemsTaskReqExit_Post_RestartExtensions_NA:
0612 break;
0613 }
0614 }
0615
0616 static void RtemsTaskReqExit_Post_TerminateExtensions_Check(
0617 RtemsTaskReqExit_Context *ctx,
0618 RtemsTaskReqExit_Post_TerminateExtensions state
0619 )
0620 {
0621 switch ( state ) {
0622 case RtemsTaskReqExit_Post_TerminateExtensions_Yes: {
0623
0624
0625
0626
0627 if ( ctx->protected ) {
0628 T_eq_u32( ctx->terminate_extension_calls, 2 );
0629 } else {
0630 T_eq_u32( ctx->terminate_extension_calls, 1 );
0631 }
0632 break;
0633 }
0634
0635 case RtemsTaskReqExit_Post_TerminateExtensions_Nop: {
0636
0637
0638
0639
0640 T_eq_u32( ctx->terminate_extension_calls, 0 );
0641 break;
0642 }
0643
0644 case RtemsTaskReqExit_Post_TerminateExtensions_NA:
0645 break;
0646 }
0647 }
0648
0649 static void RtemsTaskReqExit_Post_Zombie_Check(
0650 RtemsTaskReqExit_Context *ctx,
0651 RtemsTaskReqExit_Post_Zombie state
0652 )
0653 {
0654 const T_scheduler_event *event;
0655 size_t index;
0656
0657 index = 0;
0658
0659 switch ( state ) {
0660 case RtemsTaskReqExit_Post_Zombie_Yes: {
0661
0662
0663
0664
0665 event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
0666 T_eq_int( event->operation, T_SCHEDULER_BLOCK );
0667 T_eq_u32( event->thread->Object.id, ctx->worker_id );
0668 T_eq_u32( event->thread->current_state, STATES_ZOMBIE );
0669
0670 if ( ctx->terminating ) {
0671
0672 event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
0673 T_eq_int( event->operation, T_SCHEDULER_UNBLOCK );
0674 T_eq_u32( event->thread->Object.id, ctx->deleter_id );
0675
0676
0677 event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
0678 T_eq_int( event->operation, T_SCHEDULER_UPDATE_PRIORITY );
0679 T_eq_u32( event->thread->Object.id, ctx->worker_id );
0680
0681
0682 event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
0683 T_eq_int( event->operation, T_SCHEDULER_BLOCK );
0684 T_eq_u32( event->thread->Object.id, ctx->deleter_id );
0685 }
0686
0687 event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
0688 T_eq_int( event->operation, T_SCHEDULER_NOP );
0689 break;
0690 }
0691
0692 case RtemsTaskReqExit_Post_Zombie_No: {
0693
0694
0695
0696
0697 T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
0698 break;
0699 }
0700
0701 case RtemsTaskReqExit_Post_Zombie_NA:
0702 break;
0703 }
0704 }
0705
0706 static void RtemsTaskReqExit_Post_ID_Check(
0707 RtemsTaskReqExit_Context *ctx,
0708 RtemsTaskReqExit_Post_ID state
0709 )
0710 {
0711 rtems_status_code sc;
0712 rtems_id id;
0713
0714 sc = rtems_task_get_scheduler( ctx->worker_id, &id );
0715
0716 switch ( state ) {
0717 case RtemsTaskReqExit_Post_ID_Valid: {
0718
0719
0720
0721 T_rsc_success( sc );
0722 break;
0723 }
0724
0725 case RtemsTaskReqExit_Post_ID_Invalid: {
0726
0727
0728
0729 T_rsc( sc, RTEMS_INVALID_ID );
0730 break;
0731 }
0732
0733 case RtemsTaskReqExit_Post_ID_NA:
0734 break;
0735 }
0736 }
0737
0738 static void RtemsTaskReqExit_Post_Delete_Check(
0739 RtemsTaskReqExit_Context *ctx,
0740 RtemsTaskReqExit_Post_Delete state
0741 )
0742 {
0743 rtems_id id;
0744
0745 id = CreateTask( "TEMP", PRIO_LOW );
0746
0747 switch ( state ) {
0748 case RtemsTaskReqExit_Post_Delete_NextAllocate: {
0749
0750
0751
0752
0753 T_eq_u32( ctx->delete_extension_calls, 1 );
0754 break;
0755 }
0756
0757 case RtemsTaskReqExit_Post_Delete_Nop: {
0758
0759
0760
0761
0762 T_eq_u32( ctx->delete_extension_calls, 0 );
0763 break;
0764 }
0765
0766 case RtemsTaskReqExit_Post_Delete_NA:
0767 break;
0768 }
0769
0770 DeleteTask( id );
0771 }
0772
0773 static void RtemsTaskReqExit_Setup( RtemsTaskReqExit_Context *ctx )
0774 {
0775 rtems_status_code sc;
0776
0777 ctx->runner_id = rtems_task_self();
0778
0779 sc = rtems_extension_create(
0780 rtems_build_name( 'T', 'E', 'S', 'T' ),
0781 &extensions,
0782 &ctx->extension_id
0783 );
0784 T_rsc_success( sc );
0785
0786 SetFatalHandler( Fatal, ctx );
0787 SetSelfPriority( PRIO_NORMAL );
0788
0789 ctx->deleter_id = CreateTask( "DELE", PRIO_HIGH );
0790 StartTask( ctx->deleter_id, Deleter, NULL );
0791 }
0792
0793 static void RtemsTaskReqExit_Setup_Wrap( void *arg )
0794 {
0795 RtemsTaskReqExit_Context *ctx;
0796
0797 ctx = arg;
0798 ctx->Map.in_action_loop = false;
0799 RtemsTaskReqExit_Setup( ctx );
0800 }
0801
0802 static void RtemsTaskReqExit_Teardown( RtemsTaskReqExit_Context *ctx )
0803 {
0804 rtems_status_code sc;
0805
0806 sc = rtems_extension_delete( ctx->extension_id );
0807 T_rsc_success( sc );
0808
0809 SetFatalHandler( NULL, NULL );
0810 DeleteTask( ctx->deleter_id );
0811 RestoreRunnerASR();
0812 RestoreRunnerPriority();
0813 }
0814
0815 static void RtemsTaskReqExit_Teardown_Wrap( void *arg )
0816 {
0817 RtemsTaskReqExit_Context *ctx;
0818
0819 ctx = arg;
0820 ctx->Map.in_action_loop = false;
0821 RtemsTaskReqExit_Teardown( ctx );
0822 }
0823
0824 static void RtemsTaskReqExit_Action( RtemsTaskReqExit_Context *ctx )
0825 {
0826 rtems_status_code sc;
0827
0828 ctx->delete_worker_expected = false;
0829 ctx->worker_id = CreateTask( "WORK", PRIO_NORMAL );
0830 ctx->delete_worker_expected = true;
0831
0832 StartTask( ctx->worker_id, Worker, ctx );
0833
0834
0835 Yield();
0836
0837 sc = rtems_signal_send( ctx->worker_id, RTEMS_SIGNAL_0 );
0838 T_rsc_success( sc );
0839
0840 if ( ctx->restarting ) {
0841 sc = rtems_task_restart( ctx->worker_id, (rtems_task_argument) ctx );
0842 T_rsc_success( sc );
0843 }
0844
0845 if ( ctx->terminating ) {
0846 sc = rtems_task_restart( ctx->deleter_id, (rtems_task_argument) ctx );
0847 T_rsc_success( sc );
0848 } else {
0849 Yield();
0850 }
0851
0852 if ( !ctx->dispatch_disabled ) {
0853 T_scheduler_log *log;
0854
0855 log = T_scheduler_record( NULL );
0856 T_eq_ptr( &log->header, &ctx->scheduler_log.header );
0857 }
0858 }
0859
0860 static void RtemsTaskReqExit_Cleanup( RtemsTaskReqExit_Context *ctx )
0861 {
0862 if ( ctx->dispatch_disabled ) {
0863 DeleteTask( ctx->worker_id );
0864 }
0865 }
0866
0867 static const RtemsTaskReqExit_Entry
0868 RtemsTaskReqExit_Entries[] = {
0869 { 0, 0, 0, 0, 0, RtemsTaskReqExit_Post_FatalError_Nop,
0870 RtemsTaskReqExit_Post_DeleteExtensions_Nop,
0871 RtemsTaskReqExit_Post_RestartExtensions_Nop,
0872 RtemsTaskReqExit_Post_TerminateExtensions_Yes,
0873 RtemsTaskReqExit_Post_Zombie_Yes, RtemsTaskReqExit_Post_ID_Invalid,
0874 RtemsTaskReqExit_Post_Delete_NextAllocate },
0875 { 0, 0, 0, 0, 0, RtemsTaskReqExit_Post_FatalError_Yes,
0876 RtemsTaskReqExit_Post_DeleteExtensions_Nop,
0877 RtemsTaskReqExit_Post_RestartExtensions_Nop,
0878 RtemsTaskReqExit_Post_TerminateExtensions_Nop,
0879 RtemsTaskReqExit_Post_Zombie_No, RtemsTaskReqExit_Post_ID_Valid,
0880 RtemsTaskReqExit_Post_Delete_Nop }
0881 };
0882
0883 static const uint8_t
0884 RtemsTaskReqExit_Map[] = {
0885 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1
0886 };
0887
0888 static size_t RtemsTaskReqExit_Scope( void *arg, char *buf, size_t n )
0889 {
0890 RtemsTaskReqExit_Context *ctx;
0891
0892 ctx = arg;
0893
0894 if ( ctx->Map.in_action_loop ) {
0895 return T_get_scope( RtemsTaskReqExit_PreDesc, buf, n, ctx->Map.pcs );
0896 }
0897
0898 return 0;
0899 }
0900
0901 static T_fixture RtemsTaskReqExit_Fixture = {
0902 .setup = RtemsTaskReqExit_Setup_Wrap,
0903 .stop = NULL,
0904 .teardown = RtemsTaskReqExit_Teardown_Wrap,
0905 .scope = RtemsTaskReqExit_Scope,
0906 .initial_context = &RtemsTaskReqExit_Instance
0907 };
0908
0909 static inline RtemsTaskReqExit_Entry RtemsTaskReqExit_PopEntry(
0910 RtemsTaskReqExit_Context *ctx
0911 )
0912 {
0913 size_t index;
0914
0915 index = ctx->Map.index;
0916 ctx->Map.index = index + 1;
0917 return RtemsTaskReqExit_Entries[
0918 RtemsTaskReqExit_Map[ index ]
0919 ];
0920 }
0921
0922 static void RtemsTaskReqExit_TestVariant( RtemsTaskReqExit_Context *ctx )
0923 {
0924 RtemsTaskReqExit_Pre_Restarting_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0925 RtemsTaskReqExit_Pre_Terminating_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0926 RtemsTaskReqExit_Pre_Protected_Prepare( ctx, ctx->Map.pcs[ 2 ] );
0927 RtemsTaskReqExit_Pre_ThreadDispatch_Prepare( ctx, ctx->Map.pcs[ 3 ] );
0928 RtemsTaskReqExit_Action( ctx );
0929 RtemsTaskReqExit_Post_FatalError_Check(
0930 ctx,
0931 ctx->Map.entry.Post_FatalError
0932 );
0933 RtemsTaskReqExit_Post_DeleteExtensions_Check(
0934 ctx,
0935 ctx->Map.entry.Post_DeleteExtensions
0936 );
0937 RtemsTaskReqExit_Post_RestartExtensions_Check(
0938 ctx,
0939 ctx->Map.entry.Post_RestartExtensions
0940 );
0941 RtemsTaskReqExit_Post_TerminateExtensions_Check(
0942 ctx,
0943 ctx->Map.entry.Post_TerminateExtensions
0944 );
0945 RtemsTaskReqExit_Post_Zombie_Check( ctx, ctx->Map.entry.Post_Zombie );
0946 RtemsTaskReqExit_Post_ID_Check( ctx, ctx->Map.entry.Post_ID );
0947 RtemsTaskReqExit_Post_Delete_Check( ctx, ctx->Map.entry.Post_Delete );
0948 }
0949
0950
0951
0952
0953 T_TEST_CASE_FIXTURE( RtemsTaskReqExit, &RtemsTaskReqExit_Fixture )
0954 {
0955 RtemsTaskReqExit_Context *ctx;
0956
0957 ctx = T_fixture_context();
0958 ctx->Map.in_action_loop = true;
0959 ctx->Map.index = 0;
0960
0961 for (
0962 ctx->Map.pcs[ 0 ] = RtemsTaskReqExit_Pre_Restarting_Yes;
0963 ctx->Map.pcs[ 0 ] < RtemsTaskReqExit_Pre_Restarting_NA;
0964 ++ctx->Map.pcs[ 0 ]
0965 ) {
0966 for (
0967 ctx->Map.pcs[ 1 ] = RtemsTaskReqExit_Pre_Terminating_Yes;
0968 ctx->Map.pcs[ 1 ] < RtemsTaskReqExit_Pre_Terminating_NA;
0969 ++ctx->Map.pcs[ 1 ]
0970 ) {
0971 for (
0972 ctx->Map.pcs[ 2 ] = RtemsTaskReqExit_Pre_Protected_Yes;
0973 ctx->Map.pcs[ 2 ] < RtemsTaskReqExit_Pre_Protected_NA;
0974 ++ctx->Map.pcs[ 2 ]
0975 ) {
0976 for (
0977 ctx->Map.pcs[ 3 ] = RtemsTaskReqExit_Pre_ThreadDispatch_Enabled;
0978 ctx->Map.pcs[ 3 ] < RtemsTaskReqExit_Pre_ThreadDispatch_NA;
0979 ++ctx->Map.pcs[ 3 ]
0980 ) {
0981 ctx->Map.entry = RtemsTaskReqExit_PopEntry( ctx );
0982 RtemsTaskReqExit_TestVariant( ctx );
0983 RtemsTaskReqExit_Cleanup( ctx );
0984 }
0985 }
0986 }
0987 }
0988 }
0989
0990