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 <rtems/score/threadimpl.h>
0056
0057 #include "tr-event-send-receive.h"
0058 #include "tx-support.h"
0059
0060 #include <rtems/test.h>
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 typedef struct {
0071 uint16_t Skip : 1;
0072 uint16_t Pre_Id_NA : 1;
0073 uint16_t Pre_Send_NA : 1;
0074 uint16_t Pre_ReceiverState_NA : 1;
0075 uint16_t Pre_Satisfy_NA : 1;
0076 uint16_t Post_SendStatus : 2;
0077 uint16_t Post_ReceiveStatus : 3;
0078 uint16_t Post_SenderPreemption : 2;
0079 } RtemsEventReqSendReceive_Entry;
0080
0081 #define PRIO_OTHER UINT32_MAX
0082
0083 typedef enum {
0084 SENDER_NONE,
0085 SENDER_SELF,
0086 SENDER_SELF_2,
0087 SENDER_WORKER,
0088 SENDER_INTERRUPT
0089 } SenderTypes;
0090
0091 typedef enum {
0092 RECEIVE_SKIP,
0093 RECEIVE_NORMAL,
0094 RECEIVE_INTERRUPT
0095 } ReceiveTypes;
0096
0097 typedef enum {
0098 RECEIVE_COND_UNKNOWN,
0099 RECEIVE_COND_SATSIFIED,
0100 RECEIVE_COND_UNSATISFIED
0101 } ReceiveConditionStates;
0102
0103
0104
0105
0106 typedef struct {
0107
0108
0109
0110
0111 SenderTypes sender_type;
0112
0113
0114
0115
0116 rtems_task_priority sender_prio;
0117
0118
0119
0120
0121 rtems_id receiver_id;
0122
0123
0124
0125
0126 rtems_event_set events_to_send;
0127
0128
0129
0130
0131 rtems_status_code send_status;
0132
0133
0134
0135
0136 ReceiveTypes receive_type;
0137
0138
0139
0140
0141
0142 rtems_option receive_option_set;
0143
0144
0145
0146
0147 rtems_interval receive_timeout;
0148
0149
0150
0151
0152
0153 rtems_event_set received_events;
0154
0155
0156
0157
0158
0159 rtems_event_set *received_events_parameter;
0160
0161
0162
0163
0164 rtems_status_code receive_status;
0165
0166
0167
0168
0169
0170 ReceiveConditionStates receive_condition_state;
0171
0172
0173
0174
0175
0176 rtems_event_set unsatisfied_pending;
0177
0178
0179
0180
0181 Thread_Control *runner_thread;
0182
0183
0184
0185
0186 rtems_id runner_id;
0187
0188
0189
0190
0191 rtems_id worker_id;
0192
0193
0194
0195
0196
0197 rtems_id worker_wakeup;
0198
0199
0200
0201
0202
0203 rtems_id runner_wakeup;
0204
0205
0206
0207
0208
0209 rtems_id runner_sched;
0210
0211
0212
0213
0214
0215 rtems_id other_sched;
0216
0217
0218
0219
0220 T_thread_switch_log_4 thread_switch_log;
0221
0222
0223
0224
0225
0226 rtems_status_code ( *send )( rtems_id, rtems_event_set );
0227
0228
0229
0230
0231
0232 rtems_status_code ( *receive )( rtems_event_set, rtems_option, rtems_interval, rtems_event_set * );
0233
0234
0235
0236
0237
0238 rtems_event_set ( *get_pending_events )( Thread_Control * );
0239
0240
0241
0242
0243
0244 unsigned int wait_class;
0245
0246
0247
0248
0249
0250 int waiting_for_event;
0251
0252 struct {
0253
0254
0255
0256
0257 size_t pci[ 4 ];
0258
0259
0260
0261
0262 size_t pcs[ 4 ];
0263
0264
0265
0266
0267 bool in_action_loop;
0268
0269
0270
0271
0272 size_t index;
0273
0274
0275
0276
0277 RtemsEventReqSendReceive_Entry entry;
0278
0279
0280
0281
0282
0283 bool skip;
0284 } Map;
0285 } RtemsEventReqSendReceive_Context;
0286
0287 static RtemsEventReqSendReceive_Context
0288 RtemsEventReqSendReceive_Instance;
0289
0290 static const char * const RtemsEventReqSendReceive_PreDesc_Id[] = {
0291 "InvId",
0292 "Task",
0293 "NA"
0294 };
0295
0296 static const char * const RtemsEventReqSendReceive_PreDesc_Send[] = {
0297 "Zero",
0298 "Unrelated",
0299 "Any",
0300 "All",
0301 "MixedAny",
0302 "MixedAll",
0303 "NA"
0304 };
0305
0306 static const char * const RtemsEventReqSendReceive_PreDesc_ReceiverState[] = {
0307 "InvAddr",
0308 "NotWaiting",
0309 "Poll",
0310 "Timeout",
0311 "Lower",
0312 "Equal",
0313 "Higher",
0314 "Other",
0315 "Intend",
0316 "NA"
0317 };
0318
0319 static const char * const RtemsEventReqSendReceive_PreDesc_Satisfy[] = {
0320 "All",
0321 "Any",
0322 "NA"
0323 };
0324
0325 static const char * const * const RtemsEventReqSendReceive_PreDesc[] = {
0326 RtemsEventReqSendReceive_PreDesc_Id,
0327 RtemsEventReqSendReceive_PreDesc_Send,
0328 RtemsEventReqSendReceive_PreDesc_ReceiverState,
0329 RtemsEventReqSendReceive_PreDesc_Satisfy,
0330 NULL
0331 };
0332
0333 #define INPUT_EVENTS ( RTEMS_EVENT_5 | RTEMS_EVENT_23 )
0334
0335 typedef RtemsEventReqSendReceive_Context Context;
0336
0337 static rtems_id CreateWakeupSema( void )
0338 {
0339 rtems_status_code sc;
0340 rtems_id id;
0341
0342 sc = rtems_semaphore_create(
0343 rtems_build_name( 'W', 'K', 'U', 'P' ),
0344 0,
0345 RTEMS_SIMPLE_BINARY_SEMAPHORE,
0346 0,
0347 &id
0348 );
0349 T_assert_rsc_success( sc );
0350
0351 return id;
0352 }
0353
0354 static void DeleteWakeupSema( rtems_id id )
0355 {
0356 if ( id != 0 ) {
0357 rtems_status_code sc;
0358
0359 sc = rtems_semaphore_delete( id );
0360 T_rsc_success( sc );
0361 }
0362 }
0363
0364 static void Wait( rtems_id id )
0365 {
0366 rtems_status_code sc;
0367
0368 sc = rtems_semaphore_obtain( id, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
0369 T_quiet_rsc_success( sc );
0370 }
0371
0372 static void Wakeup( rtems_id id )
0373 {
0374 rtems_status_code sc;
0375
0376 sc = rtems_semaphore_release( id );
0377 T_quiet_rsc_success( sc );
0378 }
0379
0380 static bool BlockedForEvent( Context *ctx, Thread_Wait_flags flags )
0381 {
0382 return flags == ( ctx->wait_class | THREAD_WAIT_STATE_BLOCKED );
0383 }
0384
0385 static bool IntendsToBlockForEvent( Context *ctx, Thread_Wait_flags flags )
0386 {
0387 return flags == ( ctx->wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK );
0388 }
0389
0390 static bool IsReady( Context *ctx, Thread_Wait_flags flags )
0391 {
0392 return flags == THREAD_WAIT_STATE_READY;
0393 }
0394
0395 static bool IsSatisfiedFlags( Context *ctx )
0396 {
0397 return IsReady(
0398 ctx,
0399 _Thread_Wait_flags_get( ctx->runner_thread )
0400 );
0401 }
0402
0403 static bool IsSatisfiedState( Context *ctx )
0404 {
0405 return ctx->runner_thread->current_state != ctx->waiting_for_event;
0406 }
0407
0408 static void SendAction( Context *ctx )
0409 {
0410 T_thread_switch_log *log;
0411
0412 log = T_thread_switch_record_4( &ctx->thread_switch_log );
0413 T_quiet_null( log );
0414 ctx->send_status = ( *ctx->send )( ctx->receiver_id, ctx->events_to_send );
0415 log = T_thread_switch_record( NULL );
0416 T_quiet_eq_ptr( &log->header, &ctx->thread_switch_log.header );
0417 }
0418
0419 static void Send(
0420 Context *ctx,
0421 bool ( *is_satsified )( Context * )
0422 )
0423 {
0424 SendAction( ctx );
0425
0426 if ( ( *is_satsified )( ctx ) ) {
0427 ctx->receive_condition_state = RECEIVE_COND_SATSIFIED;
0428 } else {
0429 rtems_status_code sc;
0430 rtems_event_set pending;
0431 rtems_event_set missing;
0432
0433 ctx->receive_condition_state = RECEIVE_COND_UNSATISFIED;
0434 pending = ( *ctx->get_pending_events )( ctx->runner_thread );
0435 ctx->unsatisfied_pending = pending;
0436
0437 missing = INPUT_EVENTS & ~ctx->events_to_send;
0438 T_ne_u32( missing, 0 );
0439 sc = ( *ctx->send )( ctx->runner_id, missing );
0440 T_rsc_success( sc );
0441
0442 pending = ( *ctx->get_pending_events )( ctx->runner_thread );
0443 T_eq_u32( pending, ctx->events_to_send & ~INPUT_EVENTS );
0444 }
0445 }
0446
0447 static void Worker( rtems_task_argument arg )
0448 {
0449 Context *ctx;
0450
0451 ctx = (Context *) arg;
0452
0453 while ( true ) {
0454 rtems_status_code sc;
0455 rtems_task_priority prio;
0456 T_thread_switch_log *log;
0457
0458 Wait( ctx->worker_wakeup );
0459
0460 switch ( ctx->sender_prio ) {
0461 case PRIO_NORMAL:
0462 case PRIO_HIGH:
0463 prio = SetSelfPriority( ctx->sender_prio );
0464 T_eq_u32( prio, PRIO_LOW );
0465 break;
0466 case PRIO_OTHER:
0467 log = T_thread_switch_record_4( &ctx->thread_switch_log );
0468 T_null( log );
0469 sc = rtems_task_set_scheduler(
0470 RTEMS_SELF,
0471 ctx->other_sched,
0472 PRIO_LOW
0473 );
0474 T_rsc_success( sc );
0475
0476
0477
0478
0479
0480
0481 while (ctx->thread_switch_log.header.recorded < 2) {
0482 RTEMS_COMPILER_MEMORY_BARRIER();
0483 }
0484
0485 log = T_thread_switch_record( NULL );
0486 T_eq_ptr( &log->header, &ctx->thread_switch_log.header );
0487 break;
0488 case PRIO_LOW:
0489 break;
0490 }
0491
0492 Send( ctx, IsSatisfiedState );
0493
0494 sc = rtems_task_set_scheduler(
0495 RTEMS_SELF,
0496 ctx->runner_sched,
0497 PRIO_HIGH
0498 );
0499 T_rsc_success( sc );
0500
0501 Wakeup( ctx->runner_wakeup );
0502 }
0503 }
0504
0505 static rtems_event_set GetPendingEvents( Context *ctx )
0506 {
0507 rtems_event_set pending;
0508 rtems_status_code sc;
0509
0510 sc = ( *ctx->receive )(
0511 RTEMS_PENDING_EVENTS,
0512 RTEMS_DEFAULT_OPTIONS,
0513 0,
0514 &pending
0515 );
0516 T_quiet_rsc_success( sc );
0517
0518 return pending;
0519 }
0520
0521 static void RtemsEventReqSendReceive_Cleanup( Context *ctx );
0522
0523 static void InterruptPrepare( void *arg )
0524 {
0525 RtemsEventReqSendReceive_Cleanup( arg );
0526 }
0527
0528 static void InterruptAction( void *arg )
0529 {
0530 Context *ctx;
0531
0532 ctx = arg;
0533 ctx->receive_status = ( *ctx->receive )(
0534 INPUT_EVENTS,
0535 ctx->receive_option_set,
0536 ctx->receive_timeout,
0537 &ctx->received_events
0538 );
0539 T_quiet_rsc_success( ctx->receive_status );
0540 }
0541
0542 static void InterruptContinue( Context *ctx )
0543 {
0544 rtems_status_code sc;
0545
0546 sc = ( *ctx->send )( ctx->receiver_id, INPUT_EVENTS );
0547 T_quiet_rsc_success( sc );
0548 }
0549
0550 static T_interrupt_test_state Interrupt( void *arg )
0551 {
0552 Context *ctx;
0553 Thread_Wait_flags flags;
0554 T_interrupt_test_state next_state;
0555 T_interrupt_test_state previous_state;
0556
0557 ctx = arg;
0558 flags = _Thread_Wait_flags_get( ctx->runner_thread );
0559
0560 if ( IntendsToBlockForEvent( ctx, flags ) ) {
0561 next_state = T_INTERRUPT_TEST_DONE;
0562 } else if ( BlockedForEvent( ctx, flags ) ) {
0563 next_state = T_INTERRUPT_TEST_LATE;
0564 } else {
0565 next_state = T_INTERRUPT_TEST_EARLY;
0566 }
0567
0568 previous_state = T_interrupt_test_change_state(
0569 T_INTERRUPT_TEST_ACTION,
0570 next_state
0571 );
0572
0573 if ( previous_state == T_INTERRUPT_TEST_ACTION ) {
0574 if ( next_state == T_INTERRUPT_TEST_DONE ) {
0575 Send( ctx, IsSatisfiedFlags );
0576 } else {
0577 InterruptContinue( ctx );
0578 }
0579 }
0580
0581 return next_state;
0582 }
0583
0584 static const T_interrupt_test_config InterruptConfig = {
0585 .prepare = InterruptPrepare,
0586 .action = InterruptAction,
0587 .interrupt = Interrupt,
0588 .max_iteration_count = 10000
0589 };
0590
0591 static void RtemsEventReqSendReceive_Pre_Id_Prepare(
0592 RtemsEventReqSendReceive_Context *ctx,
0593 RtemsEventReqSendReceive_Pre_Id state
0594 )
0595 {
0596 switch ( state ) {
0597 case RtemsEventReqSendReceive_Pre_Id_InvId: {
0598
0599
0600
0601
0602 ctx->receiver_id = 0xffffffff;
0603 ctx->sender_type = SENDER_SELF;
0604 break;
0605 }
0606
0607 case RtemsEventReqSendReceive_Pre_Id_Task: {
0608
0609
0610
0611
0612 ctx->receiver_id = ctx->runner_id;
0613 break;
0614 }
0615
0616 case RtemsEventReqSendReceive_Pre_Id_NA:
0617 break;
0618 }
0619 }
0620
0621 static void RtemsEventReqSendReceive_Pre_Send_Prepare(
0622 RtemsEventReqSendReceive_Context *ctx,
0623 RtemsEventReqSendReceive_Pre_Send state
0624 )
0625 {
0626 switch ( state ) {
0627 case RtemsEventReqSendReceive_Pre_Send_Zero: {
0628
0629
0630
0631 ctx->events_to_send = 0;
0632 break;
0633 }
0634
0635 case RtemsEventReqSendReceive_Pre_Send_Unrelated: {
0636
0637
0638
0639 ctx->events_to_send = RTEMS_EVENT_7;
0640 break;
0641 }
0642
0643 case RtemsEventReqSendReceive_Pre_Send_Any: {
0644
0645
0646
0647
0648 ctx->events_to_send = RTEMS_EVENT_5;
0649 break;
0650 }
0651
0652 case RtemsEventReqSendReceive_Pre_Send_All: {
0653
0654
0655
0656
0657 ctx->events_to_send = RTEMS_EVENT_5 | RTEMS_EVENT_23;
0658 break;
0659 }
0660
0661 case RtemsEventReqSendReceive_Pre_Send_MixedAny: {
0662
0663
0664
0665
0666 ctx->events_to_send = RTEMS_EVENT_5 | RTEMS_EVENT_7;
0667 break;
0668 }
0669
0670 case RtemsEventReqSendReceive_Pre_Send_MixedAll: {
0671
0672
0673
0674
0675 ctx->events_to_send = RTEMS_EVENT_5 | RTEMS_EVENT_7 | RTEMS_EVENT_23;
0676 break;
0677 }
0678
0679 case RtemsEventReqSendReceive_Pre_Send_NA:
0680 break;
0681 }
0682 }
0683
0684 static void RtemsEventReqSendReceive_Pre_ReceiverState_Prepare(
0685 RtemsEventReqSendReceive_Context *ctx,
0686 RtemsEventReqSendReceive_Pre_ReceiverState state
0687 )
0688 {
0689 switch ( state ) {
0690 case RtemsEventReqSendReceive_Pre_ReceiverState_InvAddr: {
0691
0692
0693
0694
0695 ctx->sender_type = SENDER_SELF;
0696 ctx->receive_type = RECEIVE_NORMAL;
0697 ctx->received_events_parameter = NULL;
0698 break;
0699 }
0700
0701 case RtemsEventReqSendReceive_Pre_ReceiverState_NotWaiting: {
0702
0703
0704
0705 ctx->sender_type = SENDER_SELF;
0706 ctx->receive_type = RECEIVE_SKIP;
0707 break;
0708 }
0709
0710 case RtemsEventReqSendReceive_Pre_ReceiverState_Poll: {
0711
0712
0713
0714 ctx->sender_type = SENDER_SELF;
0715 ctx->receive_type = RECEIVE_NORMAL;
0716 ctx->receive_option_set |= RTEMS_NO_WAIT;
0717 break;
0718 }
0719
0720 case RtemsEventReqSendReceive_Pre_ReceiverState_Timeout: {
0721
0722
0723
0724
0725 ctx->sender_type = SENDER_SELF_2;
0726 ctx->receive_type = RECEIVE_NORMAL;
0727 ctx->receive_timeout = 1;
0728 break;
0729 }
0730
0731 case RtemsEventReqSendReceive_Pre_ReceiverState_Lower: {
0732
0733
0734
0735
0736 ctx->sender_type = SENDER_WORKER;
0737 ctx->sender_prio = PRIO_HIGH;
0738 ctx->receive_type = RECEIVE_NORMAL;
0739 break;
0740 }
0741
0742 case RtemsEventReqSendReceive_Pre_ReceiverState_Equal: {
0743
0744
0745
0746
0747 ctx->sender_type = SENDER_WORKER;
0748 ctx->sender_prio = PRIO_NORMAL;
0749 ctx->receive_type = RECEIVE_NORMAL;
0750 break;
0751 }
0752
0753 case RtemsEventReqSendReceive_Pre_ReceiverState_Higher: {
0754
0755
0756
0757
0758 ctx->sender_type = SENDER_WORKER;
0759 ctx->sender_prio = PRIO_LOW;
0760 ctx->receive_type = RECEIVE_NORMAL;
0761 break;
0762 }
0763
0764 case RtemsEventReqSendReceive_Pre_ReceiverState_Other: {
0765
0766
0767
0768
0769 ctx->sender_type = SENDER_WORKER;
0770 ctx->sender_prio = PRIO_OTHER;
0771 ctx->receive_type = RECEIVE_NORMAL;
0772 break;
0773 }
0774
0775 case RtemsEventReqSendReceive_Pre_ReceiverState_Intend: {
0776
0777
0778
0779 ctx->sender_type = SENDER_INTERRUPT;
0780 ctx->receive_type = RECEIVE_INTERRUPT;
0781 break;
0782 }
0783
0784 case RtemsEventReqSendReceive_Pre_ReceiverState_NA:
0785 break;
0786 }
0787 }
0788
0789 static void RtemsEventReqSendReceive_Pre_Satisfy_Prepare(
0790 RtemsEventReqSendReceive_Context *ctx,
0791 RtemsEventReqSendReceive_Pre_Satisfy state
0792 )
0793 {
0794 switch ( state ) {
0795 case RtemsEventReqSendReceive_Pre_Satisfy_All: {
0796
0797
0798
0799 ctx->receive_option_set |= RTEMS_EVENT_ALL;
0800 break;
0801 }
0802
0803 case RtemsEventReqSendReceive_Pre_Satisfy_Any: {
0804
0805
0806
0807 ctx->receive_option_set |= RTEMS_EVENT_ANY;
0808 break;
0809 }
0810
0811 case RtemsEventReqSendReceive_Pre_Satisfy_NA:
0812 break;
0813 }
0814 }
0815
0816 static void RtemsEventReqSendReceive_Post_SendStatus_Check(
0817 RtemsEventReqSendReceive_Context *ctx,
0818 RtemsEventReqSendReceive_Post_SendStatus state
0819 )
0820 {
0821 switch ( state ) {
0822 case RtemsEventReqSendReceive_Post_SendStatus_Ok: {
0823
0824
0825
0826 T_rsc_success( ctx->send_status );
0827 break;
0828 }
0829
0830 case RtemsEventReqSendReceive_Post_SendStatus_InvId: {
0831
0832
0833
0834 T_rsc( ctx->send_status, RTEMS_INVALID_ID );
0835 break;
0836 }
0837
0838 case RtemsEventReqSendReceive_Post_SendStatus_NA:
0839 break;
0840 }
0841 }
0842
0843 static void RtemsEventReqSendReceive_Post_ReceiveStatus_Check(
0844 RtemsEventReqSendReceive_Context *ctx,
0845 RtemsEventReqSendReceive_Post_ReceiveStatus state
0846 )
0847 {
0848 switch ( state ) {
0849 case RtemsEventReqSendReceive_Post_ReceiveStatus_None: {
0850
0851
0852
0853 T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN );
0854 T_eq_u32( GetPendingEvents( ctx ), 0 );
0855 break;
0856 }
0857
0858 case RtemsEventReqSendReceive_Post_ReceiveStatus_Pending: {
0859
0860
0861
0862 T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN );
0863 T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send );
0864 break;
0865 }
0866
0867 case RtemsEventReqSendReceive_Post_ReceiveStatus_Timeout: {
0868
0869
0870
0871
0872 T_rsc( ctx->receive_status, RTEMS_TIMEOUT );
0873 T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN );
0874 T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send );
0875 break;
0876 }
0877
0878 case RtemsEventReqSendReceive_Post_ReceiveStatus_Satisfied: {
0879
0880
0881
0882
0883
0884
0885 T_rsc( ctx->receive_status, RTEMS_SUCCESSFUL );
0886
0887 if ( ctx->receive_type != RECEIVE_NORMAL ) {
0888 T_eq_int( ctx->receive_condition_state, RECEIVE_COND_SATSIFIED );
0889 }
0890
0891 T_eq_u32( ctx->received_events, ctx->events_to_send & INPUT_EVENTS );
0892 T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send & ~INPUT_EVENTS );
0893 break;
0894 }
0895
0896 case RtemsEventReqSendReceive_Post_ReceiveStatus_Unsatisfied: {
0897
0898
0899
0900
0901 T_rsc( ctx->receive_status, RTEMS_UNSATISFIED );
0902 T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN );
0903 T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send );
0904 break;
0905 }
0906
0907 case RtemsEventReqSendReceive_Post_ReceiveStatus_Blocked: {
0908
0909
0910
0911
0912 T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNSATISFIED );
0913 T_eq_u32( ctx->unsatisfied_pending, ctx->events_to_send );
0914 break;
0915 }
0916
0917 case RtemsEventReqSendReceive_Post_ReceiveStatus_InvAddr: {
0918
0919
0920
0921
0922 T_rsc( ctx->receive_status, RTEMS_INVALID_ADDRESS );
0923 T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN );
0924 T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send );
0925 break;
0926 }
0927
0928 case RtemsEventReqSendReceive_Post_ReceiveStatus_NA:
0929 break;
0930 }
0931 }
0932
0933 static void RtemsEventReqSendReceive_Post_SenderPreemption_Check(
0934 RtemsEventReqSendReceive_Context *ctx,
0935 RtemsEventReqSendReceive_Post_SenderPreemption state
0936 )
0937 {
0938 const T_thread_switch_log_4 *log;
0939 size_t i;
0940
0941 log = &ctx->thread_switch_log;
0942
0943 switch ( state ) {
0944 case RtemsEventReqSendReceive_Post_SenderPreemption_No: {
0945
0946
0947
0948
0949
0950
0951
0952
0953
0954 T_le_sz( log->header.recorded, 1 );
0955
0956 for ( i = 0; i < log->header.recorded; ++i ) {
0957 T_ne_u32( log->events[ i ].executing, ctx->worker_id );
0958 T_eq_u32( log->events[ i ].heir, ctx->runner_id );
0959 }
0960 break;
0961 }
0962
0963 case RtemsEventReqSendReceive_Post_SenderPreemption_Yes: {
0964
0965
0966
0967
0968 T_eq_sz( log->header.recorded, 2 );
0969 T_eq_u32( log->events[ 0 ].heir, ctx->runner_id );
0970 T_eq_u32( log->events[ 1 ].heir, ctx->worker_id );
0971 break;
0972 }
0973
0974 case RtemsEventReqSendReceive_Post_SenderPreemption_NA:
0975 break;
0976 }
0977 }
0978
0979 static void RtemsEventReqSendReceive_Setup(
0980 RtemsEventReqSendReceive_Context *ctx
0981 )
0982 {
0983 rtems_status_code sc;
0984
0985 ctx->runner_thread = _Thread_Get_executing();
0986 ctx->runner_id = ctx->runner_thread->Object.id;
0987 ctx->worker_wakeup = CreateWakeupSema();
0988 ctx->runner_wakeup = CreateWakeupSema();
0989
0990 sc = rtems_task_get_scheduler( RTEMS_SELF, &ctx->runner_sched );
0991 T_rsc_success( sc );
0992
0993 #if defined(RTEMS_SMP)
0994 sc = rtems_scheduler_ident_by_processor( 1, &ctx->other_sched );
0995 T_rsc_success( sc );
0996 T_ne_u32( ctx->runner_sched, ctx->other_sched );
0997 #endif
0998
0999 SetSelfPriority( PRIO_NORMAL );
1000 ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
1001 StartTask( ctx->worker_id, Worker, ctx );
1002 }
1003
1004 static void RtemsEventReqSendReceive_Setup_Wrap( void *arg )
1005 {
1006 RtemsEventReqSendReceive_Context *ctx;
1007
1008 ctx = arg;
1009 ctx->Map.in_action_loop = false;
1010 RtemsEventReqSendReceive_Setup( ctx );
1011 }
1012
1013 static void RtemsEventReqSendReceive_Teardown(
1014 RtemsEventReqSendReceive_Context *ctx
1015 )
1016 {
1017 DeleteTask( ctx->worker_id );
1018 DeleteWakeupSema( ctx->worker_wakeup );
1019 DeleteWakeupSema( ctx->runner_wakeup );
1020 RestoreRunnerPriority();
1021 }
1022
1023 static void RtemsEventReqSendReceive_Teardown_Wrap( void *arg )
1024 {
1025 RtemsEventReqSendReceive_Context *ctx;
1026
1027 ctx = arg;
1028 ctx->Map.in_action_loop = false;
1029 RtemsEventReqSendReceive_Teardown( ctx );
1030 }
1031
1032 static void RtemsEventReqSendReceive_Prepare(
1033 RtemsEventReqSendReceive_Context *ctx
1034 )
1035 {
1036 ctx->events_to_send = 0;
1037 ctx->send_status = RTEMS_INCORRECT_STATE;
1038 ctx->received_events = 0xffffffff;
1039 ctx->received_events_parameter = &ctx->received_events;
1040 ctx->receive_option_set = 0;
1041 ctx->receive_timeout = RTEMS_NO_TIMEOUT;
1042 ctx->sender_type = SENDER_NONE;
1043 ctx->sender_prio = PRIO_NORMAL;
1044 ctx->receive_type = RECEIVE_SKIP;
1045 ctx->receive_condition_state = RECEIVE_COND_UNKNOWN;
1046 ctx->unsatisfied_pending = 0xffffffff;
1047 memset( &ctx->thread_switch_log, 0, sizeof( ctx->thread_switch_log ) );
1048 T_eq_u32( GetPendingEvents( ctx ), 0 );
1049 }
1050
1051 static void RtemsEventReqSendReceive_Action(
1052 RtemsEventReqSendReceive_Context *ctx
1053 )
1054 {
1055 if ( ctx->sender_type == SENDER_SELF ) {
1056 SendAction( ctx );
1057 } else if ( ctx->sender_type == SENDER_WORKER ) {
1058 Wakeup( ctx->worker_wakeup );
1059 }
1060
1061 if ( ctx->receive_type == RECEIVE_NORMAL ) {
1062 ctx->receive_status = ( *ctx->receive )(
1063 INPUT_EVENTS,
1064 ctx->receive_option_set,
1065 ctx->receive_timeout,
1066 ctx->received_events_parameter
1067 );
1068 } else if ( ctx->receive_type == RECEIVE_INTERRUPT ) {
1069 T_interrupt_test_state state;
1070
1071 state = T_interrupt_test( &InterruptConfig, ctx );
1072 T_eq_int( state, T_INTERRUPT_TEST_DONE );
1073 }
1074
1075 if ( ctx->sender_type == SENDER_SELF_2 ) {
1076 SendAction( ctx );
1077 } else if ( ctx->sender_type == SENDER_WORKER ) {
1078 rtems_task_priority prio;
1079
1080 Wait( ctx->runner_wakeup );
1081 prio = SetPriority( ctx->worker_id, PRIO_LOW );
1082 T_eq_u32( prio, PRIO_HIGH );
1083 }
1084 }
1085
1086 static void RtemsEventReqSendReceive_Cleanup(
1087 RtemsEventReqSendReceive_Context *ctx
1088 )
1089 {
1090 rtems_status_code sc;
1091 rtems_event_set events;
1092
1093 events = 0;
1094 sc = ( *ctx->receive )(
1095 RTEMS_ALL_EVENTS,
1096 RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
1097 0,
1098 &events
1099 );
1100 if ( sc == RTEMS_SUCCESSFUL ) {
1101 T_quiet_ne_u32( events, 0 );
1102 } else {
1103 T_quiet_rsc( sc, RTEMS_UNSATISFIED );
1104 T_quiet_eq_u32( events, 0 );
1105 }
1106 }
1107
1108 static const RtemsEventReqSendReceive_Entry
1109 RtemsEventReqSendReceive_Entries[] = {
1110 { 0, 0, 1, 1, 1, RtemsEventReqSendReceive_Post_SendStatus_InvId,
1111 RtemsEventReqSendReceive_Post_ReceiveStatus_None,
1112 RtemsEventReqSendReceive_Post_SenderPreemption_No },
1113 { 0, 0, 0, 0, 1, RtemsEventReqSendReceive_Post_SendStatus_Ok,
1114 RtemsEventReqSendReceive_Post_ReceiveStatus_Pending,
1115 RtemsEventReqSendReceive_Post_SenderPreemption_No },
1116 { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok,
1117 RtemsEventReqSendReceive_Post_ReceiveStatus_Blocked,
1118 RtemsEventReqSendReceive_Post_SenderPreemption_No },
1119 { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok,
1120 RtemsEventReqSendReceive_Post_ReceiveStatus_Satisfied,
1121 RtemsEventReqSendReceive_Post_SenderPreemption_No },
1122 { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok,
1123 RtemsEventReqSendReceive_Post_ReceiveStatus_Timeout,
1124 RtemsEventReqSendReceive_Post_SenderPreemption_No },
1125 { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok,
1126 RtemsEventReqSendReceive_Post_ReceiveStatus_Unsatisfied,
1127 RtemsEventReqSendReceive_Post_SenderPreemption_No },
1128 #if defined(RTEMS_SMP)
1129 { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok,
1130 RtemsEventReqSendReceive_Post_ReceiveStatus_Blocked,
1131 RtemsEventReqSendReceive_Post_SenderPreemption_No },
1132 #else
1133 { 1, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_NA,
1134 RtemsEventReqSendReceive_Post_ReceiveStatus_NA,
1135 RtemsEventReqSendReceive_Post_SenderPreemption_NA },
1136 #endif
1137 { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok,
1138 RtemsEventReqSendReceive_Post_ReceiveStatus_Satisfied,
1139 RtemsEventReqSendReceive_Post_SenderPreemption_Yes },
1140 #if defined(RTEMS_SMP)
1141 { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok,
1142 RtemsEventReqSendReceive_Post_ReceiveStatus_Satisfied,
1143 RtemsEventReqSendReceive_Post_SenderPreemption_No }
1144 #else
1145 { 1, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_NA,
1146 RtemsEventReqSendReceive_Post_ReceiveStatus_NA,
1147 RtemsEventReqSendReceive_Post_SenderPreemption_NA }
1148 #endif
1149 };
1150
1151 static const uint8_t
1152 RtemsEventReqSendReceive_Map[] = {
1153 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1154 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1155 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1156 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1157 0, 0, 0, 0, 1, 1, 1, 1, 5, 5, 4, 4, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 1, 1, 1, 1,
1158 5, 5, 4, 4, 2, 2, 2, 2, 2, 2, 6, 6, 2, 2, 1, 1, 1, 1, 5, 3, 4, 4, 2, 3, 2, 3,
1159 2, 7, 6, 8, 2, 3, 1, 1, 1, 1, 3, 3, 4, 4, 3, 3, 3, 3, 7, 7, 8, 8, 3, 3, 1, 1,
1160 1, 1, 5, 3, 4, 4, 2, 3, 2, 3, 2, 7, 6, 8, 2, 3, 1, 1, 1, 1, 3, 3, 4, 4, 3, 3,
1161 3, 3, 7, 7, 8, 8, 3, 3
1162 };
1163
1164 static size_t RtemsEventReqSendReceive_Scope( void *arg, char *buf, size_t n )
1165 {
1166 RtemsEventReqSendReceive_Context *ctx;
1167
1168 ctx = arg;
1169
1170 if ( ctx->Map.in_action_loop ) {
1171 return T_get_scope(
1172 RtemsEventReqSendReceive_PreDesc,
1173 buf,
1174 n,
1175 ctx->Map.pcs
1176 );
1177 }
1178
1179 return 0;
1180 }
1181
1182 static T_fixture RtemsEventReqSendReceive_Fixture = {
1183 .setup = RtemsEventReqSendReceive_Setup_Wrap,
1184 .stop = NULL,
1185 .teardown = RtemsEventReqSendReceive_Teardown_Wrap,
1186 .scope = RtemsEventReqSendReceive_Scope,
1187 .initial_context = &RtemsEventReqSendReceive_Instance
1188 };
1189
1190 static inline RtemsEventReqSendReceive_Entry RtemsEventReqSendReceive_PopEntry(
1191 RtemsEventReqSendReceive_Context *ctx
1192 )
1193 {
1194 size_t index;
1195
1196 index = ctx->Map.index;
1197 ctx->Map.index = index + 1;
1198 return RtemsEventReqSendReceive_Entries[
1199 RtemsEventReqSendReceive_Map[ index ]
1200 ];
1201 }
1202
1203 static void RtemsEventReqSendReceive_SetPreConditionStates(
1204 RtemsEventReqSendReceive_Context *ctx
1205 )
1206 {
1207 ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
1208
1209 if ( ctx->Map.entry.Pre_Send_NA ) {
1210 ctx->Map.pcs[ 1 ] = RtemsEventReqSendReceive_Pre_Send_NA;
1211 } else {
1212 ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
1213 }
1214
1215 if ( ctx->Map.entry.Pre_ReceiverState_NA ) {
1216 ctx->Map.pcs[ 2 ] = RtemsEventReqSendReceive_Pre_ReceiverState_NA;
1217 } else {
1218 ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
1219 }
1220
1221 if ( ctx->Map.entry.Pre_Satisfy_NA ) {
1222 ctx->Map.pcs[ 3 ] = RtemsEventReqSendReceive_Pre_Satisfy_NA;
1223 } else {
1224 ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
1225 }
1226 }
1227
1228 static void RtemsEventReqSendReceive_TestVariant(
1229 RtemsEventReqSendReceive_Context *ctx
1230 )
1231 {
1232 RtemsEventReqSendReceive_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
1233 RtemsEventReqSendReceive_Pre_Send_Prepare( ctx, ctx->Map.pcs[ 1 ] );
1234 RtemsEventReqSendReceive_Pre_ReceiverState_Prepare( ctx, ctx->Map.pcs[ 2 ] );
1235 RtemsEventReqSendReceive_Pre_Satisfy_Prepare( ctx, ctx->Map.pcs[ 3 ] );
1236 RtemsEventReqSendReceive_Action( ctx );
1237 RtemsEventReqSendReceive_Post_SendStatus_Check(
1238 ctx,
1239 ctx->Map.entry.Post_SendStatus
1240 );
1241 RtemsEventReqSendReceive_Post_ReceiveStatus_Check(
1242 ctx,
1243 ctx->Map.entry.Post_ReceiveStatus
1244 );
1245 RtemsEventReqSendReceive_Post_SenderPreemption_Check(
1246 ctx,
1247 ctx->Map.entry.Post_SenderPreemption
1248 );
1249 }
1250
1251 static T_fixture_node RtemsEventReqSendReceive_Node;
1252
1253 static T_remark RtemsEventReqSendReceive_Remark = {
1254 .next = NULL,
1255 .remark = "RtemsEventReqSendReceive"
1256 };
1257
1258 void RtemsEventReqSendReceive_Run(
1259 rtems_status_code ( *send )( rtems_id, rtems_event_set ),
1260 rtems_status_code ( *receive )( rtems_event_set, rtems_option, rtems_interval, rtems_event_set * ),
1261 rtems_event_set ( *get_pending_events )( Thread_Control * ),
1262 unsigned int wait_class,
1263 int waiting_for_event
1264 )
1265 {
1266 RtemsEventReqSendReceive_Context *ctx;
1267
1268 ctx = &RtemsEventReqSendReceive_Instance;
1269 ctx->send = send;
1270 ctx->receive = receive;
1271 ctx->get_pending_events = get_pending_events;
1272 ctx->wait_class = wait_class;
1273 ctx->waiting_for_event = waiting_for_event;
1274
1275 ctx = T_push_fixture(
1276 &RtemsEventReqSendReceive_Node,
1277 &RtemsEventReqSendReceive_Fixture
1278 );
1279 ctx->Map.in_action_loop = true;
1280 ctx->Map.index = 0;
1281
1282 for (
1283 ctx->Map.pci[ 0 ] = RtemsEventReqSendReceive_Pre_Id_InvId;
1284 ctx->Map.pci[ 0 ] < RtemsEventReqSendReceive_Pre_Id_NA;
1285 ++ctx->Map.pci[ 0 ]
1286 ) {
1287 for (
1288 ctx->Map.pci[ 1 ] = RtemsEventReqSendReceive_Pre_Send_Zero;
1289 ctx->Map.pci[ 1 ] < RtemsEventReqSendReceive_Pre_Send_NA;
1290 ++ctx->Map.pci[ 1 ]
1291 ) {
1292 for (
1293 ctx->Map.pci[ 2 ] = RtemsEventReqSendReceive_Pre_ReceiverState_InvAddr;
1294 ctx->Map.pci[ 2 ] < RtemsEventReqSendReceive_Pre_ReceiverState_NA;
1295 ++ctx->Map.pci[ 2 ]
1296 ) {
1297 for (
1298 ctx->Map.pci[ 3 ] = RtemsEventReqSendReceive_Pre_Satisfy_All;
1299 ctx->Map.pci[ 3 ] < RtemsEventReqSendReceive_Pre_Satisfy_NA;
1300 ++ctx->Map.pci[ 3 ]
1301 ) {
1302 ctx->Map.entry = RtemsEventReqSendReceive_PopEntry( ctx );
1303
1304 if ( ctx->Map.entry.Skip ) {
1305 continue;
1306 }
1307
1308 RtemsEventReqSendReceive_SetPreConditionStates( ctx );
1309 RtemsEventReqSendReceive_Prepare( ctx );
1310 RtemsEventReqSendReceive_TestVariant( ctx );
1311 RtemsEventReqSendReceive_Cleanup( ctx );
1312 }
1313 }
1314 }
1315 }
1316
1317 T_add_remark( &RtemsEventReqSendReceive_Remark );
1318 T_pop_fixture();
1319 }
1320
1321