summaryrefslogtreecommitdiffstats
path: root/testsuites/validation
diff options
context:
space:
mode:
Diffstat (limited to 'testsuites/validation')
-rw-r--r--testsuites/validation/bsps/tc-fatal-sparc-leon3-shutdown-halt.c142
-rw-r--r--testsuites/validation/bsps/tc-fatal-sparc-leon3-shutdown-request.c179
-rw-r--r--testsuites/validation/bsps/tc-sparc-gr712rc.c124
-rw-r--r--testsuites/validation/bsps/tr-fatal-clock-xil-ttc-irq-install.c187
-rw-r--r--testsuites/validation/bsps/tr-fatal-clock-xil-ttc-irq-install.h84
-rw-r--r--testsuites/validation/bsps/tr-fatal-sparc-leon3-cache-snooping-disabled-boot.c175
-rw-r--r--testsuites/validation/bsps/tr-fatal-sparc-leon3-cache-snooping-disabled-boot.h84
-rw-r--r--testsuites/validation/bsps/tr-fatal-sparc-leon3-cache-snooping-disabled-secondary.c176
-rw-r--r--testsuites/validation/bsps/tr-fatal-sparc-leon3-cache-snooping-disabled-secondary.h84
-rw-r--r--testsuites/validation/bsps/tr-fatal-sparc-leon3-clock-initialization.c190
-rw-r--r--testsuites/validation/bsps/tr-fatal-sparc-leon3-clock-initialization.h84
-rw-r--r--testsuites/validation/bsps/ts-fatal-clock-xil-ttc-irq-install.c79
-rw-r--r--testsuites/validation/bsps/ts-fatal-sparc-leon3-cache-snooping-disabled-boot.c79
-rw-r--r--testsuites/validation/bsps/ts-fatal-sparc-leon3-cache-snooping-disabled-secondary.c82
-rw-r--r--testsuites/validation/bsps/ts-fatal-sparc-leon3-clock-initialization.c79
-rw-r--r--testsuites/validation/bsps/ts-fatal-sparc-leon3-shutdown-response.c94
-rw-r--r--testsuites/validation/bsps/ts-fatal-sparc-leon3-shutdown.c177
-rw-r--r--testsuites/validation/bsps/ts-validation-bsp-0.c73
-rw-r--r--testsuites/validation/tc-acfg-appl-does-not-need-clock-driver.c130
-rw-r--r--testsuites/validation/tc-acfg-appl-needs-clock-driver.c128
-rw-r--r--testsuites/validation/tc-acfg-default.c398
-rw-r--r--testsuites/validation/tc-acfg-disabled-bsp-settings.c140
-rw-r--r--testsuites/validation/tc-acfg-one-cpu.c156
-rw-r--r--testsuites/validation/tc-acfg-scheduler-edf-smp.c132
-rw-r--r--testsuites/validation/tc-acfg-scheduler-table-entries-one-cpu.c102
-rw-r--r--testsuites/validation/tc-acfg.c415
-rw-r--r--testsuites/validation/tc-attr.c350
-rw-r--r--testsuites/validation/tc-barrier-create.c8
-rw-r--r--testsuites/validation/tc-barrier-delete.c8
-rw-r--r--testsuites/validation/tc-barrier-ident.c119
-rw-r--r--testsuites/validation/tc-barrier-performance.c638
-rw-r--r--testsuites/validation/tc-barrier-release.c53
-rw-r--r--testsuites/validation/tc-barrier-wait.c82
-rw-r--r--testsuites/validation/tc-basedefs-no-debug.c135
-rw-r--r--testsuites/validation/tc-basedefs-pendant.c122
-rw-r--r--testsuites/validation/tc-basedefs-pendant.h93
-rw-r--r--testsuites/validation/tc-basedefs.c2033
-rw-r--r--testsuites/validation/tc-bsp-interrupt-handler-dispatch-unchecked.c649
-rw-r--r--testsuites/validation/tc-c.c189
-rw-r--r--testsuites/validation/tc-cache.c675
-rw-r--r--testsuites/validation/tc-clock-get-tod.c470
-rw-r--r--testsuites/validation/tc-clock-get-uptime.c338
-rw-r--r--testsuites/validation/tc-clock-nanosleep.c1027
-rw-r--r--testsuites/validation/tc-clock-set.c839
-rw-r--r--testsuites/validation/tc-clock.c181
-rw-r--r--testsuites/validation/tc-cpu-performance.c270
-rw-r--r--testsuites/validation/tc-cpuuse.c166
-rw-r--r--testsuites/validation/tc-dev-clock-xil-ttc.c136
-rw-r--r--testsuites/validation/tc-dev-grlib-apbuart-inbyte-nonblocking.c348
-rw-r--r--testsuites/validation/tc-dev-grlib-io.c295
-rw-r--r--testsuites/validation/tc-dev-grlib-irqamp-get-timestamp.c304
-rw-r--r--testsuites/validation/tc-event-performance.c591
-rw-r--r--testsuites/validation/tc-event-send-receive.c202
-rw-r--r--testsuites/validation/tc-events.c197
-rw-r--r--testsuites/validation/tc-flsl.c275
-rw-r--r--testsuites/validation/tc-futex-wait.c411
-rw-r--r--testsuites/validation/tc-futex-wake.c409
-rw-r--r--testsuites/validation/tc-intr-clear.c45
-rw-r--r--testsuites/validation/tc-intr-entry-install.c267
-rw-r--r--testsuites/validation/tc-intr-entry-remove.c185
-rw-r--r--testsuites/validation/tc-intr-get-affinity.c72
-rw-r--r--testsuites/validation/tc-intr-get-attributes.c11
-rw-r--r--testsuites/validation/tc-intr-handler-iterate.c54
-rw-r--r--testsuites/validation/tc-intr-is-pending.c95
-rw-r--r--testsuites/validation/tc-intr-non-smp.c170
-rw-r--r--testsuites/validation/tc-intr-raise-on.c76
-rw-r--r--testsuites/validation/tc-intr-raise.c69
-rw-r--r--testsuites/validation/tc-intr-set-affinity.c281
-rw-r--r--testsuites/validation/tc-intr-smp-only.c225
-rw-r--r--testsuites/validation/tc-intr-vector-disable.c63
-rw-r--r--testsuites/validation/tc-intr-vector-enable.c65
-rw-r--r--testsuites/validation/tc-intr-vector-is-enabled.c55
-rw-r--r--testsuites/validation/tc-intr.c286
-rw-r--r--testsuites/validation/tc-io-getchark.c328
-rw-r--r--testsuites/validation/tc-io-put-char.c319
-rw-r--r--testsuites/validation/tc-io-putc.c319
-rw-r--r--testsuites/validation/tc-message-broadcast.c1203
-rw-r--r--testsuites/validation/tc-message-construct-errors.c932
-rw-r--r--testsuites/validation/tc-message-construct.c1058
-rw-r--r--testsuites/validation/tc-message-delete.c479
-rw-r--r--testsuites/validation/tc-message-flush-pending.c981
-rw-r--r--testsuites/validation/tc-message-ident.c129
-rw-r--r--testsuites/validation/tc-message-macros.c147
-rw-r--r--testsuites/validation/tc-message-performance.c946
-rw-r--r--testsuites/validation/tc-message-receive.c1473
-rw-r--r--testsuites/validation/tc-message-urgent-send.c1166
-rw-r--r--testsuites/validation/tc-modes.c363
-rw-r--r--testsuites/validation/tc-object.c62
-rw-r--r--testsuites/validation/tc-options.c202
-rw-r--r--testsuites/validation/tc-part-create.c791
-rw-r--r--testsuites/validation/tc-part-delete.c396
-rw-r--r--testsuites/validation/tc-part-get.c526
-rw-r--r--testsuites/validation/tc-part-ident.c123
-rw-r--r--testsuites/validation/tc-part-performance.c171
-rw-r--r--testsuites/validation/tc-part-return.c486
-rw-r--r--testsuites/validation/tc-part.c196
-rw-r--r--testsuites/validation/tc-preinit-array.c150
-rw-r--r--testsuites/validation/tc-ratemon-cancel.c882
-rw-r--r--testsuites/validation/tc-ratemon-create.c529
-rw-r--r--testsuites/validation/tc-ratemon-delete.c368
-rw-r--r--testsuites/validation/tc-ratemon-get-status.c1170
-rw-r--r--testsuites/validation/tc-ratemon-ident.c117
-rw-r--r--testsuites/validation/tc-ratemon-period.c1273
-rw-r--r--testsuites/validation/tc-ratemon-timeout.c961
-rw-r--r--testsuites/validation/tc-sched-smp-edf-set-affinity.c1628
-rw-r--r--testsuites/validation/tc-sched-smp-edf.c111
-rw-r--r--testsuites/validation/tc-sched-smp.c1404
-rw-r--r--testsuites/validation/tc-sched-yield.c845
-rw-r--r--testsuites/validation/tc-scheduler-add-processor.c790
-rw-r--r--testsuites/validation/tc-scheduler-get-maximum-priority.c463
-rw-r--r--testsuites/validation/tc-scheduler-get-processor-set.c550
-rw-r--r--testsuites/validation/tc-scheduler-ident-by-processor-set.c743
-rw-r--r--testsuites/validation/tc-scheduler-ident-by-processor.c593
-rw-r--r--testsuites/validation/tc-scheduler-ident.c405
-rw-r--r--testsuites/validation/tc-scheduler-non-smp.c131
-rw-r--r--testsuites/validation/tc-scheduler-remove-processor.c1485
-rw-r--r--testsuites/validation/tc-scheduler-smp-only.c255
-rw-r--r--testsuites/validation/tc-scheduler.c156
-rw-r--r--testsuites/validation/tc-score-fatal.c462
-rw-r--r--testsuites/validation/tc-score-isr.c285
-rw-r--r--testsuites/validation/tc-score-smp-per-cpu-jobs.c151
-rw-r--r--testsuites/validation/tc-score-smp-thread.c554
-rw-r--r--testsuites/validation/tc-score-thread-smp-one-cpu.c183
-rw-r--r--testsuites/validation/tc-score-thread-tls-max-zero.c109
-rw-r--r--testsuites/validation/tc-score-thread-tls.c135
-rw-r--r--testsuites/validation/tc-score-thread.c446
-rw-r--r--testsuites/validation/tc-score-tq-smp.c571
-rw-r--r--testsuites/validation/tc-score-tq.c190
-rw-r--r--testsuites/validation/tc-sem-create.c1559
-rw-r--r--testsuites/validation/tc-sem-delete.c759
-rw-r--r--testsuites/validation/tc-sem-flush.c629
-rw-r--r--testsuites/validation/tc-sem-ident.c121
-rw-r--r--testsuites/validation/tc-sem-mrsp-obtain.c1202
-rw-r--r--testsuites/validation/tc-sem-obtain.c733
-rw-r--r--testsuites/validation/tc-sem-performance.c968
-rw-r--r--testsuites/validation/tc-sem-release.c615
-rw-r--r--testsuites/validation/tc-sem-set-priority.c1136
-rw-r--r--testsuites/validation/tc-sem-smp.c478
-rw-r--r--testsuites/validation/tc-sem-timeout.c476
-rw-r--r--testsuites/validation/tc-sem-uni.c226
-rw-r--r--testsuites/validation/tc-signal-catch.c10
-rw-r--r--testsuites/validation/tc-signal-send.c16
-rw-r--r--testsuites/validation/tc-signals.c134
-rw-r--r--testsuites/validation/tc-start-of-optional-processor-failed.c116
-rw-r--r--testsuites/validation/tc-status-is-equal.c286
-rw-r--r--testsuites/validation/tc-status-is-successful.c293
-rw-r--r--testsuites/validation/tc-status-text.c914
-rw-r--r--testsuites/validation/tc-status.c121
-rw-r--r--testsuites/validation/tc-support-is-name-valid.c293
-rw-r--r--testsuites/validation/tc-support.c126
-rw-r--r--testsuites/validation/tc-sys-lock.c433
-rw-r--r--testsuites/validation/tc-task-construct-errors.c1207
-rw-r--r--testsuites/validation/tc-task-construct.c4950
-rw-r--r--testsuites/validation/tc-task-create-errors.c17
-rw-r--r--testsuites/validation/tc-task-delete.c4844
-rw-r--r--testsuites/validation/tc-task-exit.c989
-rw-r--r--testsuites/validation/tc-task-get-affinity.c519
-rw-r--r--testsuites/validation/tc-task-get-priority.c619
-rw-r--r--testsuites/validation/tc-task-get-scheduler.c419
-rw-r--r--testsuites/validation/tc-task-ident.c338
-rw-r--r--testsuites/validation/tc-task-is-suspended.c429
-rw-r--r--testsuites/validation/tc-task-mode.c2019
-rw-r--r--testsuites/validation/tc-task-performance.c1152
-rw-r--r--testsuites/validation/tc-task-restart.c2760
-rw-r--r--testsuites/validation/tc-task-resume.c411
-rw-r--r--testsuites/validation/tc-task-set-affinity.c683
-rw-r--r--testsuites/validation/tc-task-set-priority.c815
-rw-r--r--testsuites/validation/tc-task-set-scheduler.c1491
-rw-r--r--testsuites/validation/tc-task-smp.c146
-rw-r--r--testsuites/validation/tc-task-start.c859
-rw-r--r--testsuites/validation/tc-task-storage-size.c427
-rw-r--r--testsuites/validation/tc-task-suspend.c411
-rw-r--r--testsuites/validation/tc-task-wake-after.c574
-rw-r--r--testsuites/validation/tc-task-wake-when.c665
-rw-r--r--testsuites/validation/tc-task.c355
-rw-r--r--testsuites/validation/tc-terminate.c446
-rw-r--r--testsuites/validation/tc-thread-idle-body-no-return.c205
-rw-r--r--testsuites/validation/tc-timecounter-get-smp.c740
-rw-r--r--testsuites/validation/tc-timecounter-get.c574
-rw-r--r--testsuites/validation/tc-timecounter-install.c1133
-rw-r--r--testsuites/validation/tc-timer-cancel.c813
-rw-r--r--testsuites/validation/tc-timer-create.c535
-rw-r--r--testsuites/validation/tc-timer-delete.c362
-rw-r--r--testsuites/validation/tc-timer-fire-after.c1161
-rw-r--r--testsuites/validation/tc-timer-fire-when.c1286
-rw-r--r--testsuites/validation/tc-timer-ident.c117
-rw-r--r--testsuites/validation/tc-timer-initiate-server.c816
-rw-r--r--testsuites/validation/tc-timer-reset.c1058
-rw-r--r--testsuites/validation/tc-timer-server-fire-after.c1301
-rw-r--r--testsuites/validation/tc-timer-server-fire-when.c1416
-rw-r--r--testsuites/validation/tc-timer.c208
-rw-r--r--testsuites/validation/tc-type.c130
-rw-r--r--testsuites/validation/tc-userext-create.c610
-rw-r--r--testsuites/validation/tc-userext-delete.c387
-rw-r--r--testsuites/validation/tc-userext-ident.c119
-rw-r--r--testsuites/validation/tc-userext.c918
-rw-r--r--testsuites/validation/tc-userext.h93
-rw-r--r--testsuites/validation/tr-event-constant.c726
-rw-r--r--testsuites/validation/tr-event-constant.h81
-rw-r--r--testsuites/validation/tr-event-send-receive.c1321
-rw-r--r--testsuites/validation/tr-event-send-receive.h152
-rw-r--r--testsuites/validation/tr-fatal-boot-processor-not-assigned-to-scheduler.c159
-rw-r--r--testsuites/validation/tr-fatal-boot-processor-not-assigned-to-scheduler.h84
-rw-r--r--testsuites/validation/tr-fatal-idle-thread-create-failed.c158
-rw-r--r--testsuites/validation/tr-fatal-idle-thread-create-failed.h84
-rw-r--r--testsuites/validation/tr-fatal-idle-thread-stack-too-small.c175
-rw-r--r--testsuites/validation/tr-fatal-idle-thread-stack-too-small.h84
-rw-r--r--testsuites/validation/tr-fatal-init-task-construct-failed.c172
-rw-r--r--testsuites/validation/tr-fatal-init-task-construct-failed.h84
-rw-r--r--testsuites/validation/tr-fatal-mandatory-processor-not-present.c158
-rw-r--r--testsuites/validation/tr-fatal-mandatory-processor-not-present.h84
-rw-r--r--testsuites/validation/tr-fatal-scheduler-requires-exactly-one-processor.c159
-rw-r--r--testsuites/validation/tr-fatal-scheduler-requires-exactly-one-processor.h84
-rw-r--r--testsuites/validation/tr-fatal-smp.c320
-rw-r--r--testsuites/validation/tr-fatal-smp.h81
-rw-r--r--testsuites/validation/tr-fatal-start-of-mandatory-processor-failed.c166
-rw-r--r--testsuites/validation/tr-fatal-start-of-mandatory-processor-failed.h84
-rw-r--r--testsuites/validation/tr-fatal-start-on-not-online-processor.c167
-rw-r--r--testsuites/validation/tr-fatal-start-on-not-online-processor.h84
-rw-r--r--testsuites/validation/tr-fatal-too-large-tls-size.c182
-rw-r--r--testsuites/validation/tr-fatal-too-large-tls-size.h84
-rw-r--r--testsuites/validation/tr-io-kernel.c125
-rw-r--r--testsuites/validation/tr-io-kernel.h75
-rw-r--r--testsuites/validation/tr-mtx-seize-try.c868
-rw-r--r--testsuites/validation/tr-mtx-seize-try.h134
-rw-r--r--testsuites/validation/tr-mtx-seize-wait.c1152
-rw-r--r--testsuites/validation/tr-mtx-seize-wait.h151
-rw-r--r--testsuites/validation/tr-mtx-surrender.c1246
-rw-r--r--testsuites/validation/tr-mtx-surrender.h160
-rw-r--r--testsuites/validation/tr-object-ident-local.c394
-rw-r--r--testsuites/validation/tr-object-ident-local.h115
-rw-r--r--testsuites/validation/tr-object-ident.c504
-rw-r--r--testsuites/validation/tr-object-ident.h127
-rw-r--r--testsuites/validation/tr-sem-seize-try.c329
-rw-r--r--testsuites/validation/tr-sem-seize-try.h97
-rw-r--r--testsuites/validation/tr-sem-seize-wait.c404
-rw-r--r--testsuites/validation/tr-sem-seize-wait.h103
-rw-r--r--testsuites/validation/tr-sem-surrender.c576
-rw-r--r--testsuites/validation/tr-sem-surrender.h118
-rw-r--r--testsuites/validation/tr-signal-constant.c206
-rw-r--r--testsuites/validation/tr-signal-constant.h81
-rw-r--r--testsuites/validation/tr-tq-enqueue-ceiling.c693
-rw-r--r--testsuites/validation/tr-tq-enqueue-ceiling.h109
-rw-r--r--testsuites/validation/tr-tq-enqueue-deadlock.c447
-rw-r--r--testsuites/validation/tr-tq-enqueue-deadlock.h97
-rw-r--r--testsuites/validation/tr-tq-enqueue-fifo.c340
-rw-r--r--testsuites/validation/tr-tq-enqueue-fifo.h91
-rw-r--r--testsuites/validation/tr-tq-enqueue-mrsp.c658
-rw-r--r--testsuites/validation/tr-tq-enqueue-mrsp.h109
-rw-r--r--testsuites/validation/tr-tq-enqueue-priority-inherit.c1742
-rw-r--r--testsuites/validation/tr-tq-enqueue-priority-inherit.h159
-rw-r--r--testsuites/validation/tr-tq-enqueue-priority.c751
-rw-r--r--testsuites/validation/tr-tq-enqueue-priority.h113
-rw-r--r--testsuites/validation/tr-tq-flush-fifo.c694
-rw-r--r--testsuites/validation/tr-tq-flush-fifo.h112
-rw-r--r--testsuites/validation/tr-tq-flush-priority-inherit.c577
-rw-r--r--testsuites/validation/tr-tq-flush-priority-inherit.h103
-rw-r--r--testsuites/validation/tr-tq-flush-priority.c424
-rw-r--r--testsuites/validation/tr-tq-flush-priority.h97
-rw-r--r--testsuites/validation/tr-tq-surrender-mrsp.c1041
-rw-r--r--testsuites/validation/tr-tq-surrender-mrsp.h148
-rw-r--r--testsuites/validation/tr-tq-surrender-priority-inherit.c2522
-rw-r--r--testsuites/validation/tr-tq-surrender-priority-inherit.h169
-rw-r--r--testsuites/validation/tr-tq-surrender.c690
-rw-r--r--testsuites/validation/tr-tq-surrender.h109
-rw-r--r--testsuites/validation/tr-tq-timeout-mrsp.c482
-rw-r--r--testsuites/validation/tr-tq-timeout-mrsp.h102
-rw-r--r--testsuites/validation/tr-tq-timeout-priority-inherit.c2160
-rw-r--r--testsuites/validation/tr-tq-timeout-priority-inherit.h160
-rw-r--r--testsuites/validation/tr-tq-timeout.c459
-rw-r--r--testsuites/validation/tr-tq-timeout.h98
-rw-r--r--testsuites/validation/ts-acfg.h83
-rw-r--r--testsuites/validation/ts-config.h126
-rw-r--r--testsuites/validation/ts-default.h184
-rw-r--r--testsuites/validation/ts-fatal-boot-processor-not-assigned-to-scheduler.c98
-rw-r--r--testsuites/validation/ts-fatal-idle-thread-create-failed.c90
-rw-r--r--testsuites/validation/ts-fatal-idle-thread-stack-too-small.c97
-rw-r--r--testsuites/validation/ts-fatal-init-task-construct-failed.c95
-rw-r--r--testsuites/validation/ts-fatal-mandatory-processor-not-present.c127
-rw-r--r--testsuites/validation/ts-fatal-scheduler-requires-exactly-one-processor.c98
-rw-r--r--testsuites/validation/ts-fatal-smp.c97
-rw-r--r--testsuites/validation/ts-fatal-start-of-mandatory-processor-failed.c97
-rw-r--r--testsuites/validation/ts-fatal-start-on-not-online-processor.c84
-rw-r--r--testsuites/validation/ts-fatal-sysinit.h161
-rw-r--r--testsuites/validation/ts-fatal-too-large-tls-size.c82
-rw-r--r--testsuites/validation/ts-idle.h104
-rw-r--r--testsuites/validation/ts-performance-no-clock-0.c (renamed from testsuites/validation/ts-performance-0.c)16
-rw-r--r--testsuites/validation/ts-terminate.c82
-rw-r--r--testsuites/validation/ts-userext.c99
-rw-r--r--testsuites/validation/ts-validation-0.c10
-rw-r--r--testsuites/validation/ts-validation-1.c18
-rw-r--r--testsuites/validation/ts-validation-acfg-0.c90
-rw-r--r--testsuites/validation/ts-validation-acfg-1.c112
-rw-r--r--testsuites/validation/ts-validation-cache.c77
-rw-r--r--testsuites/validation/ts-validation-intr.c80
-rw-r--r--testsuites/validation/ts-validation-io-kernel.c150
-rw-r--r--testsuites/validation/ts-validation-no-clock-0.c81
-rw-r--r--testsuites/validation/ts-validation-non-smp.c74
-rw-r--r--testsuites/validation/ts-validation-one-cpu-0.c79
-rw-r--r--testsuites/validation/ts-validation-one-cpu-1.c84
-rw-r--r--testsuites/validation/ts-validation-smp-one-cpu-0.c76
-rw-r--r--testsuites/validation/ts-validation-smp-only-0.c78
-rw-r--r--testsuites/validation/ts-validation-smp-only-2.c102
-rw-r--r--testsuites/validation/ts-validation-timecounter-0.c77
-rw-r--r--testsuites/validation/ts-validation-timecounter-1.c75
-rw-r--r--testsuites/validation/ts-validation-timecounter-smp-0.c77
-rw-r--r--testsuites/validation/ts-validation-tls-0.c74
-rw-r--r--testsuites/validation/ts-validation-tls-1.c75
-rw-r--r--testsuites/validation/tx-call-within-isr.c106
-rw-r--r--testsuites/validation/tx-default-task-config.c61
-rw-r--r--testsuites/validation/tx-interrupt.c46
-rw-r--r--testsuites/validation/tx-io-relax.c67
-rw-r--r--testsuites/validation/tx-memory-alloc.c79
-rw-r--r--testsuites/validation/tx-preemption-intervention.c155
-rw-r--r--testsuites/validation/tx-support.c898
-rw-r--r--testsuites/validation/tx-support.h499
-rw-r--r--testsuites/validation/tx-thread-queue.c858
-rw-r--r--testsuites/validation/tx-thread-queue.h537
-rw-r--r--testsuites/validation/tx-timecounter.c160
-rw-r--r--testsuites/validation/tx-timer-server.c150
-rw-r--r--testsuites/validation/tx-wrap-thread-queue.c144
321 files changed, 133110 insertions, 2780 deletions
diff --git a/testsuites/validation/bsps/tc-fatal-sparc-leon3-shutdown-halt.c b/testsuites/validation/bsps/tc-fatal-sparc-leon3-shutdown-halt.c
new file mode 100644
index 0000000000..0b0b5cf5b7
--- /dev/null
+++ b/testsuites/validation/bsps/tc-fatal-sparc-leon3-shutdown-halt.c
@@ -0,0 +1,142 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup BspSparcLeon3ValFatalShutdownHalt
+ */
+
+/*
+ * Copyright (C) 2021, 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/sysinit.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup BspSparcLeon3ValFatalShutdownHalt \
+ * spec:/bsp/sparc/leon3/val/fatal-shutdown-halt
+ *
+ * @ingroup TestsuitesBspsFatalSparcLeon3Shutdown
+ *
+ * @brief Tests the leon3 BSP family shutdown procedure.
+ *
+ * This test case performs the following actions:
+ *
+ * - Check the effects of the leon3 BSP family shutdown procedure.
+ *
+ * - Check that no dynamic fatal error extension was invoked. This shows
+ * that the leon3 BSP family shutdown procedure called the wrapped
+ * _CPU_Fatal_halt() function of the test suite.
+ *
+ * @{
+ */
+
+static Atomic_Uint dynamic_fatal_extension_counter;
+
+static rtems_status_code status;
+
+static unsigned int Add( Atomic_Uint *a, unsigned int b )
+{
+ return _Atomic_Fetch_add_uint( a, b, ATOMIC_ORDER_RELAXED );
+}
+
+static void DynamicFatalHandler(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code
+)
+{
+ (void) source;
+ (void) code;
+ (void) always_set_to_false;
+ (void) Add( &dynamic_fatal_extension_counter, 1 );
+}
+
+static void InitBspSparcLeon3ValFatalShutdownHalt( void )
+{
+ rtems_extensions_table table = { .fatal = DynamicFatalHandler };
+ rtems_id id;
+
+ status = rtems_extension_create( OBJECT_NAME, &table, &id );
+}
+
+RTEMS_SYSINIT_ITEM(
+ InitBspSparcLeon3ValFatalShutdownHalt,
+ RTEMS_SYSINIT_DEVICE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_MIDDLE
+);
+
+/**
+ * @brief Check the effects of the leon3 BSP family shutdown procedure.
+ */
+static void BspSparcLeon3ValFatalShutdownHalt_Action_0( void )
+{
+ uint32_t counter;
+
+ /*
+ * Check that no dynamic fatal error extension was invoked. This shows that
+ * the leon3 BSP family shutdown procedure called the wrapped
+ * _CPU_Fatal_halt() function of the test suite.
+ */
+ T_step_rsc_success( 0, status );
+ counter = Add( &dynamic_fatal_extension_counter, 0 );
+ T_step_eq_u32( 1, counter, 0 );
+}
+
+/**
+ * @fn void T_case_body_BspSparcLeon3ValFatalShutdownHalt( void )
+ */
+T_TEST_CASE( BspSparcLeon3ValFatalShutdownHalt )
+{
+ T_plan( 2 );
+
+ BspSparcLeon3ValFatalShutdownHalt_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/bsps/tc-fatal-sparc-leon3-shutdown-request.c b/testsuites/validation/bsps/tc-fatal-sparc-leon3-shutdown-request.c
new file mode 100644
index 0000000000..46bc44e7cb
--- /dev/null
+++ b/testsuites/validation/bsps/tc-fatal-sparc-leon3-shutdown-request.c
@@ -0,0 +1,179 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup BspSparcLeon3ValFatalShutdownRequest
+ */
+
+/*
+ * Copyright (C) 2021, 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <bsp/leon3.h>
+#include <rtems/sysinit.h>
+#include <rtems/score/smpimpl.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup BspSparcLeon3ValFatalShutdownRequest \
+ * spec:/bsp/sparc/leon3/val/fatal-shutdown-request
+ *
+ * @ingroup TestsuitesBspsFatalSparcLeon3Shutdown
+ *
+ * @brief Tests the leon3 BSP family SMP-specific shutdown procedure.
+ *
+ * This test case performs the following actions:
+ *
+ * - Check the effects of the leon3 BSP family shutdown procedure.
+ *
+ * - Check that the second processor was not powered down during system
+ * initialization.
+ *
+ * - Wait until the second processor is powered down.
+ *
+ * - Check that the RTEMS_FATAL_SOURCE_SMP with SMP_FATAL_SHUTDOWN_RESPONSE
+ * fatal error occurred exactly once.
+ *
+ * - Check that the RTEMS_FATAL_SOURCE_SMP with SMP_FATAL_SHUTDOWN_RESPONSE
+ * fatal error occurred on the second processor.
+ *
+ * @{
+ */
+
+static uint32_t mpstat_during_sysinit;
+
+static Atomic_Uint shutdown_response_counter;
+
+static uint32_t shutdown_response_cpu_index = UINT32_MAX;
+
+static unsigned int Add( Atomic_Uint *a, unsigned int b )
+{
+ return _Atomic_Fetch_add_uint( a, b, ATOMIC_ORDER_RELAXED );
+}
+
+static void ShutdownFatalHandler(
+ rtems_fatal_source source,
+ rtems_fatal_code code,
+ void *arg
+)
+{
+ T_null( arg );
+
+ if (
+ source == RTEMS_FATAL_SOURCE_SMP &&
+ code == SMP_FATAL_SHUTDOWN_RESPONSE
+ ) {
+ (void) Add( &shutdown_response_counter, 1 );
+ shutdown_response_cpu_index = rtems_scheduler_get_processor();
+ }
+}
+
+static void InitBspSparcLeon3ValFatalShutdownRequest( void )
+{
+ irqamp *regs;
+
+ regs = LEON3_IrqCtrl_Regs;
+ mpstat_during_sysinit = grlib_load_32( &regs->mpstat );
+ SetFatalHandler( ShutdownFatalHandler, NULL );
+}
+
+RTEMS_SYSINIT_ITEM(
+ InitBspSparcLeon3ValFatalShutdownRequest,
+ RTEMS_SYSINIT_DEVICE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_MIDDLE
+);
+
+/**
+ * @brief Check the effects of the leon3 BSP family shutdown procedure.
+ */
+static void BspSparcLeon3ValFatalShutdownRequest_Action_0( void )
+{
+ irqamp *regs;
+ uint32_t counter;
+
+ regs = LEON3_IrqCtrl_Regs;
+
+ /*
+ * Check that the second processor was not powered down during system
+ * initialization.
+ */
+ T_step_eq_u32( 0, mpstat_during_sysinit & 0x2, 0 );
+
+ /*
+ * Wait until the second processor is powered down.
+ */
+ while ( ( grlib_load_32( &regs->mpstat ) & 0x2 ) != 0x2U ) {
+ /* Wait */
+ }
+
+ /*
+ * Check that the RTEMS_FATAL_SOURCE_SMP with SMP_FATAL_SHUTDOWN_RESPONSE
+ * fatal error occurred exactly once.
+ */
+ counter = Add( &shutdown_response_counter, 0 );
+ T_step_eq_uint( 1, counter, 1 );
+
+ /*
+ * Check that the RTEMS_FATAL_SOURCE_SMP with SMP_FATAL_SHUTDOWN_RESPONSE
+ * fatal error occurred on the second processor.
+ */
+ T_step_eq_u32( 2, shutdown_response_cpu_index, 1 );
+}
+
+/**
+ * @fn void T_case_body_BspSparcLeon3ValFatalShutdownRequest( void )
+ */
+T_TEST_CASE( BspSparcLeon3ValFatalShutdownRequest )
+{
+ T_plan( 3 );
+
+ BspSparcLeon3ValFatalShutdownRequest_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/bsps/tc-sparc-gr712rc.c b/testsuites/validation/bsps/tc-sparc-gr712rc.c
new file mode 100644
index 0000000000..a16de3d6ed
--- /dev/null
+++ b/testsuites/validation/bsps/tc-sparc-gr712rc.c
@@ -0,0 +1,124 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup BspSparcLeon3ValGr712rc
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <bsp.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup BspSparcLeon3ValGr712rc spec:/bsp/sparc/leon3/val/gr712rc
+ *
+ * @ingroup TestsuitesBspsValidationBsp0
+ *
+ * @brief This test case collection provides validation test cases for the
+ * ``sparc/gr712rc`` BSP.
+ *
+ * This test case performs the following actions:
+ *
+ * - Validate the use of the ``-mfix-gr712rc`` compiler option.
+ *
+ * - Check that the compiler built-in define ``__FIX_LEON3FT_B2BST`` is
+ * defined.
+ *
+ * - Check that the compiler built-in define ``__FIX_LEON3FT_TN0018`` is
+ * defined.
+ *
+ * - Check that the ``SPARC_LEON3FT_B2BST_NOP`` define expands to a ``nop``
+ * instruction.
+ *
+ * @{
+ */
+
+/**
+ * @brief Validate the use of the ``-mfix-gr712rc`` compiler option.
+ */
+static void BspSparcLeon3ValGr712rc_Action_0( void )
+{
+ const char *s;
+
+ /*
+ * Check that the compiler built-in define ``__FIX_LEON3FT_B2BST`` is
+ * defined.
+ */
+ #if !defined(__FIX_LEON3FT_B2BST)
+ #error "__FIX_LEON3FT_B2BST is not defined"
+ #endif
+
+ /*
+ * Check that the compiler built-in define ``__FIX_LEON3FT_TN0018`` is
+ * defined.
+ */
+ #if !defined(__FIX_LEON3FT_TN0018)
+ #error "__FIX_LEON3FT_TN0018 is not defined"
+ #endif
+
+ /*
+ * Check that the ``SPARC_LEON3FT_B2BST_NOP`` define expands to a ``nop``
+ * instruction.
+ */
+ s = RTEMS_XSTRING( SPARC_LEON3FT_B2BST_NOP );
+ T_true( IsEqualIgnoreWhiteSpace( s, "nop" ) );
+}
+
+/**
+ * @fn void T_case_body_BspSparcLeon3ValGr712rc( void )
+ */
+T_TEST_CASE( BspSparcLeon3ValGr712rc )
+{
+ BspSparcLeon3ValGr712rc_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/bsps/tr-fatal-clock-xil-ttc-irq-install.c b/testsuites/validation/bsps/tr-fatal-clock-xil-ttc-irq-install.c
new file mode 100644
index 0000000000..731b454ee4
--- /dev/null
+++ b/testsuites/validation/bsps/tr-fatal-clock-xil-ttc-irq-install.c
@@ -0,0 +1,187 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup DevClockXilTtcValFatalIrqInstall
+ */
+
+/*
+ * Copyright (C) 2024 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <bsp.h>
+#include <rtems.h>
+#include <bsp/fatal.h>
+#include <rtems/sysinit.h>
+
+#include "tr-fatal-clock-xil-ttc-irq-install.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup DevClockXilTtcValFatalIrqInstall \
+ * spec:/dev/clock/xil-ttc/val/fatal-irq-install
+ *
+ * @ingroup TestsuitesBspsFatalClockXilTtcIrqInstall
+ *
+ * @brief Tests a fatal error.
+ *
+ * This test case performs the following actions:
+ *
+ * - The test action is carried out by the OccupyClockInterrupt() system
+ * initialization handler.
+ *
+ * - Check that the expected fatal source is present.
+ *
+ * - Check that the expected fatal code is present.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/dev/clock/xil-ttc/val/fatal-irq-install test
+ * case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a copy of the corresponding
+ * DevClockXilTtcValFatalIrqInstall_Run() parameter.
+ */
+ rtems_fatal_source source;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * DevClockXilTtcValFatalIrqInstall_Run() parameter.
+ */
+ rtems_fatal_code code;
+} DevClockXilTtcValFatalIrqInstall_Context;
+
+static DevClockXilTtcValFatalIrqInstall_Context
+ DevClockXilTtcValFatalIrqInstall_Instance;
+
+static void ClockInterrupt( void *arg )
+{
+ (void) arg;
+}
+
+static rtems_interrupt_entry interrupt_entry = RTEMS_INTERRUPT_ENTRY_INITIALIZER(
+ ClockInterrupt,
+ NULL,
+ "Clock"
+);
+
+static void OccupyClockInterrupt( void )
+{
+ (void) rtems_interrupt_entry_install(
+ XIL_CLOCK_TTC_IRQ,
+ RTEMS_INTERRUPT_UNIQUE,
+ &interrupt_entry
+ );
+}
+
+RTEMS_SYSINIT_ITEM(
+ OccupyClockInterrupt,
+ RTEMS_SYSINIT_DEVICE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_FIRST
+);
+
+static T_fixture DevClockXilTtcValFatalIrqInstall_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &DevClockXilTtcValFatalIrqInstall_Instance
+};
+
+/**
+ * @brief The test action is carried out by the OccupyClockInterrupt() system
+ * initialization handler.
+ */
+static void DevClockXilTtcValFatalIrqInstall_Action_0(
+ DevClockXilTtcValFatalIrqInstall_Context *ctx
+)
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the expected fatal source is present.
+ */
+ T_step_eq_int( 0, ctx->source, RTEMS_FATAL_SOURCE_BSP );
+
+ /*
+ * Check that the expected fatal code is present.
+ */
+ T_step_eq_ulong(
+ 1,
+ ctx->code,
+ XIL_FATAL_TTC_IRQ_INSTALL
+ );
+}
+
+void DevClockXilTtcValFatalIrqInstall_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+)
+{
+ DevClockXilTtcValFatalIrqInstall_Context *ctx;
+
+ ctx = &DevClockXilTtcValFatalIrqInstall_Instance;
+ ctx->source = source;
+ ctx->code = code;
+
+ ctx = T_case_begin(
+ "DevClockXilTtcValFatalIrqInstall",
+ &DevClockXilTtcValFatalIrqInstall_Fixture
+ );
+
+ T_plan( 2 );
+
+ DevClockXilTtcValFatalIrqInstall_Action_0( ctx );
+
+ T_case_end();
+}
+
+/** @} */
diff --git a/testsuites/validation/bsps/tr-fatal-clock-xil-ttc-irq-install.h b/testsuites/validation/bsps/tr-fatal-clock-xil-ttc-irq-install.h
new file mode 100644
index 0000000000..74021233a0
--- /dev/null
+++ b/testsuites/validation/bsps/tr-fatal-clock-xil-ttc-irq-install.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup DevClockXilTtcValFatalIrqInstall
+ */
+
+/*
+ * Copyright (C) 2024 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_FATAL_CLOCK_XIL_TTC_IRQ_INSTALL_H
+#define _TR_FATAL_CLOCK_XIL_TTC_IRQ_INSTALL_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup DevClockXilTtcValFatalIrqInstall
+ *
+ * @{
+ */
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param source is fatal source.
+ *
+ * @param code is fatal code.
+ */
+void DevClockXilTtcValFatalIrqInstall_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_FATAL_CLOCK_XIL_TTC_IRQ_INSTALL_H */
diff --git a/testsuites/validation/bsps/tr-fatal-sparc-leon3-cache-snooping-disabled-boot.c b/testsuites/validation/bsps/tr-fatal-sparc-leon3-cache-snooping-disabled-boot.c
new file mode 100644
index 0000000000..748fd88e70
--- /dev/null
+++ b/testsuites/validation/bsps/tr-fatal-sparc-leon3-cache-snooping-disabled-boot.c
@@ -0,0 +1,175 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup BspSparcLeon3ValFatalCacheSnoopingDisabledBoot
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <bsp/fatal.h>
+#include <bsp/leon3.h>
+#include <rtems/sysinit.h>
+
+#include "tr-fatal-sparc-leon3-cache-snooping-disabled-boot.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup BspSparcLeon3ValFatalCacheSnoopingDisabledBoot \
+ * spec:/bsp/sparc/leon3/val/fatal-cache-snooping-disabled-boot
+ *
+ * @ingroup TestsuitesBspsFatalSparcLeon3CacheSnoopingDisabledBoot
+ *
+ * @brief Tests a fatal error.
+ *
+ * This test case performs the following actions:
+ *
+ * - The test action is carried out by the DisableCacheSnooping() system
+ * initialization handler.
+ *
+ * - Check that the expected fatal source is present.
+ *
+ * - Check that the expected fatal code is present.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for
+ * spec:/bsp/sparc/leon3/val/fatal-cache-snooping-disabled-boot test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a copy of the corresponding
+ * BspSparcLeon3ValFatalCacheSnoopingDisabledBoot_Run() parameter.
+ */
+ rtems_fatal_source source;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * BspSparcLeon3ValFatalCacheSnoopingDisabledBoot_Run() parameter.
+ */
+ rtems_fatal_code code;
+} BspSparcLeon3ValFatalCacheSnoopingDisabledBoot_Context;
+
+static BspSparcLeon3ValFatalCacheSnoopingDisabledBoot_Context
+ BspSparcLeon3ValFatalCacheSnoopingDisabledBoot_Instance;
+
+static void DisableCacheSnooping( void )
+{
+ uint32_t control;
+
+ control = leon3_get_cache_control_register();
+ control &= ~LEON3_REG_CACHE_CTRL_DS;
+ leon3_set_cache_control_register( control );
+}
+
+RTEMS_SYSINIT_ITEM(
+ DisableCacheSnooping,
+ RTEMS_SYSINIT_BSP_EARLY,
+ RTEMS_SYSINIT_ORDER_FIRST
+);
+
+static T_fixture BspSparcLeon3ValFatalCacheSnoopingDisabledBoot_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &BspSparcLeon3ValFatalCacheSnoopingDisabledBoot_Instance
+};
+
+/**
+ * @brief The test action is carried out by the DisableCacheSnooping() system
+ * initialization handler.
+ */
+static void BspSparcLeon3ValFatalCacheSnoopingDisabledBoot_Action_0(
+ BspSparcLeon3ValFatalCacheSnoopingDisabledBoot_Context *ctx
+)
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the expected fatal source is present.
+ */
+ T_step_eq_int( 0, ctx->source, RTEMS_FATAL_SOURCE_BSP );
+
+ /*
+ * Check that the expected fatal code is present.
+ */
+ T_step_eq_ulong(
+ 1,
+ ctx->code,
+ LEON3_FATAL_INVALID_CACHE_CONFIG_BOOT_PROCESSOR
+ );
+}
+
+void BspSparcLeon3ValFatalCacheSnoopingDisabledBoot_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+)
+{
+ BspSparcLeon3ValFatalCacheSnoopingDisabledBoot_Context *ctx;
+
+ ctx = &BspSparcLeon3ValFatalCacheSnoopingDisabledBoot_Instance;
+ ctx->source = source;
+ ctx->code = code;
+
+ ctx = T_case_begin(
+ "BspSparcLeon3ValFatalCacheSnoopingDisabledBoot",
+ &BspSparcLeon3ValFatalCacheSnoopingDisabledBoot_Fixture
+ );
+
+ T_plan( 2 );
+
+ BspSparcLeon3ValFatalCacheSnoopingDisabledBoot_Action_0( ctx );
+
+ T_case_end();
+}
+
+/** @} */
diff --git a/testsuites/validation/bsps/tr-fatal-sparc-leon3-cache-snooping-disabled-boot.h b/testsuites/validation/bsps/tr-fatal-sparc-leon3-cache-snooping-disabled-boot.h
new file mode 100644
index 0000000000..e375e6baac
--- /dev/null
+++ b/testsuites/validation/bsps/tr-fatal-sparc-leon3-cache-snooping-disabled-boot.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup BspSparcLeon3ValFatalCacheSnoopingDisabledBoot
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_FATAL_SPARC_LEON3_CACHE_SNOOPING_DISABLED_BOOT_H
+#define _TR_FATAL_SPARC_LEON3_CACHE_SNOOPING_DISABLED_BOOT_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup BspSparcLeon3ValFatalCacheSnoopingDisabledBoot
+ *
+ * @{
+ */
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param source is fatal source.
+ *
+ * @param code is fatal code.
+ */
+void BspSparcLeon3ValFatalCacheSnoopingDisabledBoot_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_FATAL_SPARC_LEON3_CACHE_SNOOPING_DISABLED_BOOT_H */
diff --git a/testsuites/validation/bsps/tr-fatal-sparc-leon3-cache-snooping-disabled-secondary.c b/testsuites/validation/bsps/tr-fatal-sparc-leon3-cache-snooping-disabled-secondary.c
new file mode 100644
index 0000000000..4d90abf42d
--- /dev/null
+++ b/testsuites/validation/bsps/tr-fatal-sparc-leon3-cache-snooping-disabled-secondary.c
@@ -0,0 +1,176 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <bsp/bootcard.h>
+#include <bsp/fatal.h>
+#include <bsp/leon3.h>
+
+#include "tr-fatal-sparc-leon3-cache-snooping-disabled-secondary.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary \
+ * spec:/bsp/sparc/leon3/val/fatal-cache-snooping-disabled-secondary
+ *
+ * @ingroup TestsuitesBspsFatalSparcLeon3CacheSnoopingDisabledSecondary
+ *
+ * @brief Tests a fatal error.
+ *
+ * This test case performs the following actions:
+ *
+ * - The test action is carried out by the wrapped
+ * bsp_start_on_secondary_processor() function.
+ *
+ * - Check that the expected fatal source is present.
+ *
+ * - Check that the expected fatal code is present.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for
+ * spec:/bsp/sparc/leon3/val/fatal-cache-snooping-disabled-secondary test
+ * case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a copy of the corresponding
+ * BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary_Run() parameter.
+ */
+ rtems_fatal_source source;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary_Run() parameter.
+ */
+ rtems_fatal_code code;
+} BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary_Context;
+
+static BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary_Context
+ BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary_Instance;
+
+void __real_bsp_start_on_secondary_processor( struct Per_CPU_Control *cpu_self );
+
+void __wrap_bsp_start_on_secondary_processor( struct Per_CPU_Control *cpu_self );
+
+void __wrap_bsp_start_on_secondary_processor( struct Per_CPU_Control *cpu_self )
+{
+ uint32_t control;
+
+ control = leon3_get_cache_control_register();
+ control &= ~LEON3_REG_CACHE_CTRL_DS;
+ leon3_set_cache_control_register( control );
+
+ __real_bsp_start_on_secondary_processor( cpu_self );
+}
+
+static T_fixture BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary_Instance
+};
+
+/**
+ * @brief The test action is carried out by the wrapped
+ * bsp_start_on_secondary_processor() function.
+ */
+static void BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary_Action_0(
+ BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary_Context *ctx
+)
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the expected fatal source is present.
+ */
+ T_step_eq_int( 0, ctx->source, RTEMS_FATAL_SOURCE_BSP );
+
+ /*
+ * Check that the expected fatal code is present.
+ */
+ T_step_eq_ulong(
+ 1,
+ ctx->code,
+ LEON3_FATAL_INVALID_CACHE_CONFIG_SECONDARY_PROCESSOR
+ );
+}
+
+void BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+)
+{
+ BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary_Context *ctx;
+
+ ctx = &BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary_Instance;
+ ctx->source = source;
+ ctx->code = code;
+
+ ctx = T_case_begin(
+ "BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary",
+ &BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary_Fixture
+ );
+
+ T_plan( 2 );
+
+ BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary_Action_0( ctx );
+
+ T_case_end();
+}
+
+/** @} */
diff --git a/testsuites/validation/bsps/tr-fatal-sparc-leon3-cache-snooping-disabled-secondary.h b/testsuites/validation/bsps/tr-fatal-sparc-leon3-cache-snooping-disabled-secondary.h
new file mode 100644
index 0000000000..0782942222
--- /dev/null
+++ b/testsuites/validation/bsps/tr-fatal-sparc-leon3-cache-snooping-disabled-secondary.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_FATAL_SPARC_LEON3_CACHE_SNOOPING_DISABLED_SECONDARY_H
+#define _TR_FATAL_SPARC_LEON3_CACHE_SNOOPING_DISABLED_SECONDARY_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary
+ *
+ * @{
+ */
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param source is fatal source.
+ *
+ * @param code is fatal code.
+ */
+void BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_FATAL_SPARC_LEON3_CACHE_SNOOPING_DISABLED_SECONDARY_H */
diff --git a/testsuites/validation/bsps/tr-fatal-sparc-leon3-clock-initialization.c b/testsuites/validation/bsps/tr-fatal-sparc-leon3-clock-initialization.c
new file mode 100644
index 0000000000..5cd81b736c
--- /dev/null
+++ b/testsuites/validation/bsps/tr-fatal-sparc-leon3-clock-initialization.c
@@ -0,0 +1,190 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup BspSparcLeon3ValFatalClockInitialization
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <bsp/fatal.h>
+#include <bsp/leon3.h>
+#include <rtems/irq-extension.h>
+#include <rtems/sysinit.h>
+
+#include "tr-fatal-sparc-leon3-clock-initialization.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup BspSparcLeon3ValFatalClockInitialization \
+ * spec:/bsp/sparc/leon3/val/fatal-clock-initialization
+ *
+ * @ingroup TestsuitesBspsFatalSparcLeon3ClockInitialization
+ *
+ * @brief Tests a fatal error.
+ *
+ * This test case performs the following actions:
+ *
+ * - The test action is carried out by the OccupyClockInterrupt() system
+ * initialization handler.
+ *
+ * - Check that the expected fatal source is present.
+ *
+ * - Check that the expected fatal code is present.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/bsp/sparc/leon3/val/fatal-clock-initialization
+ * test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a copy of the corresponding
+ * BspSparcLeon3ValFatalClockInitialization_Run() parameter.
+ */
+ rtems_fatal_source source;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * BspSparcLeon3ValFatalClockInitialization_Run() parameter.
+ */
+ rtems_fatal_code code;
+} BspSparcLeon3ValFatalClockInitialization_Context;
+
+static BspSparcLeon3ValFatalClockInitialization_Context
+ BspSparcLeon3ValFatalClockInitialization_Instance;
+
+static void ClockInterrupt( void *arg )
+{
+ (void) arg;
+}
+
+static rtems_interrupt_entry interrupt_entry = RTEMS_INTERRUPT_ENTRY_INITIALIZER(
+ ClockInterrupt,
+ NULL,
+ "Clock"
+);
+
+static void OccupyClockInterrupt( void )
+{
+ rtems_vector_number vector;
+
+ vector = GPTIMER_CONFIG_IRQ_GET( grlib_load_32( &LEON3_Timer_Regs->config ) );
+ (void) rtems_interrupt_entry_install(
+ vector,
+ RTEMS_INTERRUPT_UNIQUE,
+ &interrupt_entry
+ );
+}
+
+RTEMS_SYSINIT_ITEM(
+ OccupyClockInterrupt,
+ RTEMS_SYSINIT_DEVICE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_FIRST
+);
+
+static T_fixture BspSparcLeon3ValFatalClockInitialization_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &BspSparcLeon3ValFatalClockInitialization_Instance
+};
+
+/**
+ * @brief The test action is carried out by the OccupyClockInterrupt() system
+ * initialization handler.
+ */
+static void BspSparcLeon3ValFatalClockInitialization_Action_0(
+ BspSparcLeon3ValFatalClockInitialization_Context *ctx
+)
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the expected fatal source is present.
+ */
+ T_step_eq_int( 0, ctx->source, RTEMS_FATAL_SOURCE_BSP );
+
+ /*
+ * Check that the expected fatal code is present.
+ */
+ T_step_eq_ulong(
+ 1,
+ ctx->code,
+ LEON3_FATAL_CLOCK_INITIALIZATION
+ );
+}
+
+void BspSparcLeon3ValFatalClockInitialization_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+)
+{
+ BspSparcLeon3ValFatalClockInitialization_Context *ctx;
+
+ ctx = &BspSparcLeon3ValFatalClockInitialization_Instance;
+ ctx->source = source;
+ ctx->code = code;
+
+ ctx = T_case_begin(
+ "BspSparcLeon3ValFatalClockInitialization",
+ &BspSparcLeon3ValFatalClockInitialization_Fixture
+ );
+
+ T_plan( 2 );
+
+ BspSparcLeon3ValFatalClockInitialization_Action_0( ctx );
+
+ T_case_end();
+}
+
+/** @} */
diff --git a/testsuites/validation/bsps/tr-fatal-sparc-leon3-clock-initialization.h b/testsuites/validation/bsps/tr-fatal-sparc-leon3-clock-initialization.h
new file mode 100644
index 0000000000..6997b3f22c
--- /dev/null
+++ b/testsuites/validation/bsps/tr-fatal-sparc-leon3-clock-initialization.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup BspSparcLeon3ValFatalClockInitialization
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_FATAL_SPARC_LEON3_CLOCK_INITIALIZATION_H
+#define _TR_FATAL_SPARC_LEON3_CLOCK_INITIALIZATION_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup BspSparcLeon3ValFatalClockInitialization
+ *
+ * @{
+ */
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param source is fatal source.
+ *
+ * @param code is fatal code.
+ */
+void BspSparcLeon3ValFatalClockInitialization_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_FATAL_SPARC_LEON3_CLOCK_INITIALIZATION_H */
diff --git a/testsuites/validation/bsps/ts-fatal-clock-xil-ttc-irq-install.c b/testsuites/validation/bsps/ts-fatal-clock-xil-ttc-irq-install.c
new file mode 100644
index 0000000000..e5c1062348
--- /dev/null
+++ b/testsuites/validation/bsps/ts-fatal-clock-xil-ttc-irq-install.c
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesBspsFatalClockXilTtcIrqInstall
+ */
+
+/*
+ * Copyright (C) 2024 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-fatal-clock-xil-ttc-irq-install.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesBspsFatalClockXilTtcIrqInstall \
+ * spec:/testsuites/bsps/fatal-clock-xil-ttc-irq-install
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains a test case which triggers a
+ * fatal error during system initialization.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesBspsFatalClockXilTtcIrqInstall";
+
+#define FATAL_SYSINIT_RUN DevClockXilTtcValFatalIrqInstall_Run
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#include "ts-fatal-sysinit.h"
+
+/** @} */
diff --git a/testsuites/validation/bsps/ts-fatal-sparc-leon3-cache-snooping-disabled-boot.c b/testsuites/validation/bsps/ts-fatal-sparc-leon3-cache-snooping-disabled-boot.c
new file mode 100644
index 0000000000..53e18b5b0b
--- /dev/null
+++ b/testsuites/validation/bsps/ts-fatal-sparc-leon3-cache-snooping-disabled-boot.c
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesBspsFatalSparcLeon3CacheSnoopingDisabledBoot
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-fatal-sparc-leon3-cache-snooping-disabled-boot.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesBspsFatalSparcLeon3CacheSnoopingDisabledBoot \
+ * spec:/testsuites/bsps/fatal-sparc-leon3-cache-snooping-disabled-boot
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains a test case which triggers a
+ * fatal error during system initialization.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesBspsFatalSparcLeon3CacheSnoopingDisabledBoot";
+
+#define FATAL_SYSINIT_RUN BspSparcLeon3ValFatalCacheSnoopingDisabledBoot_Run
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#include "ts-fatal-sysinit.h"
+
+/** @} */
diff --git a/testsuites/validation/bsps/ts-fatal-sparc-leon3-cache-snooping-disabled-secondary.c b/testsuites/validation/bsps/ts-fatal-sparc-leon3-cache-snooping-disabled-secondary.c
new file mode 100644
index 0000000000..3b8829dcf9
--- /dev/null
+++ b/testsuites/validation/bsps/ts-fatal-sparc-leon3-cache-snooping-disabled-secondary.c
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesBspsFatalSparcLeon3CacheSnoopingDisabledSecondary
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-fatal-sparc-leon3-cache-snooping-disabled-secondary.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesBspsFatalSparcLeon3CacheSnoopingDisabledSecondary \
+ * spec:/testsuites/bsps/fatal-sparc-leon3-cache-snooping-disabled-secondary
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains a test case which triggers a
+ * fatal error during system initialization.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesBspsFatalSparcLeon3CacheSnoopingDisabledSecondary";
+
+#define FATAL_SYSINIT_RUN \
+ BspSparcLeon3ValFatalCacheSnoopingDisabledSecondary_Run
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 2
+
+#include "ts-fatal-sysinit.h"
+
+/** @} */
diff --git a/testsuites/validation/bsps/ts-fatal-sparc-leon3-clock-initialization.c b/testsuites/validation/bsps/ts-fatal-sparc-leon3-clock-initialization.c
new file mode 100644
index 0000000000..b75223537f
--- /dev/null
+++ b/testsuites/validation/bsps/ts-fatal-sparc-leon3-clock-initialization.c
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesBspsFatalSparcLeon3ClockInitialization
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-fatal-sparc-leon3-clock-initialization.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesBspsFatalSparcLeon3ClockInitialization \
+ * spec:/testsuites/bsps/fatal-sparc-leon3-clock-initialization
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains a test case which triggers a
+ * fatal error during system initialization.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesBspsFatalSparcLeon3ClockInitialization";
+
+#define FATAL_SYSINIT_RUN BspSparcLeon3ValFatalClockInitialization_Run
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+
+#include "ts-fatal-sysinit.h"
+
+/** @} */
diff --git a/testsuites/validation/bsps/ts-fatal-sparc-leon3-shutdown-response.c b/testsuites/validation/bsps/ts-fatal-sparc-leon3-shutdown-response.c
new file mode 100644
index 0000000000..d730b6d027
--- /dev/null
+++ b/testsuites/validation/bsps/ts-fatal-sparc-leon3-shutdown-response.c
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestSuiteTestsuitesFatalBspSparcLeon3ShutdownResponse
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/smpimpl.h>
+
+#include "tr-fatal-sparc-leon3-shutdown-response.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RTEMSTestSuiteTestsuitesFatalBspSparcLeon3ShutdownResponse \
+ * spec:/testsuites/fatal-sparc-leon3-shutdown-response
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains a test case which performs a
+ * system shutdown.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "FatalBspSparcLeon3ShutdownResponse";
+
+#define FATAL_SYSINIT_RUN BspSparcLeon3ValFatalShutdownResponse_Run
+
+static void FatalSysinitExit( rtems_fatal_code exit_code )
+{
+ if ( exit_code == 0 ) {
+ rtems_fatal( RTEMS_FATAL_SOURCE_SMP, SMP_FATAL_SHUTDOWN );
+ } else {
+ rtems_fatal( RTEMS_FATAL_SOURCE_EXIT, exit_code );
+ }
+}
+
+#define FATAL_SYSINIT_EXIT( exit_code ) FatalSysinitExit( exit_code )
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 2
+
+#include "ts-fatal-sysinit.h"
+
+/** @} */
diff --git a/testsuites/validation/bsps/ts-fatal-sparc-leon3-shutdown.c b/testsuites/validation/bsps/ts-fatal-sparc-leon3-shutdown.c
new file mode 100644
index 0000000000..bc229e7824
--- /dev/null
+++ b/testsuites/validation/bsps/ts-fatal-sparc-leon3-shutdown.c
@@ -0,0 +1,177 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesBspsFatalSparcLeon3Shutdown
+ */
+
+/*
+ * Copyright (C) 2021, 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <rtems/test-info.h>
+#include <rtems/test.h>
+#include <rtems/testopts.h>
+#include <rtems/score/smpimpl.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesBspsFatalSparcLeon3Shutdown \
+ * spec:/testsuites/bsps/fatal-sparc-leon3-shutdown
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite provides an application configuration to
+ * perform a shutdown.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesBspsFatalSparcLeon3Shutdown";
+
+static char buffer[ 512 ];
+
+static const T_action actions[] = {
+ T_report_hash_sha256
+};
+
+static const T_config test_config = {
+ .name = rtems_test_name,
+ .buf = buffer,
+ .buf_size = sizeof( buffer ),
+ .putchar = rtems_put_char,
+ .verbosity = RTEMS_TEST_VERBOSITY,
+ .now = T_now_tick,
+ .allocate = T_memory_allocate,
+ .deallocate = T_memory_deallocate,
+ .action_count = T_ARRAY_SIZE( actions ),
+ .actions = actions
+};
+
+void __real__CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr code );
+
+void __wrap__CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr code );
+
+void __wrap__CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr code )
+{
+ int exit_code;
+
+ T_register();
+ exit_code = T_main( &test_config );
+
+ if ( exit_code == 0 ) {
+ rtems_test_end( rtems_test_name );
+ }
+
+#if defined(RTEMS_GCOV_COVERAGE)
+ rtems_test_gcov_dump_info();
+#endif
+ __real__CPU_Fatal_halt( source, code );
+}
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#if defined(RTEMS_SMP)
+#define CONFIGURE_MAXIMUM_PROCESSORS 2
+
+#include <rtems/score/scheduleredfsmp.h>
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#include <rtems/scheduler.h>
+
+RTEMS_SCHEDULER_EDF_SMP( a );
+
+#define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
+ RTEMS_SCHEDULER_TABLE_EDF_SMP( a, TEST_SCHEDULER_A_NAME )
+
+#define CONFIGURE_SCHEDULER_ASSIGNMENTS \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY )
+#endif /* RTEMS_SMP */
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 1
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_IDLE_TASK_STORAGE_SIZE RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
+
+static void *ShutdownIdleBody( uintptr_t arg )
+{
+#if defined(RTEMS_SMP)
+ if ( rtems_scheduler_get_processor() == 0 ) {
+ rtems_test_begin( rtems_test_name, TEST_STATE );
+ rtems_fatal( RTEMS_FATAL_SOURCE_SMP, SMP_FATAL_SHUTDOWN );
+ }
+
+ return _CPU_Thread_Idle_body( arg );
+#else
+ rtems_test_begin( rtems_test_name, TEST_STATE );
+ rtems_fatal( RTEMS_FATAL_SOURCE_APPLICATION, 123 );
+#endif
+}
+
+#define CONFIGURE_IDLE_TASK_BODY ShutdownIdleBody
+
+#define CONFIGURE_INITIAL_EXTENSIONS { .fatal = FatalInitialExtension }
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
+
+/** @} */
diff --git a/testsuites/validation/bsps/ts-validation-bsp-0.c b/testsuites/validation/bsps/ts-validation-bsp-0.c
new file mode 100644
index 0000000000..c072c8fdf1
--- /dev/null
+++ b/testsuites/validation/bsps/ts-validation-bsp-0.c
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesBspsValidationBsp0
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesBspsValidationBsp0 \
+ * spec:/testsuites/bsps/validation-bsp-0
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This general purpose validation test suite provides enough resources
+ * to run target-specific tests.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesBspsValidationBsp0";
+
+#include "ts-default.h"
+
+/** @} */
diff --git a/testsuites/validation/tc-acfg-appl-does-not-need-clock-driver.c b/testsuites/validation/tc-acfg-appl-does-not-need-clock-driver.c
new file mode 100644
index 0000000000..632ce8f164
--- /dev/null
+++ b/testsuites/validation/tc-acfg-appl-does-not-need-clock-driver.c
@@ -0,0 +1,130 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup AcfgValApplDoesNotNeedClockDriver
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup AcfgValApplDoesNotNeedClockDriver \
+ * spec:/acfg/val/appl-does-not-need-clock-driver
+ *
+ * @ingroup TestsuitesValidationAcfg0
+ *
+ * @brief Tests the effect of the
+ * CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER application configuration
+ * option.
+ *
+ * This test case performs the following actions:
+ *
+ * - Get the current clock ticks since boot value. Busy wait for at least one
+ * clock tick interval.
+ *
+ * - Check that the clock ticks since boot count did not change while busy
+ * waiting for more than one clock tick interval.
+ *
+ * @{
+ */
+
+/**
+ * @brief Get the current clock ticks since boot value. Busy wait for at least
+ * one clock tick interval.
+ */
+static void AcfgValApplDoesNotNeedClockDriver_Action_0( void )
+{
+ T_time time_per_clock_tick;
+ T_ticks duration;
+ T_ticks elapsed;
+ T_ticks t0;
+ T_ticks t1;
+ rtems_interval ticks_since_boot;
+
+ ticks_since_boot = rtems_clock_get_ticks_since_boot();
+
+ time_per_clock_tick = T_seconds_and_nanoseconds_to_time(
+ 0,
+ rtems_configuration_get_nanoseconds_per_tick()
+ );
+ duration = 2 * T_time_to_ticks( time_per_clock_tick );
+ elapsed = 0;
+ t0 = T_tick();
+
+ while ( elapsed < duration ) {
+ t1 = T_tick();
+ elapsed += t1 - t0;
+ t0 = t1;
+ }
+
+ /*
+ * Check that the clock ticks since boot count did not change while busy
+ * waiting for more than one clock tick interval.
+ */
+ T_step_eq_u32(
+ 0,
+ rtems_clock_get_ticks_since_boot(),
+ ticks_since_boot
+ );
+}
+
+/**
+ * @fn void T_case_body_AcfgValApplDoesNotNeedClockDriver( void )
+ */
+T_TEST_CASE( AcfgValApplDoesNotNeedClockDriver )
+{
+ T_plan( 1 );
+
+ AcfgValApplDoesNotNeedClockDriver_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-acfg-appl-needs-clock-driver.c b/testsuites/validation/tc-acfg-appl-needs-clock-driver.c
new file mode 100644
index 0000000000..fe62dd7de6
--- /dev/null
+++ b/testsuites/validation/tc-acfg-appl-needs-clock-driver.c
@@ -0,0 +1,128 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup AcfgValApplNeedsClockDriver
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup AcfgValApplNeedsClockDriver spec:/acfg/val/appl-needs-clock-driver
+ *
+ * @ingroup TestsuitesValidation0
+ *
+ * @brief Tests the effect of the CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+ * application configuration option.
+ *
+ * This test case performs the following actions:
+ *
+ * - Get the current clock ticks since boot value. Busy wait for at least one
+ * clock tick interval.
+ *
+ * - Check that the clock ticks since boot count changed while busy waiting
+ * for more than one clock tick interval.
+ *
+ * @{
+ */
+
+/**
+ * @brief Get the current clock ticks since boot value. Busy wait for at least
+ * one clock tick interval.
+ */
+static void AcfgValApplNeedsClockDriver_Action_0( void )
+{
+ T_time time_per_clock_tick;
+ T_ticks duration;
+ T_ticks elapsed;
+ T_ticks t0;
+ T_ticks t1;
+ rtems_interval ticks_since_boot;
+
+ ticks_since_boot = rtems_clock_get_ticks_since_boot();
+
+ time_per_clock_tick = T_seconds_and_nanoseconds_to_time(
+ 0,
+ rtems_configuration_get_nanoseconds_per_tick()
+ );
+ duration = 2 * T_time_to_ticks( time_per_clock_tick );
+ elapsed = 0;
+ t0 = T_tick();
+
+ while ( elapsed < duration ) {
+ t1 = T_tick();
+ elapsed += t1 - t0;
+ t0 = t1;
+ }
+
+ /*
+ * Check that the clock ticks since boot count changed while busy waiting for
+ * more than one clock tick interval.
+ */
+ T_step_gt_u32(
+ 0,
+ rtems_clock_get_ticks_since_boot() - ticks_since_boot,
+ 0
+ );
+}
+
+/**
+ * @fn void T_case_body_AcfgValApplNeedsClockDriver( void )
+ */
+T_TEST_CASE( AcfgValApplNeedsClockDriver )
+{
+ T_plan( 1 );
+
+ AcfgValApplNeedsClockDriver_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-acfg-default.c b/testsuites/validation/tc-acfg-default.c
new file mode 100644
index 0000000000..bc23363c49
--- /dev/null
+++ b/testsuites/validation/tc-acfg-default.c
@@ -0,0 +1,398 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup AcfgValDefault
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <bsp.h>
+#include <string.h>
+#include <rtems/score/userextdata.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup AcfgValDefault spec:/acfg/val/default
+ *
+ * @ingroup TestsuitesValidationAcfg0
+ *
+ * @brief Tests the default values of application configuration options.
+ *
+ * This test case performs the following actions:
+ *
+ * - Check the effect of application configuration options with optional
+ * BSP-provided settings.
+ *
+ * - Check the configured CONFIGURE_IDLE_TASK_BODY.
+ *
+ * - Check the default value of CONFIGURE_IDLE_TASK_STACK_SIZE where the
+ * optional BSP-provided default value is enabled.
+ *
+ * - Check the default value of CONFIGURE_INTERRUPT_STACK_SIZE where the
+ * optional BSP-provided default value is enabled.
+ *
+ * - Check the BSP-provided initial extension is registered.
+ *
+ * - Try to create a barrier.
+ *
+ * - Check that the returned status code is RTEMS_TOO_MANY.
+ *
+ * - Try to construct a message queue.
+ *
+ * - Check that the returned status code is RTEMS_TOO_MANY.
+ *
+ * - Try to create a partition.
+ *
+ * - Check that the returned status code is RTEMS_TOO_MANY.
+ *
+ * - Try to create a period.
+ *
+ * - Check that the returned status code is RTEMS_TOO_MANY.
+ *
+ * - Check that the processor maximum is one.
+ *
+ * - Try to create a semaphore.
+ *
+ * - Check that the returned status code is RTEMS_TOO_MANY.
+ *
+ * - Try to construct a task.
+ *
+ * - Check that the returned status code is RTEMS_TOO_MANY.
+ *
+ * - Check the default CONFIGURE_MAXIMUM_TASKS value. A maximum Classic API
+ * task value of zero is only configurable if
+ * CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION is defined or
+ * CONFIGURE_MAXIMUM_POSIX_THREADS is set to a positive value. The default
+ * value of zero for CONFIGURE_MAXIMUM_POSIX_THREADS is used by the test
+ * suite containing the test case. The test suite defines
+ * CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION.
+ *
+ * - Try to create a timer.
+ *
+ * - Check that the returned status code is RTEMS_TOO_MANY.
+ *
+ * - Try to create a user extension set.
+ *
+ * - Check that the returned status code is RTEMS_TOO_MANY.
+ *
+ * @{
+ */
+
+#define NAME rtems_build_name( 'N', 'A', 'M', 'E' )
+
+RTEMS_ALIGNED(RTEMS_TASK_STORAGE_ALIGNMENT) static char task_storage[
+ RTEMS_TASK_STORAGE_SIZE(
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_ATTRIBUTES
+ )
+];
+
+static const rtems_task_config task_config = {
+ .name = NAME,
+ .initial_priority = 1,
+ .storage_area = task_storage,
+ .storage_size = sizeof( task_storage ),
+ .maximum_thread_local_storage_size = 0,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = RTEMS_DEFAULT_ATTRIBUTES
+};
+
+/**
+ * @brief Check the effect of application configuration options with optional
+ * BSP-provided settings.
+ */
+static void AcfgValDefault_Action_0( void )
+{
+ rtems_extensions_table bsp = BSP_INITIAL_EXTENSION;
+
+ /*
+ * Check the configured CONFIGURE_IDLE_TASK_BODY.
+ */
+ T_step_eq_ptr( 0, rtems_configuration_get_idle_task(), IdleBody );
+
+ /*
+ * Check the default value of CONFIGURE_IDLE_TASK_STACK_SIZE where the
+ * optional BSP-provided default value is enabled.
+ */
+ T_step_eq_sz(
+ 1,
+ rtems_configuration_get_idle_task_stack_size(),
+ #if defined(BSP_IDLE_TASK_STACK_SIZE)
+ BSP_IDLE_TASK_STACK_SIZE
+ #else
+ CPU_STACK_MINIMUM_SIZE
+ #endif
+ );
+
+ /*
+ * Check the default value of CONFIGURE_INTERRUPT_STACK_SIZE where the
+ * optional BSP-provided default value is enabled.
+ */
+ T_step_eq_sz(
+ 2,
+ rtems_configuration_get_interrupt_stack_size(),
+ #if defined(BSP_INTERRUPT_STACK_SIZE)
+ BSP_INTERRUPT_STACK_SIZE
+ #else
+ CPU_STACK_MINIMUM_SIZE
+ #endif
+ );
+
+ /*
+ * Check the BSP-provided initial extension is registered.
+ */
+ T_step_eq_sz( 3, _User_extensions_Initial_count, 1 );
+ T_step_eq_ptr(
+ 4,
+ _User_extensions_Initial_extensions[ 0 ].fatal,
+ bsp.fatal
+ );
+}
+
+/**
+ * @brief Try to create a barrier.
+ */
+static void AcfgValDefault_Action_1( void )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ sc = rtems_barrier_create(
+ NAME,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ 1,
+ &id
+ );
+
+ /*
+ * Check that the returned status code is RTEMS_TOO_MANY.
+ */
+ T_step_rsc( 5, sc, RTEMS_TOO_MANY );
+}
+
+/**
+ * @brief Try to construct a message queue.
+ */
+static void AcfgValDefault_Action_2( void )
+{
+ rtems_message_queue_config config;
+ RTEMS_MESSAGE_QUEUE_BUFFER( 1 ) buffers[ 1 ];
+ rtems_status_code sc;
+ rtems_id id;
+
+ memset( &config, 0, sizeof( config ) );
+ config.name = NAME;
+ config.maximum_pending_messages = 1;
+ config.maximum_message_size = 1;
+ config.storage_size = sizeof( buffers );
+ config.storage_area = buffers;
+ config.attributes = RTEMS_DEFAULT_ATTRIBUTES;
+
+ sc = rtems_message_queue_construct( &config, &id );
+
+ /*
+ * Check that the returned status code is RTEMS_TOO_MANY.
+ */
+ T_step_rsc( 6, sc, RTEMS_TOO_MANY );
+}
+
+/**
+ * @brief Try to create a partition.
+ */
+static void AcfgValDefault_Action_3( void )
+{
+ RTEMS_ALIGNED( RTEMS_PARTITION_ALIGNMENT ) uint8_t buffers[ 1 ][ 32 ];
+ rtems_status_code sc;
+ rtems_id id;
+
+ sc = rtems_partition_create(
+ NAME,
+ buffers,
+ sizeof( buffers ),
+ sizeof( buffers[ 0 ] ),
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &id
+ );
+
+ /*
+ * Check that the returned status code is RTEMS_TOO_MANY.
+ */
+ T_step_rsc( 7, sc, RTEMS_TOO_MANY );
+}
+
+/**
+ * @brief Try to create a period.
+ */
+static void AcfgValDefault_Action_4( void )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ sc = rtems_rate_monotonic_create( NAME, &id );
+
+ /*
+ * Check that the returned status code is RTEMS_TOO_MANY.
+ */
+ T_step_rsc( 8, sc, RTEMS_TOO_MANY );
+}
+
+/**
+ * @brief Check that the processor maximum is one.
+ */
+static void AcfgValDefault_Action_5( void )
+{
+ T_step_eq_u32( 9, rtems_scheduler_get_processor_maximum(), 1 );
+}
+
+/**
+ * @brief Try to create a semaphore.
+ */
+static void AcfgValDefault_Action_6( void )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ sc = rtems_semaphore_create(
+ NAME,
+ 0,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ 0,
+ &id
+ );
+
+ /*
+ * Check that the returned status code is RTEMS_TOO_MANY.
+ */
+ T_step_rsc( 10, sc, RTEMS_TOO_MANY );
+}
+
+/**
+ * @brief Try to construct a task.
+ */
+static void AcfgValDefault_Action_7( void )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ sc = rtems_task_construct( &task_config, &id );
+
+ /*
+ * Check that the returned status code is RTEMS_TOO_MANY.
+ */
+ T_step_rsc( 11, sc, RTEMS_TOO_MANY );
+
+ /*
+ * Check the default CONFIGURE_MAXIMUM_TASKS value. A maximum Classic API
+ * task value of zero is only configurable if
+ * CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION is defined or
+ * CONFIGURE_MAXIMUM_POSIX_THREADS is set to a positive value. The default
+ * value of zero for CONFIGURE_MAXIMUM_POSIX_THREADS is used by the test
+ * suite containing the test case. The test suite defines
+ * CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION.
+ */
+ T_step_eq_u32( 12, rtems_configuration_get_maximum_tasks(), 0 );
+}
+
+/**
+ * @brief Try to create a timer.
+ */
+static void AcfgValDefault_Action_8( void )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ sc = rtems_timer_create( NAME, &id );
+
+ /*
+ * Check that the returned status code is RTEMS_TOO_MANY.
+ */
+ T_step_rsc( 13, sc, RTEMS_TOO_MANY );
+}
+
+/**
+ * @brief Try to create a user extension set.
+ */
+static void AcfgValDefault_Action_9( void )
+{
+ rtems_extensions_table table;
+ rtems_status_code sc;
+ rtems_id id;
+
+ memset( &table, 0, sizeof( table ) );
+ sc = rtems_extension_create( NAME, &table, &id );
+
+ /*
+ * Check that the returned status code is RTEMS_TOO_MANY.
+ */
+ T_step_rsc( 14, sc, RTEMS_TOO_MANY );
+}
+
+/**
+ * @fn void T_case_body_AcfgValDefault( void )
+ */
+T_TEST_CASE( AcfgValDefault )
+{
+ T_plan( 15 );
+
+ AcfgValDefault_Action_0();
+ AcfgValDefault_Action_1();
+ AcfgValDefault_Action_2();
+ AcfgValDefault_Action_3();
+ AcfgValDefault_Action_4();
+ AcfgValDefault_Action_5();
+ AcfgValDefault_Action_6();
+ AcfgValDefault_Action_7();
+ AcfgValDefault_Action_8();
+ AcfgValDefault_Action_9();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-acfg-disabled-bsp-settings.c b/testsuites/validation/tc-acfg-disabled-bsp-settings.c
new file mode 100644
index 0000000000..acd5d454e3
--- /dev/null
+++ b/testsuites/validation/tc-acfg-disabled-bsp-settings.c
@@ -0,0 +1,140 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup AcfgValDisabledBspSettings
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <bsp.h>
+#include <rtems/score/userextdata.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup AcfgValDisabledBspSettings spec:/acfg/val/disabled-bsp-settings
+ *
+ * @ingroup TestsuitesValidationAcfg1
+ *
+ * @brief Tests the default values of application configuration options where
+ * all optional BSP provided settings are disabled.
+ *
+ * This test case performs the following actions:
+ *
+ * - Check the effect of application configuration options with optional
+ * BSP-provided settings.
+ *
+ * - Check the default value CONFIGURE_IDLE_TASK_BODY where the optional
+ * BSP-provided default value is disabled.
+ *
+ * - Check the default value CONFIGURE_IDLE_TASK_STACK_SIZE where the
+ * optional BSP-provided default value is disabled.
+ *
+ * - Check the default value CONFIGURE_INTERRUPT_STACK_SIZE where the
+ * optional BSP-provided default value is disabled.
+ *
+ * - Check the BSP-provided initial extension is not registered.
+ *
+ * @{
+ */
+
+/**
+ * @brief Check the effect of application configuration options with optional
+ * BSP-provided settings.
+ */
+static void AcfgValDisabledBspSettings_Action_0( void )
+{
+ rtems_extensions_table bsp = BSP_INITIAL_EXTENSION;
+
+ /*
+ * Check the default value CONFIGURE_IDLE_TASK_BODY where the optional
+ * BSP-provided default value is disabled.
+ */
+ T_eq_ptr(
+ rtems_configuration_get_idle_task(),
+ _CPU_Thread_Idle_body
+ );
+
+ /*
+ * Check the default value CONFIGURE_IDLE_TASK_STACK_SIZE where the optional
+ * BSP-provided default value is disabled.
+ */
+ T_eq_sz(
+ rtems_configuration_get_idle_task_stack_size(),
+ CPU_STACK_MINIMUM_SIZE
+ );
+
+ /*
+ * Check the default value CONFIGURE_INTERRUPT_STACK_SIZE where the optional
+ * BSP-provided default value is disabled.
+ */
+ T_eq_sz(
+ rtems_configuration_get_interrupt_stack_size(),
+ CPU_STACK_MINIMUM_SIZE
+ );
+
+ /*
+ * Check the BSP-provided initial extension is not registered.
+ */
+ T_eq_sz( _User_extensions_Initial_count, 1 );
+ T_ne_ptr(
+ _User_extensions_Initial_extensions[ 0 ].fatal,
+ bsp.fatal
+ );
+}
+
+/**
+ * @fn void T_case_body_AcfgValDisabledBspSettings( void )
+ */
+T_TEST_CASE( AcfgValDisabledBspSettings )
+{
+ AcfgValDisabledBspSettings_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-acfg-one-cpu.c b/testsuites/validation/tc-acfg-one-cpu.c
new file mode 100644
index 0000000000..8806e11b4e
--- /dev/null
+++ b/testsuites/validation/tc-acfg-one-cpu.c
@@ -0,0 +1,156 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup AcfgValOneCpu
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/score/schedulerpriority.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup AcfgValOneCpu spec:/acfg/val/one-cpu
+ *
+ * @ingroup TestsuitesValidationOneCpu0
+ *
+ * @brief Tests the effect of application configuration options.
+ *
+ * This test case performs the following actions:
+ *
+ * - Check the effect of application configuration options.
+ *
+ * - Check that the CONFIGURE_MAXIMUM_PRIORITY application configuration
+ * option resulted in the expected system setting using
+ * spec:/rtems/task/if/maximum-priority.
+ *
+ * - Check that the Deterministic Priority Scheduler which was configured by
+ * the CONFIGURE_SCHEDULER_PRIORITY application configuration in the test
+ * suite.
+ *
+ * - Check that we are able to identify the scheduler by the name configured
+ * by the CONFIGURE_SCHEDULER_PRIORITY application configuration option in
+ * the test suite.
+ *
+ * @{
+ */
+
+static uint32_t yield_count;
+
+void __real__Scheduler_priority_Yield(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+);
+
+void __wrap__Scheduler_priority_Yield(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+);
+
+void __wrap__Scheduler_priority_Yield(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+)
+{
+ ++yield_count;
+ __real__Scheduler_priority_Yield( scheduler, thread, node );
+}
+
+/**
+ * @brief Check the effect of application configuration options.
+ */
+static void AcfgValOneCpu_Action_0( void )
+{
+ rtems_status_code sc;
+ rtems_id id;
+ uint32_t yield_count_before;
+
+ /*
+ * Check that the CONFIGURE_MAXIMUM_PRIORITY application configuration option
+ * resulted in the expected system setting using
+ * spec:/rtems/task/if/maximum-priority.
+ */
+ T_eq_u32( RTEMS_MAXIMUM_PRIORITY, 127 );
+
+ /*
+ * Check that the Deterministic Priority Scheduler which was configured by
+ * the CONFIGURE_SCHEDULER_PRIORITY application configuration in the test
+ * suite.
+ */
+ yield_count_before = yield_count;
+ sc = rtems_task_wake_after( RTEMS_YIELD_PROCESSOR );
+ T_rsc_success( sc );
+ T_eq_u32( yield_count, yield_count_before + 1 );
+
+ /*
+ * Check that we are able to identify the scheduler by the name configured by
+ * the CONFIGURE_SCHEDULER_PRIORITY application configuration option in the
+ * test suite.
+ */
+ sc = rtems_scheduler_ident( TEST_SCHEDULER_A_NAME, &id );
+ T_rsc_success( sc );
+}
+
+/**
+ * @fn void T_case_body_AcfgValOneCpu( void )
+ */
+T_TEST_CASE( AcfgValOneCpu )
+{
+ AcfgValOneCpu_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-acfg-scheduler-edf-smp.c b/testsuites/validation/tc-acfg-scheduler-edf-smp.c
new file mode 100644
index 0000000000..bbd974a588
--- /dev/null
+++ b/testsuites/validation/tc-acfg-scheduler-edf-smp.c
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup AcfgValSchedulerEdfSmp
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/score/scheduleredfsmp.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup AcfgValSchedulerEdfSmp spec:/acfg/val/scheduler-edf-smp
+ *
+ * @ingroup TestsuitesValidationSmpOnly0
+ *
+ * @brief Tests the effect of application configuration options.
+ *
+ * This test case performs the following actions:
+ *
+ * - Check the effect of application configuration options.
+ *
+ * - Check that the Earliest Deadline First SMP Scheduler which was
+ * configured by the CONFIGURE_SCHEDULER_EDF_SMP application configuration
+ * in the test suite.
+ *
+ * @{
+ */
+
+static uint32_t yield_count;
+
+void __real__Scheduler_EDF_SMP_Yield(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+);
+
+void __wrap__Scheduler_EDF_SMP_Yield(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+);
+
+void __wrap__Scheduler_EDF_SMP_Yield(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+)
+{
+ ++yield_count;
+ __real__Scheduler_EDF_SMP_Yield( scheduler, thread, node );
+}
+
+/**
+ * @brief Check the effect of application configuration options.
+ */
+static void AcfgValSchedulerEdfSmp_Action_0( void )
+{
+ rtems_status_code sc;
+ uint32_t yield_count_before;
+
+ /*
+ * Check that the Earliest Deadline First SMP Scheduler which was configured
+ * by the CONFIGURE_SCHEDULER_EDF_SMP application configuration in the test
+ * suite.
+ */
+ yield_count_before = yield_count;
+ sc = rtems_task_wake_after( RTEMS_YIELD_PROCESSOR );
+ T_rsc_success( sc );
+ T_eq_u32( yield_count, yield_count_before + 1 );
+}
+
+/**
+ * @fn void T_case_body_AcfgValSchedulerEdfSmp( void )
+ */
+T_TEST_CASE( AcfgValSchedulerEdfSmp )
+{
+ AcfgValSchedulerEdfSmp_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-acfg-scheduler-table-entries-one-cpu.c b/testsuites/validation/tc-acfg-scheduler-table-entries-one-cpu.c
new file mode 100644
index 0000000000..48db6c4244
--- /dev/null
+++ b/testsuites/validation/tc-acfg-scheduler-table-entries-one-cpu.c
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup AcfgValSchedulerTableEntriesOneCpu
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup AcfgValSchedulerTableEntriesOneCpu \
+ * spec:/acfg/val/scheduler-table-entries-one-cpu
+ *
+ * @ingroup TestsuitesValidationOneCpu1
+ *
+ * @brief Tests the effect of CONFIGURE_SCHEDULER_TABLE_ENTRIES the application
+ * configuration options in a configuration with only one processor.
+ *
+ * This test case performs the following actions:
+ *
+ * - Check the effect of the application configuration option.
+ *
+ * - Check that the CONFIGURE_SCHEDULER_TABLE_ENTRIES application
+ * configuration option resulted in the expected system setting using
+ * RTEMS_MAXIMUM_PRIORITY.
+ *
+ * @{
+ */
+
+/**
+ * @brief Check the effect of the application configuration option.
+ */
+static void AcfgValSchedulerTableEntriesOneCpu_Action_0( void )
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the CONFIGURE_SCHEDULER_TABLE_ENTRIES application configuration
+ * option resulted in the expected system setting using
+ * RTEMS_MAXIMUM_PRIORITY.
+ */
+ T_eq_u32( RTEMS_MAXIMUM_PRIORITY, 63 );
+}
+
+/**
+ * @fn void T_case_body_AcfgValSchedulerTableEntriesOneCpu( void )
+ */
+T_TEST_CASE( AcfgValSchedulerTableEntriesOneCpu )
+{
+ AcfgValSchedulerTableEntriesOneCpu_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-acfg.c b/testsuites/validation/tc-acfg.c
new file mode 100644
index 0000000000..60f32ad929
--- /dev/null
+++ b/testsuites/validation/tc-acfg.c
@@ -0,0 +1,415 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup AcfgValAcfg
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <bsp.h>
+#include <rtems/confdefs.h>
+#include <rtems/score/heap.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup AcfgValAcfg spec:/acfg/val/acfg
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests the effect of application configuration options.
+ *
+ * This test case performs the following actions:
+ *
+ * - Check the effect of application configuration options. In addition, this
+ * test case validates the effect of CONFIGURE_INIT. The test case includes
+ * rtems/confdefs.h without defining CONFIGURE_INIT before the include. If
+ * this header would define configuration data structures, then linking the
+ * test suite executable would result in multiple definition errors. This
+ * header is included in the test suite runner translation unit while
+ * CONFIGURE_INIT is defined before the include. If this would not result in
+ * the definition of application defined configuration data structures, then
+ * the checks below for non-default settings would fail.
+ *
+ * - Check the default value CONFIGURE_IDLE_TASK_BODY where the optional
+ * BSP-provided default value is enabled.
+ *
+ * - Check the configured CONFIGURE_INIT_TASK_ARGUMENTS. This validates also
+ * the effect of CONFIGURE_INIT_TASK_ENTRY_POINT and
+ * CONFIGURE_RTEMS_INIT_TASKS_TABLE.
+ *
+ * - Check the configured CONFIGURE_INIT_TASK_INITIAL_MODES.
+ *
+ * - Check the configured CONFIGURE_INIT_TASK_NAME.
+ *
+ * - Check the configured CONFIGURE_INIT_TASK_PRIORITY. A priority of zero
+ * can only be set for system tasks. This validates also
+ * CONFIGURE_INIT_TASK_ATTRIBUTES.
+ *
+ * - Check that the configured
+ * CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE value reduced the
+ * stack space size.
+ *
+ * - Check the configured CONFIGURE_MAXIMUM_BARRIERS value.
+ *
+ * - Check the configured CONFIGURE_MAXIMUM_USER_EXTENSIONS value.
+ *
+ * - Check the configured CONFIGURE_MAXIMUM_MESSAGE_QUEUES value.
+ *
+ * - Check the configured CONFIGURE_MAXIMUM_PARTITIONS value.
+ *
+ * - Check the configured CONFIGURE_MAXIMUM_PERIODS value.
+ *
+ * - Check the default CONFIGURE_MAXIMUM_PORTS value.
+ *
+ * - Check the configured CONFIGURE_MAXIMUM_PROCESSORS value.
+ *
+ * - Check the default CONFIGURE_MAXIMUM_REGIONS value.
+ *
+ * - Check the configured CONFIGURE_MAXIMUM_SEMAPHORES value.
+ *
+ * - Check the configured CONFIGURE_MAXIMUM_TASKS value.
+ *
+ * - Check the configured CONFIGURE_MAXIMUM_TIMERS value.
+ *
+ * - Check the configured CONFIGURE_MICROSECONDS_PER_TICK value in
+ * microseconds.
+ *
+ * - Check the configured CONFIGURE_MICROSECONDS_PER_TICK value in
+ * milliseconds.
+ *
+ * - Check the configured CONFIGURE_MICROSECONDS_PER_TICK value in
+ * nanoseconds.
+ *
+ * - Check the configured CONFIGURE_TASK_STACK_ALLOCATOR hook. Using the
+ * test stack allocator validates also
+ * spec:/acfg/if/init-task-construct-storage-size, since the
+ * test_task_stack_allocate() allocate handler only supports
+ * CONFIGURE_MAXIMUM_TASKS minus one stacks and the validation test for
+ * spec:/rtems/task/req/create-errors creates for some pre-condition
+ * variants all tasks until RTEMS_TOO_MANY is returned. In addition,
+ * test_task_stack_allocate() checks that the allocation size is greater
+ * than or equal to TEST_MINIMUM_STACK_SIZE which validates
+ * CONFIGURE_MINIMUM_TASK_STACK_SIZE.
+ *
+ * - Check the configured CONFIGURE_TASK_STACK_ALLOCATOR_AVOIDS_WORK_SPACE
+ * value.
+ *
+ * - Check the configured CONFIGURE_TASK_STACK_DEALLOCATOR hook.
+ *
+ * - Check the configured CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE hook.
+ *
+ * - Check the configured CONFIGURE_IDLE_TASK_STACK_SIZE value.
+ *
+ * - Check the configured CONFIGURE_INTERRUPT_STACK_SIZE value.
+ *
+ * - Check the configured CONFIGURE_TICKS_PER_TIMESLICE value.
+ *
+ * @{
+ */
+
+/**
+ * @brief Check the effect of application configuration options. In addition,
+ * this test case validates the effect of CONFIGURE_INIT. The test case
+ * includes rtems/confdefs.h without defining CONFIGURE_INIT before the
+ * include. If this header would define configuration data structures, then
+ * linking the test suite executable would result in multiple definition
+ * errors. This header is included in the test suite runner translation unit
+ * while CONFIGURE_INIT is defined before the include. If this would not
+ * result in the definition of application defined configuration data
+ * structures, then the checks below for non-default settings would fail.
+ */
+static void AcfgValAcfg_Action_0( void )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ /*
+ * Check the default value CONFIGURE_IDLE_TASK_BODY where the optional
+ * BSP-provided default value is enabled.
+ */
+ T_eq_ptr(
+ rtems_configuration_get_idle_task(),
+ #if defined(BSP_IDLE_TASK_BODY)
+ BSP_IDLE_TASK_BODY
+ #else
+ _CPU_Thread_Idle_body
+ #endif
+ );
+
+ /*
+ * Check the configured CONFIGURE_INIT_TASK_ARGUMENTS. This validates also
+ * the effect of CONFIGURE_INIT_TASK_ENTRY_POINT and
+ * CONFIGURE_RTEMS_INIT_TASKS_TABLE.
+ */
+ T_eq_ulong( test_runner_argument, TEST_RUNNER_ARGUMENT );
+
+ /*
+ * Check the configured CONFIGURE_INIT_TASK_INITIAL_MODES.
+ */
+ T_eq_u32( test_runner_initial_modes, TEST_RUNNER_INITIAL_MODES );
+
+ /*
+ * Check the configured CONFIGURE_INIT_TASK_NAME.
+ */
+ sc = rtems_task_ident( TEST_RUNNER_NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc_success( sc );
+ T_eq_u32( id, rtems_task_self() );
+
+ /*
+ * Check the configured CONFIGURE_INIT_TASK_PRIORITY. A priority of zero can
+ * only be set for system tasks. This validates also
+ * CONFIGURE_INIT_TASK_ATTRIBUTES.
+ */
+ T_eq_u32( test_runner_initial_priority, 0 );
+
+ /*
+ * Check that the configured
+ * CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE value reduced the stack
+ * space size.
+ */
+ T_eq_uptr(
+ _Stack_Space_size,
+ RTEMS_ALIGN_UP( HEAP_BLOCK_HEADER_SIZE, CPU_HEAP_ALIGNMENT )
+ );
+
+ /*
+ * Check the configured CONFIGURE_MAXIMUM_BARRIERS value.
+ */
+ T_eq_u32(
+ rtems_configuration_get_maximum_barriers(),
+ TEST_MAXIMUM_BARRIERS
+ );
+
+ /*
+ * Check the configured CONFIGURE_MAXIMUM_USER_EXTENSIONS value.
+ */
+ T_eq_u32(
+ rtems_configuration_get_maximum_extensions(),
+ TEST_MAXIMUM_USER_EXTENSIONS
+ );
+
+ /*
+ * Check the configured CONFIGURE_MAXIMUM_MESSAGE_QUEUES value.
+ */
+ T_eq_u32(
+ rtems_configuration_get_maximum_message_queues(),
+ TEST_MAXIMUM_MESSAGE_QUEUES
+ );
+
+ /*
+ * Check the configured CONFIGURE_MAXIMUM_PARTITIONS value.
+ */
+ T_eq_u32(
+ rtems_configuration_get_maximum_partitions(),
+ TEST_MAXIMUM_PARTITIONS
+ );
+
+ /*
+ * Check the configured CONFIGURE_MAXIMUM_PERIODS value.
+ */
+ T_eq_u32(
+ rtems_configuration_get_maximum_periods(),
+ TEST_MAXIMUM_PERIODS
+ );
+
+ /*
+ * Check the default CONFIGURE_MAXIMUM_PORTS value.
+ */
+ T_eq_u32(
+ rtems_configuration_get_maximum_ports(),
+ 0
+ );
+
+ /*
+ * Check the configured CONFIGURE_MAXIMUM_PROCESSORS value.
+ */
+ T_eq_u32(
+ rtems_configuration_get_maximum_processors(),
+ #if defined(RTEMS_SMP)
+ 5
+ #else
+ 1
+ #endif
+ );
+
+ /*
+ * Check the default CONFIGURE_MAXIMUM_REGIONS value.
+ */
+ T_eq_u32(
+ rtems_configuration_get_maximum_regions(),
+ 0
+ );
+
+ /*
+ * Check the configured CONFIGURE_MAXIMUM_SEMAPHORES value.
+ */
+ T_eq_u32(
+ rtems_configuration_get_maximum_semaphores(),
+ TEST_MAXIMUM_SEMAPHORES
+ );
+
+ /*
+ * Check the configured CONFIGURE_MAXIMUM_TASKS value.
+ */
+ T_eq_u32(
+ rtems_configuration_get_maximum_tasks(),
+ TEST_MAXIMUM_TASKS
+ );
+
+ /*
+ * Check the configured CONFIGURE_MAXIMUM_TIMERS value.
+ */
+ T_eq_u32(
+ rtems_configuration_get_maximum_timers(),
+ TEST_MAXIMUM_TIMERS
+ );
+
+ /*
+ * Check the configured CONFIGURE_MICROSECONDS_PER_TICK value in
+ * microseconds.
+ */
+ T_eq_u32(
+ rtems_configuration_get_microseconds_per_tick(),
+ TEST_MICROSECONDS_PER_TICK
+ );
+
+ /*
+ * Check the configured CONFIGURE_MICROSECONDS_PER_TICK value in
+ * milliseconds.
+ */
+ T_eq_u32(
+ rtems_configuration_get_milliseconds_per_tick(),
+ TEST_MICROSECONDS_PER_TICK / 1000
+ );
+
+ /*
+ * Check the configured CONFIGURE_MICROSECONDS_PER_TICK value in nanoseconds.
+ */
+ T_eq_u32(
+ rtems_configuration_get_nanoseconds_per_tick(),
+ TEST_MICROSECONDS_PER_TICK * 1000
+ );
+
+ /*
+ * Check the configured CONFIGURE_TASK_STACK_ALLOCATOR hook. Using the test
+ * stack allocator validates also
+ * spec:/acfg/if/init-task-construct-storage-size, since the
+ * test_task_stack_allocate() allocate handler only supports
+ * CONFIGURE_MAXIMUM_TASKS minus one stacks and the validation test for
+ * spec:/rtems/task/req/create-errors creates for some pre-condition variants
+ * all tasks until RTEMS_TOO_MANY is returned. In addition,
+ * test_task_stack_allocate() checks that the allocation size is greater than
+ * or equal to TEST_MINIMUM_STACK_SIZE which validates
+ * CONFIGURE_MINIMUM_TASK_STACK_SIZE.
+ */
+ T_eq_ptr(
+ rtems_configuration_get_stack_allocate_hook(),
+ test_task_stack_allocate
+ );
+
+ /*
+ * Check the configured CONFIGURE_TASK_STACK_ALLOCATOR_AVOIDS_WORK_SPACE
+ * value.
+ */
+ T_true( rtems_configuration_get_stack_allocator_avoids_work_space() );
+
+ /*
+ * Check the configured CONFIGURE_TASK_STACK_DEALLOCATOR hook.
+ */
+ T_eq_ptr(
+ rtems_configuration_get_stack_free_hook(),
+ test_task_stack_deallocate
+ );
+
+ /*
+ * Check the configured CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE hook.
+ */
+ T_eq_ptr(
+ rtems_configuration_get_stack_allocate_for_idle_hook(),
+ test_idle_task_stack_allocate
+ );
+
+ /*
+ * Check the configured CONFIGURE_IDLE_TASK_STACK_SIZE value.
+ */
+ T_eq_sz(
+ rtems_configuration_get_idle_task_stack_size(),
+ TEST_IDLE_STACK_SIZE
+ );
+
+ /*
+ * Check the configured CONFIGURE_INTERRUPT_STACK_SIZE value.
+ */
+ T_eq_sz(
+ rtems_configuration_get_interrupt_stack_size(),
+ TEST_INTERRUPT_STACK_SIZE
+ );
+
+ /*
+ * Check the configured CONFIGURE_TICKS_PER_TIMESLICE value.
+ */
+ T_eq_u32(
+ rtems_configuration_get_ticks_per_timeslice(),
+ TEST_TICKS_PER_TIMESLICE
+ );
+}
+
+/**
+ * @fn void T_case_body_AcfgValAcfg( void )
+ */
+T_TEST_CASE( AcfgValAcfg )
+{
+ AcfgValAcfg_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-attr.c b/testsuites/validation/tc-attr.c
new file mode 100644
index 0000000000..05128372bf
--- /dev/null
+++ b/testsuites/validation/tc-attr.c
@@ -0,0 +1,350 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsAttrValAttr
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsAttrValAttr spec:/rtems/attr/val/attr
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests the attribute constants of the Classic API.
+ *
+ * This test case performs the following actions:
+ *
+ * - Validate the non-default attribute constants.
+ *
+ * - Check that RTEMS_BARRIER_AUTOMATIC_RELEASE is a power of two.
+ *
+ * - Check that RTEMS_BINARY_SEMAPHORE is a power of two.
+ *
+ * - Check that RTEMS_FLOATING_POINT is a power of two.
+ *
+ * - Check that RTEMS_GLOBAL is a power of two.
+ *
+ * - Check that RTEMS_INHERIT_PRIORITY is a power of two.
+ *
+ * - Check that RTEMS_MULTIPROCESSOR_RESOURCE_SHARING is a power of two.
+ *
+ * - Check that RTEMS_PRIORITY is a power of two.
+ *
+ * - Check that RTEMS_PRIORITY_CEILING is a power of two.
+ *
+ * - Check that RTEMS_SIMPLE_BINARY_SEMAPHORE is a power of two.
+ *
+ * - Check that RTEMS_SYSTEM_TASK is a power of two.
+ *
+ * - Validate the default attribute constants.
+ *
+ * - Check that RTEMS_APPLICATION_TASK is equal to zero.
+ *
+ * - Check that RTEMS_BARRIER_MANUAL_RELEASE is equal to zero.
+ *
+ * - Check that RTEMS_COUNTING_SEMAPHORE is equal to zero.
+ *
+ * - Check that RTEMS_DEFAULT_ATTRIBUTES is equal to zero.
+ *
+ * - Check that RTEMS_FIFO is equal to zero.
+ *
+ * - Check that RTEMS_LOCAL is equal to zero.
+ *
+ * - Check that RTEMS_NO_FLOATING_POINT is equal to zero.
+ *
+ * - Check that RTEMS_NO_INHERIT_PRIORITY is equal to zero.
+ *
+ * - Check that RTEMS_NO_MULTIPROCESSOR_RESOURCE_SHARING is equal to zero.
+ *
+ * - Check that RTEMS_NO_PRIORITY_CEILING is equal to zero.
+ *
+ * - Calculate the bitwise or of all non-default attribute constants.
+ *
+ * - Check that the count of set bits in the calculated value is equal to the
+ * count of non-default attribute constants. Since each non-default
+ * attribute constant is a power of two, this proves that each constant has
+ * a unique value.
+ *
+ * - Calculate the bitwise or of the RTEMS_BINARY_SEMAPHORE,
+ * RTEMS_COUNTING_SEMAPHORE, and RTEMS_SIMPLE_BINARY_SEMAPHORE attribute
+ * constants.
+ *
+ * - Check that the calculated value is equal to RTEMS_SEMAPHORE_CLASS.
+ *
+ * - Check the value of RTEMS_DEFAULT_ATTRIBUTES.
+ *
+ * - Check RTEMS_DEFAULT_ATTRIBUTES equals RTEMS_FIFO | RTEMS_LOCAL.
+ *
+ * @{
+ */
+
+static bool IsPowerOfTwo( rtems_attribute attribute )
+{
+ return attribute != 0 && ( attribute & ( attribute - 1 ) ) == 0;
+}
+
+static int PopCount( rtems_attribute attributes )
+{
+ int count;
+
+ count = 0;
+
+ while ( attributes != 0 ) {
+ ++count;
+ attributes &= attributes - 1;
+ }
+
+ return count;
+}
+
+/**
+ * @brief Validate the non-default attribute constants.
+ */
+static void RtemsAttrValAttr_Action_0( void )
+{
+ /* No action */
+
+ /*
+ * Check that RTEMS_BARRIER_AUTOMATIC_RELEASE is a power of two.
+ */
+ T_step_true( 0, IsPowerOfTwo( RTEMS_BARRIER_AUTOMATIC_RELEASE ) );
+
+ /*
+ * Check that RTEMS_BINARY_SEMAPHORE is a power of two.
+ */
+ T_step_true( 1, IsPowerOfTwo( RTEMS_BINARY_SEMAPHORE ) );
+
+ /*
+ * Check that RTEMS_FLOATING_POINT is a power of two.
+ */
+ T_step_true( 2, IsPowerOfTwo( RTEMS_FLOATING_POINT ) );
+
+ /*
+ * Check that RTEMS_GLOBAL is a power of two.
+ */
+ T_step_true( 3, IsPowerOfTwo( RTEMS_GLOBAL ) );
+
+ /*
+ * Check that RTEMS_INHERIT_PRIORITY is a power of two.
+ */
+ T_step_true( 4, IsPowerOfTwo( RTEMS_INHERIT_PRIORITY ) );
+
+ /*
+ * Check that RTEMS_MULTIPROCESSOR_RESOURCE_SHARING is a power of two.
+ */
+ T_step_true(
+ 5,
+ IsPowerOfTwo( RTEMS_MULTIPROCESSOR_RESOURCE_SHARING )
+ );
+
+ /*
+ * Check that RTEMS_PRIORITY is a power of two.
+ */
+ T_step_true( 6, IsPowerOfTwo( RTEMS_PRIORITY ) );
+
+ /*
+ * Check that RTEMS_PRIORITY_CEILING is a power of two.
+ */
+ T_step_true( 7, IsPowerOfTwo( RTEMS_PRIORITY_CEILING ) );
+
+ /*
+ * Check that RTEMS_SIMPLE_BINARY_SEMAPHORE is a power of two.
+ */
+ T_step_true( 8, IsPowerOfTwo( RTEMS_SIMPLE_BINARY_SEMAPHORE ) );
+
+ /*
+ * Check that RTEMS_SYSTEM_TASK is a power of two.
+ */
+ T_step_true( 9, IsPowerOfTwo( RTEMS_SYSTEM_TASK ) );
+}
+
+/**
+ * @brief Validate the default attribute constants.
+ */
+static void RtemsAttrValAttr_Action_1( void )
+{
+ /* No action */
+
+ /*
+ * Check that RTEMS_APPLICATION_TASK is equal to zero.
+ */
+ T_step_eq_u32( 10, RTEMS_APPLICATION_TASK, 0 );
+
+ /*
+ * Check that RTEMS_BARRIER_MANUAL_RELEASE is equal to zero.
+ */
+ T_step_eq_u32( 11, RTEMS_BARRIER_MANUAL_RELEASE, 0 );
+
+ /*
+ * Check that RTEMS_COUNTING_SEMAPHORE is equal to zero.
+ */
+ T_step_eq_u32( 12, RTEMS_COUNTING_SEMAPHORE, 0 );
+
+ /*
+ * Check that RTEMS_DEFAULT_ATTRIBUTES is equal to zero.
+ */
+ T_step_eq_u32( 13, RTEMS_DEFAULT_ATTRIBUTES, 0 );
+
+ /*
+ * Check that RTEMS_FIFO is equal to zero.
+ */
+ T_step_eq_u32( 14, RTEMS_FIFO, 0 );
+
+ /*
+ * Check that RTEMS_LOCAL is equal to zero.
+ */
+ T_step_eq_u32( 15, RTEMS_LOCAL, 0 );
+
+ /*
+ * Check that RTEMS_NO_FLOATING_POINT is equal to zero.
+ */
+ T_step_eq_u32( 16, RTEMS_NO_FLOATING_POINT, 0 );
+
+ /*
+ * Check that RTEMS_NO_INHERIT_PRIORITY is equal to zero.
+ */
+ T_step_eq_u32( 17, RTEMS_NO_INHERIT_PRIORITY, 0 );
+
+ /*
+ * Check that RTEMS_NO_MULTIPROCESSOR_RESOURCE_SHARING is equal to zero.
+ */
+ T_step_eq_u32( 18, RTEMS_NO_MULTIPROCESSOR_RESOURCE_SHARING, 0 );
+
+ /*
+ * Check that RTEMS_NO_PRIORITY_CEILING is equal to zero.
+ */
+ T_step_eq_u32( 19, RTEMS_NO_PRIORITY_CEILING, 0 );
+}
+
+/**
+ * @brief Calculate the bitwise or of all non-default attribute constants.
+ */
+static void RtemsAttrValAttr_Action_2( void )
+{
+ rtems_attribute attributes;
+
+ attributes = 0;
+ attributes |= RTEMS_BARRIER_AUTOMATIC_RELEASE;
+ attributes |= RTEMS_BINARY_SEMAPHORE;
+ attributes |= RTEMS_FLOATING_POINT;
+ attributes |= RTEMS_GLOBAL;
+ attributes |= RTEMS_INHERIT_PRIORITY;
+ attributes |= RTEMS_MULTIPROCESSOR_RESOURCE_SHARING;
+ attributes |= RTEMS_PRIORITY;
+ attributes |= RTEMS_PRIORITY_CEILING;
+ attributes |= RTEMS_SEMAPHORE_CLASS;
+ attributes |= RTEMS_SIMPLE_BINARY_SEMAPHORE;
+ attributes |= RTEMS_SYSTEM_TASK;
+
+ /*
+ * Check that the count of set bits in the calculated value is equal to the
+ * count of non-default attribute constants. Since each non-default
+ * attribute constant is a power of two, this proves that each constant has a
+ * unique value.
+ */
+ T_step_eq_int( 20, PopCount( attributes ), 10 );
+}
+
+/**
+ * @brief Calculate the bitwise or of the RTEMS_BINARY_SEMAPHORE,
+ * RTEMS_COUNTING_SEMAPHORE, and RTEMS_SIMPLE_BINARY_SEMAPHORE attribute
+ * constants.
+ */
+static void RtemsAttrValAttr_Action_3( void )
+{
+ rtems_attribute attributes;
+
+ attributes = 0;
+ attributes |= RTEMS_BINARY_SEMAPHORE;
+ attributes |= RTEMS_COUNTING_SEMAPHORE;
+ attributes |= RTEMS_SIMPLE_BINARY_SEMAPHORE;
+
+ /*
+ * Check that the calculated value is equal to RTEMS_SEMAPHORE_CLASS.
+ */
+ T_step_eq_u32( 21, RTEMS_SEMAPHORE_CLASS, attributes );
+}
+
+/**
+ * @brief Check the value of RTEMS_DEFAULT_ATTRIBUTES.
+ */
+static void RtemsAttrValAttr_Action_4( void )
+{
+ /* No action */
+
+ /*
+ * Check RTEMS_DEFAULT_ATTRIBUTES equals RTEMS_FIFO | RTEMS_LOCAL.
+ */
+ T_step_eq_int(
+ 22,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ RTEMS_FIFO | RTEMS_LOCAL
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsAttrValAttr( void )
+ */
+T_TEST_CASE( RtemsAttrValAttr )
+{
+ T_plan( 23 );
+
+ RtemsAttrValAttr_Action_0();
+ RtemsAttrValAttr_Action_1();
+ RtemsAttrValAttr_Action_2();
+ RtemsAttrValAttr_Action_3();
+ RtemsAttrValAttr_Action_4();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-barrier-create.c b/testsuites/validation/tc-barrier-create.c
index 628d1a4a09..ba35d0ad97 100644
--- a/testsuites/validation/tc-barrier-create.c
+++ b/testsuites/validation/tc-barrier-create.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsBarrierReqCreate
+ * @ingroup RtemsBarrierReqCreate
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -60,9 +60,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsBarrierReqCreate spec:/rtems/barrier/req/create
+ * @defgroup RtemsBarrierReqCreate spec:/rtems/barrier/req/create
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationNoClock0
*
* @{
*/
diff --git a/testsuites/validation/tc-barrier-delete.c b/testsuites/validation/tc-barrier-delete.c
index df974fd374..456459c343 100644
--- a/testsuites/validation/tc-barrier-delete.c
+++ b/testsuites/validation/tc-barrier-delete.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsBarrierReqDelete
+ * @ingroup RtemsBarrierReqDelete
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -60,9 +60,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsBarrierReqDelete spec:/rtems/barrier/req/delete
+ * @defgroup RtemsBarrierReqDelete spec:/rtems/barrier/req/delete
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationNoClock0
*
* @{
*/
diff --git a/testsuites/validation/tc-barrier-ident.c b/testsuites/validation/tc-barrier-ident.c
new file mode 100644
index 0000000000..0378301fb8
--- /dev/null
+++ b/testsuites/validation/tc-barrier-ident.c
@@ -0,0 +1,119 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsBarrierValIdent
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-object-ident-local.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsBarrierValIdent spec:/rtems/barrier/val/ident
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Test the rtems_barrier_ident() directive.
+ *
+ * This test case performs the following actions:
+ *
+ * - Run the generic object identification tests for Classic API partition
+ * class objects defined by spec:/rtems/req/ident-local.
+ *
+ * @{
+ */
+
+#define NAME_LOCAL_OBJECT rtems_build_name( 'B', 'A', 'R', 'R' )
+
+static rtems_status_code ClassicBarrierIdentAction(
+ rtems_name name,
+ rtems_id *id
+)
+{
+ return rtems_barrier_ident( name, id );
+}
+
+/**
+ * @brief Run the generic object identification tests for Classic API partition
+ * class objects defined by spec:/rtems/req/ident-local.
+ */
+static void RtemsBarrierValIdent_Action_0( void )
+{
+ rtems_status_code sc;
+ rtems_id id_local_object;
+
+ sc = rtems_barrier_create(
+ NAME_LOCAL_OBJECT,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ 1,
+ &id_local_object
+ );
+ T_assert_rsc_success( sc );
+
+ RtemsReqIdentLocal_Run(
+ id_local_object,
+ NAME_LOCAL_OBJECT,
+ ClassicBarrierIdentAction
+ );
+
+ sc = rtems_barrier_delete( id_local_object );
+ T_rsc_success( sc );
+}
+
+/**
+ * @fn void T_case_body_RtemsBarrierValIdent( void )
+ */
+T_TEST_CASE( RtemsBarrierValIdent )
+{
+ RtemsBarrierValIdent_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-barrier-performance.c b/testsuites/validation/tc-barrier-performance.c
new file mode 100644
index 0000000000..52ca8685b6
--- /dev/null
+++ b/testsuites/validation/tc-barrier-performance.c
@@ -0,0 +1,638 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsBarrierValPerf
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsBarrierValPerf spec:/rtems/barrier/val/perf
+ *
+ * @ingroup TestsuitesPerformanceNoClock0
+ *
+ * @brief This test case provides a context to run @ref RTEMSAPIClassicBarrier
+ * performance tests.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/rtems/barrier/val/perf test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides a barrier identifier.
+ */
+ rtems_id barrier_id;
+
+ /**
+ * @brief This member provides a worker identifier.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member provides a status code.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member references the measure runtime context.
+ */
+ T_measure_runtime_context *context;
+
+ /**
+ * @brief This member provides the measure runtime request.
+ */
+ T_measure_runtime_request request;
+
+ /**
+ * @brief This member provides an optional measurement begin time point.
+ */
+ T_ticks begin;
+
+ /**
+ * @brief This member provides an optional measurement end time point.
+ */
+ T_ticks end;
+} RtemsBarrierValPerf_Context;
+
+static RtemsBarrierValPerf_Context
+ RtemsBarrierValPerf_Instance;
+
+typedef RtemsBarrierValPerf_Context Context;
+
+static void BarrierWaitWorker( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ while ( true ) {
+ rtems_status_code sc;
+
+ sc = rtems_barrier_wait( ctx->barrier_id, RTEMS_NO_TIMEOUT );
+ ctx->end = T_tick();
+ T_quiet_rsc_success( sc );
+ }
+}
+
+static void RtemsBarrierValPerf_Setup_Context(
+ RtemsBarrierValPerf_Context *ctx
+)
+{
+ T_measure_runtime_config config;
+
+ memset( &config, 0, sizeof( config ) );
+ config.sample_count = 100;
+ ctx->request.arg = ctx;
+ ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES;
+ ctx->context = T_measure_runtime_create( &config );
+ T_assert_not_null( ctx->context );
+}
+
+static void RtemsBarrierValPerf_Setup_Wrap( void *arg )
+{
+ RtemsBarrierValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsBarrierValPerf_Setup_Context( ctx );
+}
+
+static T_fixture RtemsBarrierValPerf_Fixture = {
+ .setup = RtemsBarrierValPerf_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &RtemsBarrierValPerf_Instance
+};
+
+/**
+ * @defgroup RtemsBarrierReqPerfReleaseAuto \
+ * spec:/rtems/barrier/req/perf-release-auto
+ *
+ * @{
+ */
+
+/**
+ * @brief Create an automatic release barrier.
+ */
+static void RtemsBarrierReqPerfReleaseAuto_Prepare(
+ RtemsBarrierValPerf_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ sc = rtems_barrier_create(
+ OBJECT_NAME,
+ RTEMS_BARRIER_AUTOMATIC_RELEASE,
+ 1,
+ &ctx->barrier_id
+ );
+ T_rsc_success( sc );
+}
+
+/**
+ * @brief Automatically release the barrier.
+ */
+static void RtemsBarrierReqPerfReleaseAuto_Body(
+ RtemsBarrierValPerf_Context *ctx
+)
+{
+ ctx->status = rtems_barrier_wait( ctx->barrier_id, RTEMS_NO_TIMEOUT );
+}
+
+static void RtemsBarrierReqPerfReleaseAuto_Body_Wrap( void *arg )
+{
+ RtemsBarrierValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsBarrierReqPerfReleaseAuto_Body( ctx );
+}
+
+/**
+ * @brief Discard samples interrupted by a clock tick.
+ */
+static bool RtemsBarrierReqPerfReleaseAuto_Teardown(
+ RtemsBarrierValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ return tic == toc;
+}
+
+static bool RtemsBarrierReqPerfReleaseAuto_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsBarrierValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsBarrierReqPerfReleaseAuto_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/**
+ * @brief Delete the barrier and the worker.
+ */
+static void RtemsBarrierReqPerfReleaseAuto_Cleanup(
+ RtemsBarrierValPerf_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ sc = rtems_barrier_delete( ctx->barrier_id );
+ T_rsc_success( sc );
+}
+
+/** @} */
+
+#if defined(RTEMS_SMP)
+/**
+ * @defgroup RtemsBarrierReqPerfReleaseAutoOtherCpu \
+ * spec:/rtems/barrier/req/perf-release-auto-other-cpu
+ *
+ * @{
+ */
+
+/**
+ * @brief Create an automatic release barrier. Create and start a worker task.
+ */
+static void RtemsBarrierReqPerfReleaseAutoOtherCpu_Prepare(
+ RtemsBarrierValPerf_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ sc = rtems_barrier_create(
+ OBJECT_NAME,
+ RTEMS_BARRIER_AUTOMATIC_RELEASE,
+ 2,
+ &ctx->barrier_id
+ );
+ T_rsc_success( sc );
+
+ ctx->worker_id = CreateTask( "WORK", PRIO_NORMAL );
+ SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+ StartTask( ctx->worker_id, BarrierWaitWorker, ctx );
+ WaitForNextTask( 1, ctx->worker_id );
+}
+
+/**
+ * @brief Automatically release the barrier.
+ */
+static void RtemsBarrierReqPerfReleaseAutoOtherCpu_Body(
+ RtemsBarrierValPerf_Context *ctx
+)
+{
+ ctx->begin = T_tick();
+ ctx->status = rtems_barrier_wait( ctx->barrier_id, RTEMS_NO_TIMEOUT );
+}
+
+static void RtemsBarrierReqPerfReleaseAutoOtherCpu_Body_Wrap( void *arg )
+{
+ RtemsBarrierValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsBarrierReqPerfReleaseAutoOtherCpu_Body( ctx );
+}
+
+/**
+ * @brief Make sure the worker waits for the next event. Set the measured
+ * runtime. Discard samples interrupted by a clock tick.
+ */
+static bool RtemsBarrierReqPerfReleaseAutoOtherCpu_Teardown(
+ RtemsBarrierValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ WaitForNextTask( 1, ctx->worker_id );
+ *delta = ctx->end - ctx->begin;
+
+ return tic == toc;
+}
+
+static bool RtemsBarrierReqPerfReleaseAutoOtherCpu_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsBarrierValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsBarrierReqPerfReleaseAutoOtherCpu_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/**
+ * @brief Delete the barrier and the worker.
+ */
+static void RtemsBarrierReqPerfReleaseAutoOtherCpu_Cleanup(
+ RtemsBarrierValPerf_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ DeleteTask( ctx->worker_id );
+
+ sc = rtems_barrier_delete( ctx->barrier_id );
+ T_rsc_success( sc );
+}
+
+/** @} */
+#endif
+
+/**
+ * @defgroup RtemsBarrierReqPerfReleaseManual \
+ * spec:/rtems/barrier/req/perf-release-manual
+ *
+ * @{
+ */
+
+/**
+ * @brief Create a manual release barrier. Create and start a worker task.
+ */
+static void RtemsBarrierReqPerfReleaseManual_Prepare(
+ RtemsBarrierValPerf_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ sc = rtems_barrier_create(
+ OBJECT_NAME,
+ RTEMS_BARRIER_MANUAL_RELEASE,
+ 0,
+ &ctx->barrier_id
+ );
+ T_rsc_success( sc );
+
+ SetSelfPriority( PRIO_NORMAL );
+ ctx->worker_id = CreateTask( "WORK", PRIO_NORMAL );
+ StartTask( ctx->worker_id, BarrierWaitWorker, ctx );
+}
+
+/**
+ * @brief Make sure the worker task is fully blocked on the barrier.
+ */
+static void RtemsBarrierReqPerfReleaseManual_Setup(
+ RtemsBarrierValPerf_Context *ctx
+)
+{
+ Yield();
+}
+
+static void RtemsBarrierReqPerfReleaseManual_Setup_Wrap( void *arg )
+{
+ RtemsBarrierValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsBarrierReqPerfReleaseManual_Setup( ctx );
+}
+
+/**
+ * @brief Release the barrier.
+ */
+static void RtemsBarrierReqPerfReleaseManual_Body(
+ RtemsBarrierValPerf_Context *ctx
+)
+{
+ uint32_t count;
+
+ ctx->status = rtems_barrier_release( ctx->barrier_id, &count );
+}
+
+static void RtemsBarrierReqPerfReleaseManual_Body_Wrap( void *arg )
+{
+ RtemsBarrierValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsBarrierReqPerfReleaseManual_Body( ctx );
+}
+
+/**
+ * @brief Discard samples interrupted by a clock tick.
+ */
+static bool RtemsBarrierReqPerfReleaseManual_Teardown(
+ RtemsBarrierValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ return tic == toc;
+}
+
+static bool RtemsBarrierReqPerfReleaseManual_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsBarrierValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsBarrierReqPerfReleaseManual_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/**
+ * @brief Delete the barrier and the worker.
+ */
+static void RtemsBarrierReqPerfReleaseManual_Cleanup(
+ RtemsBarrierValPerf_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ DeleteTask( ctx->worker_id );
+
+ sc = rtems_barrier_delete( ctx->barrier_id );
+ T_rsc_success( sc );
+
+ RestoreRunnerPriority();
+}
+
+/** @} */
+
+/**
+ * @defgroup RtemsBarrierReqPerfReleaseManualPreempt \
+ * spec:/rtems/barrier/req/perf-release-manual-preempt
+ *
+ * @{
+ */
+
+/**
+ * @brief Create a manual release barrier. Create and start a worker task.
+ */
+static void RtemsBarrierReqPerfReleaseManualPreempt_Prepare(
+ RtemsBarrierValPerf_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ sc = rtems_barrier_create(
+ OBJECT_NAME,
+ RTEMS_BARRIER_MANUAL_RELEASE,
+ 0,
+ &ctx->barrier_id
+ );
+ T_rsc_success( sc );
+
+ SetSelfPriority( PRIO_NORMAL );
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, BarrierWaitWorker, ctx );
+}
+
+/**
+ * @brief Release the barrier.
+ */
+static void RtemsBarrierReqPerfReleaseManualPreempt_Body(
+ RtemsBarrierValPerf_Context *ctx
+)
+{
+ uint32_t count;
+
+ ctx->begin = T_tick();
+ ctx->status = rtems_barrier_release( ctx->barrier_id, &count );
+}
+
+static void RtemsBarrierReqPerfReleaseManualPreempt_Body_Wrap( void *arg )
+{
+ RtemsBarrierValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsBarrierReqPerfReleaseManualPreempt_Body( ctx );
+}
+
+/**
+ * @brief Set the measured runtime. Discard samples interrupted by a clock
+ * tick.
+ */
+static bool RtemsBarrierReqPerfReleaseManualPreempt_Teardown(
+ RtemsBarrierValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+
+ return tic == toc;
+}
+
+static bool RtemsBarrierReqPerfReleaseManualPreempt_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsBarrierValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsBarrierReqPerfReleaseManualPreempt_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/**
+ * @brief Delete the barrier and the worker.
+ */
+static void RtemsBarrierReqPerfReleaseManualPreempt_Cleanup(
+ RtemsBarrierValPerf_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ DeleteTask( ctx->worker_id );
+
+ sc = rtems_barrier_delete( ctx->barrier_id );
+ T_rsc_success( sc );
+
+ RestoreRunnerPriority();
+}
+
+/** @} */
+
+/**
+ * @fn void T_case_body_RtemsBarrierValPerf( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsBarrierValPerf, &RtemsBarrierValPerf_Fixture )
+{
+ RtemsBarrierValPerf_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ RtemsBarrierReqPerfReleaseAuto_Prepare( ctx );
+ ctx->request.name = "RtemsBarrierReqPerfReleaseAuto";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsBarrierReqPerfReleaseAuto_Body_Wrap;
+ ctx->request.teardown = RtemsBarrierReqPerfReleaseAuto_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsBarrierReqPerfReleaseAuto_Cleanup( ctx );
+
+ #if defined(RTEMS_SMP)
+ RtemsBarrierReqPerfReleaseAutoOtherCpu_Prepare( ctx );
+ ctx->request.name = "RtemsBarrierReqPerfReleaseAutoOtherCpu";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsBarrierReqPerfReleaseAutoOtherCpu_Body_Wrap;
+ ctx->request.teardown = RtemsBarrierReqPerfReleaseAutoOtherCpu_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsBarrierReqPerfReleaseAutoOtherCpu_Cleanup( ctx );
+ #endif
+
+ RtemsBarrierReqPerfReleaseManual_Prepare( ctx );
+ ctx->request.name = "RtemsBarrierReqPerfReleaseManual";
+ ctx->request.setup = RtemsBarrierReqPerfReleaseManual_Setup_Wrap;
+ ctx->request.body = RtemsBarrierReqPerfReleaseManual_Body_Wrap;
+ ctx->request.teardown = RtemsBarrierReqPerfReleaseManual_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsBarrierReqPerfReleaseManual_Cleanup( ctx );
+
+ RtemsBarrierReqPerfReleaseManualPreempt_Prepare( ctx );
+ ctx->request.name = "RtemsBarrierReqPerfReleaseManualPreempt";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsBarrierReqPerfReleaseManualPreempt_Body_Wrap;
+ ctx->request.teardown = RtemsBarrierReqPerfReleaseManualPreempt_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsBarrierReqPerfReleaseManualPreempt_Cleanup( ctx );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-barrier-release.c b/testsuites/validation/tc-barrier-release.c
index de77e22027..b584943531 100644
--- a/testsuites/validation/tc-barrier-release.c
+++ b/testsuites/validation/tc-barrier-release.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsBarrierReqRelease
+ * @ingroup RtemsBarrierReqRelease
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -60,10 +60,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsBarrierReqRelease \
- * spec:/rtems/barrier/req/release
+ * @defgroup RtemsBarrierReqRelease spec:/rtems/barrier/req/release
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationNoClock0
*
* @{
*/
@@ -131,6 +130,12 @@ typedef struct {
struct {
/**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 3 ];
+
+ /**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 3 ];
@@ -500,16 +505,27 @@ static inline RtemsBarrierReqRelease_Entry RtemsBarrierReqRelease_PopEntry(
];
}
+static void RtemsBarrierReqRelease_SetPreConditionStates(
+ RtemsBarrierReqRelease_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+
+ if ( ctx->Map.entry.Pre_Waiting_NA ) {
+ ctx->Map.pcs[ 2 ] = RtemsBarrierReqRelease_Pre_Waiting_NA;
+ } else {
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ }
+}
+
static void RtemsBarrierReqRelease_TestVariant(
RtemsBarrierReqRelease_Context *ctx
)
{
RtemsBarrierReqRelease_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsBarrierReqRelease_Pre_Released_Prepare( ctx, ctx->Map.pcs[ 1 ] );
- RtemsBarrierReqRelease_Pre_Waiting_Prepare(
- ctx,
- ctx->Map.entry.Pre_Waiting_NA ? RtemsBarrierReqRelease_Pre_Waiting_NA : ctx->Map.pcs[ 2 ]
- );
+ RtemsBarrierReqRelease_Pre_Waiting_Prepare( ctx, ctx->Map.pcs[ 2 ] );
RtemsBarrierReqRelease_Action( ctx );
RtemsBarrierReqRelease_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
RtemsBarrierReqRelease_Post_ReleasedVar_Check(
@@ -530,21 +546,22 @@ T_TEST_CASE_FIXTURE( RtemsBarrierReqRelease, &RtemsBarrierReqRelease_Fixture )
ctx->Map.index = 0;
for (
- ctx->Map.pcs[ 0 ] = RtemsBarrierReqRelease_Pre_Id_NoObj;
- ctx->Map.pcs[ 0 ] < RtemsBarrierReqRelease_Pre_Id_NA;
- ++ctx->Map.pcs[ 0 ]
+ ctx->Map.pci[ 0 ] = RtemsBarrierReqRelease_Pre_Id_NoObj;
+ ctx->Map.pci[ 0 ] < RtemsBarrierReqRelease_Pre_Id_NA;
+ ++ctx->Map.pci[ 0 ]
) {
for (
- ctx->Map.pcs[ 1 ] = RtemsBarrierReqRelease_Pre_Released_Valid;
- ctx->Map.pcs[ 1 ] < RtemsBarrierReqRelease_Pre_Released_NA;
- ++ctx->Map.pcs[ 1 ]
+ ctx->Map.pci[ 1 ] = RtemsBarrierReqRelease_Pre_Released_Valid;
+ ctx->Map.pci[ 1 ] < RtemsBarrierReqRelease_Pre_Released_NA;
+ ++ctx->Map.pci[ 1 ]
) {
for (
- ctx->Map.pcs[ 2 ] = RtemsBarrierReqRelease_Pre_Waiting_Zero;
- ctx->Map.pcs[ 2 ] < RtemsBarrierReqRelease_Pre_Waiting_NA;
- ++ctx->Map.pcs[ 2 ]
+ ctx->Map.pci[ 2 ] = RtemsBarrierReqRelease_Pre_Waiting_Zero;
+ ctx->Map.pci[ 2 ] < RtemsBarrierReqRelease_Pre_Waiting_NA;
+ ++ctx->Map.pci[ 2 ]
) {
ctx->Map.entry = RtemsBarrierReqRelease_PopEntry( ctx );
+ RtemsBarrierReqRelease_SetPreConditionStates( ctx );
RtemsBarrierReqRelease_TestVariant( ctx );
}
}
diff --git a/testsuites/validation/tc-barrier-wait.c b/testsuites/validation/tc-barrier-wait.c
index 54632cf7ca..49d29a45c8 100644
--- a/testsuites/validation/tc-barrier-wait.c
+++ b/testsuites/validation/tc-barrier-wait.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsBarrierReqWait
+ * @ingroup RtemsBarrierReqWait
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -60,9 +60,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsBarrierReqWait spec:/rtems/barrier/req/wait
+ * @defgroup RtemsBarrierReqWait spec:/rtems/barrier/req/wait
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationNoClock0
*
* @{
*/
@@ -127,6 +127,12 @@ typedef struct {
struct {
/**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 3 ];
+
+ /**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 3 ];
@@ -187,7 +193,7 @@ static const char * const * const RtemsBarrierReqWait_PreDesc[] = {
#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
-#define EVENT_CHECK_TIMER RTEMS_EVENT_0
+#define EVENT_TIMER_INACTIVE RTEMS_EVENT_0
#define EVENT_WAIT RTEMS_EVENT_1
@@ -195,6 +201,8 @@ static const char * const * const RtemsBarrierReqWait_PreDesc[] = {
#define EVENT_DELETE RTEMS_EVENT_3
+#define EVENT_TIMER_EXPIRE RTEMS_EVENT_4
+
typedef RtemsBarrierReqWait_Context Context;
static void Worker( rtems_task_argument arg )
@@ -209,7 +217,7 @@ static void Worker( rtems_task_argument arg )
events = ReceiveAnyEvents();
- if ( ( events & EVENT_CHECK_TIMER ) != 0 ) {
+ if ( ( events & EVENT_TIMER_INACTIVE ) != 0 ) {
T_eq_int(
T_get_thread_timer_state( ctx->main_id ),
T_THREAD_TIMER_INACTIVE
@@ -256,6 +264,14 @@ static void Worker( rtems_task_argument arg )
prio = SetSelfPriority( prio );
T_eq_u32( prio, PRIO_HIGH );
}
+
+ if ( ( events & EVENT_TIMER_EXPIRE ) != 0 ) {
+ T_eq_int(
+ T_get_thread_timer_state( ctx->main_id ),
+ T_THREAD_TIMER_SCHEDULED
+ );
+ FinalClockTick();
+ }
}
}
@@ -306,7 +322,7 @@ static void RtemsBarrierReqWait_Pre_Timeout_Prepare(
/*
* While the ``released`` parameter is a clock tick interval.
*/
- ctx->timeout = 2;
+ ctx->timeout = UINT32_MAX;
break;
}
@@ -335,7 +351,9 @@ static void RtemsBarrierReqWait_Pre_Satisfy_Prepare(
* released or deleted.
*/
if ( ctx->timeout == RTEMS_NO_TIMEOUT ) {
- SendEvents( ctx->low_worker_id, EVENT_CHECK_TIMER | EVENT_RELEASE );
+ SendEvents( ctx->low_worker_id, EVENT_TIMER_INACTIVE | EVENT_RELEASE );
+ } else {
+ SendEvents( ctx->low_worker_id, EVENT_TIMER_EXPIRE );
}
break;
}
@@ -544,17 +562,30 @@ static inline RtemsBarrierReqWait_Entry RtemsBarrierReqWait_PopEntry(
];
}
+static void RtemsBarrierReqWait_SetPreConditionStates(
+ RtemsBarrierReqWait_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+
+ if ( ctx->Map.entry.Pre_Timeout_NA ) {
+ ctx->Map.pcs[ 1 ] = RtemsBarrierReqWait_Pre_Timeout_NA;
+ } else {
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Satisfy_NA ) {
+ ctx->Map.pcs[ 2 ] = RtemsBarrierReqWait_Pre_Satisfy_NA;
+ } else {
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ }
+}
+
static void RtemsBarrierReqWait_TestVariant( RtemsBarrierReqWait_Context *ctx )
{
RtemsBarrierReqWait_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
- RtemsBarrierReqWait_Pre_Timeout_Prepare(
- ctx,
- ctx->Map.entry.Pre_Timeout_NA ? RtemsBarrierReqWait_Pre_Timeout_NA : ctx->Map.pcs[ 1 ]
- );
- RtemsBarrierReqWait_Pre_Satisfy_Prepare(
- ctx,
- ctx->Map.entry.Pre_Satisfy_NA ? RtemsBarrierReqWait_Pre_Satisfy_NA : ctx->Map.pcs[ 2 ]
- );
+ RtemsBarrierReqWait_Pre_Timeout_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsBarrierReqWait_Pre_Satisfy_Prepare( ctx, ctx->Map.pcs[ 2 ] );
RtemsBarrierReqWait_Action( ctx );
RtemsBarrierReqWait_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
}
@@ -571,19 +602,19 @@ T_TEST_CASE_FIXTURE( RtemsBarrierReqWait, &RtemsBarrierReqWait_Fixture )
ctx->Map.index = 0;
for (
- ctx->Map.pcs[ 0 ] = RtemsBarrierReqWait_Pre_Id_NoObj;
- ctx->Map.pcs[ 0 ] < RtemsBarrierReqWait_Pre_Id_NA;
- ++ctx->Map.pcs[ 0 ]
+ ctx->Map.pci[ 0 ] = RtemsBarrierReqWait_Pre_Id_NoObj;
+ ctx->Map.pci[ 0 ] < RtemsBarrierReqWait_Pre_Id_NA;
+ ++ctx->Map.pci[ 0 ]
) {
for (
- ctx->Map.pcs[ 1 ] = RtemsBarrierReqWait_Pre_Timeout_Ticks;
- ctx->Map.pcs[ 1 ] < RtemsBarrierReqWait_Pre_Timeout_NA;
- ++ctx->Map.pcs[ 1 ]
+ ctx->Map.pci[ 1 ] = RtemsBarrierReqWait_Pre_Timeout_Ticks;
+ ctx->Map.pci[ 1 ] < RtemsBarrierReqWait_Pre_Timeout_NA;
+ ++ctx->Map.pci[ 1 ]
) {
for (
- ctx->Map.pcs[ 2 ] = RtemsBarrierReqWait_Pre_Satisfy_Never;
- ctx->Map.pcs[ 2 ] < RtemsBarrierReqWait_Pre_Satisfy_NA;
- ++ctx->Map.pcs[ 2 ]
+ ctx->Map.pci[ 2 ] = RtemsBarrierReqWait_Pre_Satisfy_Never;
+ ctx->Map.pci[ 2 ] < RtemsBarrierReqWait_Pre_Satisfy_NA;
+ ++ctx->Map.pci[ 2 ]
) {
ctx->Map.entry = RtemsBarrierReqWait_PopEntry( ctx );
@@ -591,6 +622,7 @@ T_TEST_CASE_FIXTURE( RtemsBarrierReqWait, &RtemsBarrierReqWait_Fixture )
continue;
}
+ RtemsBarrierReqWait_SetPreConditionStates( ctx );
RtemsBarrierReqWait_TestVariant( ctx );
}
}
diff --git a/testsuites/validation/tc-basedefs-no-debug.c b/testsuites/validation/tc-basedefs-no-debug.c
new file mode 100644
index 0000000000..b3cfa5dd40
--- /dev/null
+++ b/testsuites/validation/tc-basedefs-no-debug.c
@@ -0,0 +1,135 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsBasedefsValBasedefsNoDebug
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsBasedefsValBasedefsNoDebug \
+ * spec:/rtems/basedefs/val/basedefs-no-debug
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests the basedefs macros where RTEMS_DEBUG is disabled.
+ *
+ * This test case performs the following actions:
+ *
+ * - Expand and stringify RTEMS_UNREACHABLE().
+ *
+ * - Check that the string is equal to the expected statement.
+ *
+ * - Expand RTEMS_FUNCTION_NAME.
+ *
+ * - Check that the string is equal to the expected function name.
+ *
+ * @{
+ */
+
+/**
+ * @brief Expand and stringify RTEMS_UNREACHABLE().
+ */
+static void RtemsBasedefsValBasedefsNoDebug_Action_0( void )
+{
+ const char *s;
+
+ s = RTEMS_XSTRING( RTEMS_UNREACHABLE() );
+
+ /*
+ * Check that the string is equal to the expected statement.
+ */
+ T_step_true(
+ 0,
+ IsEqualIgnoreWhiteSpace(
+ s,
+ "__builtin_unreachable()"
+ )
+ );
+}
+
+/**
+ * @brief Expand RTEMS_FUNCTION_NAME.
+ */
+static void RtemsBasedefsValBasedefsNoDebug_Action_1( void )
+{
+ const char *s;
+
+ s = RTEMS_FUNCTION_NAME;
+
+ /*
+ * Check that the string is equal to the expected function name.
+ */
+ T_step_true(
+ 1,
+ IsEqualIgnoreWhiteSpace(
+ s,
+ "RtemsBasedefsValBasedefsNoDebug_Action_1"
+ )
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsBasedefsValBasedefsNoDebug( void )
+ */
+T_TEST_CASE( RtemsBasedefsValBasedefsNoDebug )
+{
+ T_plan( 2 );
+
+ RtemsBasedefsValBasedefsNoDebug_Action_0();
+ RtemsBasedefsValBasedefsNoDebug_Action_1();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-basedefs-pendant.c b/testsuites/validation/tc-basedefs-pendant.c
new file mode 100644
index 0000000000..620e2d0efa
--- /dev/null
+++ b/testsuites/validation/tc-basedefs-pendant.c
@@ -0,0 +1,122 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsBasedefsValBasedefs
+ *
+ * @brief Helper file to verify the requirements towards the basedefs.
+ *
+ * The specification items in
+ * (rtems-central/)spec/rtems/basedefs/req/[*] represent
+ * requirements towards the basedefs in
+ * (rtems/)cpukit/include/rtems/score/basedefs.h.
+ * There are automated verification tests generated from
+ * (rtems-central/)spec/rtems/basedefs/val/[*] and placed
+ * in (rtems/)testsuites/validation/tc-basedefs-0.c.
+ *
+ * Yet, not every test can be placed in the same compilation unit
+ * (tc-basedefs-0.c). Hence, the code which must be placed
+ * in an extra compilation unit is put here and this file
+ * is linked to tc-basedefs-0.c to be accessible from the tests.
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tc-basedefs-pendant.h"
+
+/* For the RTEMS_SYMBOL_NAME tests */
+#undef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__ SyMbOl_
+#define SyMbOl_symbol_id prefix_symbol_id
+#define SYMBOL_NAME symbol_name
+
+uintptr_t basedefs_get_global_symbol( void )
+{
+ return (uintptr_t) global_symbol;
+}
+
+int basedefs_use_prefixed_symbol_name( void )
+{
+ const int SyMbOl_symbol_name = 124;
+ return RTEMS_SYMBOL_NAME( symbol_name );
+}
+
+int basedefs_use_prefixed_upper_symbol_name( void )
+{
+ const int SyMbOl_symbol_name = 125;
+ return RTEMS_SYMBOL_NAME( SYMBOL_NAME );
+}
+
+int basedefs_use_prefixed_symbol_id( void )
+{
+ const int prefix_symbol_id = 126;
+ return RTEMS_SYMBOL_NAME( symbol_id );
+}
+
+int basedefs_weak_alias_1_func( int i )
+{
+ return 10 * i;
+}
+
+const volatile int basedefs_weak_1_var = 62;
+
+int basedefs_weak_1_func( void )
+{
+ return 65;
+}
+
+static RTEMS_ALIGNED( 64 ) int allocated_memory_dummy;
+
+void *basedefs_malloclike_func( size_t size )
+{
+ return &allocated_memory_dummy;
+}
+
+void *basedefs_alloc_align_func( size_t size, void **p, size_t alignment )
+{
+ *p = &allocated_memory_dummy;
+ return &allocated_memory_dummy;
+}
+
+void *basedefs_alloc_size_func( size_t size )
+{
+ return &allocated_memory_dummy;
+}
+
+void *basedefs_alloc_size_2_func( size_t size0, size_t size1 )
+{
+ return &allocated_memory_dummy;
+}
+
+void basedefs_free( void *ptr )
+{
+ (void) ptr;
+}
diff --git a/testsuites/validation/tc-basedefs-pendant.h b/testsuites/validation/tc-basedefs-pendant.h
new file mode 100644
index 0000000000..7c1fbd8ae3
--- /dev/null
+++ b/testsuites/validation/tc-basedefs-pendant.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsBasedefsValBasedefs
+ *
+ * @brief Helper file to verify the requirements towards the basedefs.
+ *
+ * This file contains solely *private* declarations shared by
+ * (rtems/)testsuites/validation/tc-basedefs-0.c and
+ * (rtems/)testsuites/validation/tc-basedefs-pendant.c.
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _TC_BASEDEFS_PENDANT_H
+#define _TC_BASEDEFS_PENDANT_H
+
+/* The define is for the RTEMS_SYMBOL_NAME tests */
+#ifndef __USER_LABEL_PREFIX__
+#define __USER_LABEL_PREFIX__
+#endif
+
+#include <rtems.h>
+
+/* Remove for C++ code */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GLOBAL_SYMBOL global_symbol
+RTEMS_DECLARE_GLOBAL_SYMBOL( GLOBAL_SYMBOL );
+
+uintptr_t basedefs_get_global_symbol( void );
+int basedefs_use_prefixed_symbol_name( void );
+int basedefs_use_prefixed_upper_symbol_name( void );
+int basedefs_use_prefixed_symbol_id( void );
+int basedefs_weak_alias_0_func( int i );
+int basedefs_weak_alias_1_func( int i );
+int basedefs_weak_0_func( void );
+int basedefs_weak_1_func( void );
+
+extern const volatile int basedefs_weak_0_var;
+
+extern const volatile int basedefs_weak_1_var;
+
+RTEMS_MALLOCLIKE void *
+basedefs_malloclike_func( size_t size );
+
+RTEMS_ALLOC_SIZE_2( 1, 2 ) void *
+basedefs_alloc_size_2_func( size_t size0, size_t size1 );
+
+RTEMS_ALLOC_ALIGN( 3 ) void *
+basedefs_alloc_align_func( size_t size, void **p, size_t alignment );
+
+RTEMS_ALLOC_SIZE( 1 ) void *
+basedefs_alloc_size_func( size_t size );
+
+RTEMS_ALLOC_SIZE_2( 1, 2 ) void *
+basedefs_alloc_size_2_func( size_t size0, size_t size1 );
+
+void basedefs_free( void *ptr );
+
+/* Remove for C++ code */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TC_BASEDEFS_PENDANT_H */
diff --git a/testsuites/validation/tc-basedefs.c b/testsuites/validation/tc-basedefs.c
new file mode 100644
index 0000000000..835f76ec64
--- /dev/null
+++ b/testsuites/validation/tc-basedefs.c
@@ -0,0 +1,2033 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsBasedefsValBasedefs
+ */
+
+/*
+ * Copyright (C) 2020, 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tc-basedefs-pendant.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsBasedefsValBasedefs spec:/rtems/basedefs/val/basedefs
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests the basedefs macros of the Classic API.
+ *
+ * This test case performs the following actions:
+ *
+ * - Use the RTEMS_ALIAS() macro.
+ *
+ * - Check that ori_func() and alias_func() are the same function.
+ *
+ * - Use the RTEMS_ALIGN_DOWN() macro in various examples.
+ *
+ * - Check that RTEMS_ALIGN_DOWN() calculates the expected result and is
+ * side-effect free.
+ *
+ * - Use the RTEMS_ALIGN_UP() macro in various examples.
+ *
+ * - Check that RTEMS_ALIGN_UP() calculates the expected result and is
+ * side-effect free.
+ *
+ * - Use the RTEMS_ALIGNED() macro.
+ *
+ * - Check that RTEMS_ALIGNED() correctly aligns a variable on the stack and
+ * a structure member.
+ *
+ * - Use the RTEMS_ALIGNOF() macro.
+ *
+ * - Check that the RTEMS_ALIGNOF() macro results in the alignment of the
+ * type.
+ *
+ * - If the RTEMS_ALIGNOF() macro would evaluate its argument, it could not
+ * figure out how much menory to reserve for it.
+ *
+ * - If the RTEMS_ALIGNOF() macro would evaluate the size expression, the
+ * division by zero would cause an error.
+ *
+ * - Ensure the constant value of the RTEMS_ALIGNOF() macro is of type
+ * size_t.
+ *
+ * - Use a function declared with the RTEMS_ALLOC_ALIGN() macro.
+ *
+ * - It cannot be checked that the RTEMS_ALLOC_ALIGN() macro has the desired
+ * effect. Yet, the check confirms that such a macro exists and that it can
+ * be used on such a memory function and that the argument counting starts
+ * at 1.
+ *
+ * - Use a function declared with the RTEMS_ALLOC_SIZE() macro.
+ *
+ * - It cannot be checked that the RTEMS_ALLOC_SIZE() macro has the desired
+ * effect. Yet, the check confirms that such a macro exists and that it can
+ * be used on such a memory function and that the argument counting starts
+ * at 1.
+ *
+ * - Use a function declared with the RTEMS_ALLOC_SIZE_2() macro.
+ *
+ * - It cannot be checked that the RTEMS_ALLOC_SIZE_2() macro has the desired
+ * effect. Yet, the check confirms that such a macro exists and that it can
+ * be used on such a memory function and that the argument counting starts
+ * at 1.
+ *
+ * - Use the RTEMS_ARRAY_SIZE() macro.
+ *
+ * - Check that the calculated size of the arrays fit their definition.
+ *
+ * - Use the RTEMS_COMPILER_DEPRECATED_ATTRIBUTE macro.
+ *
+ * - It cannot automatically be checked that the
+ * RTEMS_COMPILER_DEPRECATED_ATTRIBUTE macro has the desired effect. The
+ * gcc compiler should issue a warning about the use of a deprecated
+ * variable on the above line where the ``compiler_deprecated_attribute``
+ * is used.
+ *
+ * - Use the RTEMS_COMPILER_MEMORY_BARRIER() macro.
+ *
+ * - It cannot be checked that the RTEMS_COMPILER_MEMORY_BARRIER() macro has
+ * the desired effect. It is only checked that such a macro exists.
+ *
+ * - Use of the RTEMS_COMPILER_NO_RETURN_ATTRIBUTE macro at the beginning of
+ * this file.
+ *
+ * - It cannot be checked that the RTEMS_COMPILER_NO_RETURN_ATTRIBUTE macro
+ * has the desired effect. It is only checked that such a macro exists.
+ *
+ * - Use the RTEMS_COMPILER_PACKED_ATTRIBUTE macro.
+ *
+ * - Check that RTEMS_COMPILER_PACKED_ATTRIBUTE correctly aligns a structure
+ * member.
+ *
+ * - Use the RTEMS_COMPILER_PURE_ATTRIBUTE macro at the beginning of this file.
+ *
+ * - It cannot be checked that the RTEMS_COMPILER_PURE_ATTRIBUTE macro has
+ * the desired effect. It is checked that such a macro exists.
+ *
+ * - Use the RTEMS_COMPILER_UNUSED_ATTRIBUTE macro.
+ *
+ * - It cannot automatically be checked that the
+ * RTEMS_COMPILER_UNUSED_ATTRIBUTE macro has the desired effect. It is
+ * checked that such a macro exists and one can manually check that no
+ * compiler warnings are produced for the compiler_unused_attribute_var.
+ *
+ * - Invoke the RTEMS_CONCAT() macro on examples.
+ *
+ * - Check that the two arguments of RTEMS_CONCAT() are concatenated to a new
+ * token.
+ *
+ * - Check that the result of the RTEMS_CONCAT() expansion is subject to a
+ * further pre-processor substitution.
+ *
+ * - Use the RTEMS_CONST macro at the beginning of this file.
+ *
+ * - It cannot be checked that the RTEMS_CONST macro has the desired effect.
+ * It is checked that such a macro exists.
+ *
+ * - Use the RTEMS_CONTAINER_OF() macro.
+ *
+ * - Check that the RTEMS_CONTAINER_OF() macro evaluates to a pointer to
+ * container_of_struct_var.
+ *
+ * - Use the RTEMS_DECLARE_GLOBAL_SYMBOL() macro in the file
+ * tc-basedefs-pendant.h.
+ *
+ * - Check that the RTEMS_DECLARE_GLOBAL_SYMBOL() macro declares a global
+ * symbol which can be accessed by function basedefs_get_global_symbol()
+ * which is defined in a file different from the file in which the gobal
+ * symbol is defined.
+ *
+ * - Use the RTEMS_DECONST() macro.
+ *
+ * - Check that the RTEMS_DECONST() macro returns a pointer which allows to
+ * write into an otherwise const value.
+ *
+ * - Use the RTEMS_DEFINE_GLOBAL_SYMBOL() macro at the beginning of this file.
+ *
+ * - Check that the RTEMS_DEFINE_GLOBAL_SYMBOL() macro defines a global
+ * symbol with the correct value.
+ *
+ * - Use a function declared with the RTEMS_DEPRECATED macro.
+ *
+ * - It cannot automatically be checked that the RTEMS_DEPRECATED macro has
+ * the desired effect. The gcc compiler should issue a warning about the
+ * use of a deprecated function on the above line where the
+ * ``deprecated_func`` is used.
+ *
+ * - Use the RTEMS_DEQUALIFY_DEPTHX() macro.
+ *
+ * - Check that the RTEMS_DEQUALIFY_DEPTHX() macro returns a pointer which
+ * allows to write into an otherwise const (volatile) value.
+ *
+ * - Use the RTEMS_DEQUALIFY() macro.
+ *
+ * - Check that the RTEMS_DEQUALIFY() macro returns a pointer which allows to
+ * write into an otherwise const volatile value.
+ *
+ * - Use the RTEMS_DEVOLATILE() macro.
+ *
+ * - Check that the RTEMS_DEVOLATILE() macro returns a pointer which allows
+ * to write into an otherwise volatile value.
+ *
+ * - Invoke the RTEMS_EXPAND() macro on an example.
+ *
+ * - Check that the argument of RTEMS_EXPAND() is expanded and returned.
+ *
+ * - Invoke the FALSE macro on an example.
+ *
+ * - Check that of FALSE is substituted by 0.
+ *
+ * - Invoke the RTEMS_HAVE_MEMBER_SAME_TYPE() macro on examples.
+ *
+ * - Check that of RTEMS_HAVE_MEMBER_SAME_TYPE() returns 0 and 1 depending on
+ * whether these types are compatible.
+ *
+ * - Use the RTEMS_INLINE_ROUTINE in the definition of function
+ * inline_routine_func() at the beginning of this file. Obtain the text the
+ * macro RTEMS_INLINE_ROUTINE produces.
+ *
+ * - Check that the RTEMS_INLINE_ROUTINE exists and that it produces the
+ * desired text.
+ *
+ * - Use a function declared with the RTEMS_MALLOCLIKE macro.
+ *
+ * - It cannot be checked that the RTEMS_MALLOCLIKE macro has the desired
+ * effect. Yet, the check confirms that such a macro exists and that it can
+ * be used on such a memory function and that it produces the correct code.
+ *
+ * - Use a function declared with the RTEMS_NO_INLINE macro.
+ *
+ * - It cannot be checked that the RTEMS_NO_INLINE macro has the desired
+ * effect. Yet, the check confirms that such a macro exists and that it can
+ * be used on such a function and that it produces the correct code.
+ *
+ * - Use of the RTEMS_NO_RETURN macro at the beginning of this file.
+ *
+ * - It cannot be checked that the RTEMS_NO_RETURN macro has the desired
+ * effect. It is only checked that such a macro exists.
+ *
+ * - Use the RTEMS_NOINIT macro on ``noinit_variable`` at the beginning of this
+ * file.
+ *
+ * - It cannot be checked that the RTEMS_NOINIT macro has the desired effect.
+ * Yet, the check confirms that such a macro exists and can be used.
+ *
+ * - Use the RTEMS_OBFUSCATE_VARIABLE() macro.
+ *
+ * - It cannot be checked that the RTEMS_OBFUSCATE_VARIABLE() macro has the
+ * desired effect. Yet, the check confirms that such a macro exists and can
+ * be used.
+ *
+ * - Use the RTEMS_PACKED macro.
+ *
+ * - Check that RTEMS_PACKED correctly aligns a structure member.
+ *
+ * - Check that RTEMS_PACKED correctly aligns all structure members.
+ *
+ * - Check that RTEMS_PACKED correctly enforces a minimal enum type.
+ *
+ * - Use the RTEMS_PREDICT_FALSE() macro.
+ *
+ * - It cannot be checked that the RTEMS_PREDICT_FALSE() macro has the
+ * desired effect. Yet, the check confirms that such a macro exists and can
+ * be used.
+ *
+ * - Use the RTEMS_PREDICT_TRUE() macro.
+ *
+ * - It cannot be checked that the RTEMS_PREDICT_TRUE() macro has the desired
+ * effect. Yet, the check confirms that such a macro exists and can be
+ * used.
+ *
+ * - Use a function declared with the RTEMS_PRINTFLIKE() macro.
+ *
+ * - It cannot automatically be checked that the RTEMS_PRINTFLIKE() macro has
+ * the desired effect. Yet, the check confirms that such a macro exists and
+ * that it can be used on such a printf-like function and that the argument
+ * numbers are correct.
+ *
+ * - Use the RTEMS_PURE macro at the beginning of this file.
+ *
+ * - It cannot be checked that the RTEMS_PURE macro has the desired effect.
+ * It is checked that such a macro exists.
+ *
+ * - Get the code the RTEMS_RETURN_ADDRESS() macro produces as string.
+ *
+ * - The check confirms that a RTEMS_RETURN_ADDRESS() macro exists and that
+ * it produces the correct code.
+ *
+ * - Use the RTEMS_SECTION() macro on ``section_variable`` and ``section_func``
+ * at the beginning of this file.
+ *
+ * - It cannot be checked that the RTEMS_SECTION() macro has the desired
+ * effect. Yet, the check confirms that such a macro exists and can be
+ * used.
+ *
+ * - Evaluate if RTEMS_STATIC_ANALYSIS is defined.
+ *
+ * - Check that RTEMS_STATIC_ANALYSIS was not defined.
+ *
+ * - Use the RTEMS_STATIC_ASSERT() macro.
+ *
+ * - It cannot be automatically check that the RTEMS_STATIC_ASSERT() macro
+ * has the desired effect. Yet, it can be checked that the macro exists and
+ * accepts the specified arguments.
+ *
+ * - Use the RTEMS_STRING() macro.
+ *
+ * - Check that the RTEMS_STRING() macro converts its arguments into a single
+ * string without applying pre-processor substitutions on its arguments.
+ *
+ * - Use the RTEMS_SYMBOL_NAME() macro with an example object.
+ *
+ * - Check that the RTEMS_SYMBOL_NAME() macro expands to the expected symbol
+ * name.
+ *
+ * - Invoke the TRUE macro on an example.
+ *
+ * - Check that of TRUE is substituted by 0.
+ *
+ * - Use of the RTEMS_TYPEOF_REFX() macro on several examples. This use is
+ * already the test as the statements will not compile without error if the
+ * macro did not evaluate to the correct type.
+ *
+ * - The checks here are proforma. The macro is tested by the fact that the
+ * action will not compile if the macro returns a wrong result.
+ *
+ * - Use the RTEMS_UNUSED macro. See also unused_func() at the beginning of
+ * this file.
+ *
+ * - It cannot automatically be checked that the RTEMS_UNUSED macro has the
+ * desired effect. It is checked that such a macro exists and one can
+ * manually check that no compiler warnings are produced for the
+ * unused_func().
+ *
+ * - It cannot automatically be checked that the RTEMS_UNUSED macro has the
+ * desired effect. It is checked that such a macro exists and one can
+ * manually check that no compiler warnings are produced for the
+ * unused_lable.
+ *
+ * - It cannot automatically be checked that the RTEMS_UNUSED macro has the
+ * desired effect. It is checked that such a macro exists and one can
+ * manually check that no compiler warnings are produced for the
+ * unused_struct.
+ *
+ * - It cannot automatically be checked that the RTEMS_UNUSED macro has the
+ * desired effect. It is checked that such a macro exists and one can
+ * manually check that no compiler warnings are produced for the unused
+ * items unused_var and the unused argument and variable in unused_func().
+ *
+ * - Use of the RTEMS_UNREACHABLE() macro in function definition of
+ * unreachable_func() at the beginning of this file.
+ *
+ * - It cannot be checked that the RTEMS_UNREACHABLE() macro has the desired
+ * effect. It is checked that such a macro exists and the compiler warning
+ * about the missing return statement is suppressed.
+ *
+ * - Use of the RTEMS_USED macro in function definition of used_func() at the
+ * beginning of this file and with used_var above.
+ *
+ * - It cannot be checked that the RTEMS_USED macro has the desired effect.
+ * It is checked that such a macro exists.
+ *
+ * - Use of the RTEMS_WARN_UNUSED_RESULT macro in function definition of
+ * warn_unused_func() at the beginning of this file.
+ *
+ * - It cannot be checked that the RTEMS_WARN_UNUSED_RESULT macro has the
+ * desired effect. The GNU C compiler should issue a warning about the
+ * disregarded result returned by the call to the ``warn_unused_func()``
+ * function.
+ *
+ * - Use of ``basedefs_weak_alias_0/1_func()`` which are defined with the
+ * RTEMS_WEAK_ALIAS() macro at the beginning of this file.
+ *
+ * - There exists no strong alias for basedefs_weak_alias_0_func(). Check
+ * that ori_func() and basedefs_weak_alias_0_func() are the same function.
+ *
+ * - File ``tc_basedefs_pndant.c`` defines a strong function for
+ * basedefs_weak_alias_1_func(). Check that ori_func() and
+ * basedefs_weak_alias_1_func() are not the same function.
+ *
+ * - Use of ``basedefs_weak_0/1_var`` and ``basedefs_weak_0/1_func()`` which
+ * are defined with the RTEMS_WEAK macro at the beginning of this file.
+ *
+ * - For ``basedefs_weak_0_var`` and ``basedefs_weak_0_func()`` there exists
+ * no other symbols with the same name. Hence, the checks test that the
+ * weak symbols are used.
+ *
+ * - ``basedefs_weak_1_var`` and ``basedefs_weak_1_func()`` are overwritten
+ * by strong symbols defined in file ``tc_basedefs_pendant.c``. Hence, the
+ * checks test that the strong variants are used.
+ *
+ * - Invoke the RTEMS_XCONCAT() macro on examples.
+ *
+ * - Check that the two arguments of RTEMS_XCONCAT() are concatenated without
+ * inserting new characters.
+ *
+ * - Check that the two arguments of RTEMS_XCONCAT() are substituted before
+ * they are concatenated.
+ *
+ * - Check that the two arguments of RTEMS_XCONCAT() are can be the macro
+ * itself.
+ *
+ * - Check that the result of the RTEMS_XCONCAT() expansion is subject to a
+ * further pre-processor substitution.
+ *
+ * - Use the RTEMS_XSTRING() macro.
+ *
+ * - Check that the RTEMS_XSTRING() macro applies pre-processor substitutions
+ * on its arguments and converts its arguments into a single string.
+ *
+ * - Use of the RTEMS_ZERO_LENGTH_ARRAY macro in a declaration of a structure.
+ *
+ * - Checked that the RTEMS_ZERO_LENGTH_ARRAY macro produces a structure
+ * similar to a structure with one element.
+ *
+ * - Use the RTEMS_DEFINE_GLOBAL_SYMBOL() macro at the beginning of this file
+ * and assign the address of the symbol to an object.
+ *
+ * - Check that the RTEMS_DEFINE_GLOBAL_SYMBOL() macro defines a global
+ * symbol with the correct value.
+ *
+ * @{
+ */
+
+#define WHITE_SPACE_STRING_MAX_LENGTH 80
+#define abccat concat
+#define abc ABC
+#define CON con
+#define CAT cat
+#define defcat concat
+#define GLOBAL_SYMBOL_VALULE( _hex ) 0x ## _hex
+#define EXPAND expand
+#define PREDICT_FALSE 1 -
+#define SECTION_NAME ".rtemsroset.test"
+#define STATIC_ASSERT_COND 0 +
+#define STRING_PREFIX str
+#define SYMBOL_NAME global_object
+#define _TO_STR2( _text ) #_text
+#define _TO_STR( _text ) _TO_STR2( _text )
+
+int global_object;
+
+extern int address_of_global_object;
+
+__asm__(
+ "\n\t.set " RTEMS_XSTRING( RTEMS_SYMBOL_NAME( address_of_global_object ) )
+ ", " RTEMS_XSTRING( RTEMS_SYMBOL_NAME( SYMBOL_NAME ) ) "\n"
+);
+
+/*
+ * For some reasons - which I fail to fully understand - _TO_STR()
+ * seems to remove spaces around `()` at times and at other times
+ * not. For example, I get
+ *
+ * * "__attribute__(( __malloc__ ))" or
+ * * "__attribute__((__malloc__))".
+ *
+ * To avoid trouble, the function below returns a version of a
+ * string without any spaces. Albeit, the implementation is rather
+ * brute and raw. It returns a pointer to a static buffer of fixed
+ * size. That will do for tests but not serve as generic function.
+ */
+static const char *remove_white_space( const char *str )
+{
+ char c;
+ int i = 0;
+ static char buffer[WHITE_SPACE_STRING_MAX_LENGTH] = {};
+
+ /* Sanity check */
+ if( strlen( str ) >= sizeof( buffer ) ) {
+ T_assert_true( false,
+ "Buffer too small; increase WHITE_SPACE_STRING_MAX_LENGTH" );
+ }
+
+ /* Copy string but skip white spaces */
+ do {
+ c = *( str++ );
+ if ( ' ' != c && '\t' !=c ) {
+ buffer[i++] = c;
+ }
+ } while ( '\0' != c );
+
+ return buffer;
+}
+
+static int alias_func( int i ) RTEMS_ALIAS( ori_func );
+
+typedef struct {
+ uint8_t c;
+ uint8_t aligned_member RTEMS_ALIGNED( 8 );
+} aligned_member_struct;
+
+static int concat( void )
+{
+ return 91;
+}
+
+RTEMS_CONST static int const_func( int arg )
+{
+ return 4 * arg;
+}
+
+RTEMS_COMPILER_NO_RETURN_ATTRIBUTE
+ static void compiler_no_return_attribute_func( int i );
+static void compiler_no_return_attribute_func( int i )
+{
+ while ( true ) {
+ /* Loop forever */
+ }
+}
+
+RTEMS_COMPILER_PURE_ATTRIBUTE static int compiler_pure_attribute_func( void )
+{
+ return 21;
+}
+
+static int global_symbol_base;
+
+RTEMS_DEFINE_GLOBAL_SYMBOL(
+ GLOBAL_SYMBOL,
+ RTEMS_SYMBOL_NAME( global_symbol_base ) + GLOBAL_SYMBOL_VALULE( abc )
+);
+
+RTEMS_DECLARE_GLOBAL_SYMBOL( global_symbol_2 );
+
+RTEMS_DEFINE_GLOBAL_SYMBOL( global_symbol_2, 0x123 );
+
+static const char * const volatile global_symbol_2_object = global_symbol_2;
+
+static int deprecated_func( int i ) RTEMS_DEPRECATED;
+static int deprecated_func( int i )
+{
+ return 3 * i;
+}
+
+static int expand( void )
+{
+ return 82;
+}
+
+RTEMS_INLINE_ROUTINE int inline_routine_func( int arg )
+{
+ return 1 << arg;
+}
+
+RTEMS_NO_INLINE static int no_inline_func( void )
+{
+ asm ("");
+ return 75;
+}
+
+RTEMS_NO_RETURN static void no_return_func( int i )
+{
+ while ( true ) {
+ /* Loop forever */
+ }
+}
+
+RTEMS_NOINIT static uint32_t noinit_variable;
+
+static int ori_func( int x )
+{
+ return 2 * x;
+}
+
+RTEMS_PRINTFLIKE(2, 3) static int printflike_func(
+ const char *prefix,
+ const char *fmt,
+ ...
+)
+{
+ int result;
+ va_list va_list;
+
+ T_printf( "%s: ", prefix );
+ va_start( va_list, fmt );
+ result = T_vprintf( fmt, va_list );
+ va_end( va_list );
+
+ return result;
+}
+
+RTEMS_PURE static int pure_func( void )
+{
+ return 21;
+}
+
+RTEMS_SECTION( ".rtemsrwset.test" ) static int section_var = 28;
+RTEMS_SECTION( SECTION_NAME ) static int section_func( int arg )
+{
+ return arg % 100;
+}
+
+static int unreachable_func( int arg )
+{
+ if ( 1 == arg % 100 ) {
+ return arg;
+ } else {
+ T_assert_true( false,
+ "Oops! Function caled with bad argument." );
+ RTEMS_UNREACHABLE();
+ }
+}
+
+RTEMS_USED static int used_var = 4711;
+RTEMS_USED static int used_func( void )
+{
+ return 35;
+}
+
+static int warn_unused_func( int arg ) RTEMS_WARN_UNUSED_RESULT;
+static int warn_unused_func( int arg )
+{
+ return arg / 3;
+}
+
+int basedefs_weak_alias_0_func( int i ) RTEMS_WEAK_ALIAS( ori_func );
+int basedefs_weak_alias_1_func( int i ) RTEMS_WEAK_ALIAS( ori_func );
+
+RTEMS_WEAK const volatile int basedefs_weak_0_var = 60;
+RTEMS_WEAK const volatile int basedefs_weak_1_var = 61;
+RTEMS_WEAK int basedefs_weak_0_func( void )
+{
+ return 63;
+}
+
+RTEMS_WEAK int basedefs_weak_1_func( void )
+{
+ return 64;
+}
+
+/**
+ * @brief Use the RTEMS_ALIAS() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_0( void )
+{
+ int alias_result;
+
+ alias_result = ori_func( 3 ) + alias_func( 5 );
+
+ /*
+ * Check that ori_func() and alias_func() are the same function.
+ */
+ T_step_eq_int( 0, alias_result, 16 );
+}
+
+/**
+ * @brief Use the RTEMS_ALIGN_DOWN() macro in various examples.
+ */
+static void RtemsBasedefsValBasedefs_Action_1( void )
+{
+ int align_down0_result;
+ int align_down1_result;
+ int align_down2_result;
+ int align_down3_result;
+ int align_down4_result;
+ int align_down5_result;
+ int align_down6_result;
+ int align_down7_result;
+ int align_down8_result;
+ int align_down9_result;
+
+ align_down0_result = RTEMS_ALIGN_DOWN( 0, 1 );
+ align_down1_result = RTEMS_ALIGN_DOWN( 0, 4 );
+ align_down2_result = RTEMS_ALIGN_DOWN( 1, 2 );
+ align_down3_result = RTEMS_ALIGN_DOWN( 2, 2 );
+ align_down4_result = RTEMS_ALIGN_DOWN( 3, 2 );
+ align_down5_result = RTEMS_ALIGN_DOWN( 4, 2 );
+ align_down6_result = RTEMS_ALIGN_DOWN( 5, 2 );
+ align_down7_result = RTEMS_ALIGN_DOWN( 255, 16 );
+ align_down8_result = RTEMS_ALIGN_DOWN( 256, 16 );
+ align_down9_result = RTEMS_ALIGN_DOWN( 257, 16 );
+
+ /*
+ * Check that RTEMS_ALIGN_DOWN() calculates the expected result and is
+ * side-effect free.
+ */
+ T_step_eq_int( 1, align_down0_result, 0 );
+ T_step_eq_int( 2, align_down1_result, 0 );
+ T_step_eq_int( 3, align_down2_result, 0 );
+ T_step_eq_int( 4, align_down3_result, 2 );
+ T_step_eq_int( 5, align_down4_result, 2 );
+ T_step_eq_int( 6, align_down5_result, 4 );
+ T_step_eq_int( 7, align_down6_result, 4 );
+ T_step_eq_int( 8, align_down7_result, 240 );
+ T_step_eq_int( 9, align_down8_result, 256 );
+ T_step_eq_int( 10, align_down9_result, 256 );
+}
+
+/**
+ * @brief Use the RTEMS_ALIGN_UP() macro in various examples.
+ */
+static void RtemsBasedefsValBasedefs_Action_2( void )
+{
+ int align_up0_result;
+ int align_up1_result;
+ int align_up2_result;
+ int align_up3_result;
+ int align_up4_result;
+ int align_up5_result;
+ int align_up6_result;
+ int align_up7_result;
+ int align_up8_result;
+ int align_up9_result;
+
+ align_up0_result = RTEMS_ALIGN_UP( 0, 1 );
+ align_up1_result = RTEMS_ALIGN_UP( 0, 4 );
+ align_up2_result = RTEMS_ALIGN_UP( 1, 2 );
+ align_up3_result = RTEMS_ALIGN_UP( 2, 2 );
+ align_up4_result = RTEMS_ALIGN_UP( 3, 2 );
+ align_up5_result = RTEMS_ALIGN_UP( 4, 2 );
+ align_up6_result = RTEMS_ALIGN_UP( 5, 2 );
+ align_up7_result = RTEMS_ALIGN_UP( 255, 16 );
+ align_up8_result = RTEMS_ALIGN_UP( 256, 16 );
+ align_up9_result = RTEMS_ALIGN_UP( 257, 16 );
+
+ /*
+ * Check that RTEMS_ALIGN_UP() calculates the expected result and is
+ * side-effect free.
+ */
+ T_step_eq_int( 11, align_up0_result, 0 );
+ T_step_eq_int( 12, align_up1_result, 0 );
+ T_step_eq_int( 13, align_up2_result, 2 );
+ T_step_eq_int( 14, align_up3_result, 2 );
+ T_step_eq_int( 15, align_up4_result, 4 );
+ T_step_eq_int( 16, align_up5_result, 4 );
+ T_step_eq_int( 17, align_up6_result, 6 );
+ T_step_eq_int( 18, align_up7_result, 256 );
+ T_step_eq_int( 19, align_up8_result, 256 );
+ T_step_eq_int( 20, align_up9_result, 272 );
+}
+
+/**
+ * @brief Use the RTEMS_ALIGNED() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_3( void )
+{
+ char unaligned_var = 'c';
+ char aligned_var RTEMS_ALIGNED( 8 ) = 'd';
+
+ (void) unaligned_var;
+
+ /*
+ * Check that RTEMS_ALIGNED() correctly aligns a variable on the stack and a
+ * structure member.
+ */
+ T_step_eq_int( 21, ( ( uintptr_t ) &aligned_var ) % 8, 0 );
+ T_step_eq_int( 22,
+ offsetof( aligned_member_struct, aligned_member ) % 8, 0 );
+}
+
+/**
+ * @brief Use the RTEMS_ALIGNOF() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_4( void )
+{
+ size_t alignof_char = RTEMS_ALIGNOF( char );
+ size_t alignof_long = RTEMS_ALIGNOF( long );
+ size_t alignof_long_array = RTEMS_ALIGNOF( long[3] );
+ size_t alignof_not_eval_array = RTEMS_ALIGNOF( long[7 / 0] );
+
+ /*
+ * Check that the RTEMS_ALIGNOF() macro results in the alignment of the type.
+ */
+ T_step_eq_sz( 23, alignof_char, 1 );
+ T_step_eq_sz( 24, alignof_long, alignof_long_array );
+
+ /*
+ * If the RTEMS_ALIGNOF() macro would evaluate its argument, it could not
+ * figure out how much menory to reserve for it.
+ */
+ T_step_eq_sz( 25, alignof_long, alignof_not_eval_array );
+
+ /*
+ * If the RTEMS_ALIGNOF() macro would evaluate the size expression, the
+ * division by zero would cause an error.
+ */
+ T_step_eq_sz( 26, alignof_long, alignof_not_eval_array );
+
+ /*
+ * Ensure the constant value of the RTEMS_ALIGNOF() macro is of type size_t.
+ */
+ T_step_true( 27,
+ __builtin_types_compatible_p( __typeof__( RTEMS_ALIGNOF( char ) ),
+ size_t ) );
+}
+
+/**
+ * @brief Use a function declared with the RTEMS_ALLOC_ALIGN() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_5( void )
+{
+ void *free_ptr;
+ void *alloc_align_ptr;
+ alloc_align_ptr = basedefs_alloc_align_func( 1024, &free_ptr, 64 );
+ basedefs_free( free_ptr );
+
+ /*
+ * It cannot be checked that the RTEMS_ALLOC_ALIGN() macro has the desired
+ * effect. Yet, the check confirms that such a macro exists and that it can
+ * be used on such a memory function and that the argument counting starts at
+ * 1.
+ */
+ T_step_not_null( 28, alloc_align_ptr );
+ T_step_eq_int( 29, ( ( uintptr_t ) alloc_align_ptr ) % 64, 0 );
+ T_step_ge_uptr( 30, ( ( uintptr_t ) alloc_align_ptr ),
+ ( ( uintptr_t ) free_ptr ) );
+ T_step_lt_uptr( 31, ( ( uintptr_t ) alloc_align_ptr ),
+ ( ( uintptr_t ) free_ptr ) + 64 );
+}
+
+/**
+ * @brief Use a function declared with the RTEMS_ALLOC_SIZE() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_6( void )
+{
+ void *alloc_size_ptr;
+ alloc_size_ptr = basedefs_alloc_size_func( 1024 );
+ basedefs_free( alloc_size_ptr );
+
+ /*
+ * It cannot be checked that the RTEMS_ALLOC_SIZE() macro has the desired
+ * effect. Yet, the check confirms that such a macro exists and that it can
+ * be used on such a memory function and that the argument counting starts at
+ * 1.
+ */
+ T_step_not_null( 32, alloc_size_ptr );
+}
+
+/**
+ * @brief Use a function declared with the RTEMS_ALLOC_SIZE_2() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_7( void )
+{
+ void *alloc_size_2_ptr;
+ alloc_size_2_ptr = basedefs_alloc_size_2_func( 8, 128 );
+ basedefs_free( alloc_size_2_ptr );
+
+ /*
+ * It cannot be checked that the RTEMS_ALLOC_SIZE_2() macro has the desired
+ * effect. Yet, the check confirms that such a macro exists and that it can
+ * be used on such a memory function and that the argument counting starts at
+ * 1.
+ */
+ T_step_not_null( 33, alloc_size_2_ptr );
+}
+
+/**
+ * @brief Use the RTEMS_ARRAY_SIZE() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_8( void )
+{
+ int array[] = { 10, 20, 30, 40, 50 };
+ unsigned char array2[12];
+ int array_size = RTEMS_ARRAY_SIZE(array);
+ int array2_size = RTEMS_ARRAY_SIZE(array2);
+
+ /*
+ * Check that the calculated size of the arrays fit their definition.
+ */
+ T_step_eq_sz( 34, array_size, 5 );
+ T_step_eq_sz( 35, array2_size, 12 );
+}
+
+/**
+ * @brief Use the RTEMS_COMPILER_DEPRECATED_ATTRIBUTE macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_9( void )
+{
+ int compiler_deprecated_attribute RTEMS_COMPILER_DEPRECATED_ATTRIBUTE = 42;
+
+ /*
+ * It cannot automatically be checked that the
+ * RTEMS_COMPILER_DEPRECATED_ATTRIBUTE macro has the desired effect. The gcc
+ * compiler should issue a warning about the use of a deprecated variable on
+ * the above line where the ``compiler_deprecated_attribute`` is used.
+ */
+ /*
+ * Derivation from Coding Style:
+ * The following code suppresses a compiler warning (instead of fixing
+ * it).
+ * Rational: The variable compiler_deprecated_attribute is not really
+ * deprecated but its purpose is to test the RTEMS_DEPRECATED macro.
+ * The RTEMS_DEPRECATED macro must result in a compiler warning here.
+ */
+ _Pragma( "GCC diagnostic push" )
+ _Pragma( "GCC diagnostic ignored \"-Wdeprecated-declarations\"" )
+ T_step_eq_int( 36, compiler_deprecated_attribute, 42 );
+ _Pragma( "GCC diagnostic pop" )
+}
+
+/**
+ * @brief Use the RTEMS_COMPILER_MEMORY_BARRIER() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_10( void )
+{
+ RTEMS_COMPILER_MEMORY_BARRIER();
+
+ /*
+ * It cannot be checked that the RTEMS_COMPILER_MEMORY_BARRIER() macro has
+ * the desired effect. It is only checked that such a macro exists.
+ */
+
+}
+
+/**
+ * @brief Use of the RTEMS_COMPILER_NO_RETURN_ATTRIBUTE macro at the beginning
+ * of this file.
+ */
+static void RtemsBasedefsValBasedefs_Action_11( void )
+{
+ (void) compiler_no_return_attribute_func;
+
+ /*
+ * It cannot be checked that the RTEMS_COMPILER_NO_RETURN_ATTRIBUTE macro has
+ * the desired effect. It is only checked that such a macro exists.
+ */
+
+}
+
+/**
+ * @brief Use the RTEMS_COMPILER_PACKED_ATTRIBUTE macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_12( void )
+{
+ typedef struct {
+ uint8_t c;
+ RTEMS_COMPILER_PACKED_ATTRIBUTE uint32_t i;
+ } compiler_packed_attribute_struct;
+ int compiler_packed_attribute_offset =
+ offsetof( compiler_packed_attribute_struct, i );
+
+ /*
+ * Check that RTEMS_COMPILER_PACKED_ATTRIBUTE correctly aligns a structure
+ * member.
+ */
+ T_step_eq_int( 37, compiler_packed_attribute_offset, 1 );
+}
+
+/**
+ * @brief Use the RTEMS_COMPILER_PURE_ATTRIBUTE macro at the beginning of this
+ * file.
+ */
+static void RtemsBasedefsValBasedefs_Action_13( void )
+{
+ int compiler_pure_attribute_result;
+ int compiler_pure_attribute_result_2;
+ compiler_pure_attribute_result = compiler_pure_attribute_func();
+ compiler_pure_attribute_result_2 =
+ compiler_pure_attribute_func();
+
+ /*
+ * It cannot be checked that the RTEMS_COMPILER_PURE_ATTRIBUTE macro has the
+ * desired effect. It is checked that such a macro exists.
+ */
+ T_step_eq_int( 38, compiler_pure_attribute_result, 21 );
+ T_step_eq_int( 39, compiler_pure_attribute_result_2, 21 );
+}
+
+/**
+ * @brief Use the RTEMS_COMPILER_UNUSED_ATTRIBUTE macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_14( void )
+{
+ int compiler_unused_attribute_var RTEMS_COMPILER_UNUSED_ATTRIBUTE;
+
+ /*
+ * It cannot automatically be checked that the
+ * RTEMS_COMPILER_UNUSED_ATTRIBUTE macro has the desired effect. It is
+ * checked that such a macro exists and one can manually check that no
+ * compiler warnings are produced for the compiler_unused_attribute_var.
+ */
+
+}
+
+/**
+ * @brief Invoke the RTEMS_CONCAT() macro on examples.
+ */
+static void RtemsBasedefsValBasedefs_Action_15( void )
+{
+ int concat0_result;
+ int concat1_result;
+ concat0_result = RTEMS_CONCAT( con, cat )();
+ concat1_result = RTEMS_CONCAT( abc, cat )();
+
+ /*
+ * Check that the two arguments of RTEMS_CONCAT() are concatenated to a new
+ * token.
+ */
+ T_step_eq_int( 40, concat0_result, 91 );
+
+ /*
+ * Check that the result of the RTEMS_CONCAT() expansion is subject to a
+ * further pre-processor substitution.
+ */
+ T_step_eq_int( 41, concat1_result, 91 );
+}
+
+/**
+ * @brief Use the RTEMS_CONST macro at the beginning of this file.
+ */
+static void RtemsBasedefsValBasedefs_Action_16( void )
+{
+ int const_result;
+ int const_result_2;
+ const_result = const_func( 7 );
+ const_result_2 = const_func( 7 );
+
+ /*
+ * It cannot be checked that the RTEMS_CONST macro has the desired effect. It
+ * is checked that such a macro exists.
+ */
+ T_step_eq_int( 42, const_result, 28 );
+ T_step_eq_int( 43, const_result_2, 28 );
+}
+
+/**
+ * @brief Use the RTEMS_CONTAINER_OF() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_17( void )
+{
+ typedef struct {
+ int a;
+ int b;
+ } container_of_struct;
+
+ container_of_struct container_of_struct_var;
+ int *container_of_struct_b_adr = &container_of_struct_var.b;
+ container_of_struct *container_of_struct_adr;
+ container_of_struct_adr =
+ RTEMS_CONTAINER_OF( container_of_struct_b_adr, container_of_struct, b );
+
+ /*
+ * Check that the RTEMS_CONTAINER_OF() macro evaluates to a pointer to
+ * container_of_struct_var.
+ */
+ T_step_eq_ptr( 44,
+ container_of_struct_adr, &container_of_struct_var );
+}
+
+/**
+ * @brief Use the RTEMS_DECLARE_GLOBAL_SYMBOL() macro in the file
+ * tc-basedefs-pendant.h.
+ */
+static void RtemsBasedefsValBasedefs_Action_18( void )
+{
+ /* No action */
+
+ /*
+ * Check that the RTEMS_DECLARE_GLOBAL_SYMBOL() macro declares a global
+ * symbol which can be accessed by function basedefs_get_global_symbol()
+ * which is defined in a file different from the file in which the gobal
+ * symbol is defined.
+ */
+ T_step_eq_uptr(
+ 45,
+ basedefs_get_global_symbol() - (uintptr_t) &global_symbol_base,
+ 0xabc
+ );
+}
+
+/**
+ * @brief Use the RTEMS_DECONST() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_19( void )
+{
+ const int deconst_array[] = { 52, 55 };
+ int *deconst_pointer;
+ deconst_pointer = RTEMS_DECONST( int *, deconst_array );
+
+ /*
+ * Check that the RTEMS_DECONST() macro returns a pointer which allows to
+ * write into an otherwise const value.
+ */
+ T_step_eq_int( 46, deconst_pointer[0], 52 );
+ T_step_eq_int( 47, deconst_pointer[1], 55 );
+ deconst_pointer[1] = 13;
+ T_step_eq_int( 48, deconst_pointer[1], 13 );
+}
+
+/**
+ * @brief Use the RTEMS_DEFINE_GLOBAL_SYMBOL() macro at the beginning of this
+ * file.
+ */
+static void RtemsBasedefsValBasedefs_Action_20( void )
+{
+ /* No action */
+
+ /*
+ * Check that the RTEMS_DEFINE_GLOBAL_SYMBOL() macro defines a global symbol
+ * with the correct value.
+ */
+ T_step_eq_uptr(
+ 49,
+ (uintptr_t) global_symbol - (uintptr_t) &global_symbol_base,
+ 0xabc
+ );
+}
+
+/**
+ * @brief Use a function declared with the RTEMS_DEPRECATED macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_21( void )
+{
+ int deprecated_result;
+ /*
+ * Derivation from Coding Style:
+ * The following code suppresses a compiler warning (instead of fixing it).
+ * Rational: The function deprecated_func() is not really deprecated
+ * but its purpose is to test the RTEMS_DEPRECATED macro.
+ * The RTEMS_DEPRECATED macro must result in a compiler warning here.
+ */
+ _Pragma( "GCC diagnostic push" )
+ _Pragma( "GCC diagnostic ignored \"-Wdeprecated-declarations\"" )
+ deprecated_result = deprecated_func( 5 );
+ _Pragma( "GCC diagnostic pop" )
+
+ /*
+ * It cannot automatically be checked that the RTEMS_DEPRECATED macro has the
+ * desired effect. The gcc compiler should issue a warning about the use of a
+ * deprecated function on the above line where the ``deprecated_func`` is
+ * used.
+ */
+ T_step_eq_int( 50, deprecated_result, 15 );
+}
+
+/**
+ * @brief Use the RTEMS_DEQUALIFY_DEPTHX() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_22( void )
+{
+ const volatile int dequalify_depthx_array[] = { 52, 55 };
+ const char dequalify_depthx_var = 'a';
+ const char *dequalify_depthx_one_pointer = &dequalify_depthx_var;
+ const char **dequalify_depthx_two_pointer =
+ &dequalify_depthx_one_pointer;
+ int *dequalify_depthx_pointer;
+ volatile char **dequalify_depthx_twice_pointer;
+ dequalify_depthx_pointer =
+ RTEMS_DEQUALIFY_DEPTHX( *, int *, dequalify_depthx_array );
+ dequalify_depthx_twice_pointer = RTEMS_DEQUALIFY_DEPTHX(
+ **, volatile char **, dequalify_depthx_two_pointer );
+
+ /*
+ * Check that the RTEMS_DEQUALIFY_DEPTHX() macro returns a pointer which
+ * allows to write into an otherwise const (volatile) value.
+ */
+ T_step_eq_int( 51, dequalify_depthx_pointer[0], 52 );
+ T_step_eq_int( 52, dequalify_depthx_pointer[1], 55 );
+ dequalify_depthx_pointer[0] = 13;
+ T_step_eq_int( 53, dequalify_depthx_pointer[0], 13 );
+ T_step_eq_char( 54, **dequalify_depthx_twice_pointer, 'a' );
+ **dequalify_depthx_twice_pointer = 'Z';
+ T_step_eq_char( 55, **dequalify_depthx_twice_pointer, 'Z' );
+}
+
+/**
+ * @brief Use the RTEMS_DEQUALIFY() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_23( void )
+{
+ const volatile int dequalify_array[] = { 52, 55 };
+ int *dequalify_pointer;
+ dequalify_pointer = RTEMS_DECONST( int *, dequalify_array );
+
+ /*
+ * Check that the RTEMS_DEQUALIFY() macro returns a pointer which allows to
+ * write into an otherwise const volatile value.
+ */
+ T_step_eq_int( 56, dequalify_pointer[0], 52 );
+ T_step_eq_int( 57, dequalify_pointer[1], 55 );
+ dequalify_pointer[0] = 13;
+ T_step_eq_int( 58, dequalify_pointer[0], 13 );
+}
+
+/**
+ * @brief Use the RTEMS_DEVOLATILE() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_24( void )
+{
+ volatile int devolatile_array[] = { 52, 55 };
+ int *devolatile_pointer;
+ devolatile_pointer = RTEMS_DEVOLATILE( int *, devolatile_array );
+
+ /*
+ * Check that the RTEMS_DEVOLATILE() macro returns a pointer which allows to
+ * write into an otherwise volatile value.
+ */
+ T_step_eq_int( 59, devolatile_pointer[0], 52 );
+ T_step_eq_int( 60, devolatile_pointer[1], 55 );
+ devolatile_pointer[1] = 13;
+ T_step_eq_int( 61, devolatile_pointer[1], 13 );
+}
+
+/**
+ * @brief Invoke the RTEMS_EXPAND() macro on an example.
+ */
+static void RtemsBasedefsValBasedefs_Action_25( void )
+{
+ int expand_result;
+ expand_result = RTEMS_EXPAND( EXPAND )();
+
+ /*
+ * Check that the argument of RTEMS_EXPAND() is expanded and returned.
+ */
+ T_step_eq_int( 62, expand_result, 82 );
+}
+
+/**
+ * @brief Invoke the FALSE macro on an example.
+ */
+static void RtemsBasedefsValBasedefs_Action_26( void )
+{
+ char *false_result;
+ false_result = _TO_STR( FALSE );
+
+ /*
+ * Check that of FALSE is substituted by 0.
+ */
+ T_step_eq_str( 63, false_result, "0" );
+}
+
+/**
+ * @brief Invoke the RTEMS_HAVE_MEMBER_SAME_TYPE() macro on examples.
+ */
+static void RtemsBasedefsValBasedefs_Action_27( void )
+{
+ typedef union {
+ short s;
+ int **i;
+ char *c;
+ int a[5];
+ } same_type_union;
+ typedef struct {
+ const short u;
+ short v;
+ int *w;
+ char *x;
+ volatile int y[5];
+ int z;
+ } same_type_struct;
+ int same_type_result_0 = RTEMS_HAVE_MEMBER_SAME_TYPE(
+ same_type_union, s, same_type_struct, v );
+ int same_type_result_1 = RTEMS_HAVE_MEMBER_SAME_TYPE(
+ same_type_union, s, same_type_struct, z );
+ int same_type_result_2 = RTEMS_HAVE_MEMBER_SAME_TYPE(
+ same_type_union, i, same_type_struct, w );
+ int same_type_result_3 = RTEMS_HAVE_MEMBER_SAME_TYPE(
+ same_type_union, c, same_type_struct, x );
+ int same_type_result_4 = RTEMS_HAVE_MEMBER_SAME_TYPE(
+ same_type_union, a, same_type_struct, y );
+ int same_type_result_5 = RTEMS_HAVE_MEMBER_SAME_TYPE(
+ same_type_union, s, same_type_union, s );
+ int same_type_result_6 = RTEMS_HAVE_MEMBER_SAME_TYPE(
+ same_type_union, i, same_type_union, i );
+ int same_type_result_7 = RTEMS_HAVE_MEMBER_SAME_TYPE(
+ same_type_union, s, same_type_struct, y );
+ int same_type_result_8 = RTEMS_HAVE_MEMBER_SAME_TYPE(
+ same_type_union, a, same_type_struct, w );
+ int same_type_result_9 = RTEMS_HAVE_MEMBER_SAME_TYPE(
+ same_type_union, s, same_type_struct, u );
+
+ /*
+ * Check that of RTEMS_HAVE_MEMBER_SAME_TYPE() returns 0 and 1 depending on
+ * whether these types are compatible.
+ */
+ T_step_eq_int( 64, same_type_result_0, 1 );
+ T_step_eq_int( 65, same_type_result_1, 0 );
+ T_step_eq_int( 66, same_type_result_2, 0 );
+ T_step_eq_int( 67, same_type_result_3, 1 );
+ T_step_eq_int( 68, same_type_result_4, 1 );
+ T_step_eq_int( 69, same_type_result_5, 1 );
+ T_step_eq_int( 70, same_type_result_6, 1 );
+ T_step_eq_int( 71, same_type_result_7, 0 );
+ T_step_eq_int( 72, same_type_result_8, 0 );
+ T_step_eq_int( 73, same_type_result_9, 1 );
+}
+
+/**
+ * @brief Use the RTEMS_INLINE_ROUTINE in the definition of function
+ * inline_routine_func() at the beginning of this file. Obtain the text the
+ * macro RTEMS_INLINE_ROUTINE produces.
+ */
+static void RtemsBasedefsValBasedefs_Action_28( void )
+{
+ const int inline_routine_step = 74;
+ int inline_routine_result;
+ char *inline_routine_text;
+ inline_routine_result = inline_routine_func( 3 );
+ inline_routine_text = _TO_STR( RTEMS_INLINE_ROUTINE );
+
+ /*
+ * Check that the RTEMS_INLINE_ROUTINE exists and that it produces the
+ * desired text.
+ */
+ if( 0 == strcmp( "static inline", inline_routine_text ) ) {
+ T_step_eq_str( inline_routine_step,
+ inline_routine_text, "static inline" );
+ } else {
+ T_step_eq_str( inline_routine_step,
+ inline_routine_text, "static __inline__" );
+ }
+ T_step_eq_int( 75, inline_routine_result, 8 );
+}
+
+/**
+ * @brief Use a function declared with the RTEMS_MALLOCLIKE macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_29( void )
+{
+ void *malloclike_ptr;
+ /*
+ * If this code is not compiled using GNU C, I still have to run a check
+ * to avoid trouble with the {step} counter of the checks.
+ */
+ const char *malloclike_text = "__attribute__((__malloc__))";
+ malloclike_ptr = basedefs_malloclike_func( 102 );
+ basedefs_free( malloclike_ptr );
+ #if defined( __GNUC__ )
+ malloclike_text = remove_white_space( _TO_STR( RTEMS_MALLOCLIKE ) );
+ #endif
+
+ /*
+ * It cannot be checked that the RTEMS_MALLOCLIKE macro has the desired
+ * effect. Yet, the check confirms that such a macro exists and that it can
+ * be used on such a memory function and that it produces the correct code.
+ */
+ T_step_not_null( 76, malloclike_ptr );
+ T_step_eq_str( 77, malloclike_text, "__attribute__((__malloc__))" );
+}
+
+/**
+ * @brief Use a function declared with the RTEMS_NO_INLINE macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_30( void )
+{
+ int no_inline_result;
+ /*
+ * If this code is not compiled using GNU C, I still have to run a check
+ * to avoid trouble with the {step} counter of the checks.
+ */
+ const char *no_inline_text = "__attribute__((__noinline__))";
+ no_inline_result = no_inline_func();
+ #if defined( __GNUC__ )
+ no_inline_text = remove_white_space( _TO_STR( RTEMS_NO_INLINE ) );
+ #endif
+
+ /*
+ * It cannot be checked that the RTEMS_NO_INLINE macro has the desired
+ * effect. Yet, the check confirms that such a macro exists and that it can
+ * be used on such a function and that it produces the correct code.
+ */
+ T_step_eq_int( 78, no_inline_result, 75 );
+ T_step_eq_str( 79, no_inline_text, "__attribute__((__noinline__))" );
+}
+
+/**
+ * @brief Use of the RTEMS_NO_RETURN macro at the beginning of this file.
+ */
+static void RtemsBasedefsValBasedefs_Action_31( void )
+{
+ (void) no_return_func;
+
+ /*
+ * It cannot be checked that the RTEMS_NO_RETURN macro has the desired
+ * effect. It is only checked that such a macro exists.
+ */
+
+}
+
+/**
+ * @brief Use the RTEMS_NOINIT macro on ``noinit_variable`` at the beginning of
+ * this file.
+ */
+static void RtemsBasedefsValBasedefs_Action_32( void )
+{
+ /* No action */
+
+ /*
+ * It cannot be checked that the RTEMS_NOINIT macro has the desired effect.
+ * Yet, the check confirms that such a macro exists and can be used.
+ */
+ T_step_not_null( 80, &noinit_variable );
+}
+
+/**
+ * @brief Use the RTEMS_OBFUSCATE_VARIABLE() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_33( void )
+{
+ short obfuscate_variable = 66;
+ RTEMS_OBFUSCATE_VARIABLE( obfuscate_variable );
+
+ /*
+ * It cannot be checked that the RTEMS_OBFUSCATE_VARIABLE() macro has the
+ * desired effect. Yet, the check confirms that such a macro exists and can
+ * be used.
+ */
+ T_step_eq_int( 81, obfuscate_variable, 66 );
+}
+
+/**
+ * @brief Use the RTEMS_PACKED macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_34( void )
+{
+ int packed_offset;
+ int packed_full_i_offset;
+ int packed_full_j_offset;
+ int packed_enum_size;
+ typedef struct {
+ uint8_t c;
+ RTEMS_PACKED uint32_t i;
+ } packed_struct;
+ typedef struct RTEMS_PACKED {
+ uint8_t c;
+ uint32_t i;
+ uint32_t j;
+ } packed_full_struct;
+ typedef enum RTEMS_PACKED {
+ red = 1,
+ green,
+ yellow,
+ blue = 255
+ } packed_enum;
+ packed_offset = offsetof( packed_struct, i );
+ packed_full_i_offset = offsetof( packed_full_struct, i );
+ packed_full_j_offset = offsetof( packed_full_struct, j );
+ packed_enum_size = sizeof( packed_enum );
+
+ /*
+ * Check that RTEMS_PACKED correctly aligns a structure member.
+ */
+ T_step_eq_int( 82, packed_offset, 1 );
+
+ /*
+ * Check that RTEMS_PACKED correctly aligns all structure members.
+ */
+ T_step_eq_int( 83, packed_full_i_offset, 1 );
+ T_step_eq_int( 84, packed_full_j_offset, 5 );
+
+ /*
+ * Check that RTEMS_PACKED correctly enforces a minimal enum type.
+ */
+ T_step_eq_int( 85, packed_enum_size, 1 );
+}
+
+/**
+ * @brief Use the RTEMS_PREDICT_FALSE() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_35( void )
+{
+ /* No action */
+
+ /*
+ * It cannot be checked that the RTEMS_PREDICT_FALSE() macro has the desired
+ * effect. Yet, the check confirms that such a macro exists and can be used.
+ */
+ T_step_eq_int( 86, RTEMS_PREDICT_FALSE( PREDICT_FALSE 1 ), 0 );
+}
+
+/**
+ * @brief Use the RTEMS_PREDICT_TRUE() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_36( void )
+{
+ /* No action */
+
+ /*
+ * It cannot be checked that the RTEMS_PREDICT_TRUE() macro has the desired
+ * effect. Yet, the check confirms that such a macro exists and can be used.
+ */
+ T_step_eq_int( 87, RTEMS_PREDICT_TRUE( 6 - 5 ), 1 );
+}
+
+/**
+ * @brief Use a function declared with the RTEMS_PRINTFLIKE() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_37( void )
+{
+ int printflike_result;
+ printflike_result = printflike_func(
+ "RTEMS_PRINTFLIKE",
+ "%d %lx %s\n",
+ 123,
+ 0xABCDEFL,
+ "test output"
+ );
+
+ /*
+ * It cannot automatically be checked that the RTEMS_PRINTFLIKE() macro has
+ * the desired effect. Yet, the check confirms that such a macro exists and
+ * that it can be used on such a printf-like function and that the argument
+ * numbers are correct.
+ */
+ T_step_eq_int( 88, printflike_result, 23 );
+}
+
+/**
+ * @brief Use the RTEMS_PURE macro at the beginning of this file.
+ */
+static void RtemsBasedefsValBasedefs_Action_38( void )
+{
+ int pure_result;
+ int pure_result_2;
+ pure_result = pure_func();
+ pure_result_2 = pure_func();
+
+ /*
+ * It cannot be checked that the RTEMS_PURE macro has the desired effect. It
+ * is checked that such a macro exists.
+ */
+ T_step_eq_int( 89, pure_result, 21 );
+ T_step_eq_int( 90, pure_result_2, 21 );
+}
+
+/**
+ * @brief Get the code the RTEMS_RETURN_ADDRESS() macro produces as string.
+ */
+static void RtemsBasedefsValBasedefs_Action_39( void )
+{
+ /*
+ * If this code is not compiled using GNU C, I still have to run a check
+ * to avoid trouble with the {step} counter of the checks.
+ */
+ const char *return_address_text = "__builtin_return_address(0)";
+ #if defined( __GNUC__ )
+ return_address_text =
+ remove_white_space( _TO_STR( RTEMS_RETURN_ADDRESS() ) );
+ #endif
+
+ /*
+ * The check confirms that a RTEMS_RETURN_ADDRESS() macro exists and that it
+ * produces the correct code.
+ */
+ T_step_eq_str( 91,
+ return_address_text, "__builtin_return_address(0)" );
+}
+
+/**
+ * @brief Use the RTEMS_SECTION() macro on ``section_variable`` and
+ * ``section_func`` at the beginning of this file.
+ */
+static void RtemsBasedefsValBasedefs_Action_40( void )
+{
+ short section_result;
+ section_result = section_func( 1234567 );
+
+ /*
+ * It cannot be checked that the RTEMS_SECTION() macro has the desired
+ * effect. Yet, the check confirms that such a macro exists and can be used.
+ */
+ T_step_eq_int( 92, section_var, 28 );
+ T_step_eq_int( 93, section_result, 67 );
+}
+
+/**
+ * @brief Evaluate if RTEMS_STATIC_ANALYSIS is defined.
+ */
+static void RtemsBasedefsValBasedefs_Action_41( void )
+{
+ #if defined(RTEMS_STATIC_ANALYSIS)
+ bool defined = true;
+ #else
+ bool defined = false;
+ #endif
+
+ /*
+ * Check that RTEMS_STATIC_ANALYSIS was not defined.
+ */
+ T_step_false( 94, defined );
+}
+
+/**
+ * @brief Use the RTEMS_STATIC_ASSERT() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_42( void )
+{
+ RTEMS_STATIC_ASSERT( STATIC_ASSERT_COND 1, RTEMS_STATIC_ASSERT_test );
+
+ /*
+ * It cannot be automatically check that the RTEMS_STATIC_ASSERT() macro has
+ * the desired effect. Yet, it can be checked that the macro exists and
+ * accepts the specified arguments.
+ */
+
+}
+
+/**
+ * @brief Use the RTEMS_STRING() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_43( void )
+{
+ const char *string_var;
+ const char *string_empty_var;
+ const char *string_multi_args_var;
+ /* strange spacing and tabs belong to the test */
+ string_var = RTEMS_STRING( \\ STRING_PREFIX cat""\n );
+ string_empty_var = RTEMS_STRING();
+ string_multi_args_var = RTEMS_STRING( STRING_PREFIX, "abc", DEF );
+
+ /*
+ * Check that the RTEMS_STRING() macro converts its arguments into a single
+ * string without applying pre-processor substitutions on its arguments.
+ */
+ T_step_eq_str( 95, string_var, "\\ STRING_PREFIX cat\"\"\n" );
+ T_step_eq_str( 96, string_empty_var, "" );
+ T_step_eq_str( 97, string_multi_args_var,
+ "STRING_PREFIX, \"abc\", DEF" );
+}
+
+/**
+ * @brief Use the RTEMS_SYMBOL_NAME() macro with an example object.
+ */
+static void RtemsBasedefsValBasedefs_Action_44( void )
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the RTEMS_SYMBOL_NAME() macro expands to the expected symbol
+ * name.
+ */
+ T_step_eq_ptr( 98, &global_object, &address_of_global_object );
+}
+
+/**
+ * @brief Invoke the TRUE macro on an example.
+ */
+static void RtemsBasedefsValBasedefs_Action_45( void )
+{
+ char *true_result;
+ true_result = _TO_STR( TRUE );
+
+ /*
+ * Check that of TRUE is substituted by 0.
+ */
+ T_step_eq_str( 99, true_result, "1" );
+}
+
+/**
+ * @brief Use of the RTEMS_TYPEOF_REFX() macro on several examples. This use
+ * is already the test as the statements will not compile without error if
+ * the macro did not evaluate to the correct type.
+ */
+static void RtemsBasedefsValBasedefs_Action_46( void )
+{
+ int type_refx_val = 7;
+ char type_refx_chr = 'c';
+ char *type_refx_chr_p = &type_refx_chr;
+ char **type_refx_chr_pp = &type_refx_chr_p;
+ const short type_refx_const_val = 333;
+ RTEMS_TYPEOF_REFX( *, int *) type_refx_x_int = 8;
+ RTEMS_TYPEOF_REFX( **, int **) type_refx_xx_int = 9;
+ RTEMS_TYPEOF_REFX( ***, int ***) type_refx_xxx_int = 10;
+ RTEMS_TYPEOF_REFX( **, int ***) type_refx_xxx_int_p = &type_refx_val;
+ RTEMS_TYPEOF_REFX( **, &type_refx_chr_p) type_refx_ax_char = 'd';
+ RTEMS_TYPEOF_REFX( *, type_refx_chr_p) type_refx_x_char = 'e';
+ RTEMS_TYPEOF_REFX( , *type_refx_chr_p) type_refx_char = 'f';
+ RTEMS_TYPEOF_REFX( *, type_refx_chr_pp[0]) type_refx_xx_char = 'g';
+ RTEMS_TYPEOF_REFX( *, const short **)
+ type_refx_xx_const_short_p = &type_refx_const_val;
+
+ /*
+ * The checks here are proforma. The macro is tested by the fact that the
+ * action will not compile if the macro returns a wrong result.
+ */
+ T_step_eq_int( 100, type_refx_val, 7 );
+ T_step_eq_int( 101, type_refx_x_int, 8 );
+ T_step_eq_int( 102, type_refx_xx_int, 9 );
+ T_step_eq_int( 103, type_refx_xxx_int, 10 );
+ T_step_eq_int( 104, *type_refx_xxx_int_p, 7 );
+ T_step_eq_char( 105, type_refx_chr, 'c' );
+ T_step_eq_char( 106, type_refx_ax_char, 'd' );
+ T_step_eq_char( 107, type_refx_x_char, 'e' );
+ T_step_eq_char( 108, type_refx_char, 'f' );
+ T_step_eq_char( 109, type_refx_xx_char, 'g' );
+ T_step_eq_short( 110, *type_refx_xx_const_short_p, 333 );
+}
+
+/**
+ * @brief Use the RTEMS_UNUSED macro. See also unused_func() at the beginning
+ * of this file.
+ */
+static void RtemsBasedefsValBasedefs_Action_47( void )
+{
+ int unused_var RTEMS_UNUSED;
+ typedef struct RTEMS_UNUSED {
+ char c;
+ int i;
+ } unused_struct_t;
+ unused_struct_t unused_struct = { '@', 13 };
+
+ /*
+ * It cannot automatically be checked that the RTEMS_UNUSED macro has the
+ * desired effect. It is checked that such a macro exists and one can
+ * manually check that no compiler warnings are produced for the
+ * unused_func().
+ */
+
+
+ /*
+ * It cannot automatically be checked that the RTEMS_UNUSED macro has the
+ * desired effect. It is checked that such a macro exists and one can
+ * manually check that no compiler warnings are produced for the
+ * unused_lable.
+ */
+ unused_lable:
+ RTEMS_UNUSED;
+
+ /*
+ * It cannot automatically be checked that the RTEMS_UNUSED macro has the
+ * desired effect. It is checked that such a macro exists and one can
+ * manually check that no compiler warnings are produced for the
+ * unused_struct.
+ */
+
+
+ /*
+ * It cannot automatically be checked that the RTEMS_UNUSED macro has the
+ * desired effect. It is checked that such a macro exists and one can
+ * manually check that no compiler warnings are produced for the unused items
+ * unused_var and the unused argument and variable in unused_func().
+ */
+
+}
+
+/**
+ * @brief Use of the RTEMS_UNREACHABLE() macro in function definition of
+ * unreachable_func() at the beginning of this file.
+ */
+static void RtemsBasedefsValBasedefs_Action_48( void )
+{
+ int unreachable_result;
+ unreachable_result = unreachable_func(2101);
+
+ /*
+ * It cannot be checked that the RTEMS_UNREACHABLE() macro has the desired
+ * effect. It is checked that such a macro exists and the compiler warning
+ * about the missing return statement is suppressed.
+ */
+ T_step_eq_int( 111, unreachable_result, 2101 );
+}
+
+/**
+ * @brief Use of the RTEMS_USED macro in function definition of used_func() at
+ * the beginning of this file and with used_var above.
+ */
+static void RtemsBasedefsValBasedefs_Action_49( void )
+{
+ /* No action */
+
+ /*
+ * It cannot be checked that the RTEMS_USED macro has the desired effect. It
+ * is checked that such a macro exists.
+ */
+
+}
+
+/**
+ * @brief Use of the RTEMS_WARN_UNUSED_RESULT macro in function definition of
+ * warn_unused_func() at the beginning of this file.
+ */
+static void RtemsBasedefsValBasedefs_Action_50( void )
+{
+ int warn_unused_result;
+ warn_unused_result = warn_unused_func( 33 );
+ /*
+ * Derivation from Coding Style:
+ * The following code suppresses a compiler warning (instead of fixing
+ * it).
+ * Rational: Ignoring the function warn_unused_func() result is not really
+ * a bug but its purpose is to test the RTEMS_WARN_UNUSED_RESULT macro.
+ * The RTEMS_WARN_UNUSED_RESULT macro must result in a compiler warning
+ * here.
+ */
+ _Pragma( "GCC diagnostic push" )
+ _Pragma( "GCC diagnostic ignored \"-Wunused-result\"" )
+ warn_unused_func( 66 );
+ _Pragma( "GCC diagnostic pop" )
+
+ /*
+ * It cannot be checked that the RTEMS_WARN_UNUSED_RESULT macro has the
+ * desired effect. The GNU C compiler should issue a warning about the
+ * disregarded result returned by the call to the ``warn_unused_func()``
+ * function.
+ */
+ T_step_eq_int( 112, warn_unused_result, 11 );
+}
+
+/**
+ * @brief Use of ``basedefs_weak_alias_0/1_func()`` which are defined with the
+ * RTEMS_WEAK_ALIAS() macro at the beginning of this file.
+ */
+static void RtemsBasedefsValBasedefs_Action_51( void )
+{
+ int weak_alias_0_result;
+ int weak_alias_1_result;
+ weak_alias_0_result = ori_func( 3 ) + basedefs_weak_alias_0_func( 5 );
+ weak_alias_1_result = ori_func( 3 ) + basedefs_weak_alias_1_func( 5 );
+
+ /*
+ * There exists no strong alias for basedefs_weak_alias_0_func(). Check that
+ * ori_func() and basedefs_weak_alias_0_func() are the same function.
+ */
+ T_step_eq_int( 113, weak_alias_0_result, 16 );
+
+ /*
+ * File ``tc_basedefs_pndant.c`` defines a strong function for
+ * basedefs_weak_alias_1_func(). Check that ori_func() and
+ * basedefs_weak_alias_1_func() are not the same function.
+ */
+ T_step_eq_int( 114, weak_alias_1_result, 56 );
+}
+
+/**
+ * @brief Use of ``basedefs_weak_0/1_var`` and ``basedefs_weak_0/1_func()``
+ * which are defined with the RTEMS_WEAK macro at the beginning of this file.
+ */
+static void RtemsBasedefsValBasedefs_Action_52( void )
+{
+ int weak_0_result;
+ int weak_1_result;
+ weak_0_result = basedefs_weak_0_func();
+ weak_1_result = basedefs_weak_1_func();
+
+ /*
+ * For ``basedefs_weak_0_var`` and ``basedefs_weak_0_func()`` there exists no
+ * other symbols with the same name. Hence, the checks test that the weak
+ * symbols are used.
+ */
+ T_step_eq_int( 115, basedefs_weak_0_var, 60 );
+ T_step_eq_int( 116, weak_0_result, 63 );
+
+ /*
+ * ``basedefs_weak_1_var`` and ``basedefs_weak_1_func()`` are overwritten by
+ * strong symbols defined in file ``tc_basedefs_pendant.c``. Hence, the
+ * checks test that the strong variants are used.
+ */
+ T_step_eq_int( 117, basedefs_weak_1_var, 62 );
+ T_step_eq_int( 118, weak_1_result, 65 );
+}
+
+/**
+ * @brief Invoke the RTEMS_XCONCAT() macro on examples.
+ */
+static void RtemsBasedefsValBasedefs_Action_53( void )
+{
+ int xconcat0_result;
+ int xconcat1_result;
+ int xconcat2_result;
+ int xconcat3_result;
+ xconcat0_result = RTEMS_XCONCAT( con, cat )();
+ xconcat1_result = RTEMS_XCONCAT( CON, CAT )();
+ xconcat2_result =
+ RTEMS_XCONCAT( RTEMS_XCONCAT( CO, N ), RTEMS_XCONCAT( ca, t ) )();
+ xconcat3_result = RTEMS_CONCAT( def, cat )();
+
+ /*
+ * Check that the two arguments of RTEMS_XCONCAT() are concatenated without
+ * inserting new characters.
+ */
+ T_step_eq_int( 119, xconcat0_result, 91 );
+
+ /*
+ * Check that the two arguments of RTEMS_XCONCAT() are substituted before
+ * they are concatenated.
+ */
+ T_step_eq_int( 120, xconcat1_result, 91 );
+
+ /*
+ * Check that the two arguments of RTEMS_XCONCAT() are can be the macro
+ * itself.
+ */
+ T_step_eq_int( 121, xconcat2_result, 91 );
+
+ /*
+ * Check that the result of the RTEMS_XCONCAT() expansion is subject to a
+ * further pre-processor substitution.
+ */
+ T_step_eq_int( 122, xconcat3_result, 91 );
+}
+
+/**
+ * @brief Use the RTEMS_XSTRING() macro.
+ */
+static void RtemsBasedefsValBasedefs_Action_54( void )
+{
+ const char *xstring_var;
+ const char *xstring_empty_var;
+ const char *string_multi_args_var;
+ /* strange spacing and tabs belong to the test */
+ xstring_var = RTEMS_XSTRING( \\ STRING_PREFIX cat""\n );
+ xstring_empty_var = RTEMS_XSTRING();
+ string_multi_args_var = RTEMS_XSTRING( STRING_PREFIX, abc, "abc", DEF );
+
+ /*
+ * Check that the RTEMS_XSTRING() macro applies pre-processor substitutions
+ * on its arguments and converts its arguments into a single string.
+ */
+ T_step_eq_str( 123, xstring_var, "\\ str cat\"\"\n" );
+ T_step_eq_str( 124, xstring_empty_var, "" );
+ T_step_eq_str( 125, string_multi_args_var,
+ "str, ABC, \"abc\", DEF" );
+}
+
+/**
+ * @brief Use of the RTEMS_ZERO_LENGTH_ARRAY macro in a declaration of a
+ * structure.
+ */
+static void RtemsBasedefsValBasedefs_Action_55( void )
+{
+ typedef struct {
+ char chr;
+ int array[RTEMS_ZERO_LENGTH_ARRAY];
+ } zero_length_struct_0;
+ typedef struct {
+ char chr;
+ int array[1];
+ } zero_length_struct_1;
+
+ /*
+ * Checked that the RTEMS_ZERO_LENGTH_ARRAY macro produces a structure
+ * similar to a structure with one element.
+ */
+ T_step_eq_sz( 126, sizeof( zero_length_struct_0 ),
+ sizeof( zero_length_struct_1 ) - sizeof( int ) );
+ T_step_eq_sz( 127, offsetof( zero_length_struct_0, chr ),
+ offsetof( zero_length_struct_1, chr ) );
+ T_step_eq_sz( 128, offsetof( zero_length_struct_0, array ),
+ offsetof( zero_length_struct_1, array ) );
+}
+
+/**
+ * @brief Use the RTEMS_DEFINE_GLOBAL_SYMBOL() macro at the beginning of this
+ * file and assign the address of the symbol to an object.
+ */
+static void RtemsBasedefsValBasedefs_Action_56( void )
+{
+ /* No action */
+
+ /*
+ * Check that the RTEMS_DEFINE_GLOBAL_SYMBOL() macro defines a global symbol
+ * with the correct value.
+ */
+ T_step_eq_uptr( 129, (uintptr_t) global_symbol_2_object, 0x123 );
+}
+
+/**
+ * @fn void T_case_body_RtemsBasedefsValBasedefs( void )
+ */
+T_TEST_CASE( RtemsBasedefsValBasedefs )
+{
+ T_plan( 130 );
+
+ RtemsBasedefsValBasedefs_Action_0();
+ RtemsBasedefsValBasedefs_Action_1();
+ RtemsBasedefsValBasedefs_Action_2();
+ RtemsBasedefsValBasedefs_Action_3();
+ RtemsBasedefsValBasedefs_Action_4();
+ RtemsBasedefsValBasedefs_Action_5();
+ RtemsBasedefsValBasedefs_Action_6();
+ RtemsBasedefsValBasedefs_Action_7();
+ RtemsBasedefsValBasedefs_Action_8();
+ RtemsBasedefsValBasedefs_Action_9();
+ RtemsBasedefsValBasedefs_Action_10();
+ RtemsBasedefsValBasedefs_Action_11();
+ RtemsBasedefsValBasedefs_Action_12();
+ RtemsBasedefsValBasedefs_Action_13();
+ RtemsBasedefsValBasedefs_Action_14();
+ RtemsBasedefsValBasedefs_Action_15();
+ RtemsBasedefsValBasedefs_Action_16();
+ RtemsBasedefsValBasedefs_Action_17();
+ RtemsBasedefsValBasedefs_Action_18();
+ RtemsBasedefsValBasedefs_Action_19();
+ RtemsBasedefsValBasedefs_Action_20();
+ RtemsBasedefsValBasedefs_Action_21();
+ RtemsBasedefsValBasedefs_Action_22();
+ RtemsBasedefsValBasedefs_Action_23();
+ RtemsBasedefsValBasedefs_Action_24();
+ RtemsBasedefsValBasedefs_Action_25();
+ RtemsBasedefsValBasedefs_Action_26();
+ RtemsBasedefsValBasedefs_Action_27();
+ RtemsBasedefsValBasedefs_Action_28();
+ RtemsBasedefsValBasedefs_Action_29();
+ RtemsBasedefsValBasedefs_Action_30();
+ RtemsBasedefsValBasedefs_Action_31();
+ RtemsBasedefsValBasedefs_Action_32();
+ RtemsBasedefsValBasedefs_Action_33();
+ RtemsBasedefsValBasedefs_Action_34();
+ RtemsBasedefsValBasedefs_Action_35();
+ RtemsBasedefsValBasedefs_Action_36();
+ RtemsBasedefsValBasedefs_Action_37();
+ RtemsBasedefsValBasedefs_Action_38();
+ RtemsBasedefsValBasedefs_Action_39();
+ RtemsBasedefsValBasedefs_Action_40();
+ RtemsBasedefsValBasedefs_Action_41();
+ RtemsBasedefsValBasedefs_Action_42();
+ RtemsBasedefsValBasedefs_Action_43();
+ RtemsBasedefsValBasedefs_Action_44();
+ RtemsBasedefsValBasedefs_Action_45();
+ RtemsBasedefsValBasedefs_Action_46();
+ RtemsBasedefsValBasedefs_Action_47();
+ RtemsBasedefsValBasedefs_Action_48();
+ RtemsBasedefsValBasedefs_Action_49();
+ RtemsBasedefsValBasedefs_Action_50();
+ RtemsBasedefsValBasedefs_Action_51();
+ RtemsBasedefsValBasedefs_Action_52();
+ RtemsBasedefsValBasedefs_Action_53();
+ RtemsBasedefsValBasedefs_Action_54();
+ RtemsBasedefsValBasedefs_Action_55();
+ RtemsBasedefsValBasedefs_Action_56();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-bsp-interrupt-handler-dispatch-unchecked.c b/testsuites/validation/tc-bsp-interrupt-handler-dispatch-unchecked.c
new file mode 100644
index 0000000000..cef52bd991
--- /dev/null
+++ b/testsuites/validation/tc-bsp-interrupt-handler-dispatch-unchecked.c
@@ -0,0 +1,649 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup BspReqInterruptHandlerDispatchUnchecked
+ */
+
+/*
+ * Copyright (C) 2021, 2023 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <setjmp.h>
+#include <bsp/irq-generic.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup BspReqInterruptHandlerDispatchUnchecked \
+ * spec:/bsp/req/interrupt-handler-dispatch-unchecked
+ *
+ * @ingroup TestsuitesValidationIntr
+ *
+ * @{
+ */
+
+typedef enum {
+ BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_Null,
+ BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_Entry,
+ BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_NA
+} BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst;
+
+typedef enum {
+ BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_Null,
+ BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_Entry,
+ BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_NA
+} BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain;
+
+typedef enum {
+ BspReqInterruptHandlerDispatchUnchecked_Post_Result_FatalError,
+ BspReqInterruptHandlerDispatchUnchecked_Post_Result_Dispatch,
+ BspReqInterruptHandlerDispatchUnchecked_Post_Result_NA
+} BspReqInterruptHandlerDispatchUnchecked_Post_Result;
+
+typedef enum {
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_SpuriousInterrupt,
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_NA
+} BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource;
+
+typedef enum {
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_Vector,
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_NA
+} BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_LoadFirst_NA : 1;
+ uint8_t Pre_LoadFirstAgain_NA : 1;
+ uint8_t Post_Result : 2;
+ uint8_t Post_FatalSource : 1;
+ uint8_t Post_FatalCode : 1;
+} BspReqInterruptHandlerDispatchUnchecked_Entry;
+
+/**
+ * @brief Test context for spec:/bsp/req/interrupt-handler-dispatch-unchecked
+ * test case.
+ */
+typedef struct {
+ /**
+ * @brief This member references the interrupt entry to restore during test
+ * case teardown.
+ */
+ rtems_interrupt_entry *entry_to_restore;
+
+ /**
+ * @brief This member provides a jump buffer to return from the fatal error.
+ */
+ jmp_buf before_call;
+
+ /**
+ * @brief This member provides an interrupt entry to be dispatched.
+ */
+ rtems_interrupt_entry entry;
+
+ /**
+ * @brief This member is true, then an interrupt occurred.
+ */
+ volatile bool interrupt_occurred;
+
+ /**
+ * @brief This member provides an entry dispatch counter.
+ */
+ uint32_t entry_counter;
+
+ /**
+ * @brief This member provides a fatal error counter.
+ */
+ uint32_t fatal_counter;
+
+ /**
+ * @brief This member contains the fatal source.
+ */
+ rtems_fatal_source fatal_source;
+
+ /**
+ * @brief This member contains a fatal code.
+ */
+ rtems_fatal_code fatal_code;
+
+ /**
+ * @brief This member contains the vector number of a testable interrupt.
+ */
+ rtems_vector_number test_vector;
+
+ /**
+ * @brief This member references the pointer to the first entry of the
+ * interrupt vector.
+ */
+ rtems_interrupt_entry **first;
+
+ /**
+ * @brief This member references an interrupt entry for the first entry of
+ * the interrupt vector or is NULL.
+ */
+ rtems_interrupt_entry *first_again;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 2 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ BspReqInterruptHandlerDispatchUnchecked_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} BspReqInterruptHandlerDispatchUnchecked_Context;
+
+static BspReqInterruptHandlerDispatchUnchecked_Context
+ BspReqInterruptHandlerDispatchUnchecked_Instance;
+
+static const char * const BspReqInterruptHandlerDispatchUnchecked_PreDesc_LoadFirst[] = {
+ "Null",
+ "Entry",
+ "NA"
+};
+
+static const char * const BspReqInterruptHandlerDispatchUnchecked_PreDesc_LoadFirstAgain[] = {
+ "Null",
+ "Entry",
+ "NA"
+};
+
+static const char * const * const BspReqInterruptHandlerDispatchUnchecked_PreDesc[] = {
+ BspReqInterruptHandlerDispatchUnchecked_PreDesc_LoadFirst,
+ BspReqInterruptHandlerDispatchUnchecked_PreDesc_LoadFirstAgain,
+ NULL
+};
+
+typedef BspReqInterruptHandlerDispatchUnchecked_Context Context;
+
+static bool test_case_active;
+
+static void Disable( const Context *ctx )
+{
+ (void) rtems_interrupt_vector_disable( ctx->test_vector );
+}
+
+static void ProcessInterrupt( Context *ctx )
+{
+ ctx->interrupt_occurred = true;
+ CallWithinISRClear();
+ Disable( ctx );
+}
+
+static void EntryRoutine( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ ++ctx->entry_counter;
+ ProcessInterrupt( ctx );
+}
+
+static void Fatal(
+ rtems_fatal_source source,
+ rtems_fatal_code code,
+ void *arg
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+ ctx->fatal_source = source;
+ ctx->fatal_code = code;
+ ++ctx->fatal_counter;
+ longjmp( ctx->before_call, 1 );
+}
+
+void __real_bsp_interrupt_handler_default( rtems_vector_number vector );
+
+void __wrap_bsp_interrupt_handler_default( rtems_vector_number vector );
+
+void __wrap_bsp_interrupt_handler_default( rtems_vector_number vector )
+{
+ if ( test_case_active ) {
+ Context *ctx;
+
+ ctx = T_fixture_context();
+ ProcessInterrupt( ctx );
+
+ if ( setjmp( ctx->before_call ) == 0 ) {
+ __real_bsp_interrupt_handler_default( vector );
+ }
+ } else {
+ __real_bsp_interrupt_handler_default( vector );
+ }
+}
+
+#if defined(RTEMS_SMP)
+void __real_bsp_interrupt_spurious( rtems_vector_number vector );
+
+void __wrap_bsp_interrupt_spurious( rtems_vector_number vector );
+
+void __wrap_bsp_interrupt_spurious( rtems_vector_number vector )
+{
+ if ( test_case_active ) {
+ Context *ctx;
+
+ ctx = T_fixture_context();
+ *ctx->first = ctx->first_again;
+ }
+
+ __real_bsp_interrupt_spurious( vector );
+}
+#endif
+
+static void BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_Prepare(
+ BspReqInterruptHandlerDispatchUnchecked_Context *ctx,
+ BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst state
+)
+{
+ switch ( state ) {
+ case BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_Null: {
+ /*
+ * While the first loaded value of the pointer to the first interrupt
+ * entry of the interrupt vector specified by the ``vector`` parameter is
+ * equal to NULL.
+ */
+ *ctx->first = NULL;
+ break;
+ }
+
+ case BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_Entry: {
+ /*
+ * While the first loaded value of the pointer to the first interrupt
+ * entry of the interrupt vector specified by the ``vector`` parameter
+ * references an object of type rtems_interrupt_entry.
+ */
+ *ctx->first = &ctx->entry;
+ break;
+ }
+
+ case BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_NA:
+ break;
+ }
+}
+
+static void BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_Prepare(
+ BspReqInterruptHandlerDispatchUnchecked_Context *ctx,
+ BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain state
+)
+{
+ switch ( state ) {
+ case BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_Null: {
+ /*
+ * While the second loaded value of the pointer to the first interrupt
+ * entry of the interrupt vector specified by the ``vector`` parameter is
+ * equal to NULL.
+ */
+ ctx->first_again = NULL;
+ break;
+ }
+
+ case BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_Entry: {
+ /*
+ * While the second loaded value of the pointer to the first interrupt
+ * entry of the interrupt vector specified by the ``vector`` parameter
+ * references an object of type rtems_interrupt_entry.
+ */
+ ctx->first_again = &ctx->entry;
+ break;
+ }
+
+ case BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_NA:
+ break;
+ }
+}
+
+static void BspReqInterruptHandlerDispatchUnchecked_Post_Result_Check(
+ BspReqInterruptHandlerDispatchUnchecked_Context *ctx,
+ BspReqInterruptHandlerDispatchUnchecked_Post_Result state
+)
+{
+ switch ( state ) {
+ case BspReqInterruptHandlerDispatchUnchecked_Post_Result_FatalError: {
+ /*
+ * A fatal error shall occur.
+ */
+ T_eq_u32( ctx->entry_counter, 0 );
+ T_eq_u32( ctx->fatal_counter, 1 );
+ break;
+ }
+
+ case BspReqInterruptHandlerDispatchUnchecked_Post_Result_Dispatch: {
+ /*
+ * The interrupt entries installed at the interrupt vector specified by
+ * the ``vector`` parameter shall be dispatched.
+ */
+ T_eq_u32( ctx->entry_counter, 1 );
+ T_eq_u32( ctx->fatal_counter, 0 );
+ break;
+ }
+
+ case BspReqInterruptHandlerDispatchUnchecked_Post_Result_NA:
+ break;
+ }
+}
+
+static void BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_Check(
+ BspReqInterruptHandlerDispatchUnchecked_Context *ctx,
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource state
+)
+{
+ switch ( state ) {
+ case BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_SpuriousInterrupt: {
+ /*
+ * The fatal source shall be equal to
+ * RTEMS_FATAL_SOURCE_SPURIOUS_INTERRUPT.
+ */
+ T_eq_int( ctx->fatal_source, RTEMS_FATAL_SOURCE_SPURIOUS_INTERRUPT );
+ break;
+ }
+
+ case BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_NA:
+ break;
+ }
+}
+
+static void BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_Check(
+ BspReqInterruptHandlerDispatchUnchecked_Context *ctx,
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode state
+)
+{
+ switch ( state ) {
+ case BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_Vector: {
+ /*
+ * The fatal code shall be equal to the ``vector`` parameter.
+ */
+ T_eq_ulong( ctx->fatal_code, ctx->test_vector );
+ break;
+ }
+
+ case BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_NA:
+ break;
+ }
+}
+
+static void BspReqInterruptHandlerDispatchUnchecked_Setup(
+ BspReqInterruptHandlerDispatchUnchecked_Context *ctx
+)
+{
+ ctx->first = NULL;
+ ctx->test_vector = CallWithinISRGetVector();
+ T_assert_lt_u32( ctx->test_vector, BSP_INTERRUPT_VECTOR_COUNT );
+ ctx->first = &bsp_interrupt_dispatch_table[
+ bsp_interrupt_dispatch_index( ctx->test_vector )
+ ];
+ ctx->entry_to_restore = *ctx->first;
+
+ rtems_interrupt_entry_initialize( &ctx->entry, EntryRoutine, ctx, "Info" );
+ test_case_active = true;
+ SetFatalHandler( Fatal, ctx );
+}
+
+static void BspReqInterruptHandlerDispatchUnchecked_Setup_Wrap( void *arg )
+{
+ BspReqInterruptHandlerDispatchUnchecked_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ BspReqInterruptHandlerDispatchUnchecked_Setup( ctx );
+}
+
+static void BspReqInterruptHandlerDispatchUnchecked_Teardown(
+ BspReqInterruptHandlerDispatchUnchecked_Context *ctx
+)
+{
+ SetFatalHandler( NULL, NULL );
+ test_case_active = false;
+
+ if ( ctx->first != NULL ) {
+ *ctx->first = ctx->entry_to_restore;
+ }
+}
+
+static void BspReqInterruptHandlerDispatchUnchecked_Teardown_Wrap( void *arg )
+{
+ BspReqInterruptHandlerDispatchUnchecked_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ BspReqInterruptHandlerDispatchUnchecked_Teardown( ctx );
+}
+
+static void BspReqInterruptHandlerDispatchUnchecked_Action(
+ BspReqInterruptHandlerDispatchUnchecked_Context *ctx
+)
+{
+ ctx->interrupt_occurred = false;
+ ctx->entry_counter = 0;
+ ctx->fatal_counter = 0;
+ ctx->fatal_source = RTEMS_FATAL_SOURCE_LAST;
+ ctx->fatal_code = UINT32_MAX;
+
+ (void) rtems_interrupt_vector_enable( ctx->test_vector );
+
+ CallWithinISRRaise();
+
+ while ( !ctx->interrupt_occurred ) {
+ /* Wait */
+ }
+
+ Disable( ctx );
+}
+
+static const BspReqInterruptHandlerDispatchUnchecked_Entry
+BspReqInterruptHandlerDispatchUnchecked_Entries[] = {
+ { 0, 0, 1, BspReqInterruptHandlerDispatchUnchecked_Post_Result_Dispatch,
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_NA,
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_NA },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, BspReqInterruptHandlerDispatchUnchecked_Post_Result_FatalError,
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_SpuriousInterrupt,
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_Vector },
+#else
+ { 0, 0, 1, BspReqInterruptHandlerDispatchUnchecked_Post_Result_FatalError,
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_SpuriousInterrupt,
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_Vector },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, BspReqInterruptHandlerDispatchUnchecked_Post_Result_Dispatch,
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_NA,
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_NA }
+#else
+ { 0, 0, 1, BspReqInterruptHandlerDispatchUnchecked_Post_Result_FatalError,
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_SpuriousInterrupt,
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_Vector }
+#endif
+};
+
+static const uint8_t
+BspReqInterruptHandlerDispatchUnchecked_Map[] = {
+ 1, 2, 0, 0
+};
+
+static size_t BspReqInterruptHandlerDispatchUnchecked_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ BspReqInterruptHandlerDispatchUnchecked_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ BspReqInterruptHandlerDispatchUnchecked_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture BspReqInterruptHandlerDispatchUnchecked_Fixture = {
+ .setup = BspReqInterruptHandlerDispatchUnchecked_Setup_Wrap,
+ .stop = NULL,
+ .teardown = BspReqInterruptHandlerDispatchUnchecked_Teardown_Wrap,
+ .scope = BspReqInterruptHandlerDispatchUnchecked_Scope,
+ .initial_context = &BspReqInterruptHandlerDispatchUnchecked_Instance
+};
+
+static inline BspReqInterruptHandlerDispatchUnchecked_Entry
+BspReqInterruptHandlerDispatchUnchecked_PopEntry(
+ BspReqInterruptHandlerDispatchUnchecked_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return BspReqInterruptHandlerDispatchUnchecked_Entries[
+ BspReqInterruptHandlerDispatchUnchecked_Map[ index ]
+ ];
+}
+
+static void BspReqInterruptHandlerDispatchUnchecked_SetPreConditionStates(
+ BspReqInterruptHandlerDispatchUnchecked_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+
+ if ( ctx->Map.entry.Pre_LoadFirstAgain_NA ) {
+ ctx->Map.pcs[ 1 ] = BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_NA;
+ } else {
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ }
+}
+
+static void BspReqInterruptHandlerDispatchUnchecked_TestVariant(
+ BspReqInterruptHandlerDispatchUnchecked_Context *ctx
+)
+{
+ BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_Prepare(
+ ctx,
+ ctx->Map.pcs[ 0 ]
+ );
+ BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_Prepare(
+ ctx,
+ ctx->Map.pcs[ 1 ]
+ );
+ BspReqInterruptHandlerDispatchUnchecked_Action( ctx );
+ BspReqInterruptHandlerDispatchUnchecked_Post_Result_Check(
+ ctx,
+ ctx->Map.entry.Post_Result
+ );
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalSource_Check(
+ ctx,
+ ctx->Map.entry.Post_FatalSource
+ );
+ BspReqInterruptHandlerDispatchUnchecked_Post_FatalCode_Check(
+ ctx,
+ ctx->Map.entry.Post_FatalCode
+ );
+}
+
+/**
+ * @fn void T_case_body_BspReqInterruptHandlerDispatchUnchecked( void )
+ */
+T_TEST_CASE_FIXTURE(
+ BspReqInterruptHandlerDispatchUnchecked,
+ &BspReqInterruptHandlerDispatchUnchecked_Fixture
+)
+{
+ BspReqInterruptHandlerDispatchUnchecked_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_Null;
+ ctx->Map.pci[ 0 ] < BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirst_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_Null;
+ ctx->Map.pci[ 1 ] < BspReqInterruptHandlerDispatchUnchecked_Pre_LoadFirstAgain_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ ctx->Map.entry = BspReqInterruptHandlerDispatchUnchecked_PopEntry( ctx );
+ BspReqInterruptHandlerDispatchUnchecked_SetPreConditionStates( ctx );
+ BspReqInterruptHandlerDispatchUnchecked_TestVariant( ctx );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-c.c b/testsuites/validation/tc-c.c
new file mode 100644
index 0000000000..646a838609
--- /dev/null
+++ b/testsuites/validation/tc-c.c
@@ -0,0 +1,189 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup CValC
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup CValC spec:/c/val/c
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests C library functions.
+ *
+ * This test case performs the following actions:
+ *
+ * - Call memcpy() for a sample set of buffers.
+ *
+ * - Call memset() for a sample set of buffers.
+ *
+ * @{
+ */
+
+static void Clear( volatile uint8_t *b, const volatile uint8_t *e )
+{
+ while ( b != e ) {
+ *b = 0;
+ ++b;
+ }
+}
+
+static bool Compare(
+ volatile uint8_t *b,
+ const volatile uint8_t *e,
+ uint8_t expected
+)
+{
+ bool result;
+
+ result = true;
+
+ while ( b != e ) {
+ result = result && *b == expected;
+ ++b;
+ }
+
+ return result;
+}
+
+/**
+ * @brief Call memcpy() for a sample set of buffers.
+ */
+static void CValC_Action_0( void )
+{
+ uint8_t src[sizeof( long ) * 10];
+ uint8_t dst[sizeof( long ) * 10];
+ uint8_t *begin;
+ uint8_t *end;
+ uint8_t *aligned_src;
+ uint8_t *aligned_dst;
+ size_t offset_src;
+
+ memset( src, 0x85, sizeof( src ) );
+ begin = dst;
+ end = begin + sizeof( dst );
+ aligned_src = (uint8_t *) RTEMS_ALIGN_UP( (uintptr_t) src, sizeof( long ) );
+ aligned_dst = (uint8_t *) RTEMS_ALIGN_UP( (uintptr_t) dst, sizeof( long ) );
+
+ for ( offset_src = 0; offset_src < sizeof( long ); ++offset_src ) {
+ size_t offset_dst;
+
+ for ( offset_dst = 0; offset_dst < sizeof( long ); ++offset_dst ) {
+ size_t size;
+
+ for ( size = 0; size < sizeof( long ) * 8; ++size ) {
+ uint8_t *s;
+ uint8_t *p;
+ uint8_t *q;
+
+ s = aligned_src + offset_src;
+ p = aligned_dst + offset_dst;
+ q = p + size;
+
+ Clear( begin, end );
+ memcpy( p, s, size );
+ T_true( Compare( begin, p, 0 ) );
+ T_true( Compare( p, q, 0x85 ) );
+ T_true( Compare( q, end, 0 ) );
+ }
+ }
+ }
+}
+
+/**
+ * @brief Call memset() for a sample set of buffers.
+ */
+static void CValC_Action_1( void )
+{
+ uint8_t dst[sizeof( long ) * 10];
+ uint8_t *begin;
+ uint8_t *end;
+ uint8_t *aligned;
+ size_t offset;
+
+ begin = dst;
+ end = begin + sizeof( dst );
+ aligned = (uint8_t *) RTEMS_ALIGN_UP( (uintptr_t) dst, sizeof( long ) );
+
+ for ( offset = 0; offset < sizeof( long ); ++offset ) {
+ size_t size;
+
+ for ( size = 0; size < sizeof( long ) * 8; ++size ) {
+ uint8_t *p;
+ uint8_t *q;
+
+ p = aligned + offset;
+ q = p + size;
+
+ Clear( begin, end );
+ memset( p, 0x85, size );
+ T_true( Compare( begin, p, 0 ) );
+ T_true( Compare( p, q, 0x85 ) );
+ T_true( Compare( q, end, 0 ) );
+ }
+ }
+}
+
+/**
+ * @fn void T_case_body_CValC( void )
+ */
+T_TEST_CASE( CValC )
+{
+ CValC_Action_0();
+ CValC_Action_1();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-cache.c b/testsuites/validation/tc-cache.c
new file mode 100644
index 0000000000..e85b9033e7
--- /dev/null
+++ b/testsuites/validation/tc-cache.c
@@ -0,0 +1,675 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsCacheValCache
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsCacheValCache spec:/rtems/cache/val/cache
+ *
+ * @ingroup TestsuitesValidationCache
+ *
+ * @brief Tests some @ref RTEMSAPIClassicCache directives.
+ *
+ * This test case performs the following actions:
+ *
+ * - Call the rtems_cache_disable_data() and rtems_cache_enable_data()
+ * directives.
+ *
+ * - Call the rtems_cache_disable_data() and rtems_cache_enable_data()
+ * directives with maskable interrupts disabled.
+ *
+ * - Call the rtems_cache_disable_instruction() and
+ * rtems_cache_enable_instruction() directives.
+ *
+ * - Call the rtems_cache_disable_instruction() and
+ * rtems_cache_enable_instruction() directives with maskable interrupts
+ * disabled.
+ *
+ * - Call the rtems_cache_freeze_data() and rtems_cache_unfreeze_data()
+ * directives.
+ *
+ * - Call the rtems_cache_freeze_data() and rtems_cache_unfreeze_data()
+ * directives with maskable interrupts disabled.
+ *
+ * - Call the rtems_cache_freeze_instruction() and
+ * rtems_cache_unfreeze_instruction() directives.
+ *
+ * - Call the rtems_cache_freeze_instruction() and
+ * rtems_cache_unfreeze_instruction() directives with maskable interrupts
+ * disabled.
+ *
+ * - Call the rtems_cache_invalidate_entire_data() directive with maskable
+ * interrupts disabled.
+ *
+ * - Call the rtems_cache_invalidate_entire_instruction() directive.
+ *
+ * - Call the rtems_cache_invalidate_entire_instruction() directive with
+ * maskable interrupts disabled.
+ *
+ * - Call the rtems_cache_flush_entire_data() directive.
+ *
+ * - Call the rtems_cache_flush_entire_data() directive with maskable
+ * interrupts disabled.
+ *
+ * - Call the rtems_cache_flush_multiple_data_lines() directive with a sample
+ * set of memory areas.
+ *
+ * - Call the rtems_cache_flush_multiple_data_lines() directive with a sample
+ * set of memory areas with maskable interrupts disabled.
+ *
+ * - Call the rtems_cache_invalidate_multiple_data_lines() directive with a
+ * sample set of memory areas.
+ *
+ * - Call the rtems_cache_invalidate_multiple_data_lines() directive with a
+ * sample set of memory areas with maskable interrupts disabled.
+ *
+ * - Call the rtems_cache_invalidate_multiple_instruction_lines() directive
+ * with a sample set of memory areas.
+ *
+ * - Call the rtems_cache_invalidate_multiple_instruction_lines() directive
+ * with a sample set of memory areas with maskable interrupts disabled.
+ *
+ * - Call the rtems_cache_instruction_sync_after_code_change() directive with a
+ * sample set of memory areas.
+ *
+ * - Call the rtems_cache_instruction_sync_after_code_change() directive with a
+ * sample set of memory areas with maskable interrupts disabled.
+ *
+ * - Call the rtems_cache_get_data_line_size(),
+ * rtems_cache_get_instruction_line_size(), and the
+ * rtems_cache_get_maximal_line_size() directives.
+ *
+ * - Check that the maximal cache line size is greater than or equal to the
+ * data cache line size.
+ *
+ * - Check that the maximal cache line size is greater than or equal to the
+ * instruction cache line size.
+ *
+ * - Call the rtems_cache_get_data_line_size(),
+ * rtems_cache_get_instruction_line_size(), and the
+ * rtems_cache_get_maximal_line_size() directives with maskable interrupts
+ * disabled.
+ *
+ * - Check that the maximal cache line size is greater than or equal to the
+ * data cache line size.
+ *
+ * - Check that the maximal cache line size is greater than or equal to the
+ * instruction cache line size.
+ *
+ * - Call the rtems_cache_get_data_cache_size() directive with increasing level
+ * starting with zero until it returns zero.
+ *
+ * - Call the rtems_cache_get_data_cache_size() directive with increasing level
+ * starting with zero until it returns zero with maskable interrupts
+ * disabled.
+ *
+ * - Call the rtems_cache_get_instruction_cache_size() directive with
+ * increasing level starting with zero until it returns zero.
+ *
+ * - Call the rtems_cache_get_instruction_cache_size() directive with
+ * increasing level starting with zero until it returns zero with maskable
+ * interrupts disabled.
+ *
+ * @{
+ */
+
+static void CallFlushMultipleDataLines( void )
+{
+ uint8_t buf[256];
+ uintptr_t data;
+ uintptr_t n;
+ uintptr_t i;
+
+ rtems_cache_flush_multiple_data_lines( NULL, 0 );
+ data = RTEMS_ALIGN_UP( (uintptr_t) &buf[ 1 ], 128 );
+
+ for ( n = 16; n <= 128 ; n *= 2 ) {
+ for ( i = 0; i < 3; ++i ) {
+ uintptr_t j;
+
+ for ( j = 0; j < 3; ++j ) {
+ rtems_cache_flush_multiple_data_lines(
+ (const void *) ( data + 1 - i ),
+ n + 1 - j
+ );
+ }
+ }
+ }
+}
+
+static void CallInvalidateMultipleDataLines( void )
+{
+ uint8_t buf[256];
+ uintptr_t data;
+ uintptr_t n;
+ uintptr_t i;
+
+ rtems_cache_invalidate_multiple_data_lines( NULL, 0 );
+ data = RTEMS_ALIGN_UP( (uintptr_t) &buf[ 1 ], 128 );
+
+ for ( n = 16; n <= 128 ; n *= 2 ) {
+ for ( i = 0; i < 3; ++i ) {
+ uintptr_t j;
+
+ for ( j = 0; j < 3; ++j ) {
+ rtems_cache_invalidate_multiple_data_lines(
+ (const void *) ( data + 1 - i ),
+ n + 1 - j
+ );
+ }
+ }
+ }
+}
+
+static void CallInvalidateMultipleInstructionLines( void )
+{
+ uintptr_t data;
+ uintptr_t n;
+ uintptr_t i;
+
+ rtems_cache_invalidate_multiple_instruction_lines( NULL, 0 );
+ data = (uintptr_t) rtems_cache_invalidate_multiple_instruction_lines;
+
+ for ( n = 16; n <= 128 ; n *= 2 ) {
+ for ( i = 0; i < 3; ++i ) {
+ uintptr_t j;
+
+ for ( j = 0; j < 3; ++j ) {
+ rtems_cache_invalidate_multiple_instruction_lines(
+ (const void *) ( data + 1 - i ),
+ n + 1 - j
+ );
+ }
+ }
+ }
+}
+
+static void CallInstructionSyncAfterCodeChange( void )
+{
+ uintptr_t data;
+ uintptr_t n;
+ uintptr_t i;
+
+ rtems_cache_instruction_sync_after_code_change( NULL, 0 );
+ data = (uintptr_t) rtems_cache_instruction_sync_after_code_change;
+
+ for ( n = 16; n <= 128 ; n *= 2 ) {
+ for ( i = 0; i < 3; ++i ) {
+ uintptr_t j;
+
+ for ( j = 0; j < 3; ++j ) {
+ rtems_cache_instruction_sync_after_code_change(
+ (const void *) ( data + 1 - i ),
+ n + 1 - j
+ );
+ }
+ }
+ }
+}
+
+static void CallGetDataSize( void )
+{
+ uint32_t level;
+ size_t n;
+
+ level = 0;
+
+ do {
+ n = rtems_cache_get_data_cache_size( level );
+ ++level;
+ } while (n != 0 );
+}
+
+static void CallGetInstructionSize( void )
+{
+ uint32_t level;
+ size_t n;
+
+ level = 0;
+
+ do {
+ n = rtems_cache_get_instruction_cache_size( level );
+ ++level;
+ } while (n != 0 );
+}
+
+/**
+ * @brief Call the rtems_cache_disable_data() and rtems_cache_enable_data()
+ * directives.
+ */
+static void RtemsCacheValCache_Action_0( void )
+{
+ rtems_cache_disable_data();
+ rtems_cache_enable_data();
+}
+
+/**
+ * @brief Call the rtems_cache_disable_data() and rtems_cache_enable_data()
+ * directives with maskable interrupts disabled.
+ */
+static void RtemsCacheValCache_Action_1( void )
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_local_disable(level);
+ rtems_cache_disable_data();
+ rtems_cache_enable_data();
+ rtems_interrupt_local_enable(level);
+}
+
+/**
+ * @brief Call the rtems_cache_disable_instruction() and
+ * rtems_cache_enable_instruction() directives.
+ */
+static void RtemsCacheValCache_Action_2( void )
+{
+ rtems_cache_disable_instruction();
+ rtems_cache_enable_instruction();
+}
+
+/**
+ * @brief Call the rtems_cache_disable_instruction() and
+ * rtems_cache_enable_instruction() directives with maskable interrupts
+ * disabled.
+ */
+static void RtemsCacheValCache_Action_3( void )
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_local_disable(level);
+ rtems_cache_disable_instruction();
+ rtems_cache_enable_instruction();
+ rtems_interrupt_local_enable(level);
+}
+
+/**
+ * @brief Call the rtems_cache_freeze_data() and rtems_cache_unfreeze_data()
+ * directives.
+ */
+static void RtemsCacheValCache_Action_4( void )
+{
+ rtems_cache_freeze_data();
+ rtems_cache_unfreeze_data();
+}
+
+/**
+ * @brief Call the rtems_cache_freeze_data() and rtems_cache_unfreeze_data()
+ * directives with maskable interrupts disabled.
+ */
+static void RtemsCacheValCache_Action_5( void )
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_local_disable(level);
+ rtems_cache_freeze_data();
+ rtems_cache_unfreeze_data();
+ rtems_interrupt_local_enable(level);
+}
+
+/**
+ * @brief Call the rtems_cache_freeze_instruction() and
+ * rtems_cache_unfreeze_instruction() directives.
+ */
+static void RtemsCacheValCache_Action_6( void )
+{
+ rtems_cache_freeze_instruction();
+ rtems_cache_unfreeze_instruction();
+}
+
+/**
+ * @brief Call the rtems_cache_freeze_instruction() and
+ * rtems_cache_unfreeze_instruction() directives with maskable interrupts
+ * disabled.
+ */
+static void RtemsCacheValCache_Action_7( void )
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_local_disable(level);
+ rtems_cache_freeze_instruction();
+ rtems_cache_unfreeze_instruction();
+ rtems_interrupt_local_enable(level);
+}
+
+/**
+ * @brief Call the rtems_cache_invalidate_entire_data() directive with maskable
+ * interrupts disabled.
+ */
+static void RtemsCacheValCache_Action_8( void )
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_local_disable(level);
+ rtems_cache_disable_data();
+ rtems_cache_invalidate_entire_data();
+ rtems_cache_enable_data();
+ rtems_interrupt_local_enable(level);
+}
+
+/**
+ * @brief Call the rtems_cache_invalidate_entire_instruction() directive.
+ */
+static void RtemsCacheValCache_Action_9( void )
+{
+ rtems_cache_invalidate_entire_instruction();
+}
+
+/**
+ * @brief Call the rtems_cache_invalidate_entire_instruction() directive with
+ * maskable interrupts disabled.
+ */
+static void RtemsCacheValCache_Action_10( void )
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_local_disable(level);
+ rtems_cache_invalidate_entire_instruction();
+ rtems_interrupt_local_enable(level);
+}
+
+/**
+ * @brief Call the rtems_cache_flush_entire_data() directive.
+ */
+static void RtemsCacheValCache_Action_11( void )
+{
+ rtems_cache_flush_entire_data();
+}
+
+/**
+ * @brief Call the rtems_cache_flush_entire_data() directive with maskable
+ * interrupts disabled.
+ */
+static void RtemsCacheValCache_Action_12( void )
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_local_disable(level);
+ rtems_cache_flush_entire_data();
+ rtems_interrupt_local_enable(level);
+}
+
+/**
+ * @brief Call the rtems_cache_flush_multiple_data_lines() directive with a
+ * sample set of memory areas.
+ */
+static void RtemsCacheValCache_Action_13( void )
+{
+ CallFlushMultipleDataLines();
+}
+
+/**
+ * @brief Call the rtems_cache_flush_multiple_data_lines() directive with a
+ * sample set of memory areas with maskable interrupts disabled.
+ */
+static void RtemsCacheValCache_Action_14( void )
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_local_disable(level);
+ CallFlushMultipleDataLines();
+ rtems_interrupt_local_enable(level);
+}
+
+/**
+ * @brief Call the rtems_cache_invalidate_multiple_data_lines() directive with
+ * a sample set of memory areas.
+ */
+static void RtemsCacheValCache_Action_15( void )
+{
+ CallInvalidateMultipleDataLines();
+}
+
+/**
+ * @brief Call the rtems_cache_invalidate_multiple_data_lines() directive with
+ * a sample set of memory areas with maskable interrupts disabled.
+ */
+static void RtemsCacheValCache_Action_16( void )
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_local_disable(level);
+ CallInvalidateMultipleDataLines();
+ rtems_interrupt_local_enable(level);
+}
+
+/**
+ * @brief Call the rtems_cache_invalidate_multiple_instruction_lines()
+ * directive with a sample set of memory areas.
+ */
+static void RtemsCacheValCache_Action_17( void )
+{
+ CallInvalidateMultipleInstructionLines();
+}
+
+/**
+ * @brief Call the rtems_cache_invalidate_multiple_instruction_lines()
+ * directive with a sample set of memory areas with maskable interrupts
+ * disabled.
+ */
+static void RtemsCacheValCache_Action_18( void )
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_local_disable(level);
+ CallInvalidateMultipleInstructionLines();
+ rtems_interrupt_local_enable(level);
+}
+
+/**
+ * @brief Call the rtems_cache_instruction_sync_after_code_change() directive
+ * with a sample set of memory areas.
+ */
+static void RtemsCacheValCache_Action_19( void )
+{
+ CallInstructionSyncAfterCodeChange();
+}
+
+/**
+ * @brief Call the rtems_cache_instruction_sync_after_code_change() directive
+ * with a sample set of memory areas with maskable interrupts disabled.
+ */
+static void RtemsCacheValCache_Action_20( void )
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_local_disable(level);
+ CallInstructionSyncAfterCodeChange();
+ rtems_interrupt_local_enable(level);
+}
+
+/**
+ * @brief Call the rtems_cache_get_data_line_size(),
+ * rtems_cache_get_instruction_line_size(), and the
+ * rtems_cache_get_maximal_line_size() directives.
+ */
+static void RtemsCacheValCache_Action_21( void )
+{
+ size_t data_line_size;
+ size_t instruction_line_size;
+ size_t maximal_line_size;
+
+ data_line_size = rtems_cache_get_data_line_size();
+ instruction_line_size = rtems_cache_get_instruction_line_size();
+ maximal_line_size = rtems_cache_get_maximal_line_size();
+
+ /*
+ * Check that the maximal cache line size is greater than or equal to the
+ * data cache line size.
+ */
+ T_step_ge_sz( 0, maximal_line_size, data_line_size );
+
+ /*
+ * Check that the maximal cache line size is greater than or equal to the
+ * instruction cache line size.
+ */
+ T_step_ge_sz( 1, maximal_line_size, instruction_line_size );
+}
+
+/**
+ * @brief Call the rtems_cache_get_data_line_size(),
+ * rtems_cache_get_instruction_line_size(), and the
+ * rtems_cache_get_maximal_line_size() directives with maskable interrupts
+ * disabled.
+ */
+static void RtemsCacheValCache_Action_22( void )
+{
+ size_t data_line_size;
+ size_t instruction_line_size;
+ size_t maximal_line_size;
+ rtems_interrupt_level level;
+
+ rtems_interrupt_local_disable(level);
+ data_line_size = rtems_cache_get_data_line_size();
+ instruction_line_size = rtems_cache_get_instruction_line_size();
+ maximal_line_size = rtems_cache_get_maximal_line_size();
+ rtems_interrupt_local_enable(level);
+
+ /*
+ * Check that the maximal cache line size is greater than or equal to the
+ * data cache line size.
+ */
+ T_step_ge_sz( 2, maximal_line_size, data_line_size );
+
+ /*
+ * Check that the maximal cache line size is greater than or equal to the
+ * instruction cache line size.
+ */
+ T_step_ge_sz( 3, maximal_line_size, instruction_line_size );
+}
+
+/**
+ * @brief Call the rtems_cache_get_data_cache_size() directive with increasing
+ * level starting with zero until it returns zero.
+ */
+static void RtemsCacheValCache_Action_23( void )
+{
+ CallGetDataSize();
+}
+
+/**
+ * @brief Call the rtems_cache_get_data_cache_size() directive with increasing
+ * level starting with zero until it returns zero with maskable interrupts
+ * disabled.
+ */
+static void RtemsCacheValCache_Action_24( void )
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_local_disable(level);
+ CallGetDataSize();
+ rtems_interrupt_local_enable(level);
+}
+
+/**
+ * @brief Call the rtems_cache_get_instruction_cache_size() directive with
+ * increasing level starting with zero until it returns zero.
+ */
+static void RtemsCacheValCache_Action_25( void )
+{
+ CallGetInstructionSize();
+}
+
+/**
+ * @brief Call the rtems_cache_get_instruction_cache_size() directive with
+ * increasing level starting with zero until it returns zero with maskable
+ * interrupts disabled.
+ */
+static void RtemsCacheValCache_Action_26( void )
+{
+ rtems_interrupt_level level;
+
+ rtems_interrupt_local_disable(level);
+ CallGetInstructionSize();
+ rtems_interrupt_local_enable(level);
+}
+
+/**
+ * @fn void T_case_body_RtemsCacheValCache( void )
+ */
+T_TEST_CASE( RtemsCacheValCache )
+{
+ T_plan( 4 );
+
+ RtemsCacheValCache_Action_0();
+ RtemsCacheValCache_Action_1();
+ RtemsCacheValCache_Action_2();
+ RtemsCacheValCache_Action_3();
+ RtemsCacheValCache_Action_4();
+ RtemsCacheValCache_Action_5();
+ RtemsCacheValCache_Action_6();
+ RtemsCacheValCache_Action_7();
+ RtemsCacheValCache_Action_8();
+ RtemsCacheValCache_Action_9();
+ RtemsCacheValCache_Action_10();
+ RtemsCacheValCache_Action_11();
+ RtemsCacheValCache_Action_12();
+ RtemsCacheValCache_Action_13();
+ RtemsCacheValCache_Action_14();
+ RtemsCacheValCache_Action_15();
+ RtemsCacheValCache_Action_16();
+ RtemsCacheValCache_Action_17();
+ RtemsCacheValCache_Action_18();
+ RtemsCacheValCache_Action_19();
+ RtemsCacheValCache_Action_20();
+ RtemsCacheValCache_Action_21();
+ RtemsCacheValCache_Action_22();
+ RtemsCacheValCache_Action_23();
+ RtemsCacheValCache_Action_24();
+ RtemsCacheValCache_Action_25();
+ RtemsCacheValCache_Action_26();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-clock-get-tod.c b/testsuites/validation/tc-clock-get-tod.c
new file mode 100644
index 0000000000..8bf5717171
--- /dev/null
+++ b/testsuites/validation/tc-clock-get-tod.c
@@ -0,0 +1,470 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsClockReqGetTod
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsClockReqGetTod spec:/rtems/clock/req/get-tod
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsClockReqGetTod_Pre_ToD_Arbitrary,
+ RtemsClockReqGetTod_Pre_ToD_Leap4,
+ RtemsClockReqGetTod_Pre_ToD_Leap400,
+ RtemsClockReqGetTod_Pre_ToD_Youngest,
+ RtemsClockReqGetTod_Pre_ToD_Oldest,
+ RtemsClockReqGetTod_Pre_ToD_NotSet,
+ RtemsClockReqGetTod_Pre_ToD_NA
+} RtemsClockReqGetTod_Pre_ToD;
+
+typedef enum {
+ RtemsClockReqGetTod_Pre_Param_Valid,
+ RtemsClockReqGetTod_Pre_Param_Null,
+ RtemsClockReqGetTod_Pre_Param_NA
+} RtemsClockReqGetTod_Pre_Param;
+
+typedef enum {
+ RtemsClockReqGetTod_Post_Status_Ok,
+ RtemsClockReqGetTod_Post_Status_InvAddr,
+ RtemsClockReqGetTod_Post_Status_NotDef,
+ RtemsClockReqGetTod_Post_Status_NA
+} RtemsClockReqGetTod_Post_Status;
+
+typedef enum {
+ RtemsClockReqGetTod_Post_Value_TimeOfDay,
+ RtemsClockReqGetTod_Post_Value_Unchanged,
+ RtemsClockReqGetTod_Post_Value_NA
+} RtemsClockReqGetTod_Post_Value;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_ToD_NA : 1;
+ uint8_t Pre_Param_NA : 1;
+ uint8_t Post_Status : 2;
+ uint8_t Post_Value : 2;
+} RtemsClockReqGetTod_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/clock/req/get-tod test case.
+ */
+typedef struct {
+ rtems_status_code set_tod_status;
+
+ rtems_time_of_day set_tod_value;
+
+ rtems_time_of_day *get_tod_ref;
+
+ rtems_time_of_day get_tod_value;
+
+ rtems_status_code get_tod_status;
+
+ bool isDef;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsClockReqGetTod_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsClockReqGetTod_Context;
+
+static RtemsClockReqGetTod_Context
+ RtemsClockReqGetTod_Instance;
+
+static const char * const RtemsClockReqGetTod_PreDesc_ToD[] = {
+ "Arbitrary",
+ "Leap4",
+ "Leap400",
+ "Youngest",
+ "Oldest",
+ "NotSet",
+ "NA"
+};
+
+static const char * const RtemsClockReqGetTod_PreDesc_Param[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsClockReqGetTod_PreDesc[] = {
+ RtemsClockReqGetTod_PreDesc_ToD,
+ RtemsClockReqGetTod_PreDesc_Param,
+ NULL
+};
+
+static void RtemsClockReqGetTod_Pre_ToD_Prepare(
+ RtemsClockReqGetTod_Context *ctx,
+ RtemsClockReqGetTod_Pre_ToD state
+)
+{
+ switch ( state ) {
+ case RtemsClockReqGetTod_Pre_ToD_Arbitrary: {
+ /*
+ * While the CLOCK_REALTIME indicates an arbitrary valid date and time
+ * between 1988-01-01T00:00:00.000000000Z and
+ * 2514-05-30T01:53:03.999999999Z.
+ */
+ ctx->set_tod_value =
+ (rtems_time_of_day) { 2023, 12, 27, 6, 7, 8,
+ rtems_clock_get_ticks_per_second() / 4 };
+ break;
+ }
+
+ case RtemsClockReqGetTod_Pre_ToD_Leap4: {
+ /*
+ * While the CLOCK_REALTIME indicates a date for a leap year with the
+ * value of 29th of February.
+ */
+ ctx->set_tod_value =
+ (rtems_time_of_day) { 2096, 2, 29, 0, 0, 0, 0 };
+ break;
+ }
+
+ case RtemsClockReqGetTod_Pre_ToD_Leap400: {
+ /*
+ * While the CLOCK_REALTIME indicates a date for a leap year with the
+ * value of 29th of February.
+ */
+ ctx->set_tod_value =
+ (rtems_time_of_day) { 2000, 2, 29, 0, 0, 0, 0 };
+ break;
+ }
+
+ case RtemsClockReqGetTod_Pre_ToD_Youngest: {
+ /*
+ * While the CLOCK_REALTIME indicates the youngest date and time accepted
+ * (1988-01-01T00:00:00.000000000Z).
+ */
+ ctx->set_tod_value =
+ (rtems_time_of_day) { 1988, 1, 1, 0, 0, 0, 0 };
+ break;
+ }
+
+ case RtemsClockReqGetTod_Pre_ToD_Oldest: {
+ /*
+ * While the CLOCK_REALTIME indicates the oldest date and time accepted
+ * (2099-12-31T23:59:59.999999999Z).
+ */
+ ctx->set_tod_value =
+ (rtems_time_of_day) { 2099, 12, 31, 23, 59, 59,
+ rtems_clock_get_ticks_per_second() - 1 };
+ break;
+ }
+
+ case RtemsClockReqGetTod_Pre_ToD_NotSet: {
+ /*
+ * While the CLOCK_REALTIME has not been set before.
+ */
+ ctx->isDef = false;
+ break;
+ }
+
+ case RtemsClockReqGetTod_Pre_ToD_NA:
+ break;
+ }
+}
+
+static void RtemsClockReqGetTod_Pre_Param_Prepare(
+ RtemsClockReqGetTod_Context *ctx,
+ RtemsClockReqGetTod_Pre_Param state
+)
+{
+ switch ( state ) {
+ case RtemsClockReqGetTod_Pre_Param_Valid: {
+ /*
+ * While the ``time_of_day`` parameter references an object of type
+ * rtems_time_of_day.
+ */
+ ctx->get_tod_ref = &ctx->get_tod_value;
+ break;
+ }
+
+ case RtemsClockReqGetTod_Pre_Param_Null: {
+ /*
+ * While the ``time_of_day`` parameter is NULL.
+ */
+ ctx->get_tod_ref = NULL;
+ break;
+ }
+
+ case RtemsClockReqGetTod_Pre_Param_NA:
+ break;
+ }
+}
+
+static void RtemsClockReqGetTod_Post_Status_Check(
+ RtemsClockReqGetTod_Context *ctx,
+ RtemsClockReqGetTod_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsClockReqGetTod_Post_Status_Ok: {
+ /*
+ * The return status of rtems_clock_get_tod() shall be RTEMS_SUCCESSFUL
+ */
+ T_rsc_success( ctx->set_tod_status );
+ T_rsc_success( ctx->get_tod_status );
+ break;
+ }
+
+ case RtemsClockReqGetTod_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_clock_get_tod() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->get_tod_status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsClockReqGetTod_Post_Status_NotDef: {
+ /*
+ * The return status of rtems_clock_get_tod() shall be RTEMS_NOT_DEFINED.
+ */
+ T_rsc( ctx->get_tod_status, RTEMS_NOT_DEFINED );
+ break;
+ }
+
+ case RtemsClockReqGetTod_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsClockReqGetTod_Post_Value_Check(
+ RtemsClockReqGetTod_Context *ctx,
+ RtemsClockReqGetTod_Post_Value state
+)
+{
+ switch ( state ) {
+ case RtemsClockReqGetTod_Post_Value_TimeOfDay: {
+ /*
+ * The value of the object referenced by the ``time_of_day`` parameter
+ * shall be set to the value of the CLOCK_REALTIME at a point in time
+ * during the call to rtems_clock_get_tod().
+ */
+ T_eq_ptr( ctx->get_tod_ref, &ctx->get_tod_value );
+ T_eq_u32( ctx->get_tod_value.year, ctx->set_tod_value.year );
+ T_eq_u32( ctx->get_tod_value.month, ctx->set_tod_value.month );
+ T_eq_u32( ctx->get_tod_value.day, ctx->set_tod_value.day );
+ T_eq_u32( ctx->get_tod_value.hour, ctx->set_tod_value.hour );
+ T_eq_u32( ctx->get_tod_value.minute, ctx->set_tod_value.minute );
+ T_eq_u32( ctx->get_tod_value.second, ctx->set_tod_value.second );
+ /* rtems_clock_set() or rtems_clock_get_tod() cause an error of 1 tick */
+ T_ge_u32( ctx->get_tod_value.ticks + 1, ctx->set_tod_value.ticks );
+ T_le_u32( ctx->get_tod_value.ticks, ctx->set_tod_value.ticks );
+ break;
+ }
+
+ case RtemsClockReqGetTod_Post_Value_Unchanged: {
+ /*
+ * Object referenced by the ``time_of_day`` parameter in past call to
+ * rtems_clock_get_tod() shall not be modified by the
+ * rtems_clock_get_tod() call.
+ */
+ T_eq_u32( ctx->get_tod_value.year, 1 );
+ T_eq_u32( ctx->get_tod_value.month, 1 );
+ T_eq_u32( ctx->get_tod_value.day, 1 );
+ T_eq_u32( ctx->get_tod_value.hour, 1 );
+ T_eq_u32( ctx->get_tod_value.minute, 1 );
+ T_eq_u32( ctx->get_tod_value.second, 1 );
+ T_eq_u32( ctx->get_tod_value.ticks, 1 );
+ break;
+ }
+
+ case RtemsClockReqGetTod_Post_Value_NA:
+ break;
+ }
+}
+
+static void RtemsClockReqGetTod_Prepare( RtemsClockReqGetTod_Context *ctx )
+{
+ ctx->get_tod_value = (rtems_time_of_day) { 1, 1, 1, 1, 1, 1, 1 };
+ ctx->get_tod_ref = &ctx->get_tod_value;
+ ctx->set_tod_value = (rtems_time_of_day) { 2023, 4, 5, 6, 7, 8, 0 };
+ ctx->isDef = true;
+}
+
+static void RtemsClockReqGetTod_Action( RtemsClockReqGetTod_Context *ctx )
+{
+ if ( ctx->isDef ) {
+ ctx->set_tod_status = rtems_clock_set( &ctx->set_tod_value );
+ ctx->get_tod_status = rtems_clock_get_tod( ctx->get_tod_ref );
+ } else {
+ UnsetClock();
+ ctx->get_tod_status = rtems_clock_get_tod( ctx->get_tod_ref );
+ }
+}
+
+static void RtemsClockReqGetTod_Cleanup( RtemsClockReqGetTod_Context *ctx )
+{
+ UnsetClock();
+}
+
+static const RtemsClockReqGetTod_Entry
+RtemsClockReqGetTod_Entries[] = {
+ { 0, 0, 0, RtemsClockReqGetTod_Post_Status_InvAddr,
+ RtemsClockReqGetTod_Post_Value_Unchanged },
+ { 0, 0, 0, RtemsClockReqGetTod_Post_Status_Ok,
+ RtemsClockReqGetTod_Post_Value_TimeOfDay },
+ { 0, 0, 0, RtemsClockReqGetTod_Post_Status_NotDef,
+ RtemsClockReqGetTod_Post_Value_Unchanged }
+};
+
+static const uint8_t
+RtemsClockReqGetTod_Map[] = {
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 0
+};
+
+static size_t RtemsClockReqGetTod_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsClockReqGetTod_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsClockReqGetTod_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsClockReqGetTod_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsClockReqGetTod_Scope,
+ .initial_context = &RtemsClockReqGetTod_Instance
+};
+
+static inline RtemsClockReqGetTod_Entry RtemsClockReqGetTod_PopEntry(
+ RtemsClockReqGetTod_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsClockReqGetTod_Entries[
+ RtemsClockReqGetTod_Map[ index ]
+ ];
+}
+
+static void RtemsClockReqGetTod_TestVariant( RtemsClockReqGetTod_Context *ctx )
+{
+ RtemsClockReqGetTod_Pre_ToD_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsClockReqGetTod_Pre_Param_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsClockReqGetTod_Action( ctx );
+ RtemsClockReqGetTod_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsClockReqGetTod_Post_Value_Check( ctx, ctx->Map.entry.Post_Value );
+}
+
+/**
+ * @fn void T_case_body_RtemsClockReqGetTod( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsClockReqGetTod, &RtemsClockReqGetTod_Fixture )
+{
+ RtemsClockReqGetTod_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsClockReqGetTod_Pre_ToD_Arbitrary;
+ ctx->Map.pcs[ 0 ] < RtemsClockReqGetTod_Pre_ToD_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsClockReqGetTod_Pre_Param_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsClockReqGetTod_Pre_Param_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ ctx->Map.entry = RtemsClockReqGetTod_PopEntry( ctx );
+ RtemsClockReqGetTod_Prepare( ctx );
+ RtemsClockReqGetTod_TestVariant( ctx );
+ RtemsClockReqGetTod_Cleanup( ctx );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-clock-get-uptime.c b/testsuites/validation/tc-clock-get-uptime.c
new file mode 100644
index 0000000000..19608c33e6
--- /dev/null
+++ b/testsuites/validation/tc-clock-get-uptime.c
@@ -0,0 +1,338 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsClockReqGetUptime
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsClockReqGetUptime spec:/rtems/clock/req/get-uptime
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsClockReqGetUptime_Pre_Uptime_Valid,
+ RtemsClockReqGetUptime_Pre_Uptime_Null,
+ RtemsClockReqGetUptime_Pre_Uptime_NA
+} RtemsClockReqGetUptime_Pre_Uptime;
+
+typedef enum {
+ RtemsClockReqGetUptime_Post_Status_Ok,
+ RtemsClockReqGetUptime_Post_Status_InvAddr,
+ RtemsClockReqGetUptime_Post_Status_NA
+} RtemsClockReqGetUptime_Post_Status;
+
+typedef enum {
+ RtemsClockReqGetUptime_Post_Uptime_Set,
+ RtemsClockReqGetUptime_Post_Uptime_Unchanged,
+ RtemsClockReqGetUptime_Post_Uptime_NA
+} RtemsClockReqGetUptime_Post_Uptime;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Uptime_NA : 1;
+ uint8_t Post_Status : 2;
+ uint8_t Post_Uptime : 2;
+} RtemsClockReqGetUptime_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/clock/req/get-uptime test case.
+ */
+typedef struct {
+ rtems_status_code status;
+
+ struct timespec *uptime;
+
+ struct timespec uptime_value;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsClockReqGetUptime_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsClockReqGetUptime_Context;
+
+static RtemsClockReqGetUptime_Context
+ RtemsClockReqGetUptime_Instance;
+
+static const char * const RtemsClockReqGetUptime_PreDesc_Uptime[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsClockReqGetUptime_PreDesc[] = {
+ RtemsClockReqGetUptime_PreDesc_Uptime,
+ NULL
+};
+
+static void RtemsClockReqGetUptime_Pre_Uptime_Prepare(
+ RtemsClockReqGetUptime_Context *ctx,
+ RtemsClockReqGetUptime_Pre_Uptime state
+)
+{
+ switch ( state ) {
+ case RtemsClockReqGetUptime_Pre_Uptime_Valid: {
+ /*
+ * While the ``uptime`` parameter references an object of type struct
+ * timespec.
+ */
+ ctx->uptime = &ctx->uptime_value;
+ break;
+ }
+
+ case RtemsClockReqGetUptime_Pre_Uptime_Null: {
+ /*
+ * While the ``uptime`` parameter is NULL.
+ */
+ ctx->uptime = NULL;
+ break;
+ }
+
+ case RtemsClockReqGetUptime_Pre_Uptime_NA:
+ break;
+ }
+}
+
+static void RtemsClockReqGetUptime_Post_Status_Check(
+ RtemsClockReqGetUptime_Context *ctx,
+ RtemsClockReqGetUptime_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsClockReqGetUptime_Post_Status_Ok: {
+ /*
+ * The return status of rtems_clock_get_uptime() shall be
+ * RTEMS_SUCCESSFUL
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsClockReqGetUptime_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_clock_get_uptime() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsClockReqGetUptime_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsClockReqGetUptime_Post_Uptime_Check(
+ RtemsClockReqGetUptime_Context *ctx,
+ RtemsClockReqGetUptime_Post_Uptime state
+)
+{
+ switch ( state ) {
+ case RtemsClockReqGetUptime_Post_Uptime_Set: {
+ /*
+ * The value of the object referenced by the ``uptime`` parameter shall
+ * be set to seconds and nanoseconds elapsed since a point in time during
+ * the system initialization and a point in time during the call of
+ * rtems_clock_get_uptime() using CLOCK_MONOTONIC as result of the
+ * rtems_clock_get_uptime() call.
+ */
+ T_eq_ptr( ctx->uptime, &ctx->uptime_value );
+ T_ge_i64( ctx->uptime_value.tv_sec, 0LL );
+ T_ge_long( ctx->uptime_value.tv_nsec, 0L );
+ T_lt_long( ctx->uptime_value.tv_nsec, 1000000000L );
+ break;
+ }
+
+ case RtemsClockReqGetUptime_Post_Uptime_Unchanged: {
+ /*
+ * Objects referenced by the ``uptime`` parameter in calls to
+ * rtems_clock_get_uptime() shall not be modified by the
+ * rtems_clock_get_uptime() call.
+ */
+ T_null( ctx->uptime );
+ break;
+ }
+
+ case RtemsClockReqGetUptime_Post_Uptime_NA:
+ break;
+ }
+}
+
+static void RtemsClockReqGetUptime_Setup( RtemsClockReqGetUptime_Context *ctx )
+{
+ ctx->uptime_value.tv_sec = -1;
+ ctx->uptime_value.tv_nsec = -1;
+}
+
+static void RtemsClockReqGetUptime_Setup_Wrap( void *arg )
+{
+ RtemsClockReqGetUptime_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsClockReqGetUptime_Setup( ctx );
+}
+
+static void RtemsClockReqGetUptime_Action(
+ RtemsClockReqGetUptime_Context *ctx
+)
+{
+ ctx->status = rtems_clock_get_uptime( ctx->uptime );
+}
+
+static const RtemsClockReqGetUptime_Entry
+RtemsClockReqGetUptime_Entries[] = {
+ { 0, 0, RtemsClockReqGetUptime_Post_Status_Ok,
+ RtemsClockReqGetUptime_Post_Uptime_Set },
+ { 0, 0, RtemsClockReqGetUptime_Post_Status_InvAddr,
+ RtemsClockReqGetUptime_Post_Uptime_Unchanged }
+};
+
+static const uint8_t
+RtemsClockReqGetUptime_Map[] = {
+ 0, 1
+};
+
+static size_t RtemsClockReqGetUptime_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsClockReqGetUptime_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsClockReqGetUptime_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsClockReqGetUptime_Fixture = {
+ .setup = RtemsClockReqGetUptime_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsClockReqGetUptime_Scope,
+ .initial_context = &RtemsClockReqGetUptime_Instance
+};
+
+static inline RtemsClockReqGetUptime_Entry RtemsClockReqGetUptime_PopEntry(
+ RtemsClockReqGetUptime_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsClockReqGetUptime_Entries[
+ RtemsClockReqGetUptime_Map[ index ]
+ ];
+}
+
+static void RtemsClockReqGetUptime_TestVariant(
+ RtemsClockReqGetUptime_Context *ctx
+)
+{
+ RtemsClockReqGetUptime_Pre_Uptime_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsClockReqGetUptime_Action( ctx );
+ RtemsClockReqGetUptime_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsClockReqGetUptime_Post_Uptime_Check( ctx, ctx->Map.entry.Post_Uptime );
+}
+
+/**
+ * @fn void T_case_body_RtemsClockReqGetUptime( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsClockReqGetUptime, &RtemsClockReqGetUptime_Fixture )
+{
+ RtemsClockReqGetUptime_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsClockReqGetUptime_Pre_Uptime_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsClockReqGetUptime_Pre_Uptime_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = RtemsClockReqGetUptime_PopEntry( ctx );
+ RtemsClockReqGetUptime_TestVariant( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-clock-nanosleep.c b/testsuites/validation/tc-clock-nanosleep.c
new file mode 100644
index 0000000000..514f5376ba
--- /dev/null
+++ b/testsuites/validation/tc-clock-nanosleep.c
@@ -0,0 +1,1027 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup CReqClockNanosleep
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <limits.h>
+#include <rtems.h>
+#include <time.h>
+#include <rtems/test-scheduler.h>
+#include <rtems/score/timecounter.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup CReqClockNanosleep spec:/c/req/clock-nanosleep
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ CReqClockNanosleep_Pre_ClockId_Monotonic,
+ CReqClockNanosleep_Pre_ClockId_Realtime,
+ CReqClockNanosleep_Pre_ClockId_Invalid,
+ CReqClockNanosleep_Pre_ClockId_NA
+} CReqClockNanosleep_Pre_ClockId;
+
+typedef enum {
+ CReqClockNanosleep_Pre_Abstime_Yes,
+ CReqClockNanosleep_Pre_Abstime_No,
+ CReqClockNanosleep_Pre_Abstime_NA
+} CReqClockNanosleep_Pre_Abstime;
+
+typedef enum {
+ CReqClockNanosleep_Pre_RQTp_Valid,
+ CReqClockNanosleep_Pre_RQTp_Null,
+ CReqClockNanosleep_Pre_RQTp_NA
+} CReqClockNanosleep_Pre_RQTp;
+
+typedef enum {
+ CReqClockNanosleep_Pre_RQTpNSec_Valid,
+ CReqClockNanosleep_Pre_RQTpNSec_Invalid,
+ CReqClockNanosleep_Pre_RQTpNSec_NA
+} CReqClockNanosleep_Pre_RQTpNSec;
+
+typedef enum {
+ CReqClockNanosleep_Pre_RQTpSec_Negative,
+ CReqClockNanosleep_Pre_RQTpSec_FarFuture,
+ CReqClockNanosleep_Pre_RQTpSec_Future,
+ CReqClockNanosleep_Pre_RQTpSec_PastOrNow,
+ CReqClockNanosleep_Pre_RQTpSec_NA
+} CReqClockNanosleep_Pre_RQTpSec;
+
+typedef enum {
+ CReqClockNanosleep_Pre_RMTp_Valid,
+ CReqClockNanosleep_Pre_RMTp_Null,
+ CReqClockNanosleep_Pre_RMTp_NA
+} CReqClockNanosleep_Pre_RMTp;
+
+typedef enum {
+ CReqClockNanosleep_Post_Status_Zero,
+ CReqClockNanosleep_Post_Status_ENOTSUP,
+ CReqClockNanosleep_Post_Status_EINVAL,
+ CReqClockNanosleep_Post_Status_NA
+} CReqClockNanosleep_Post_Status;
+
+typedef enum {
+ CReqClockNanosleep_Post_Timer_Inactive,
+ CReqClockNanosleep_Post_Timer_Monotonic,
+ CReqClockNanosleep_Post_Timer_Realtime,
+ CReqClockNanosleep_Post_Timer_NA
+} CReqClockNanosleep_Post_Timer;
+
+typedef enum {
+ CReqClockNanosleep_Post_Expire_Last,
+ CReqClockNanosleep_Post_Expire_Absolute,
+ CReqClockNanosleep_Post_Expire_Relative,
+ CReqClockNanosleep_Post_Expire_NA
+} CReqClockNanosleep_Post_Expire;
+
+typedef enum {
+ CReqClockNanosleep_Post_Scheduler_Block,
+ CReqClockNanosleep_Post_Scheduler_BlockUnblock,
+ CReqClockNanosleep_Post_Scheduler_Nop,
+ CReqClockNanosleep_Post_Scheduler_NA
+} CReqClockNanosleep_Post_Scheduler;
+
+typedef enum {
+ CReqClockNanosleep_Post_RMTp_Zero,
+ CReqClockNanosleep_Post_RMTp_Nop,
+ CReqClockNanosleep_Post_RMTp_NA
+} CReqClockNanosleep_Post_RMTp;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_ClockId_NA : 1;
+ uint32_t Pre_Abstime_NA : 1;
+ uint32_t Pre_RQTp_NA : 1;
+ uint32_t Pre_RQTpNSec_NA : 1;
+ uint32_t Pre_RQTpSec_NA : 1;
+ uint32_t Pre_RMTp_NA : 1;
+ uint32_t Post_Status : 2;
+ uint32_t Post_Timer : 2;
+ uint32_t Post_Expire : 2;
+ uint32_t Post_Scheduler : 2;
+ uint32_t Post_RMTp : 2;
+} CReqClockNanosleep_Entry;
+
+/**
+ * @brief Test context for spec:/c/req/clock-nanosleep test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides the scheduler operation records.
+ */
+ T_scheduler_log_4 scheduler_log;
+
+ /**
+ * @brief This member contains the CLOCK_REALTIME value before the
+ * clock_nanosleep() call.
+ */
+ struct timespec now_realtime;
+
+ /**
+ * @brief This member contains the CLOCK_MONOTONIC value before the
+ * clock_nanosleep() call.
+ */
+ struct timespec now_monotonic;
+
+ /**
+ * @brief This member contains the worker task identifier.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member contains the timer information of the worker task.
+ */
+ TaskTimerInfo timer_info;
+
+ /**
+ * @brief This member provides the object referenced by the ``rqtp``
+ * parameter.
+ */
+ struct timespec rqtp_obj;
+
+ /**
+ * @brief This member provides the object referenced by the ``rmtp``
+ * parameter.
+ */
+ struct timespec rmtp_obj;
+
+ /**
+ * @brief This member contains the return value of the clock_nanosleep()
+ * call.
+ */
+ int status;
+
+ /**
+ * @brief This member specifies the ``clock_id`` parameter value.
+ */
+ clockid_t clock_id;
+
+ /**
+ * @brief This member specifies the ``flags`` parameter value.
+ */
+ int flags;
+
+ /**
+ * @brief This member specifies the ``rqtp`` parameter value.
+ */
+ const struct timespec *rqtp;
+
+ /**
+ * @brief This member specifies the ``rmtp`` parameter value.
+ */
+ struct timespec *rmtp;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 6 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 6 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ CReqClockNanosleep_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} CReqClockNanosleep_Context;
+
+static CReqClockNanosleep_Context
+ CReqClockNanosleep_Instance;
+
+static const char * const CReqClockNanosleep_PreDesc_ClockId[] = {
+ "Monotonic",
+ "Realtime",
+ "Invalid",
+ "NA"
+};
+
+static const char * const CReqClockNanosleep_PreDesc_Abstime[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const CReqClockNanosleep_PreDesc_RQTp[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const CReqClockNanosleep_PreDesc_RQTpNSec[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const CReqClockNanosleep_PreDesc_RQTpSec[] = {
+ "Negative",
+ "FarFuture",
+ "Future",
+ "PastOrNow",
+ "NA"
+};
+
+static const char * const CReqClockNanosleep_PreDesc_RMTp[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const CReqClockNanosleep_PreDesc[] = {
+ CReqClockNanosleep_PreDesc_ClockId,
+ CReqClockNanosleep_PreDesc_Abstime,
+ CReqClockNanosleep_PreDesc_RQTp,
+ CReqClockNanosleep_PreDesc_RQTpNSec,
+ CReqClockNanosleep_PreDesc_RQTpSec,
+ CReqClockNanosleep_PreDesc_RMTp,
+ NULL
+};
+
+typedef CReqClockNanosleep_Context Context;
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ while ( true ) {
+ T_scheduler_log *log;
+ uint32_t counter;
+
+ SuspendSelf();
+
+ log = T_scheduler_record_4( &ctx->scheduler_log );
+ T_null( log );
+
+ counter = GetTimecountCounter();
+ _Timecounter_Nanotime( &ctx->now_realtime );
+ SetTimecountCounter( counter );
+
+ counter = GetTimecountCounter();
+ _Timecounter_Nanouptime( &ctx->now_monotonic );
+ SetTimecountCounter( counter );
+
+ ctx->status = clock_nanosleep(
+ ctx->clock_id,
+ ctx->flags,
+ ctx->rqtp,
+ ctx->rmtp
+ );
+
+ (void) T_scheduler_record( NULL );
+ }
+}
+
+static void CReqClockNanosleep_Pre_ClockId_Prepare(
+ CReqClockNanosleep_Context *ctx,
+ CReqClockNanosleep_Pre_ClockId state
+)
+{
+ switch ( state ) {
+ case CReqClockNanosleep_Pre_ClockId_Monotonic: {
+ /*
+ * While the ``clock_id`` parameter is equal to CLOCK_MONOTONIC.
+ */
+ ctx->clock_id = CLOCK_MONOTONIC;
+ break;
+ }
+
+ case CReqClockNanosleep_Pre_ClockId_Realtime: {
+ /*
+ * While the ``clock_id`` parameter is equal to CLOCK_REALTIME.
+ */
+ ctx->clock_id = CLOCK_REALTIME;
+ break;
+ }
+
+ case CReqClockNanosleep_Pre_ClockId_Invalid: {
+ /*
+ * While the ``clock_id`` parameter is an invalid clock identifier.
+ */
+ ctx->clock_id = INT_MAX;
+ break;
+ }
+
+ case CReqClockNanosleep_Pre_ClockId_NA:
+ break;
+ }
+}
+
+static void CReqClockNanosleep_Pre_Abstime_Prepare(
+ CReqClockNanosleep_Context *ctx,
+ CReqClockNanosleep_Pre_Abstime state
+)
+{
+ switch ( state ) {
+ case CReqClockNanosleep_Pre_Abstime_Yes: {
+ /*
+ * While the ``flags`` parameter indicates an absolute time.
+ */
+ ctx->flags |= TIMER_ABSTIME;
+ break;
+ }
+
+ case CReqClockNanosleep_Pre_Abstime_No: {
+ /*
+ * While the ``flags`` parameter does not indicate an absolute time.
+ */
+ /* This is the default */
+ break;
+ }
+
+ case CReqClockNanosleep_Pre_Abstime_NA:
+ break;
+ }
+}
+
+static void CReqClockNanosleep_Pre_RQTp_Prepare(
+ CReqClockNanosleep_Context *ctx,
+ CReqClockNanosleep_Pre_RQTp state
+)
+{
+ switch ( state ) {
+ case CReqClockNanosleep_Pre_RQTp_Valid: {
+ /*
+ * While the ``rqtp`` parameter references an object of type struct
+ * timespec.
+ */
+ ctx->rqtp = &ctx->rqtp_obj;
+ break;
+ }
+
+ case CReqClockNanosleep_Pre_RQTp_Null: {
+ /*
+ * While the ``rqtp`` parameter is equal to NULL.
+ */
+ ctx->rqtp = NULL;
+ break;
+ }
+
+ case CReqClockNanosleep_Pre_RQTp_NA:
+ break;
+ }
+}
+
+static void CReqClockNanosleep_Pre_RQTpNSec_Prepare(
+ CReqClockNanosleep_Context *ctx,
+ CReqClockNanosleep_Pre_RQTpNSec state
+)
+{
+ switch ( state ) {
+ case CReqClockNanosleep_Pre_RQTpNSec_Valid: {
+ /*
+ * While the ``tv_nsec`` member of the object referenced by the ``rqtp``
+ * parameter is a valid nanoseconds value.
+ */
+ ctx->rqtp_obj.tv_nsec = 999999999;
+ break;
+ }
+
+ case CReqClockNanosleep_Pre_RQTpNSec_Invalid: {
+ /*
+ * While the ``tv_nsec`` member of the object referenced by the ``rqtp``
+ * parameter is an invalid nanoseconds value.
+ */
+ ctx->rqtp_obj.tv_nsec = -1;
+ break;
+ }
+
+ case CReqClockNanosleep_Pre_RQTpNSec_NA:
+ break;
+ }
+}
+
+static void CReqClockNanosleep_Pre_RQTpSec_Prepare(
+ CReqClockNanosleep_Context *ctx,
+ CReqClockNanosleep_Pre_RQTpSec state
+)
+{
+ switch ( state ) {
+ case CReqClockNanosleep_Pre_RQTpSec_Negative: {
+ /*
+ * While the ``tv_sec`` member of the object referenced by the ``rqtp``
+ * parameter is negative.
+ */
+ ctx->rqtp_obj.tv_sec = -238479;
+ break;
+ }
+
+ case CReqClockNanosleep_Pre_RQTpSec_FarFuture: {
+ /*
+ * While the ``tv_sec`` member of the object referenced by the ``rqtp``
+ * parameter specifies a time point which is past the implementation
+ * limit.
+ */
+ ctx->rqtp_obj.tv_sec = INT64_MAX;
+ break;
+ }
+
+ case CReqClockNanosleep_Pre_RQTpSec_Future: {
+ /*
+ * While the ``tv_sec`` member of the object referenced by the ``rqtp``
+ * parameter specifies a time point which is after the current time of
+ * the clock specified by the ``clock_id`` parameter and is within the
+ * implementation limits.
+ */
+ ctx->rqtp_obj.tv_sec = 1621322302;
+ break;
+ }
+
+ case CReqClockNanosleep_Pre_RQTpSec_PastOrNow: {
+ /*
+ * While the ``tv_sec`` member of the object referenced by the ``rqtp``
+ * parameter is non-negative and specifies a time point which is before
+ * or at the current time of the clock specified by the ``clock_id``
+ * parameter.
+ */
+ ctx->rqtp_obj.tv_sec = 0;
+
+ if ( ctx->rqtp_obj.tv_nsec == 999999999 ) {
+ ctx->rqtp_obj.tv_nsec = 0;
+ }
+ break;
+ }
+
+ case CReqClockNanosleep_Pre_RQTpSec_NA:
+ break;
+ }
+}
+
+static void CReqClockNanosleep_Pre_RMTp_Prepare(
+ CReqClockNanosleep_Context *ctx,
+ CReqClockNanosleep_Pre_RMTp state
+)
+{
+ switch ( state ) {
+ case CReqClockNanosleep_Pre_RMTp_Valid: {
+ /*
+ * While the ``rmtp`` parameter references an object of type struct
+ * timespec.
+ */
+ ctx->rmtp = &ctx->rmtp_obj;
+ break;
+ }
+
+ case CReqClockNanosleep_Pre_RMTp_Null: {
+ /*
+ * While the ``rmtp`` parameter is equal to NULL.
+ */
+ ctx->rmtp = NULL;
+ break;
+ }
+
+ case CReqClockNanosleep_Pre_RMTp_NA:
+ break;
+ }
+}
+
+static void CReqClockNanosleep_Post_Status_Check(
+ CReqClockNanosleep_Context *ctx,
+ CReqClockNanosleep_Post_Status state
+)
+{
+ switch ( state ) {
+ case CReqClockNanosleep_Post_Status_Zero: {
+ /*
+ * The return value of clock_nanosleep() shall be equal to zero.
+ */
+ T_eq_int( ctx->status, 0 );
+ break;
+ }
+
+ case CReqClockNanosleep_Post_Status_ENOTSUP: {
+ /*
+ * The return value of clock_nanosleep() shall be equal to ENOTSUP.
+ */
+ T_eq_int( ctx->status, ENOTSUP );
+ break;
+ }
+
+ case CReqClockNanosleep_Post_Status_EINVAL: {
+ /*
+ * The return value of clock_nanosleep() shall be equal to EINVAL.
+ */
+ T_eq_int( ctx->status, EINVAL );
+ break;
+ }
+
+ case CReqClockNanosleep_Post_Status_NA:
+ break;
+ }
+}
+
+static void CReqClockNanosleep_Post_Timer_Check(
+ CReqClockNanosleep_Context *ctx,
+ CReqClockNanosleep_Post_Timer state
+)
+{
+ switch ( state ) {
+ case CReqClockNanosleep_Post_Timer_Inactive: {
+ /*
+ * The timer of the calling task shall be inactive.
+ */
+ T_eq_int( ctx->timer_info.state, TASK_TIMER_INACTIVE );
+ break;
+ }
+
+ case CReqClockNanosleep_Post_Timer_Monotonic: {
+ /*
+ * The timer of the calling task shall be active using the
+ * CLOCK_MONOTONIC.
+ */
+ T_eq_int( ctx->timer_info.state, TASK_TIMER_MONOTONIC );
+ break;
+ }
+
+ case CReqClockNanosleep_Post_Timer_Realtime: {
+ /*
+ * The timer of the calling task shall be active using the
+ * CLOCK_REALTIME.
+ */
+ T_eq_int( ctx->timer_info.state, TASK_TIMER_REALTIME );
+ break;
+ }
+
+ case CReqClockNanosleep_Post_Timer_NA:
+ break;
+ }
+}
+
+static void CReqClockNanosleep_Post_Expire_Check(
+ CReqClockNanosleep_Context *ctx,
+ CReqClockNanosleep_Post_Expire state
+)
+{
+ struct timespec expire;
+
+ switch ( state ) {
+ case CReqClockNanosleep_Post_Expire_Last: {
+ /*
+ * The timer of the calling task shall expire at the last valid time
+ * point of the clock specified by the ``clock_id`` parameter.
+ */
+ T_eq_u64( ctx->timer_info.expire_ticks, 0xffffffffffffffff );
+ break;
+ }
+
+ case CReqClockNanosleep_Post_Expire_Absolute: {
+ /*
+ * The timer of the calling task shall expire at the time point specified
+ * by the ``rqtp`` parameter.
+ */
+ T_eq_i64( ctx->timer_info.expire_timespec.tv_sec, ctx->rqtp_obj.tv_sec );
+ T_eq_long(
+ ctx->timer_info.expire_timespec.tv_nsec,
+ ctx->rqtp_obj.tv_nsec
+ );
+ break;
+ }
+
+ case CReqClockNanosleep_Post_Expire_Relative: {
+ /*
+ * The timer of the calling task shall expire at the time point specified
+ * by the sum of the current time of the clock specified by
+ * CLOCK_MONOTONIC and the interval specified by the ``rqtp`` parameter.
+ */
+ expire = ctx->now_monotonic;
+ expire.tv_sec += ctx->rqtp_obj.tv_sec;
+ expire.tv_nsec += ctx->rqtp_obj.tv_nsec;
+
+ if ( expire.tv_nsec >= 1000000000 ) {
+ ++expire.tv_sec;
+ expire.tv_nsec -= 1000000000;
+ }
+
+ T_eq_i64( ctx->timer_info.expire_timespec.tv_sec, expire.tv_sec );
+ T_eq_long( ctx->timer_info.expire_timespec.tv_nsec, expire.tv_nsec );
+ break;
+ }
+
+ case CReqClockNanosleep_Post_Expire_NA:
+ break;
+ }
+}
+
+static void CReqClockNanosleep_Post_Scheduler_Check(
+ CReqClockNanosleep_Context *ctx,
+ CReqClockNanosleep_Post_Scheduler state
+)
+{
+ switch ( state ) {
+ case CReqClockNanosleep_Post_Scheduler_Block: {
+ /*
+ * The calling task shall be blocked by the scheduler exactly once by the
+ * clock_nanosleep() call.
+ */
+ T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_BLOCK
+ );
+ break;
+ }
+
+ case CReqClockNanosleep_Post_Scheduler_BlockUnblock: {
+ /*
+ * The calling task shall be blocked exactly once by the scheduler and
+ * then unblocked in the same thread dispatch critical section by the
+ * clock_nanosleep() call.
+ */
+ T_eq_sz( ctx->scheduler_log.header.recorded, 2 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_BLOCK
+ );
+ T_eq_int(
+ ctx->scheduler_log.events[ 1 ].operation,
+ T_SCHEDULER_UNBLOCK
+ );
+ break;
+ }
+
+ case CReqClockNanosleep_Post_Scheduler_Nop: {
+ /*
+ * The calling task shall not be altered by the scheduler by the
+ * clock_nanosleep() call.
+ */
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ break;
+ }
+
+ case CReqClockNanosleep_Post_Scheduler_NA:
+ break;
+ }
+}
+
+static void CReqClockNanosleep_Post_RMTp_Check(
+ CReqClockNanosleep_Context *ctx,
+ CReqClockNanosleep_Post_RMTp state
+)
+{
+ switch ( state ) {
+ case CReqClockNanosleep_Post_RMTp_Zero: {
+ /*
+ * The object referenced by the ``rmtp`` parameter shall be cleared to
+ * zero after the return of the clock_nanosleep() call.
+ */
+ T_eq_i64( ctx->rmtp_obj.tv_sec, 0 );
+ T_eq_long( ctx->rmtp_obj.tv_nsec, 0 );
+ break;
+ }
+
+ case CReqClockNanosleep_Post_RMTp_Nop: {
+ /*
+ * Objects referenced by the ``rmtp`` parameter in past calls to
+ * clock_nanosleep() shall not be accessed by the clock_nanosleep() call.
+ */
+ T_eq_i64( ctx->rmtp_obj.tv_sec, -1 );
+ T_eq_long( ctx->rmtp_obj.tv_nsec, -1 );
+ break;
+ }
+
+ case CReqClockNanosleep_Post_RMTp_NA:
+ break;
+ }
+}
+
+static void CReqClockNanosleep_Setup( CReqClockNanosleep_Context *ctx )
+{
+ rtems_time_of_day now = { 1988, 1, 1, 0, 0, 0, 0 };
+ T_rsc_success( rtems_clock_set( &now ) );
+ SetSelfPriority( PRIO_NORMAL );
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+static void CReqClockNanosleep_Setup_Wrap( void *arg )
+{
+ CReqClockNanosleep_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ CReqClockNanosleep_Setup( ctx );
+}
+
+static void CReqClockNanosleep_Teardown( CReqClockNanosleep_Context *ctx )
+{
+ DeleteTask( ctx->worker_id );
+ RestoreRunnerPriority();
+}
+
+static void CReqClockNanosleep_Teardown_Wrap( void *arg )
+{
+ CReqClockNanosleep_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ CReqClockNanosleep_Teardown( ctx );
+}
+
+static void CReqClockNanosleep_Prepare( CReqClockNanosleep_Context *ctx )
+{
+ ctx->status = -1;
+ ctx->flags = 0;
+ ctx->rmtp_obj.tv_sec = -1;
+ ctx->rmtp_obj.tv_nsec = -1;
+}
+
+static void CReqClockNanosleep_Action( CReqClockNanosleep_Context *ctx )
+{
+ ResumeTask( ctx->worker_id );
+ (void) T_scheduler_record( NULL );
+ GetTaskTimerInfo( ctx->worker_id, &ctx->timer_info );
+ ClockTick();
+ FinalClockTick();
+}
+
+static const CReqClockNanosleep_Entry
+CReqClockNanosleep_Entries[] = {
+ { 0, 0, 0, 0, 1, 1, 0, CReqClockNanosleep_Post_Status_EINVAL,
+ CReqClockNanosleep_Post_Timer_Inactive, CReqClockNanosleep_Post_Expire_NA,
+ CReqClockNanosleep_Post_Scheduler_BlockUnblock,
+ CReqClockNanosleep_Post_RMTp_Nop },
+ { 0, 0, 0, 0, 1, 1, 0, CReqClockNanosleep_Post_Status_ENOTSUP,
+ CReqClockNanosleep_Post_Timer_Inactive, CReqClockNanosleep_Post_Expire_NA,
+ CReqClockNanosleep_Post_Scheduler_Nop, CReqClockNanosleep_Post_RMTp_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_EINVAL,
+ CReqClockNanosleep_Post_Timer_Inactive, CReqClockNanosleep_Post_Expire_NA,
+ CReqClockNanosleep_Post_Scheduler_BlockUnblock,
+ CReqClockNanosleep_Post_RMTp_Nop },
+ { 0, 0, 0, 0, 1, 1, 0, CReqClockNanosleep_Post_Status_EINVAL,
+ CReqClockNanosleep_Post_Timer_Inactive, CReqClockNanosleep_Post_Expire_NA,
+ CReqClockNanosleep_Post_Scheduler_BlockUnblock,
+ CReqClockNanosleep_Post_RMTp_Zero },
+ { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_ENOTSUP,
+ CReqClockNanosleep_Post_Timer_Inactive, CReqClockNanosleep_Post_Expire_NA,
+ CReqClockNanosleep_Post_Scheduler_Nop, CReqClockNanosleep_Post_RMTp_Nop },
+ { 1, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_NA,
+ CReqClockNanosleep_Post_Timer_NA, CReqClockNanosleep_Post_Expire_NA,
+ CReqClockNanosleep_Post_Scheduler_NA, CReqClockNanosleep_Post_RMTp_NA },
+ { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
+ CReqClockNanosleep_Post_Timer_Inactive, CReqClockNanosleep_Post_Expire_NA,
+ CReqClockNanosleep_Post_Scheduler_BlockUnblock,
+ CReqClockNanosleep_Post_RMTp_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_EINVAL,
+ CReqClockNanosleep_Post_Timer_Inactive, CReqClockNanosleep_Post_Expire_NA,
+ CReqClockNanosleep_Post_Scheduler_BlockUnblock,
+ CReqClockNanosleep_Post_RMTp_Zero },
+ { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
+ CReqClockNanosleep_Post_Timer_Monotonic,
+ CReqClockNanosleep_Post_Expire_Last,
+ CReqClockNanosleep_Post_Scheduler_Block, CReqClockNanosleep_Post_RMTp_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
+ CReqClockNanosleep_Post_Timer_Monotonic,
+ CReqClockNanosleep_Post_Expire_Absolute,
+ CReqClockNanosleep_Post_Scheduler_Block, CReqClockNanosleep_Post_RMTp_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
+ CReqClockNanosleep_Post_Timer_Monotonic,
+ CReqClockNanosleep_Post_Expire_Last,
+ CReqClockNanosleep_Post_Scheduler_Block, CReqClockNanosleep_Post_RMTp_Zero },
+ { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
+ CReqClockNanosleep_Post_Timer_Monotonic,
+ CReqClockNanosleep_Post_Expire_Relative,
+ CReqClockNanosleep_Post_Scheduler_Block, CReqClockNanosleep_Post_RMTp_Zero },
+ { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
+ CReqClockNanosleep_Post_Timer_Monotonic,
+ CReqClockNanosleep_Post_Expire_Relative,
+ CReqClockNanosleep_Post_Scheduler_Block, CReqClockNanosleep_Post_RMTp_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
+ CReqClockNanosleep_Post_Timer_Inactive, CReqClockNanosleep_Post_Expire_NA,
+ CReqClockNanosleep_Post_Scheduler_BlockUnblock,
+ CReqClockNanosleep_Post_RMTp_Zero },
+ { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
+ CReqClockNanosleep_Post_Timer_Realtime,
+ CReqClockNanosleep_Post_Expire_Last,
+ CReqClockNanosleep_Post_Scheduler_Block, CReqClockNanosleep_Post_RMTp_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, CReqClockNanosleep_Post_Status_Zero,
+ CReqClockNanosleep_Post_Timer_Realtime,
+ CReqClockNanosleep_Post_Expire_Absolute,
+ CReqClockNanosleep_Post_Scheduler_Block, CReqClockNanosleep_Post_RMTp_Nop }
+};
+
+static const uint8_t
+CReqClockNanosleep_Map[] = {
+ 6, 6, 8, 8, 9, 9, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7, 2, 10, 8, 11, 12, 13, 6, 7, 2, 7, 2, 7, 2, 7, 2, 3, 0,
+ 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 6, 6, 14, 14, 15, 15, 6, 6, 2, 2,
+ 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 2, 10,
+ 8, 11, 12, 13, 6, 7, 2, 7, 2, 7, 2, 7, 2, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0,
+ 3, 0, 3, 0, 4, 4, 4, 4, 5, 5, 5, 5, 4, 4, 4, 4, 5, 5, 5, 5, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 4, 4, 4, 5, 5, 5, 5, 4, 4, 4, 4, 5, 5, 5, 5,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+};
+
+static size_t CReqClockNanosleep_Scope( void *arg, char *buf, size_t n )
+{
+ CReqClockNanosleep_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( CReqClockNanosleep_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture CReqClockNanosleep_Fixture = {
+ .setup = CReqClockNanosleep_Setup_Wrap,
+ .stop = NULL,
+ .teardown = CReqClockNanosleep_Teardown_Wrap,
+ .scope = CReqClockNanosleep_Scope,
+ .initial_context = &CReqClockNanosleep_Instance
+};
+
+static inline CReqClockNanosleep_Entry CReqClockNanosleep_PopEntry(
+ CReqClockNanosleep_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return CReqClockNanosleep_Entries[
+ CReqClockNanosleep_Map[ index ]
+ ];
+}
+
+static void CReqClockNanosleep_SetPreConditionStates(
+ CReqClockNanosleep_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+
+ if ( ctx->Map.entry.Pre_RQTpNSec_NA ) {
+ ctx->Map.pcs[ 3 ] = CReqClockNanosleep_Pre_RQTpNSec_NA;
+ } else {
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ }
+
+ if ( ctx->Map.entry.Pre_RQTpSec_NA ) {
+ ctx->Map.pcs[ 4 ] = CReqClockNanosleep_Pre_RQTpSec_NA;
+ } else {
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+ }
+
+ ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
+}
+
+static void CReqClockNanosleep_TestVariant( CReqClockNanosleep_Context *ctx )
+{
+ CReqClockNanosleep_Pre_ClockId_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ CReqClockNanosleep_Pre_Abstime_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ CReqClockNanosleep_Pre_RQTp_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ CReqClockNanosleep_Pre_RQTpNSec_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ CReqClockNanosleep_Pre_RQTpSec_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ CReqClockNanosleep_Pre_RMTp_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ CReqClockNanosleep_Action( ctx );
+ CReqClockNanosleep_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ CReqClockNanosleep_Post_Timer_Check( ctx, ctx->Map.entry.Post_Timer );
+ CReqClockNanosleep_Post_Expire_Check( ctx, ctx->Map.entry.Post_Expire );
+ CReqClockNanosleep_Post_Scheduler_Check(
+ ctx,
+ ctx->Map.entry.Post_Scheduler
+ );
+ CReqClockNanosleep_Post_RMTp_Check( ctx, ctx->Map.entry.Post_RMTp );
+}
+
+/**
+ * @fn void T_case_body_CReqClockNanosleep( void )
+ */
+T_TEST_CASE_FIXTURE( CReqClockNanosleep, &CReqClockNanosleep_Fixture )
+{
+ CReqClockNanosleep_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = CReqClockNanosleep_Pre_ClockId_Monotonic;
+ ctx->Map.pci[ 0 ] < CReqClockNanosleep_Pre_ClockId_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = CReqClockNanosleep_Pre_Abstime_Yes;
+ ctx->Map.pci[ 1 ] < CReqClockNanosleep_Pre_Abstime_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = CReqClockNanosleep_Pre_RQTp_Valid;
+ ctx->Map.pci[ 2 ] < CReqClockNanosleep_Pre_RQTp_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = CReqClockNanosleep_Pre_RQTpNSec_Valid;
+ ctx->Map.pci[ 3 ] < CReqClockNanosleep_Pre_RQTpNSec_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ for (
+ ctx->Map.pci[ 4 ] = CReqClockNanosleep_Pre_RQTpSec_Negative;
+ ctx->Map.pci[ 4 ] < CReqClockNanosleep_Pre_RQTpSec_NA;
+ ++ctx->Map.pci[ 4 ]
+ ) {
+ for (
+ ctx->Map.pci[ 5 ] = CReqClockNanosleep_Pre_RMTp_Valid;
+ ctx->Map.pci[ 5 ] < CReqClockNanosleep_Pre_RMTp_NA;
+ ++ctx->Map.pci[ 5 ]
+ ) {
+ ctx->Map.entry = CReqClockNanosleep_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ CReqClockNanosleep_SetPreConditionStates( ctx );
+ CReqClockNanosleep_Prepare( ctx );
+ CReqClockNanosleep_TestVariant( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-clock-set.c b/testsuites/validation/tc-clock-set.c
new file mode 100644
index 0000000000..0ed631004b
--- /dev/null
+++ b/testsuites/validation/tc-clock-set.c
@@ -0,0 +1,839 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsClockReqSet
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/score/todimpl.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsClockReqSet spec:/rtems/clock/req/set
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsClockReqSet_Pre_ToD_Valid,
+ RtemsClockReqSet_Pre_ToD_ValidLeap4,
+ RtemsClockReqSet_Pre_ToD_ValidLeap400,
+ RtemsClockReqSet_Pre_ToD_Youngest,
+ RtemsClockReqSet_Pre_ToD_Oldest,
+ RtemsClockReqSet_Pre_ToD_TooJung,
+ RtemsClockReqSet_Pre_ToD_TooOld,
+ RtemsClockReqSet_Pre_ToD_InvMonth0,
+ RtemsClockReqSet_Pre_ToD_InvMonth,
+ RtemsClockReqSet_Pre_ToD_InvDay0,
+ RtemsClockReqSet_Pre_ToD_InvDay,
+ RtemsClockReqSet_Pre_ToD_InvHour,
+ RtemsClockReqSet_Pre_ToD_InvMinute,
+ RtemsClockReqSet_Pre_ToD_InvSecond,
+ RtemsClockReqSet_Pre_ToD_InvTicks,
+ RtemsClockReqSet_Pre_ToD_InvLeap4,
+ RtemsClockReqSet_Pre_ToD_InvLeap100,
+ RtemsClockReqSet_Pre_ToD_InvLeap400,
+ RtemsClockReqSet_Pre_ToD_AtTimer,
+ RtemsClockReqSet_Pre_ToD_BeforeTimer,
+ RtemsClockReqSet_Pre_ToD_AfterTimer,
+ RtemsClockReqSet_Pre_ToD_Null,
+ RtemsClockReqSet_Pre_ToD_NA
+} RtemsClockReqSet_Pre_ToD;
+
+typedef enum {
+ RtemsClockReqSet_Pre_Hook_None,
+ RtemsClockReqSet_Pre_Hook_Ok,
+ RtemsClockReqSet_Pre_Hook_NotOk,
+ RtemsClockReqSet_Pre_Hook_NA
+} RtemsClockReqSet_Pre_Hook;
+
+typedef enum {
+ RtemsClockReqSet_Post_Status_Ok,
+ RtemsClockReqSet_Post_Status_InvAddr,
+ RtemsClockReqSet_Post_Status_InvClk,
+ RtemsClockReqSet_Post_Status_Hook,
+ RtemsClockReqSet_Post_Status_NA
+} RtemsClockReqSet_Post_Status;
+
+typedef enum {
+ RtemsClockReqSet_Post_Clock_Set,
+ RtemsClockReqSet_Post_Clock_Nop,
+ RtemsClockReqSet_Post_Clock_NA
+} RtemsClockReqSet_Post_Clock;
+
+typedef enum {
+ RtemsClockReqSet_Post_Timer_Triggered,
+ RtemsClockReqSet_Post_Timer_Nop,
+ RtemsClockReqSet_Post_Timer_NA
+} RtemsClockReqSet_Post_Timer;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_ToD_NA : 1;
+ uint16_t Pre_Hook_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_Clock : 2;
+ uint16_t Post_Timer : 2;
+} RtemsClockReqSet_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/clock/req/set test case.
+ */
+typedef struct {
+ rtems_status_code status;
+
+ bool register_hook;
+
+ Status_Control hook_status;
+
+ rtems_time_of_day *target_tod;
+
+ rtems_time_of_day target_tod_value;
+
+ rtems_time_of_day tod_before;
+
+ rtems_status_code get_tod_before_status;
+
+ rtems_time_of_day tod_after;
+
+ rtems_status_code get_tod_after_status;
+
+ rtems_id timer_id;
+
+ int timer_routine_counter;
+
+ rtems_time_of_day timer_routine_tod;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsClockReqSet_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsClockReqSet_Context;
+
+static RtemsClockReqSet_Context
+ RtemsClockReqSet_Instance;
+
+static const char * const RtemsClockReqSet_PreDesc_ToD[] = {
+ "Valid",
+ "ValidLeap4",
+ "ValidLeap400",
+ "Youngest",
+ "Oldest",
+ "TooJung",
+ "TooOld",
+ "InvMonth0",
+ "InvMonth",
+ "InvDay0",
+ "InvDay",
+ "InvHour",
+ "InvMinute",
+ "InvSecond",
+ "InvTicks",
+ "InvLeap4",
+ "InvLeap100",
+ "InvLeap400",
+ "AtTimer",
+ "BeforeTimer",
+ "AfterTimer",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsClockReqSet_PreDesc_Hook[] = {
+ "None",
+ "Ok",
+ "NotOk",
+ "NA"
+};
+
+static const char * const * const RtemsClockReqSet_PreDesc[] = {
+ RtemsClockReqSet_PreDesc_ToD,
+ RtemsClockReqSet_PreDesc_Hook,
+ NULL
+};
+
+typedef RtemsClockReqSet_Context Context;
+
+static rtems_timer_service_routine _TOD_timer_routine(
+ rtems_id timer_id,
+ void *user_data
+)
+{
+ Context *ctx = user_data;
+ rtems_status_code status;
+ ++ctx->timer_routine_counter;
+ status = rtems_clock_get_tod( &ctx->timer_routine_tod );
+ T_rsc_success( status );
+}
+
+static void _TOD_prepare_timer( Context *ctx )
+{
+ rtems_status_code status;
+ rtems_time_of_day tod = { 1988, 1, 1, 0, 0, 0, 0 };
+
+ status = rtems_clock_set( &tod );
+ T_rsc_success( status );
+
+ tod.year = 1989;
+ status = rtems_timer_fire_when(
+ ctx->timer_id,
+ &tod,
+ _TOD_timer_routine,
+ ctx
+ );
+ T_rsc_success( status );
+}
+
+static Status_Control TODHook(
+ TOD_Action action,
+ const struct timespec *tod
+)
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+ T_eq_int( action, TOD_ACTION_SET_CLOCK );
+ T_not_null( tod );
+
+ return ctx->hook_status;
+}
+
+static void RtemsClockReqSet_Pre_ToD_Prepare(
+ RtemsClockReqSet_Context *ctx,
+ RtemsClockReqSet_Pre_ToD state
+)
+{
+ switch ( state ) {
+ case RtemsClockReqSet_Pre_ToD_Valid: {
+ /*
+ * While the ``time_of_day`` parameter references an arbitrary valid date
+ * and time between 1988-01-01T00:00:00.000000000Z and
+ * 2105-12-31T23:59:59.999999999Z.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 2021, 3, 11, 11, 10, 59,
+ rtems_clock_get_ticks_per_second() / 2 };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_ValidLeap4: {
+ /*
+ * While the ``time_of_day`` parameter references a date for a leap year
+ * with the value of 29th of February.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 2096, 2, 29, 0, 0, 0, 0 };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_ValidLeap400: {
+ /*
+ * While the ``time_of_day`` parameter references a date for a leap year
+ * with the value of 29th of February.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 2000, 2, 29, 0, 0, 0, 0 };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_Youngest: {
+ /*
+ * While the ``time_of_day`` parameter references the youngest date and
+ * time accepted (1988-01-01T00:00:00.000000000Z).
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 1988, 1, 1, 0, 0, 0, 0 };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_Oldest: {
+ /*
+ * While the ``time_of_day`` parameter references the oldest date and
+ * time accepted (2099-12-31T23:59:59.999999999Z).
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 2099, 12, 31, 23, 59, 59,
+ rtems_clock_get_ticks_per_second() - 1 };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_TooJung: {
+ /*
+ * While the ``time_of_day`` parameter references a valid date and time
+ * younger than 1988-01-01T00:00:00.000000000Z.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 1987, 12, 31, 23, 59, 59,
+ rtems_clock_get_ticks_per_second() - 1 };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_TooOld: {
+ /*
+ * While the ``time_of_day`` parameter references a valid date and time
+ * older than 2105-12-31T23:59:59.999999999Z.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 2106, 1, 1, 0, 0, 0, 0 };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_InvMonth0: {
+ /*
+ * While the ``time_of_day`` parameter is invalid because the value of
+ * the month is 0.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 2021, 0, 11, 11, 10, 59, 1 };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_InvMonth: {
+ /*
+ * While the ``time_of_day`` parameter is invalid because the value of
+ * the month is larger than 12.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 2021, 13, 11, 11, 10, 59, 1 };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_InvDay0: {
+ /*
+ * While the ``time_of_day`` parameter is invalid because the value of
+ * the day is 0.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 2021, 3, 0, 11, 10, 59, 1 };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_InvDay: {
+ /*
+ * While the ``time_of_day`` parameter is invalid because the value of
+ * the day is larger than the days of the month.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 2021, 2, 29, 11, 10, 59, 1 };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_InvHour: {
+ /*
+ * While the ``time_of_day`` parameter is invalid because the value of
+ * the hour is larger than 23.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 2021, 3, 11, 24, 10, 59, 1 };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_InvMinute: {
+ /*
+ * While the ``time_of_day`` parameter is invalid because the value of
+ * the minute is larger than 59.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 2021, 3, 11, 11, 60, 59, 1 };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_InvSecond: {
+ /*
+ * While the ``time_of_day`` parameter is invalid because the value of
+ * the second is larger than 59.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 2021, 3, 11, 11, 10, 60, 1 };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_InvTicks: {
+ /*
+ * While the ``time_of_day`` parameter is invalid because the value of
+ * the ticks are larger or equal to the ticks per second.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 2021, 3, 11, 11, 10, 60,
+ rtems_clock_get_ticks_per_second() };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_InvLeap4: {
+ /*
+ * While the ``time_of_day`` parameter is invalid because the value 30th
+ * of February does not exist in a leap year.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 2104, 2, 30, 0, 0, 0, 0 };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_InvLeap100: {
+ /*
+ * While the ``time_of_day`` parameter is invalid because the value 29th
+ * of February does not exist in a non-leap year.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 2100, 2, 29, 0, 0, 0, 0 };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_InvLeap400: {
+ /*
+ * While the ``time_of_day`` parameter is invalid because the value 30th
+ * of February does not exist in a leap year.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 2000, 2, 30, 0, 0, 0, 0 };
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_AtTimer: {
+ /*
+ * While the ``time_of_day`` parameter references the same point in time
+ * when a timer should fire.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 1989, 1, 1, 0, 0, 0, 0 };
+ _TOD_prepare_timer( ctx );
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_BeforeTimer: {
+ /*
+ * While the ``time_of_day`` parameter references a point in time before
+ * a timer should fire.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 1988, 12, 31, 23, 59, 59, 0 };
+ _TOD_prepare_timer( ctx );
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_AfterTimer: {
+ /*
+ * While the ``time_of_day`` parameter references a point in time after a
+ * timer should fire.
+ */
+ ctx->target_tod_value =
+ (rtems_time_of_day) { 1989, 1, 1, 1, 0, 0, 0 };
+ _TOD_prepare_timer( ctx );
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_Null: {
+ /*
+ * WHile the ``time_of_day`` parameter is NULL.
+ */
+ ctx->target_tod = NULL;
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_ToD_NA:
+ break;
+ }
+}
+
+static void RtemsClockReqSet_Pre_Hook_Prepare(
+ RtemsClockReqSet_Context *ctx,
+ RtemsClockReqSet_Pre_Hook state
+)
+{
+ switch ( state ) {
+ case RtemsClockReqSet_Pre_Hook_None: {
+ /*
+ * While no TOD hook is registered.
+ */
+ ctx->register_hook = false;
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_Hook_Ok: {
+ /*
+ * While all TOD hooks invoked by the rtems_clock_set() call return a
+ * status code equal to STATUS_SUCCESSFUL.
+ */
+ ctx->register_hook = true;
+ ctx->hook_status = STATUS_SUCCESSFUL;
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_Hook_NotOk: {
+ /*
+ * While at least one TOD hook invoked by the rtems_clock_set() call
+ * returns a status code not equal to STATUS_SUCCESSFUL.
+ */
+ ctx->register_hook = true;
+ ctx->hook_status = STATUS_UNAVAILABLE;
+ break;
+ }
+
+ case RtemsClockReqSet_Pre_Hook_NA:
+ break;
+ }
+}
+
+static void RtemsClockReqSet_Post_Status_Check(
+ RtemsClockReqSet_Context *ctx,
+ RtemsClockReqSet_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsClockReqSet_Post_Status_Ok: {
+ /*
+ * The return status of rtems_clock_set() shall be RTEMS_SUCCESSFUL
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsClockReqSet_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_clock_set() shall be RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsClockReqSet_Post_Status_InvClk: {
+ /*
+ * The return status of rtems_clock_set() shall be RTEMS_INVALID_CLOCK.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_CLOCK );
+ break;
+ }
+
+ case RtemsClockReqSet_Post_Status_Hook: {
+ /*
+ * The return status of rtems_clock_set() shall be derived from the
+ * status returned by the TOD hook.
+ */
+ T_rsc( ctx->status, RTEMS_UNSATISFIED );
+ break;
+ }
+
+ case RtemsClockReqSet_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsClockReqSet_Post_Clock_Check(
+ RtemsClockReqSet_Context *ctx,
+ RtemsClockReqSet_Post_Clock state
+)
+{
+ switch ( state ) {
+ case RtemsClockReqSet_Post_Clock_Set: {
+ /*
+ * The CLOCK_REALTIME shall be set to the values of the object referenced
+ * by the ``time_of_day`` parameter during the rtems_clock_set() call.
+ */
+ T_eq_ptr( ctx->target_tod, &ctx->target_tod_value );
+ T_rsc_success( ctx->get_tod_after_status );
+ T_eq_u32( ctx->tod_after.year, ctx->target_tod_value.year );
+ T_eq_u32( ctx->tod_after.month, ctx->target_tod_value.month );
+ T_eq_u32( ctx->tod_after.day, ctx->target_tod_value.day );
+ T_eq_u32( ctx->tod_after.hour, ctx->target_tod_value.hour );
+ T_eq_u32( ctx->tod_after.minute, ctx->target_tod_value.minute );
+ T_eq_u32( ctx->tod_after.second, ctx->target_tod_value.second );
+ /* rtems_clock_set() or rtems_clock_get_tod() cause an error of 1 tick */
+ T_ge_u32( ctx->tod_after.ticks + 1, ctx->target_tod_value.ticks );
+ T_le_u32( ctx->tod_after.ticks, ctx->target_tod_value.ticks );
+ break;
+ }
+
+ case RtemsClockReqSet_Post_Clock_Nop: {
+ /*
+ * The state of the CLOCK_REALTIME shall not be changed by the
+ * rtems_clock_set() call.
+ */
+ T_rsc_success( ctx->get_tod_before_status );
+ T_eq_u32( ctx->tod_after.year, ctx->tod_before.year );
+ T_eq_u32( ctx->tod_after.month, ctx->tod_before.month );
+ T_eq_u32( ctx->tod_after.day, ctx->tod_before.day );
+ T_eq_u32( ctx->tod_after.hour, ctx->tod_before.hour );
+ T_eq_u32( ctx->tod_after.minute, ctx->tod_before.minute );
+ T_eq_u32( ctx->tod_after.second, ctx->tod_before.second );
+ T_eq_u32( ctx->tod_after.ticks, ctx->tod_before.ticks );
+ break;
+ }
+
+ case RtemsClockReqSet_Post_Clock_NA:
+ break;
+ }
+}
+
+static void RtemsClockReqSet_Post_Timer_Check(
+ RtemsClockReqSet_Context *ctx,
+ RtemsClockReqSet_Post_Timer state
+)
+{
+ switch ( state ) {
+ case RtemsClockReqSet_Post_Timer_Triggered: {
+ /*
+ * The timer routine shall be executed once after the CLOCK_REALTIME has
+ * been set and before the execution of the rtems_clock_set() call
+ * terminates.
+ */
+ T_eq_int( ctx->timer_routine_counter, 1 );
+ T_eq_u32( ctx->timer_routine_tod.year, 1989 );
+ T_eq_u32( ctx->timer_routine_tod.month, 1 );
+ T_eq_u32( ctx->timer_routine_tod.day, 1 );
+ T_eq_u32( ctx->timer_routine_tod.minute, 0 );
+ T_eq_u32( ctx->timer_routine_tod.second, 0 );
+ T_eq_u32( ctx->timer_routine_tod.ticks, 0 );
+ break;
+ }
+
+ case RtemsClockReqSet_Post_Timer_Nop: {
+ /*
+ * The the timer routine shall not be invoked during the
+ * rtems_clock_set() call.
+ */
+ T_eq_int( ctx->timer_routine_counter, 0 );
+ break;
+ }
+
+ case RtemsClockReqSet_Post_Timer_NA:
+ break;
+ }
+}
+
+static void RtemsClockReqSet_Setup( RtemsClockReqSet_Context *ctx )
+{
+ rtems_status_code status;
+ rtems_name timer_name = rtems_build_name( 'T', 'M', 'R', '0' );
+ ctx->timer_id = RTEMS_ID_NONE;
+
+ ctx->target_tod = &ctx->target_tod_value;
+
+ status = rtems_timer_create( timer_name, &ctx->timer_id );
+ T_rsc_success( status );
+}
+
+static void RtemsClockReqSet_Setup_Wrap( void *arg )
+{
+ RtemsClockReqSet_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsClockReqSet_Setup( ctx );
+}
+
+static void RtemsClockReqSet_Teardown( RtemsClockReqSet_Context *ctx )
+{
+ rtems_status_code status;
+
+ if ( RTEMS_ID_NONE != ctx->timer_id ) {
+ status = rtems_timer_delete( ctx->timer_id );
+ T_rsc_success( status );
+ }
+}
+
+static void RtemsClockReqSet_Teardown_Wrap( void *arg )
+{
+ RtemsClockReqSet_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsClockReqSet_Teardown( ctx );
+}
+
+static void RtemsClockReqSet_Prepare( RtemsClockReqSet_Context *ctx )
+{
+ rtems_status_code status;
+
+ status = rtems_timer_cancel( ctx->timer_id );
+ T_rsc_success( status );
+ ctx->timer_routine_counter = 0;
+ ctx->timer_routine_tod = (rtems_time_of_day) { 0, 0, 0, 0, 0, 0, 0 };
+}
+
+static void RtemsClockReqSet_Action( RtemsClockReqSet_Context *ctx )
+{
+ TOD_Hook hook = {
+ .handler = TODHook
+ };
+
+ if ( ctx->register_hook ) {
+ _TOD_Hook_Register( &hook );
+ }
+
+ ctx->get_tod_before_status = rtems_clock_get_tod( &ctx->tod_before );
+ ctx->status = rtems_clock_set( ctx->target_tod );
+ ctx->get_tod_after_status = rtems_clock_get_tod( &ctx->tod_after );
+
+ if ( ctx->register_hook ) {
+ _TOD_Hook_Unregister( &hook );
+ }
+}
+
+static const RtemsClockReqSet_Entry
+RtemsClockReqSet_Entries[] = {
+ { 0, 0, 0, RtemsClockReqSet_Post_Status_InvClk,
+ RtemsClockReqSet_Post_Clock_Nop, RtemsClockReqSet_Post_Timer_Nop },
+ { 0, 0, 0, RtemsClockReqSet_Post_Status_Ok, RtemsClockReqSet_Post_Clock_Set,
+ RtemsClockReqSet_Post_Timer_Nop },
+ { 0, 0, 0, RtemsClockReqSet_Post_Status_Hook,
+ RtemsClockReqSet_Post_Clock_Nop, RtemsClockReqSet_Post_Timer_Nop },
+ { 0, 0, 0, RtemsClockReqSet_Post_Status_Ok, RtemsClockReqSet_Post_Clock_Set,
+ RtemsClockReqSet_Post_Timer_Triggered },
+ { 0, 0, 0, RtemsClockReqSet_Post_Status_InvAddr,
+ RtemsClockReqSet_Post_Clock_Nop, RtemsClockReqSet_Post_Timer_Nop }
+};
+
+static const uint8_t
+RtemsClockReqSet_Map[] = {
+ 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 3, 2, 1, 1, 2, 3, 3, 2, 4, 4, 4
+};
+
+static size_t RtemsClockReqSet_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsClockReqSet_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsClockReqSet_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsClockReqSet_Fixture = {
+ .setup = RtemsClockReqSet_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsClockReqSet_Teardown_Wrap,
+ .scope = RtemsClockReqSet_Scope,
+ .initial_context = &RtemsClockReqSet_Instance
+};
+
+static inline RtemsClockReqSet_Entry RtemsClockReqSet_PopEntry(
+ RtemsClockReqSet_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsClockReqSet_Entries[
+ RtemsClockReqSet_Map[ index ]
+ ];
+}
+
+static void RtemsClockReqSet_TestVariant( RtemsClockReqSet_Context *ctx )
+{
+ RtemsClockReqSet_Pre_ToD_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsClockReqSet_Pre_Hook_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsClockReqSet_Action( ctx );
+ RtemsClockReqSet_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsClockReqSet_Post_Clock_Check( ctx, ctx->Map.entry.Post_Clock );
+ RtemsClockReqSet_Post_Timer_Check( ctx, ctx->Map.entry.Post_Timer );
+}
+
+/**
+ * @fn void T_case_body_RtemsClockReqSet( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsClockReqSet, &RtemsClockReqSet_Fixture )
+{
+ RtemsClockReqSet_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsClockReqSet_Pre_ToD_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsClockReqSet_Pre_ToD_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsClockReqSet_Pre_Hook_None;
+ ctx->Map.pcs[ 1 ] < RtemsClockReqSet_Pre_Hook_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ ctx->Map.entry = RtemsClockReqSet_PopEntry( ctx );
+ RtemsClockReqSet_Prepare( ctx );
+ RtemsClockReqSet_TestVariant( ctx );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-clock.c b/testsuites/validation/tc-clock.c
new file mode 100644
index 0000000000..7e21e6d77c
--- /dev/null
+++ b/testsuites/validation/tc-clock.c
@@ -0,0 +1,181 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsClockValClock
+ */
+
+/*
+ * Copyright (C) 2021, 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsClockValClock spec:/rtems/clock/val/clock
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests some @ref RTEMSAPIClassicClock directives.
+ *
+ * This test case performs the following actions:
+ *
+ * - Use the rtems_clock_get_ticks_since_boot() directive before and after
+ * exactly one clock tick.
+ *
+ * - Check that clock tick gets incremented.
+ *
+ * - Use the rtems_clock_get_ticks_since_boot() directive before and after
+ * exactly one clock tick.
+ *
+ * - Check that clock tick gets incremented.
+ *
+ * - Use the rtems_clock_get_ticks_per_second() directive.
+ *
+ * - Check that rtems_clock_get_ticks_per_second() actually returns 1us /
+ * CONFIGURE_MICROSECONDS_PER_TICK.
+ *
+ * - Use the rtems_clock_get_ticks_per_second() directive.
+ *
+ * - Check that rtems_clock_get_ticks_per_second() actually returns 1us /
+ * CONFIGURE_MICROSECONDS_PER_TICK.
+ *
+ * @{
+ */
+
+/**
+ * @brief Use the rtems_clock_get_ticks_since_boot() directive before and after
+ * exactly one clock tick.
+ */
+static void RtemsClockValClock_Action_0( void )
+{
+ rtems_interval result_0;
+ rtems_interval result_1;
+
+ result_0 = rtems_clock_get_ticks_since_boot();
+ ClockTick();
+ result_1 = rtems_clock_get_ticks_since_boot();
+
+ /*
+ * Check that clock tick gets incremented.
+ */
+ T_step_eq_u32( 0, result_1 - result_0, 1 );
+}
+
+/**
+ * @brief Use the rtems_clock_get_ticks_since_boot() directive before and after
+ * exactly one clock tick.
+ */
+static void RtemsClockValClock_Action_1( void )
+{
+ rtems_interval result_0;
+ rtems_interval result_1;
+
+ #undef rtems_clock_get_ticks_since_boot
+
+ result_0 = rtems_clock_get_ticks_since_boot();
+ ClockTick();
+ result_1 = rtems_clock_get_ticks_since_boot();
+
+ /*
+ * Check that clock tick gets incremented.
+ */
+ T_step_eq_u32( 1, result_1 - result_0, 1 );
+}
+
+/**
+ * @brief Use the rtems_clock_get_ticks_per_second() directive.
+ */
+static void RtemsClockValClock_Action_2( void )
+{
+ rtems_interval result;
+
+ result = rtems_clock_get_ticks_per_second();
+
+ /*
+ * Check that rtems_clock_get_ticks_per_second() actually returns 1us /
+ * CONFIGURE_MICROSECONDS_PER_TICK.
+ */
+ T_step_eq_u32( 2, result, 1000000UL / TEST_MICROSECONDS_PER_TICK );
+}
+
+/**
+ * @brief Use the rtems_clock_get_ticks_per_second() directive.
+ */
+static void RtemsClockValClock_Action_3( void )
+{
+ rtems_interval result;
+
+ #undef rtems_clock_get_ticks_per_second
+
+ result = rtems_clock_get_ticks_per_second();
+
+ /*
+ * Check that rtems_clock_get_ticks_per_second() actually returns 1us /
+ * CONFIGURE_MICROSECONDS_PER_TICK.
+ */
+ T_step_eq_u32( 3, result, 1000000UL / TEST_MICROSECONDS_PER_TICK );
+}
+
+/**
+ * @fn void T_case_body_RtemsClockValClock( void )
+ */
+T_TEST_CASE( RtemsClockValClock )
+{
+ T_plan( 4 );
+
+ RtemsClockValClock_Action_0();
+ RtemsClockValClock_Action_1();
+ RtemsClockValClock_Action_2();
+ RtemsClockValClock_Action_3();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-cpu-performance.c b/testsuites/validation/tc-cpu-performance.c
new file mode 100644
index 0000000000..4f090e704f
--- /dev/null
+++ b/testsuites/validation/tc-cpu-performance.c
@@ -0,0 +1,270 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreCpuValPerf
+ */
+
+/*
+ * Copyright (C) 2023 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/cpuimpl.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreCpuValPerf spec:/score/cpu/val/perf
+ *
+ * @ingroup TestsuitesPerformanceNoClock0
+ *
+ * @brief This test case provides a context to run CPU port performance tests.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/score/cpu/val/perf test case.
+ */
+typedef struct {
+ /**
+ * @brief This member references the measure runtime context.
+ */
+ T_measure_runtime_context *context;
+
+ /**
+ * @brief This member provides the measure runtime request.
+ */
+ T_measure_runtime_request request;
+
+ /**
+ * @brief This member provides an optional measurement begin time point.
+ */
+ T_ticks begin;
+
+ /**
+ * @brief This member provides an optional measurement end time point.
+ */
+ T_ticks end;
+} ScoreCpuValPerf_Context;
+
+static ScoreCpuValPerf_Context
+ ScoreCpuValPerf_Instance;
+
+static void ScoreCpuValPerf_Setup_Context( ScoreCpuValPerf_Context *ctx )
+{
+ T_measure_runtime_config config;
+
+ memset( &config, 0, sizeof( config ) );
+ config.sample_count = 100;
+ ctx->request.arg = ctx;
+ ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES;
+ ctx->context = T_measure_runtime_create( &config );
+ T_assert_not_null( ctx->context );
+}
+
+static void ScoreCpuValPerf_Setup_Wrap( void *arg )
+{
+ ScoreCpuValPerf_Context *ctx;
+
+ ctx = arg;
+ ScoreCpuValPerf_Setup_Context( ctx );
+}
+
+static T_fixture ScoreCpuValPerf_Fixture = {
+ .setup = ScoreCpuValPerf_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &ScoreCpuValPerf_Instance
+};
+
+/**
+ * @defgroup ScoreCpuReqPerfEmpty spec:/score/cpu/req/perf-empty
+ *
+ * @{
+ */
+
+/**
+ * @brief Do nothing and just return.
+ */
+static void ScoreCpuReqPerfEmpty_Body( ScoreCpuValPerf_Context *ctx )
+{
+ /* No code */
+}
+
+static void ScoreCpuReqPerfEmpty_Body_Wrap( void *arg )
+{
+ ScoreCpuValPerf_Context *ctx;
+
+ ctx = arg;
+ ScoreCpuReqPerfEmpty_Body( ctx );
+}
+
+/**
+ * @brief Discard samples interrupted by a clock tick.
+ */
+static bool ScoreCpuReqPerfEmpty_Teardown(
+ ScoreCpuValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ return tic == toc;
+}
+
+static bool ScoreCpuReqPerfEmpty_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ ScoreCpuValPerf_Context *ctx;
+
+ ctx = arg;
+ return ScoreCpuReqPerfEmpty_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/** @} */
+
+/**
+ * @defgroup ScoreCpuReqPerfNops spec:/score/cpu/req/perf-nops
+ *
+ * @{
+ */
+
+/**
+ * @brief Execute exactly 1000 no-operation instructions.
+ */
+static void ScoreCpuReqPerfNops_Body( ScoreCpuValPerf_Context *ctx )
+{
+ #define NOPS_10 \
+ _CPU_Instruction_no_operation(); _CPU_Instruction_no_operation(); \
+ _CPU_Instruction_no_operation(); _CPU_Instruction_no_operation(); \
+ _CPU_Instruction_no_operation(); _CPU_Instruction_no_operation(); \
+ _CPU_Instruction_no_operation(); _CPU_Instruction_no_operation(); \
+ _CPU_Instruction_no_operation(); _CPU_Instruction_no_operation();
+ #define NOPS_100 NOPS_10 NOPS_10 NOPS_10 NOPS_10 NOPS_10 NOPS_10 NOPS_10 \
+ NOPS_10 NOPS_10 NOPS_10
+ NOPS_100
+ NOPS_100
+ NOPS_100
+ NOPS_100
+ NOPS_100
+ NOPS_100
+ NOPS_100
+ NOPS_100
+ NOPS_100
+ NOPS_100
+}
+
+static void ScoreCpuReqPerfNops_Body_Wrap( void *arg )
+{
+ ScoreCpuValPerf_Context *ctx;
+
+ ctx = arg;
+ ScoreCpuReqPerfNops_Body( ctx );
+}
+
+/**
+ * @brief Discard samples interrupted by a clock tick.
+ */
+static bool ScoreCpuReqPerfNops_Teardown(
+ ScoreCpuValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ return tic == toc;
+}
+
+static bool ScoreCpuReqPerfNops_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ ScoreCpuValPerf_Context *ctx;
+
+ ctx = arg;
+ return ScoreCpuReqPerfNops_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/** @} */
+
+/**
+ * @fn void T_case_body_ScoreCpuValPerf( void )
+ */
+T_TEST_CASE_FIXTURE( ScoreCpuValPerf, &ScoreCpuValPerf_Fixture )
+{
+ ScoreCpuValPerf_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ ctx->request.name = "ScoreCpuReqPerfEmpty";
+ ctx->request.setup = NULL;
+ ctx->request.body = ScoreCpuReqPerfEmpty_Body_Wrap;
+ ctx->request.teardown = ScoreCpuReqPerfEmpty_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ ctx->request.name = "ScoreCpuReqPerfNops";
+ ctx->request.setup = NULL;
+ ctx->request.body = ScoreCpuReqPerfNops_Body_Wrap;
+ ctx->request.teardown = ScoreCpuReqPerfNops_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-cpuuse.c b/testsuites/validation/tc-cpuuse.c
new file mode 100644
index 0000000000..f554a0b4e1
--- /dev/null
+++ b/testsuites/validation/tc-cpuuse.c
@@ -0,0 +1,166 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsCpuuseValCpuuse
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/cpuuse.h>
+#include <rtems/score/threadimpl.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsCpuuseValCpuuse spec:/rtems/cpuuse/val/cpuuse
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests the CPU usage reporting and reset.
+ *
+ * This test case performs the following actions:
+ *
+ * - Create a worker thread. Generate some CPU usage.
+ *
+ * - Check that we have a non-zero CPU usage. Reset the CPU usage. Check
+ * that it was cleared to zero.
+ *
+ * - Clean up all used resources.
+ *
+ * @{
+ */
+
+static void Worker( rtems_task_argument arg )
+{
+ (void) arg;
+
+ while ( true ) {
+ Yield();
+ }
+}
+
+/**
+ * @brief Create a worker thread. Generate some CPU usage.
+ */
+static void RtemsCpuuseValCpuuse_Action_0( void )
+{
+ rtems_id id;
+ Thread_Control *self;
+ Thread_Control *other;
+ Timestamp_Control cpu_usage_self;
+ Timestamp_Control cpu_usage_other;
+ uint32_t idle_tasks;
+ uint32_t cpu_index;
+
+ idle_tasks = 0;
+
+ for ( cpu_index = 0; cpu_index < rtems_scheduler_get_processor_maximum(); ++cpu_index ) {
+ rtems_status_code sc;
+ rtems_id unused;
+
+ sc = rtems_scheduler_ident_by_processor( cpu_index, &unused );
+
+ if ( sc == RTEMS_SUCCESSFUL ) {
+ ++idle_tasks;
+ }
+ }
+
+ id = CreateTask( "WORK", GetSelfPriority() );
+ StartTask( id, Worker, NULL );
+
+ self = GetThread( RTEMS_SELF );
+ other = GetThread( id );
+
+ Yield();
+ Yield();
+
+ /*
+ * Check that we have a non-zero CPU usage. Reset the CPU usage. Check that
+ * it was cleared to zero.
+ */
+ TimecounterTick();
+
+ cpu_usage_self = _Thread_Get_CPU_time_used( self );
+ cpu_usage_other = _Thread_Get_CPU_time_used( other );
+
+ T_gt_i64( _Thread_Get_CPU_time_used_after_last_reset( self ), 0 );
+ T_gt_i64( _Thread_Get_CPU_time_used_after_last_reset( other ), 0 );
+
+ rtems_cpu_usage_reset();
+
+ /*
+ * Our CPU usage after the last reset is now exactly one tick of the
+ * software timecounter.
+ */
+ T_eq_i64( _Thread_Get_CPU_time_used_after_last_reset( self ), 4295 );
+ T_eq_i64(
+ _Thread_Get_CPU_time_used( self ),
+ cpu_usage_self + 12885 + 4295 * idle_tasks
+ );
+
+ T_eq_i64( _Thread_Get_CPU_time_used_after_last_reset( other ), 0 );
+ T_eq_i64( _Thread_Get_CPU_time_used( other ), cpu_usage_other );
+
+ /*
+ * Clean up all used resources.
+ */
+ DeleteTask( id );
+}
+
+/**
+ * @fn void T_case_body_RtemsCpuuseValCpuuse( void )
+ */
+T_TEST_CASE( RtemsCpuuseValCpuuse )
+{
+ RtemsCpuuseValCpuuse_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-dev-clock-xil-ttc.c b/testsuites/validation/tc-dev-clock-xil-ttc.c
new file mode 100644
index 0000000000..70f49a4cc6
--- /dev/null
+++ b/testsuites/validation/tc-dev-clock-xil-ttc.c
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup DevClockXilTtcValTickCatchUp
+ */
+
+/*
+ * Copyright (C) 2024 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <sys/time.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup DevClockXilTtcValTickCatchUp \
+ * spec:/dev/clock/xil-ttc/val/tick-catch-up
+ *
+ * @ingroup TestsuitesBspsValidationBsp0
+ *
+ * @brief Tests some Xilinx TTC clock driver functions.
+ *
+ * This test case performs the following actions:
+ *
+ * - Synchronize with the clock tick. Disable interrupts. Busy wait three
+ * clock tick intervals. Enable interrupts.
+ *
+ * - Check that exactly three clock ticks happened once interrupts are
+ * enabled again.
+ *
+ * @{
+ */
+
+/**
+ * @brief Synchronize with the clock tick. Disable interrupts. Busy wait
+ * three clock tick intervals. Enable interrupts.
+ */
+static void DevClockXilTtcValTickCatchUp_Action_0( void )
+{
+ uint32_t ns_per_tick;
+ uint64_t three_ticks_interval;
+ rtems_interrupt_level level;
+ rtems_interval t_0;
+ rtems_interval t_1;
+ rtems_interval t_2;
+ uint64_t m_0;
+ uint64_t m_1;
+
+ ns_per_tick = rtems_configuration_get_nanoseconds_per_tick();
+ three_ticks_interval = ( 7 * (uint64_t) nstosbt( ns_per_tick ) ) / 2;
+ t_0 = rtems_clock_get_ticks_since_boot();
+
+ /* Synchronize with clock tick */
+ do {
+ t_1 = rtems_clock_get_ticks_since_boot();
+ m_0 = (uint64_t) rtems_clock_get_monotonic_sbintime();
+ } while ( t_0 == t_1 );
+
+ rtems_interrupt_local_disable( level );
+
+ do {
+ m_1 = (uint64_t) rtems_clock_get_monotonic_sbintime();
+ } while ( m_1 - m_0 <= three_ticks_interval );
+
+ rtems_interrupt_local_enable( level );
+
+ /*
+ * Make sure the clock interrupt was serviced after the interrupt enable.
+ */
+ do {
+ t_2 = rtems_clock_get_ticks_since_boot();
+ } while ( t_1 == t_2 );
+
+ /*
+ * Check that exactly three clock ticks happened once interrupts are enabled
+ * again.
+ */
+ T_step_eq_u32( 0, t_2 - t_1, 3 );
+}
+
+/**
+ * @fn void T_case_body_DevClockXilTtcValTickCatchUp( void )
+ */
+T_TEST_CASE( DevClockXilTtcValTickCatchUp )
+{
+ T_plan( 1 );
+
+ DevClockXilTtcValTickCatchUp_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-dev-grlib-apbuart-inbyte-nonblocking.c b/testsuites/validation/tc-dev-grlib-apbuart-inbyte-nonblocking.c
new file mode 100644
index 0000000000..b33b6f1a25
--- /dev/null
+++ b/testsuites/validation/tc-dev-grlib-apbuart-inbyte-nonblocking.c
@@ -0,0 +1,348 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup DevGrlibReqApbuartInbyteNonblocking
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <grlib/apbuart.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup DevGrlibReqApbuartInbyteNonblocking \
+ * spec:/dev/grlib/req/apbuart-inbyte-nonblocking
+ *
+ * @ingroup TestsuitesBspsValidationBsp0
+ *
+ * @{
+ */
+
+typedef enum {
+ DevGrlibReqApbuartInbyteNonblocking_Pre_DataReady_Yes,
+ DevGrlibReqApbuartInbyteNonblocking_Pre_DataReady_No,
+ DevGrlibReqApbuartInbyteNonblocking_Pre_DataReady_NA
+} DevGrlibReqApbuartInbyteNonblocking_Pre_DataReady;
+
+typedef enum {
+ DevGrlibReqApbuartInbyteNonblocking_Post_Result_Data,
+ DevGrlibReqApbuartInbyteNonblocking_Post_Result_MinusOne,
+ DevGrlibReqApbuartInbyteNonblocking_Post_Result_NA
+} DevGrlibReqApbuartInbyteNonblocking_Post_Result;
+
+typedef enum {
+ DevGrlibReqApbuartInbyteNonblocking_Post_ErrorFlags_Cleared,
+ DevGrlibReqApbuartInbyteNonblocking_Post_ErrorFlags_NA
+} DevGrlibReqApbuartInbyteNonblocking_Post_ErrorFlags;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_DataReady_NA : 1;
+ uint8_t Post_Result : 2;
+ uint8_t Post_ErrorFlags : 1;
+} DevGrlibReqApbuartInbyteNonblocking_Entry;
+
+/**
+ * @brief Test context for spec:/dev/grlib/req/apbuart-inbyte-nonblocking test
+ * case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides the APBUART register block.
+ */
+ apbuart regs;
+
+ /**
+ * @brief This member contains the return value of the
+ * apbuart_inbyte_nonblocking() call.
+ */
+ int result;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ DevGrlibReqApbuartInbyteNonblocking_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} DevGrlibReqApbuartInbyteNonblocking_Context;
+
+static DevGrlibReqApbuartInbyteNonblocking_Context
+ DevGrlibReqApbuartInbyteNonblocking_Instance;
+
+static const char * const DevGrlibReqApbuartInbyteNonblocking_PreDesc_DataReady[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const DevGrlibReqApbuartInbyteNonblocking_PreDesc[] = {
+ DevGrlibReqApbuartInbyteNonblocking_PreDesc_DataReady,
+ NULL
+};
+
+static void DevGrlibReqApbuartInbyteNonblocking_Pre_DataReady_Prepare(
+ DevGrlibReqApbuartInbyteNonblocking_Context *ctx,
+ DevGrlibReqApbuartInbyteNonblocking_Pre_DataReady state
+)
+{
+ switch ( state ) {
+ case DevGrlibReqApbuartInbyteNonblocking_Pre_DataReady_Yes: {
+ /*
+ * While the data ready flag is set in the status register of the
+ * register block specified by ``regs`` parameter.
+ */
+ ctx->regs.status |= APBUART_STATUS_DR;
+ break;
+ }
+
+ case DevGrlibReqApbuartInbyteNonblocking_Pre_DataReady_No: {
+ /*
+ * While the data ready flag is cleared in the status register of the
+ * register block specified by ``regs`` parameter.
+ */
+ ctx->regs.status &= ~APBUART_STATUS_DR;
+ break;
+ }
+
+ case DevGrlibReqApbuartInbyteNonblocking_Pre_DataReady_NA:
+ break;
+ }
+}
+
+static void DevGrlibReqApbuartInbyteNonblocking_Post_Result_Check(
+ DevGrlibReqApbuartInbyteNonblocking_Context *ctx,
+ DevGrlibReqApbuartInbyteNonblocking_Post_Result state
+)
+{
+ switch ( state ) {
+ case DevGrlibReqApbuartInbyteNonblocking_Post_Result_Data: {
+ /*
+ * The return value of apbuart_inbyte_nonblocking() shall be the data
+ * read from the data register of the register block specified by
+ * ``regs``.
+ */
+ T_eq_int( ctx->result, 0xff );
+ break;
+ }
+
+ case DevGrlibReqApbuartInbyteNonblocking_Post_Result_MinusOne: {
+ /*
+ * The return value of apbuart_inbyte_nonblocking() shall be minus one.
+ */
+ T_eq_int( ctx->result, -1 );
+ break;
+ }
+
+ case DevGrlibReqApbuartInbyteNonblocking_Post_Result_NA:
+ break;
+ }
+}
+
+static void DevGrlibReqApbuartInbyteNonblocking_Post_ErrorFlags_Check(
+ DevGrlibReqApbuartInbyteNonblocking_Context *ctx,
+ DevGrlibReqApbuartInbyteNonblocking_Post_ErrorFlags state
+)
+{
+ switch ( state ) {
+ case DevGrlibReqApbuartInbyteNonblocking_Post_ErrorFlags_Cleared: {
+ /*
+ * The framing error, parity error, overrun, and break received flags in
+ * the status register of the register block specified by ``regs`` shall
+ * be cleared.
+ */
+ T_eq_u32( ctx->regs.status & 0x78, 0 );
+ break;
+ }
+
+ case DevGrlibReqApbuartInbyteNonblocking_Post_ErrorFlags_NA:
+ break;
+ }
+}
+
+static void DevGrlibReqApbuartInbyteNonblocking_Prepare(
+ DevGrlibReqApbuartInbyteNonblocking_Context *ctx
+)
+{
+ memset( &ctx->regs, 0, sizeof( ctx->regs ) );
+ ctx->regs.status = 0x78;
+ ctx->regs.data = 0xff;
+}
+
+static void DevGrlibReqApbuartInbyteNonblocking_Action(
+ DevGrlibReqApbuartInbyteNonblocking_Context *ctx
+)
+{
+ ctx->result = apbuart_inbyte_nonblocking( &ctx->regs );
+}
+
+static const DevGrlibReqApbuartInbyteNonblocking_Entry
+DevGrlibReqApbuartInbyteNonblocking_Entries[] = {
+ { 0, 0, DevGrlibReqApbuartInbyteNonblocking_Post_Result_Data,
+ DevGrlibReqApbuartInbyteNonblocking_Post_ErrorFlags_Cleared },
+ { 0, 0, DevGrlibReqApbuartInbyteNonblocking_Post_Result_MinusOne,
+ DevGrlibReqApbuartInbyteNonblocking_Post_ErrorFlags_Cleared }
+};
+
+static const uint8_t
+DevGrlibReqApbuartInbyteNonblocking_Map[] = {
+ 0, 1
+};
+
+static size_t DevGrlibReqApbuartInbyteNonblocking_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ DevGrlibReqApbuartInbyteNonblocking_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ DevGrlibReqApbuartInbyteNonblocking_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture DevGrlibReqApbuartInbyteNonblocking_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = DevGrlibReqApbuartInbyteNonblocking_Scope,
+ .initial_context = &DevGrlibReqApbuartInbyteNonblocking_Instance
+};
+
+static inline DevGrlibReqApbuartInbyteNonblocking_Entry
+DevGrlibReqApbuartInbyteNonblocking_PopEntry(
+ DevGrlibReqApbuartInbyteNonblocking_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return DevGrlibReqApbuartInbyteNonblocking_Entries[
+ DevGrlibReqApbuartInbyteNonblocking_Map[ index ]
+ ];
+}
+
+static void DevGrlibReqApbuartInbyteNonblocking_TestVariant(
+ DevGrlibReqApbuartInbyteNonblocking_Context *ctx
+)
+{
+ DevGrlibReqApbuartInbyteNonblocking_Pre_DataReady_Prepare(
+ ctx,
+ ctx->Map.pcs[ 0 ]
+ );
+ DevGrlibReqApbuartInbyteNonblocking_Action( ctx );
+ DevGrlibReqApbuartInbyteNonblocking_Post_Result_Check(
+ ctx,
+ ctx->Map.entry.Post_Result
+ );
+ DevGrlibReqApbuartInbyteNonblocking_Post_ErrorFlags_Check(
+ ctx,
+ ctx->Map.entry.Post_ErrorFlags
+ );
+}
+
+/**
+ * @fn void T_case_body_DevGrlibReqApbuartInbyteNonblocking( void )
+ */
+T_TEST_CASE_FIXTURE(
+ DevGrlibReqApbuartInbyteNonblocking,
+ &DevGrlibReqApbuartInbyteNonblocking_Fixture
+)
+{
+ DevGrlibReqApbuartInbyteNonblocking_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = DevGrlibReqApbuartInbyteNonblocking_Pre_DataReady_Yes;
+ ctx->Map.pcs[ 0 ] < DevGrlibReqApbuartInbyteNonblocking_Pre_DataReady_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = DevGrlibReqApbuartInbyteNonblocking_PopEntry( ctx );
+ DevGrlibReqApbuartInbyteNonblocking_Prepare( ctx );
+ DevGrlibReqApbuartInbyteNonblocking_TestVariant( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-dev-grlib-io.c b/testsuites/validation/tc-dev-grlib-io.c
new file mode 100644
index 0000000000..5bfc3fcfab
--- /dev/null
+++ b/testsuites/validation/tc-dev-grlib-io.c
@@ -0,0 +1,295 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup DevGrlibValIo
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <grlib/apbuart.h>
+#include <grlib/io.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup DevGrlibValIo spec:/dev/grlib/val/io
+ *
+ * @ingroup TestsuitesBspsValidationBsp0
+ *
+ * @brief Tests some @ref RTEMSDeviceGRLIB directives.
+ *
+ * This test case performs the following actions:
+ *
+ * - Call grlib_load_8() to load a prepared value.
+ *
+ * - Check that the returned value is equal to the prepared value.
+ *
+ * - Call grlib_load_16() to load a prepared value.
+ *
+ * - Check that the returned value is equal to the prepared value.
+ *
+ * - Call grlib_load_32() to load a prepared value.
+ *
+ * - Check that the returned value is equal to the prepared value.
+ *
+ * - Call grlib_load_64() to load a prepared value.
+ *
+ * - Check that the returned value is equal to the prepared value.
+ *
+ * - Call grlib_store_8() to store a value to an object.
+ *
+ * - Check that the value of the object is equal to the stored value.
+ *
+ * - Call grlib_store_16() to store a value to an object.
+ *
+ * - Check that the value of the object is equal to the stored value.
+ *
+ * - Call grlib_store_32() to store a value to an object.
+ *
+ * - Check that the value of the object is equal to the stored value.
+ *
+ * - Call grlib_store_64() to store a value to an object.
+ *
+ * - Check that the value of the object is equal to the stored value.
+ *
+ * - Call apbuart_outbyte_polled() to store a character to the data register.
+ * The transmitter FIFO shall be initially non-empty. The status is checked
+ * by apbuart_outbyte_wait().
+ *
+ * - Check that the transmitter FIFO empty flag was set by ApbuartIORelax().
+ *
+ * - Check that the data register was written by apbuart_outbyte_polled().
+ *
+ * @{
+ */
+
+static void ApbuartIORelax( void *arg )
+{
+ apbuart *regs;
+
+ regs = arg;
+ regs->status = 0x4;
+ T_quiet_eq_u32( regs->data, 0 );
+}
+
+/**
+ * @brief Call grlib_load_8() to load a prepared value.
+ */
+static void DevGrlibValIo_Action_0( void )
+{
+ uint8_t reg_8;
+ uint8_t val_8;
+
+ reg_8 = 0x81;
+ val_8 = grlib_load_8( &reg_8 );
+
+ /*
+ * Check that the returned value is equal to the prepared value.
+ */
+ T_step_eq_u8( 0, val_8, 0x81 );
+}
+
+/**
+ * @brief Call grlib_load_16() to load a prepared value.
+ */
+static void DevGrlibValIo_Action_1( void )
+{
+ uint16_t reg_16;
+ uint16_t val_16;
+
+ reg_16 = 0x8001;
+ val_16 = grlib_load_16( &reg_16 );
+
+ /*
+ * Check that the returned value is equal to the prepared value.
+ */
+ T_step_eq_u16( 1, val_16, 0x8001 );
+}
+
+/**
+ * @brief Call grlib_load_32() to load a prepared value.
+ */
+static void DevGrlibValIo_Action_2( void )
+{
+ uint32_t reg_32;
+ uint32_t val_32;
+
+ reg_32 = 0x80000001;
+ val_32 = grlib_load_32( &reg_32 );
+
+ /*
+ * Check that the returned value is equal to the prepared value.
+ */
+ T_step_eq_u32( 2, val_32, 0x80000001 );
+}
+
+/**
+ * @brief Call grlib_load_64() to load a prepared value.
+ */
+static void DevGrlibValIo_Action_3( void )
+{
+ uint64_t reg_64;
+ uint64_t val_64;
+
+ reg_64 = 0x8000000000000001;
+ val_64 = grlib_load_64( &reg_64 );
+
+ /*
+ * Check that the returned value is equal to the prepared value.
+ */
+ T_step_eq_u64( 3, val_64, 0x8000000000000001 );
+}
+
+/**
+ * @brief Call grlib_store_8() to store a value to an object.
+ */
+static void DevGrlibValIo_Action_4( void )
+{
+ uint8_t reg_8;
+
+ grlib_store_8( &reg_8, 0x81 );
+
+ /*
+ * Check that the value of the object is equal to the stored value.
+ */
+ T_step_eq_u8( 4, reg_8, 0x81 );
+}
+
+/**
+ * @brief Call grlib_store_16() to store a value to an object.
+ */
+static void DevGrlibValIo_Action_5( void )
+{
+ uint16_t reg_16;
+
+ grlib_store_16( &reg_16, 0x8001 );
+
+ /*
+ * Check that the value of the object is equal to the stored value.
+ */
+ T_step_eq_u16( 5, reg_16, 0x8001 );
+}
+
+/**
+ * @brief Call grlib_store_32() to store a value to an object.
+ */
+static void DevGrlibValIo_Action_6( void )
+{
+ uint32_t reg_32;
+
+ grlib_store_32( &reg_32, 0x80000001 );
+
+ /*
+ * Check that the value of the object is equal to the stored value.
+ */
+ T_step_eq_u32( 6, reg_32, 0x80000001 );
+}
+
+/**
+ * @brief Call grlib_store_64() to store a value to an object.
+ */
+static void DevGrlibValIo_Action_7( void )
+{
+ uint64_t reg_64;
+
+ grlib_store_64( &reg_64, 0x8000000000000001 );
+
+ /*
+ * Check that the value of the object is equal to the stored value.
+ */
+ T_step_eq_u64( 7, reg_64, 0x8000000000000001 );
+}
+
+/**
+ * @brief Call apbuart_outbyte_polled() to store a character to the data
+ * register. The transmitter FIFO shall be initially non-empty. The status
+ * is checked by apbuart_outbyte_wait().
+ */
+static void DevGrlibValIo_Action_8( void )
+{
+ apbuart regs;
+
+ memset( &regs, 0, sizeof( regs ) );
+ SetIORelaxHandler( ApbuartIORelax, &regs );
+ apbuart_outbyte_polled( &regs, (char) 0xff );
+ SetIORelaxHandler( NULL, NULL );
+
+ /*
+ * Check that the transmitter FIFO empty flag was set by ApbuartIORelax().
+ */
+ T_step_eq_u32( 8, regs.status, APBUART_STATUS_TE );
+
+ /*
+ * Check that the data register was written by apbuart_outbyte_polled().
+ */
+ T_step_eq_u32( 9, regs.data, 0xff );
+}
+
+/**
+ * @fn void T_case_body_DevGrlibValIo( void )
+ */
+T_TEST_CASE( DevGrlibValIo )
+{
+ T_plan( 10 );
+
+ DevGrlibValIo_Action_0();
+ DevGrlibValIo_Action_1();
+ DevGrlibValIo_Action_2();
+ DevGrlibValIo_Action_3();
+ DevGrlibValIo_Action_4();
+ DevGrlibValIo_Action_5();
+ DevGrlibValIo_Action_6();
+ DevGrlibValIo_Action_7();
+ DevGrlibValIo_Action_8();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-dev-grlib-irqamp-get-timestamp.c b/testsuites/validation/tc-dev-grlib-irqamp-get-timestamp.c
new file mode 100644
index 0000000000..a064c479b9
--- /dev/null
+++ b/testsuites/validation/tc-dev-grlib-irqamp-get-timestamp.c
@@ -0,0 +1,304 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup DevGrlibReqIrqampGetTimestamp
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <grlib/irqamp.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup DevGrlibReqIrqampGetTimestamp \
+ * spec:/dev/grlib/req/irqamp-get-timestamp
+ *
+ * @ingroup TestsuitesBspsValidationBsp0
+ *
+ * @{
+ */
+
+typedef enum {
+ DevGrlibReqIrqampGetTimestamp_Pre_NumberOfTimestampRegisterSets_Zero,
+ DevGrlibReqIrqampGetTimestamp_Pre_NumberOfTimestampRegisterSets_Positive,
+ DevGrlibReqIrqampGetTimestamp_Pre_NumberOfTimestampRegisterSets_NA
+} DevGrlibReqIrqampGetTimestamp_Pre_NumberOfTimestampRegisterSets;
+
+typedef enum {
+ DevGrlibReqIrqampGetTimestamp_Post_Result_Registers,
+ DevGrlibReqIrqampGetTimestamp_Post_Result_Null,
+ DevGrlibReqIrqampGetTimestamp_Post_Result_NA
+} DevGrlibReqIrqampGetTimestamp_Post_Result;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_NumberOfTimestampRegisterSets_NA : 1;
+ uint8_t Post_Result : 2;
+} DevGrlibReqIrqampGetTimestamp_Entry;
+
+/**
+ * @brief Test context for spec:/dev/grlib/req/irqamp-get-timestamp test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the return value of the
+ * irqamp_get_timestamp_registers() call.
+ */
+ irqamp_timestamp *result;
+
+ /**
+ * @brief This member contains the IRQ(A)MP register block.
+ */
+ irqamp irqamp_regs;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ DevGrlibReqIrqampGetTimestamp_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} DevGrlibReqIrqampGetTimestamp_Context;
+
+static DevGrlibReqIrqampGetTimestamp_Context
+ DevGrlibReqIrqampGetTimestamp_Instance;
+
+static const char * const DevGrlibReqIrqampGetTimestamp_PreDesc_NumberOfTimestampRegisterSets[] = {
+ "Zero",
+ "Positive",
+ "NA"
+};
+
+static const char * const * const DevGrlibReqIrqampGetTimestamp_PreDesc[] = {
+ DevGrlibReqIrqampGetTimestamp_PreDesc_NumberOfTimestampRegisterSets,
+ NULL
+};
+
+static void
+DevGrlibReqIrqampGetTimestamp_Pre_NumberOfTimestampRegisterSets_Prepare(
+ DevGrlibReqIrqampGetTimestamp_Context *ctx,
+ DevGrlibReqIrqampGetTimestamp_Pre_NumberOfTimestampRegisterSets state
+)
+{
+ switch ( state ) {
+ case DevGrlibReqIrqampGetTimestamp_Pre_NumberOfTimestampRegisterSets_Zero: {
+ /*
+ * While the number of timestamp register sets indicated by the IRQ(A)MP
+ * register block specified by the ``irqamp_regs`` parameter is zero.
+ */
+ ctx->irqamp_regs.itstmp[ 0 ].itstmpc = 0;
+ break;
+ }
+
+ case DevGrlibReqIrqampGetTimestamp_Pre_NumberOfTimestampRegisterSets_Positive: {
+ /*
+ * While the number of timestamp register sets indicated by the IRQ(A)MP
+ * register block specified by the ``irqamp_regs`` parameter is positive.
+ */
+ ctx->irqamp_regs.itstmp[ 0 ].itstmpc = IRQAMP_ITSTMPC_TSTAMP( 1 );
+ break;
+ }
+
+ case DevGrlibReqIrqampGetTimestamp_Pre_NumberOfTimestampRegisterSets_NA:
+ break;
+ }
+}
+
+static void DevGrlibReqIrqampGetTimestamp_Post_Result_Check(
+ DevGrlibReqIrqampGetTimestamp_Context *ctx,
+ DevGrlibReqIrqampGetTimestamp_Post_Result state
+)
+{
+ switch ( state ) {
+ case DevGrlibReqIrqampGetTimestamp_Post_Result_Registers: {
+ /*
+ * The return value of irqamp_get_timestamp_registers() shall be address
+ * of the timestamping register block contained in the IRQ(A)MP register
+ * block specified by the ``irqamp_regs`` parameter.
+ */
+ T_not_null( ctx->result );
+ break;
+ }
+
+ case DevGrlibReqIrqampGetTimestamp_Post_Result_Null: {
+ /*
+ * The return value of irqamp_get_timestamp_registers() shall be false.
+ */
+ T_null( ctx->result );
+ break;
+ }
+
+ case DevGrlibReqIrqampGetTimestamp_Post_Result_NA:
+ break;
+ }
+}
+
+static void DevGrlibReqIrqampGetTimestamp_Action(
+ DevGrlibReqIrqampGetTimestamp_Context *ctx
+)
+{
+ ctx->result = irqamp_get_timestamp_registers( &ctx->irqamp_regs );
+}
+
+static const DevGrlibReqIrqampGetTimestamp_Entry
+DevGrlibReqIrqampGetTimestamp_Entries[] = {
+ { 0, 0, DevGrlibReqIrqampGetTimestamp_Post_Result_Null },
+ { 0, 0, DevGrlibReqIrqampGetTimestamp_Post_Result_Registers }
+};
+
+static const uint8_t
+DevGrlibReqIrqampGetTimestamp_Map[] = {
+ 0, 1
+};
+
+static size_t DevGrlibReqIrqampGetTimestamp_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ DevGrlibReqIrqampGetTimestamp_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ DevGrlibReqIrqampGetTimestamp_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture DevGrlibReqIrqampGetTimestamp_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = DevGrlibReqIrqampGetTimestamp_Scope,
+ .initial_context = &DevGrlibReqIrqampGetTimestamp_Instance
+};
+
+static inline DevGrlibReqIrqampGetTimestamp_Entry
+DevGrlibReqIrqampGetTimestamp_PopEntry(
+ DevGrlibReqIrqampGetTimestamp_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return DevGrlibReqIrqampGetTimestamp_Entries[
+ DevGrlibReqIrqampGetTimestamp_Map[ index ]
+ ];
+}
+
+static void DevGrlibReqIrqampGetTimestamp_TestVariant(
+ DevGrlibReqIrqampGetTimestamp_Context *ctx
+)
+{
+ DevGrlibReqIrqampGetTimestamp_Pre_NumberOfTimestampRegisterSets_Prepare(
+ ctx,
+ ctx->Map.pcs[ 0 ]
+ );
+ DevGrlibReqIrqampGetTimestamp_Action( ctx );
+ DevGrlibReqIrqampGetTimestamp_Post_Result_Check(
+ ctx,
+ ctx->Map.entry.Post_Result
+ );
+}
+
+/**
+ * @fn void T_case_body_DevGrlibReqIrqampGetTimestamp( void )
+ */
+T_TEST_CASE_FIXTURE(
+ DevGrlibReqIrqampGetTimestamp,
+ &DevGrlibReqIrqampGetTimestamp_Fixture
+)
+{
+ DevGrlibReqIrqampGetTimestamp_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = DevGrlibReqIrqampGetTimestamp_Pre_NumberOfTimestampRegisterSets_Zero;
+ ctx->Map.pcs[ 0 ] < DevGrlibReqIrqampGetTimestamp_Pre_NumberOfTimestampRegisterSets_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = DevGrlibReqIrqampGetTimestamp_PopEntry( ctx );
+ DevGrlibReqIrqampGetTimestamp_TestVariant( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-event-performance.c b/testsuites/validation/tc-event-performance.c
new file mode 100644
index 0000000000..9cf71e92f5
--- /dev/null
+++ b/testsuites/validation/tc-event-performance.c
@@ -0,0 +1,591 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsEventValPerf
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsEventValPerf spec:/rtems/event/val/perf
+ *
+ * @ingroup TestsuitesPerformanceNoClock0
+ *
+ * @brief This test case provides a context to run @ref RTEMSAPIClassicEvent
+ * performance tests.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/rtems/event/val/perf test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides a worker identifier.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member provides a status code.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member references the measure runtime context.
+ */
+ T_measure_runtime_context *context;
+
+ /**
+ * @brief This member provides the measure runtime request.
+ */
+ T_measure_runtime_request request;
+
+ /**
+ * @brief This member provides an optional measurement begin time point.
+ */
+ T_ticks begin;
+
+ /**
+ * @brief This member provides an optional measurement end time point.
+ */
+ T_ticks end;
+} RtemsEventValPerf_Context;
+
+static RtemsEventValPerf_Context
+ RtemsEventValPerf_Instance;
+
+#define EVENT_END RTEMS_EVENT_0
+
+#define EVENT_OTHER RTEMS_EVENT_1
+
+typedef RtemsEventValPerf_Context Context;
+
+static void Send( const Context *ctx, rtems_event_set events )
+{
+ SendEvents( ctx->worker_id, events );
+}
+
+static void Satisfy( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ ctx->begin = T_tick();
+ ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
+}
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ while ( true ) {
+ rtems_event_set events;
+ rtems_status_code sc;
+ T_ticks ticks;
+
+ sc = rtems_event_receive(
+ EVENT_END | EVENT_OTHER,
+ RTEMS_EVENT_ALL | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &events
+ );
+ ticks = T_tick();
+ T_quiet_rsc_success( sc );
+
+ if ( ( events & EVENT_END ) != 0 ) {
+ ctx->end = ticks;
+ }
+ }
+}
+
+static void RtemsEventValPerf_Setup_Context( RtemsEventValPerf_Context *ctx )
+{
+ T_measure_runtime_config config;
+
+ memset( &config, 0, sizeof( config ) );
+ config.sample_count = 100;
+ ctx->request.arg = ctx;
+ ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES;
+ ctx->context = T_measure_runtime_create( &config );
+ T_assert_not_null( ctx->context );
+}
+
+/**
+ * @brief Create a mutex and a worker task.
+ */
+static void RtemsEventValPerf_Setup( RtemsEventValPerf_Context *ctx )
+{
+ SetSelfPriority( PRIO_NORMAL );
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+static void RtemsEventValPerf_Setup_Wrap( void *arg )
+{
+ RtemsEventValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsEventValPerf_Setup_Context( ctx );
+ RtemsEventValPerf_Setup( ctx );
+}
+
+/**
+ * @brief Delete the worker task and the mutex.
+ */
+static void RtemsEventValPerf_Teardown( RtemsEventValPerf_Context *ctx )
+{
+ DeleteTask( ctx->worker_id );
+ RestoreRunnerPriority();
+}
+
+static void RtemsEventValPerf_Teardown_Wrap( void *arg )
+{
+ RtemsEventValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsEventValPerf_Teardown( ctx );
+}
+
+static T_fixture RtemsEventValPerf_Fixture = {
+ .setup = RtemsEventValPerf_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsEventValPerf_Teardown_Wrap,
+ .scope = NULL,
+ .initial_context = &RtemsEventValPerf_Instance
+};
+
+/**
+ * @defgroup RtemsEventReqPerfIsrPreempt spec:/rtems/event/req/perf-isr-preempt
+ *
+ * @{
+ */
+
+/**
+ * @brief Send two events from with interrupt context. Satisfy the event
+ * condition.
+ */
+static void RtemsEventReqPerfIsrPreempt_Body( RtemsEventValPerf_Context *ctx )
+{
+ CallWithinISR( Satisfy, ctx );
+}
+
+static void RtemsEventReqPerfIsrPreempt_Body_Wrap( void *arg )
+{
+ RtemsEventValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsEventReqPerfIsrPreempt_Body( ctx );
+}
+
+/**
+ * @brief Set the measured runtime. Discard samples interrupted by a clock
+ * tick.
+ */
+static bool RtemsEventReqPerfIsrPreempt_Teardown(
+ RtemsEventValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+
+ return tic == toc;
+}
+
+static bool RtemsEventReqPerfIsrPreempt_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsEventValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsEventReqPerfIsrPreempt_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/** @} */
+
+/**
+ * @defgroup RtemsEventReqPerfOther spec:/rtems/event/req/perf-other
+ *
+ * @{
+ */
+
+/**
+ * @brief Lower the worker priority.
+ */
+static void RtemsEventReqPerfOther_Setup( RtemsEventValPerf_Context *ctx )
+{
+ SetPriority( ctx->worker_id, PRIO_LOW );
+}
+
+static void RtemsEventReqPerfOther_Setup_Wrap( void *arg )
+{
+ RtemsEventValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsEventReqPerfOther_Setup( ctx );
+}
+
+/**
+ * @brief Send two events. Satisfy the event condition.
+ */
+static void RtemsEventReqPerfOther_Body( RtemsEventValPerf_Context *ctx )
+{
+ ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
+}
+
+static void RtemsEventReqPerfOther_Body_Wrap( void *arg )
+{
+ RtemsEventValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsEventReqPerfOther_Body( ctx );
+}
+
+/**
+ * @brief Restore the worker priority. Discard samples interrupted by a clock
+ * tick.
+ */
+static bool RtemsEventReqPerfOther_Teardown(
+ RtemsEventValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ SetPriority( ctx->worker_id, PRIO_HIGH );
+
+ return tic == toc;
+}
+
+static bool RtemsEventReqPerfOther_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsEventValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsEventReqPerfOther_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/** @} */
+
+#if defined(RTEMS_SMP)
+/**
+ * @defgroup RtemsEventReqPerfOtherCpu spec:/rtems/event/req/perf-other-cpu
+ *
+ * @{
+ */
+
+/**
+ * @brief Move worker to scheduler B.
+ */
+static void RtemsEventReqPerfOtherCpu_Prepare( RtemsEventValPerf_Context *ctx )
+{
+ SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+}
+
+/**
+ * @brief Send two events. Satisfy the event condition.
+ */
+static void RtemsEventReqPerfOtherCpu_Body( RtemsEventValPerf_Context *ctx )
+{
+ ctx->begin = T_tick();
+ ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
+}
+
+static void RtemsEventReqPerfOtherCpu_Body_Wrap( void *arg )
+{
+ RtemsEventValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsEventReqPerfOtherCpu_Body( ctx );
+}
+
+/**
+ * @brief Make sure the worker waits for the next event. Set the measured
+ * runtime. Discard samples interrupted by a clock tick.
+ */
+static bool RtemsEventReqPerfOtherCpu_Teardown(
+ RtemsEventValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ WaitForNextTask( 1, ctx->worker_id );
+ *delta = ctx->end - ctx->begin;
+
+ return tic == toc;
+}
+
+static bool RtemsEventReqPerfOtherCpu_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsEventValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsEventReqPerfOtherCpu_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/**
+ * @brief Move worker to scheduler A.
+ */
+static void RtemsEventReqPerfOtherCpu_Cleanup( RtemsEventValPerf_Context *ctx )
+{
+ SetScheduler( ctx->worker_id, SCHEDULER_A_ID, PRIO_HIGH );
+}
+
+/** @} */
+#endif
+
+/**
+ * @defgroup RtemsEventReqPerfOtherNotSatisfied \
+ * spec:/rtems/event/req/perf-other-not-satisfied
+ *
+ * @{
+ */
+
+/**
+ * @brief Send an event. Do not satisfy the event condition.
+ */
+static void RtemsEventReqPerfOtherNotSatisfied_Body(
+ RtemsEventValPerf_Context *ctx
+)
+{
+ ctx->status = rtems_event_send( ctx->worker_id, EVENT_OTHER );
+}
+
+static void RtemsEventReqPerfOtherNotSatisfied_Body_Wrap( void *arg )
+{
+ RtemsEventValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsEventReqPerfOtherNotSatisfied_Body( ctx );
+}
+
+/**
+ * @brief Let the worker wait for the next set of events. Discard samples
+ * interrupted by a clock tick.
+ */
+static bool RtemsEventReqPerfOtherNotSatisfied_Teardown(
+ RtemsEventValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ Send( ctx, EVENT_END );
+
+ return tic == toc;
+}
+
+static bool RtemsEventReqPerfOtherNotSatisfied_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsEventValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsEventReqPerfOtherNotSatisfied_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/** @} */
+
+/**
+ * @defgroup RtemsEventReqPerfOtherPreempt \
+ * spec:/rtems/event/req/perf-other-preempt
+ *
+ * @{
+ */
+
+/**
+ * @brief Send two events. Satisfy the event condition.
+ */
+static void RtemsEventReqPerfOtherPreempt_Body(
+ RtemsEventValPerf_Context *ctx
+)
+{
+ ctx->begin = T_tick();
+ ctx->status = rtems_event_send( ctx->worker_id, EVENT_END | EVENT_OTHER );
+}
+
+static void RtemsEventReqPerfOtherPreempt_Body_Wrap( void *arg )
+{
+ RtemsEventValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsEventReqPerfOtherPreempt_Body( ctx );
+}
+
+/**
+ * @brief Set the measured runtime. Discard samples interrupted by a clock
+ * tick.
+ */
+static bool RtemsEventReqPerfOtherPreempt_Teardown(
+ RtemsEventValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+
+ return tic == toc;
+}
+
+static bool RtemsEventReqPerfOtherPreempt_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsEventValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsEventReqPerfOtherPreempt_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/** @} */
+
+/**
+ * @fn void T_case_body_RtemsEventValPerf( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsEventValPerf, &RtemsEventValPerf_Fixture )
+{
+ RtemsEventValPerf_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ ctx->request.name = "RtemsEventReqPerfIsrPreempt";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsEventReqPerfIsrPreempt_Body_Wrap;
+ ctx->request.teardown = RtemsEventReqPerfIsrPreempt_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ ctx->request.name = "RtemsEventReqPerfOther";
+ ctx->request.setup = RtemsEventReqPerfOther_Setup_Wrap;
+ ctx->request.body = RtemsEventReqPerfOther_Body_Wrap;
+ ctx->request.teardown = RtemsEventReqPerfOther_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ #if defined(RTEMS_SMP)
+ RtemsEventReqPerfOtherCpu_Prepare( ctx );
+ ctx->request.name = "RtemsEventReqPerfOtherCpu";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsEventReqPerfOtherCpu_Body_Wrap;
+ ctx->request.teardown = RtemsEventReqPerfOtherCpu_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsEventReqPerfOtherCpu_Cleanup( ctx );
+ #endif
+
+ ctx->request.name = "RtemsEventReqPerfOtherNotSatisfied";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsEventReqPerfOtherNotSatisfied_Body_Wrap;
+ ctx->request.teardown = RtemsEventReqPerfOtherNotSatisfied_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ ctx->request.name = "RtemsEventReqPerfOtherPreempt";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsEventReqPerfOtherPreempt_Body_Wrap;
+ ctx->request.teardown = RtemsEventReqPerfOtherPreempt_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-event-send-receive.c b/testsuites/validation/tc-event-send-receive.c
new file mode 100644
index 0000000000..54a527cbaa
--- /dev/null
+++ b/testsuites/validation/tc-event-send-receive.c
@@ -0,0 +1,202 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsEventValSendReceive
+ * @ingroup RtemsEventValSystemSendReceive
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/rtems/eventimpl.h>
+#include <rtems/rtems/tasksdata.h>
+#include <rtems/score/statesimpl.h>
+#include <rtems/score/threadimpl.h>
+
+#include "tr-event-send-receive.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsEventValSendReceive spec:/rtems/event/val/send-receive
+ *
+ * @ingroup TestsuitesValidation0
+ *
+ * @brief Tests the rtems_event_send() and rtems_event_receive() directives.
+ *
+ * This test case performs the following actions:
+ *
+ * - Run the event send and receive tests for the application event set defined
+ * by spec:/rtems/event/req/send-receive.
+ *
+ * @{
+ */
+
+static rtems_status_code EventSend(
+ rtems_id id,
+ rtems_event_set event_in
+)
+{
+ return rtems_event_send( id, event_in );
+}
+
+static rtems_status_code EventReceive(
+ rtems_id event_in,
+ rtems_option option_set,
+ rtems_interval ticks,
+ rtems_event_set *event_out
+)
+{
+ return rtems_event_receive( event_in, option_set, ticks, event_out );
+}
+
+static rtems_event_set GetPendingEvents( Thread_Control *thread )
+{
+ RTEMS_API_Control *api;
+
+ api = thread->API_Extensions[ THREAD_API_RTEMS ];
+ return api->Event.pending_events;
+}
+
+/**
+ * @brief Run the event send and receive tests for the application event set
+ * defined by spec:/rtems/event/req/send-receive.
+ */
+static void RtemsEventValSendReceive_Action_0( void )
+{
+ RtemsEventReqSendReceive_Run(
+ EventSend,
+ EventReceive,
+ GetPendingEvents,
+ THREAD_WAIT_CLASS_EVENT,
+ STATES_WAITING_FOR_EVENT
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsEventValSendReceive( void )
+ */
+T_TEST_CASE( RtemsEventValSendReceive )
+{
+ RtemsEventValSendReceive_Action_0();
+}
+
+/** @} */
+
+/**
+ * @defgroup RtemsEventValSystemSendReceive \
+ * spec:/rtems/event/val/system-send-receive
+ *
+ * @ingroup TestsuitesValidation0
+ *
+ * @brief Tests the rtems_event_system_send() and rtems_event_system_receive()
+ * directives.
+ *
+ * This test case performs the following actions:
+ *
+ * - Run the event send and receive tests for the system event set defined by
+ * spec:/rtems/event/req/send-receive.
+ *
+ * @{
+ */
+
+static rtems_status_code EventSystemSend(
+ rtems_id id,
+ rtems_event_set event_in
+)
+{
+ return rtems_event_system_send( id, event_in );
+}
+
+static rtems_status_code EventSystemReceive(
+ rtems_id event_in,
+ rtems_option option_set,
+ rtems_interval ticks,
+ rtems_event_set *event_out
+)
+{
+ return rtems_event_system_receive(
+ event_in,
+ option_set,
+ ticks,
+ event_out
+ );
+}
+
+static rtems_event_set GetPendingSystemEvents( Thread_Control *thread )
+{
+ RTEMS_API_Control *api;
+
+ api = thread->API_Extensions[ THREAD_API_RTEMS ];
+ return api->System_event.pending_events;
+}
+
+/**
+ * @brief Run the event send and receive tests for the system event set defined
+ * by spec:/rtems/event/req/send-receive.
+ */
+static void RtemsEventValSystemSendReceive_Action_0( void )
+{
+ RtemsEventReqSendReceive_Run(
+ EventSystemSend,
+ EventSystemReceive,
+ GetPendingSystemEvents,
+ THREAD_WAIT_CLASS_SYSTEM_EVENT,
+ STATES_WAITING_FOR_SYSTEM_EVENT
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsEventValSystemSendReceive( void )
+ */
+T_TEST_CASE( RtemsEventValSystemSendReceive )
+{
+ RtemsEventValSystemSendReceive_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-events.c b/testsuites/validation/tc-events.c
new file mode 100644
index 0000000000..e7d009fe8a
--- /dev/null
+++ b/testsuites/validation/tc-events.c
@@ -0,0 +1,197 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsEventValEvents
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tr-event-constant.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsEventValEvents spec:/rtems/event/val/events
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests the Event Manager API.
+ *
+ * This test case performs the following actions:
+ *
+ * - Run the event constant and number test for all 32 event constants.
+ *
+ * - Check that RTEMS_PENDING_EVENTS is a constant expression which evaluates
+ * to a value of zero.
+ *
+ * - Calculate the value of a bitwise or of all 32 event constants.
+ *
+ * - Check that the value is equal to RTEMS_ALL_EVENTS.
+ *
+ * - Validate the Event Manager directive options.
+ *
+ * - Check that RTEMS_EVENT_ALL is equal to zero.
+ *
+ * - Check that RTEMS_EVENT_ANY is a power of two.
+ *
+ * @{
+ */
+
+static const rtems_event_set events[] = {
+ RTEMS_EVENT_0,
+ RTEMS_EVENT_1,
+ RTEMS_EVENT_2,
+ RTEMS_EVENT_3,
+ RTEMS_EVENT_4,
+ RTEMS_EVENT_5,
+ RTEMS_EVENT_6,
+ RTEMS_EVENT_7,
+ RTEMS_EVENT_8,
+ RTEMS_EVENT_9,
+ RTEMS_EVENT_10,
+ RTEMS_EVENT_11,
+ RTEMS_EVENT_12,
+ RTEMS_EVENT_13,
+ RTEMS_EVENT_14,
+ RTEMS_EVENT_15,
+ RTEMS_EVENT_16,
+ RTEMS_EVENT_17,
+ RTEMS_EVENT_18,
+ RTEMS_EVENT_19,
+ RTEMS_EVENT_20,
+ RTEMS_EVENT_21,
+ RTEMS_EVENT_22,
+ RTEMS_EVENT_23,
+ RTEMS_EVENT_24,
+ RTEMS_EVENT_25,
+ RTEMS_EVENT_26,
+ RTEMS_EVENT_27,
+ RTEMS_EVENT_28,
+ RTEMS_EVENT_29,
+ RTEMS_EVENT_30,
+ RTEMS_EVENT_31
+};
+
+/**
+ * @brief Run the event constant and number test for all 32 event constants.
+ */
+static void RtemsEventValEvents_Action_0( void )
+{
+ unsigned int i;
+
+ for ( i = 0; i < 32; ++i ) {
+ RtemsEventValEventConstant_Run( events[ i ], i );
+ T_step( i ); /* Accounts for 32 test plan steps */
+ }
+}
+
+/**
+ * @brief Check that RTEMS_PENDING_EVENTS is a constant expression which
+ * evaluates to a value of zero.
+ */
+static void RtemsEventValEvents_Action_1( void )
+{
+ RTEMS_STATIC_ASSERT( RTEMS_PENDING_EVENTS == 0, PENDING_EVENTS );
+}
+
+/**
+ * @brief Calculate the value of a bitwise or of all 32 event constants.
+ */
+static void RtemsEventValEvents_Action_2( void )
+{
+ rtems_event_set all;
+ int i;
+
+ all = 0;
+
+ for ( i = 0; i < 32; ++i ) {
+ all |= events[ i ];
+ }
+
+ /*
+ * Check that the value is equal to RTEMS_ALL_EVENTS.
+ */
+ T_step_eq_u32( 32, all, RTEMS_ALL_EVENTS );
+}
+
+/**
+ * @brief Validate the Event Manager directive options.
+ */
+static void RtemsEventValEvents_Action_3( void )
+{
+ /* No action */
+
+ /*
+ * Check that RTEMS_EVENT_ALL is equal to zero.
+ */
+ T_step_eq_u32( 33, RTEMS_EVENT_ALL, 0 );
+
+ /*
+ * Check that RTEMS_EVENT_ANY is a power of two.
+ */
+ T_step_ne_u32( 34, RTEMS_EVENT_ANY, 0 );
+ T_step_eq_u32( 35, RTEMS_EVENT_ANY & ( RTEMS_EVENT_ANY - 1 ), 0 );
+}
+
+/**
+ * @fn void T_case_body_RtemsEventValEvents( void )
+ */
+T_TEST_CASE( RtemsEventValEvents )
+{
+ T_plan( 36 );
+
+ RtemsEventValEvents_Action_0();
+ RtemsEventValEvents_Action_1();
+ RtemsEventValEvents_Action_2();
+ RtemsEventValEvents_Action_3();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-flsl.c b/testsuites/validation/tc-flsl.c
new file mode 100644
index 0000000000..95f0ed9ccf
--- /dev/null
+++ b/testsuites/validation/tc-flsl.c
@@ -0,0 +1,275 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup CReqFlsl
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <strings.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup CReqFlsl spec:/c/req/flsl
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ CReqFlsl_Pre_Value_Zero,
+ CReqFlsl_Pre_Value_NonZero,
+ CReqFlsl_Pre_Value_NA
+} CReqFlsl_Pre_Value;
+
+typedef enum {
+ CReqFlsl_Post_Result_Zero,
+ CReqFlsl_Post_Result_LastBitSet,
+ CReqFlsl_Post_Result_NA
+} CReqFlsl_Post_Result;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Value_NA : 1;
+ uint8_t Post_Result : 2;
+} CReqFlsl_Entry;
+
+/**
+ * @brief Test context for spec:/c/req/flsl test case.
+ */
+typedef struct {
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ CReqFlsl_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} CReqFlsl_Context;
+
+static CReqFlsl_Context
+ CReqFlsl_Instance;
+
+static const char * const CReqFlsl_PreDesc_Value[] = {
+ "Zero",
+ "NonZero",
+ "NA"
+};
+
+static const char * const * const CReqFlsl_PreDesc[] = {
+ CReqFlsl_PreDesc_Value,
+ NULL
+};
+
+static void CReqFlsl_Pre_Value_Prepare(
+ CReqFlsl_Context *ctx,
+ CReqFlsl_Pre_Value state
+)
+{
+ switch ( state ) {
+ case CReqFlsl_Pre_Value_Zero: {
+ /*
+ * While the parameter value is equal to zero.
+ */
+ /* Nothing to prepare */
+ break;
+ }
+
+ case CReqFlsl_Pre_Value_NonZero: {
+ /*
+ * While the parameter value is not equal to zero.
+ */
+ /* Nothing to prepare */
+ break;
+ }
+
+ case CReqFlsl_Pre_Value_NA:
+ break;
+ }
+}
+
+static void CReqFlsl_Post_Result_Check(
+ CReqFlsl_Context *ctx,
+ CReqFlsl_Post_Result state
+)
+{
+ int expected_result;
+ long value;
+ size_t i;
+
+ switch ( state ) {
+ case CReqFlsl_Post_Result_Zero: {
+ /*
+ * The return value of flsl() shall be equal to zero.
+ */
+ T_eq_int( flsl( 0 ), 0 );
+ break;
+ }
+
+ case CReqFlsl_Post_Result_LastBitSet: {
+ /*
+ * The return value of flsl() shall be equal to the index of the
+ * most-significant bit set in the parameter value.
+ */
+ expected_result = 1;
+ value = 1;
+
+ for ( i = 0; i < sizeof( long ) * CHAR_BIT; ++i ) {
+ T_eq_int( flsl( value ), expected_result );
+ ++expected_result;
+ value <<= 1;
+ }
+ break;
+ }
+
+ case CReqFlsl_Post_Result_NA:
+ break;
+ }
+}
+
+static void CReqFlsl_Action( CReqFlsl_Context *ctx )
+{
+ /* The action is performed in the post-condition states */
+}
+
+static const CReqFlsl_Entry
+CReqFlsl_Entries[] = {
+ { 0, 0, CReqFlsl_Post_Result_Zero },
+ { 0, 0, CReqFlsl_Post_Result_LastBitSet }
+};
+
+static const uint8_t
+CReqFlsl_Map[] = {
+ 0, 1
+};
+
+static size_t CReqFlsl_Scope( void *arg, char *buf, size_t n )
+{
+ CReqFlsl_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( CReqFlsl_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture CReqFlsl_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = CReqFlsl_Scope,
+ .initial_context = &CReqFlsl_Instance
+};
+
+static inline CReqFlsl_Entry CReqFlsl_PopEntry( CReqFlsl_Context *ctx )
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return CReqFlsl_Entries[
+ CReqFlsl_Map[ index ]
+ ];
+}
+
+static void CReqFlsl_TestVariant( CReqFlsl_Context *ctx )
+{
+ CReqFlsl_Pre_Value_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ CReqFlsl_Action( ctx );
+ CReqFlsl_Post_Result_Check( ctx, ctx->Map.entry.Post_Result );
+}
+
+/**
+ * @fn void T_case_body_CReqFlsl( void )
+ */
+T_TEST_CASE_FIXTURE( CReqFlsl, &CReqFlsl_Fixture )
+{
+ CReqFlsl_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = CReqFlsl_Pre_Value_Zero;
+ ctx->Map.pcs[ 0 ] < CReqFlsl_Pre_Value_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = CReqFlsl_PopEntry( ctx );
+ CReqFlsl_TestVariant( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-futex-wait.c b/testsuites/validation/tc-futex-wait.c
new file mode 100644
index 0000000000..3730df2a40
--- /dev/null
+++ b/testsuites/validation/tc-futex-wait.c
@@ -0,0 +1,411 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup NewlibReqFutexWait
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <rtems.h>
+#include <sys/lock.h>
+
+#include "tr-tq-enqueue-fifo.h"
+#include "tx-thread-queue.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup NewlibReqFutexWait spec:/newlib/req/futex-wait
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ NewlibReqFutexWait_Pre_State_Equal,
+ NewlibReqFutexWait_Pre_State_NotEqual,
+ NewlibReqFutexWait_Pre_State_NA
+} NewlibReqFutexWait_Pre_State;
+
+typedef enum {
+ NewlibReqFutexWait_Post_Result_Zero,
+ NewlibReqFutexWait_Post_Result_EAGAIN,
+ NewlibReqFutexWait_Post_Result_NA
+} NewlibReqFutexWait_Post_Result;
+
+typedef enum {
+ NewlibReqFutexWait_Post_Enqueue_No,
+ NewlibReqFutexWait_Post_Enqueue_Yes,
+ NewlibReqFutexWait_Post_Enqueue_NA
+} NewlibReqFutexWait_Post_Enqueue;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_State_NA : 1;
+ uint8_t Post_Result : 2;
+ uint8_t Post_Enqueue : 2;
+} NewlibReqFutexWait_Entry;
+
+/**
+ * @brief Test context for spec:/newlib/req/futex-wait test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the thread queue test context.
+ */
+ TQContext tq_ctx;
+
+ /**
+ * @brief This member specifies the expected futex state value.
+ */
+ int expected_value;
+
+ /**
+ * @brief This member provides the futex object.
+ */
+ struct _Futex_Control futex;
+
+ /**
+ * @brief This member provides the futex state.
+ */
+ int state;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ NewlibReqFutexWait_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} NewlibReqFutexWait_Context;
+
+static NewlibReqFutexWait_Context
+ NewlibReqFutexWait_Instance;
+
+static const char * const NewlibReqFutexWait_PreDesc_State[] = {
+ "Equal",
+ "NotEqual",
+ "NA"
+};
+
+static const char * const * const NewlibReqFutexWait_PreDesc[] = {
+ NewlibReqFutexWait_PreDesc_State,
+ NULL
+};
+
+typedef NewlibReqFutexWait_Context Context;
+
+static Context *ToContext( TQContext *tq_ctx )
+{
+ return RTEMS_CONTAINER_OF( tq_ctx, Context, tq_ctx );
+}
+
+static Status_Control Enqueue( TQContext *tq_ctx, TQWait wait )
+{
+ Context *ctx;
+ int eno;
+
+ ctx = ToContext( tq_ctx );
+ eno = _Futex_Wait( &ctx->futex, &ctx->state, ctx->expected_value );
+ T_eq_int( eno, 0 );
+
+ return STATUS_BUILD( 0, eno );
+}
+
+static void EnqueueDone( TQContext *tq_ctx )
+{
+ Context *ctx;
+ int count;
+
+ ctx = ToContext( tq_ctx );
+ count = _Futex_Wake( &ctx->futex, INT_MAX );
+ T_eq_int( count, (int) ctx->tq_ctx.how_many );
+}
+
+static void NewlibReqFutexWait_Pre_State_Prepare(
+ NewlibReqFutexWait_Context *ctx,
+ NewlibReqFutexWait_Pre_State state
+)
+{
+ switch ( state ) {
+ case NewlibReqFutexWait_Pre_State_Equal: {
+ /*
+ * While the expected futex state value is equal to the actual futex
+ * state value.
+ */
+ ctx->expected_value = 0;
+ break;
+ }
+
+ case NewlibReqFutexWait_Pre_State_NotEqual: {
+ /*
+ * While the expected futex state value is not equal to the actual futex
+ * state value.
+ */
+ ctx->expected_value = 1;
+ break;
+ }
+
+ case NewlibReqFutexWait_Pre_State_NA:
+ break;
+ }
+}
+
+static void NewlibReqFutexWait_Post_Result_Check(
+ NewlibReqFutexWait_Context *ctx,
+ NewlibReqFutexWait_Post_Result state
+)
+{
+ int eno;
+
+ switch ( state ) {
+ case NewlibReqFutexWait_Post_Result_Zero: {
+ /*
+ * The return status of _Futex_Wait() shall be zero.
+ */
+ /* This result is checked by Enqueue() */
+ break;
+ }
+
+ case NewlibReqFutexWait_Post_Result_EAGAIN: {
+ /*
+ * The return status of _Futex_Wait() shall be EAGAIN.
+ */
+ eno = _Futex_Wait( &ctx->futex, &ctx->state, ctx->expected_value );
+ T_eq_int( eno, EAGAIN );
+ break;
+ }
+
+ case NewlibReqFutexWait_Post_Result_NA:
+ break;
+ }
+}
+
+static void NewlibReqFutexWait_Post_Enqueue_Check(
+ NewlibReqFutexWait_Context *ctx,
+ NewlibReqFutexWait_Post_Enqueue state
+)
+{
+ switch ( state ) {
+ case NewlibReqFutexWait_Post_Enqueue_No: {
+ /*
+ * The calling thread shall not be enqueued on the thread queue of the
+ * futex object.
+ */
+ /* The runner would block forever */
+ break;
+ }
+
+ case NewlibReqFutexWait_Post_Enqueue_Yes: {
+ /*
+ * The calling thread shall be enqueued in FIFO order on the thread queue
+ * of the futex object.
+ */
+ ScoreTqReqEnqueueFifo_Run( &ctx->tq_ctx );
+ break;
+ }
+
+ case NewlibReqFutexWait_Post_Enqueue_NA:
+ break;
+ }
+}
+
+static void NewlibReqFutexWait_Setup( NewlibReqFutexWait_Context *ctx )
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->tq_ctx.discipline = TQ_FIFO;
+ ctx->tq_ctx.wait = TQ_WAIT_FOREVER;
+ ctx->tq_ctx.enqueue_prepare = TQDoNothing;
+ ctx->tq_ctx.enqueue = Enqueue;
+ ctx->tq_ctx.enqueue_done = EnqueueDone;
+ ctx->tq_ctx.surrender = TQDoNothingSuccessfully;
+ ctx->tq_ctx.convert_status = TQConvertStatusPOSIX;
+ TQInitialize( &ctx->tq_ctx );
+}
+
+static void NewlibReqFutexWait_Setup_Wrap( void *arg )
+{
+ NewlibReqFutexWait_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ NewlibReqFutexWait_Setup( ctx );
+}
+
+static void NewlibReqFutexWait_Teardown( NewlibReqFutexWait_Context *ctx )
+{
+ TQDestroy( &ctx->tq_ctx );
+}
+
+static void NewlibReqFutexWait_Teardown_Wrap( void *arg )
+{
+ NewlibReqFutexWait_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ NewlibReqFutexWait_Teardown( ctx );
+}
+
+static void NewlibReqFutexWait_Prepare( NewlibReqFutexWait_Context *ctx )
+{
+ _Futex_Initialize( &ctx->futex );
+ ctx->state = 0;
+}
+
+static void NewlibReqFutexWait_Action( NewlibReqFutexWait_Context *ctx )
+{
+ /* The action is performed in the post-conditions. */
+}
+
+static void NewlibReqFutexWait_Cleanup( NewlibReqFutexWait_Context *ctx )
+{
+ _Futex_Destroy( &ctx->futex );
+}
+
+static const NewlibReqFutexWait_Entry
+NewlibReqFutexWait_Entries[] = {
+ { 0, 0, NewlibReqFutexWait_Post_Result_Zero,
+ NewlibReqFutexWait_Post_Enqueue_Yes },
+ { 0, 0, NewlibReqFutexWait_Post_Result_EAGAIN,
+ NewlibReqFutexWait_Post_Enqueue_No }
+};
+
+static const uint8_t
+NewlibReqFutexWait_Map[] = {
+ 0, 1
+};
+
+static size_t NewlibReqFutexWait_Scope( void *arg, char *buf, size_t n )
+{
+ NewlibReqFutexWait_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( NewlibReqFutexWait_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture NewlibReqFutexWait_Fixture = {
+ .setup = NewlibReqFutexWait_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NewlibReqFutexWait_Teardown_Wrap,
+ .scope = NewlibReqFutexWait_Scope,
+ .initial_context = &NewlibReqFutexWait_Instance
+};
+
+static inline NewlibReqFutexWait_Entry NewlibReqFutexWait_PopEntry(
+ NewlibReqFutexWait_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return NewlibReqFutexWait_Entries[
+ NewlibReqFutexWait_Map[ index ]
+ ];
+}
+
+static void NewlibReqFutexWait_TestVariant( NewlibReqFutexWait_Context *ctx )
+{
+ NewlibReqFutexWait_Pre_State_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ NewlibReqFutexWait_Action( ctx );
+ NewlibReqFutexWait_Post_Result_Check( ctx, ctx->Map.entry.Post_Result );
+ NewlibReqFutexWait_Post_Enqueue_Check( ctx, ctx->Map.entry.Post_Enqueue );
+}
+
+/**
+ * @fn void T_case_body_NewlibReqFutexWait( void )
+ */
+T_TEST_CASE_FIXTURE( NewlibReqFutexWait, &NewlibReqFutexWait_Fixture )
+{
+ NewlibReqFutexWait_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = NewlibReqFutexWait_Pre_State_Equal;
+ ctx->Map.pcs[ 0 ] < NewlibReqFutexWait_Pre_State_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = NewlibReqFutexWait_PopEntry( ctx );
+ NewlibReqFutexWait_Prepare( ctx );
+ NewlibReqFutexWait_TestVariant( ctx );
+ NewlibReqFutexWait_Cleanup( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-futex-wake.c b/testsuites/validation/tc-futex-wake.c
new file mode 100644
index 0000000000..baaa0daa6b
--- /dev/null
+++ b/testsuites/validation/tc-futex-wake.c
@@ -0,0 +1,409 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup NewlibReqFutexWake
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <rtems.h>
+#include <sys/lock.h>
+
+#include "tr-tq-flush-fifo.h"
+#include "tx-thread-queue.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup NewlibReqFutexWake spec:/newlib/req/futex-wake
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ NewlibReqFutexWake_Pre_Count_NegativeOrZero,
+ NewlibReqFutexWake_Pre_Count_Positive,
+ NewlibReqFutexWake_Pre_Count_NA
+} NewlibReqFutexWake_Pre_Count;
+
+typedef enum {
+ NewlibReqFutexWake_Post_Result_Count,
+ NewlibReqFutexWake_Post_Result_NA
+} NewlibReqFutexWake_Post_Result;
+
+typedef enum {
+ NewlibReqFutexWake_Post_Flush_No,
+ NewlibReqFutexWake_Post_Flush_Yes,
+ NewlibReqFutexWake_Post_Flush_NA
+} NewlibReqFutexWake_Post_Flush;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Count_NA : 1;
+ uint8_t Post_Result : 1;
+ uint8_t Post_Flush : 2;
+} NewlibReqFutexWake_Entry;
+
+/**
+ * @brief Test context for spec:/newlib/req/futex-wake test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the thread queue test context.
+ */
+ TQContext tq_ctx;
+
+ /**
+ * @brief This member provides the futex object.
+ */
+ struct _Futex_Control futex;
+
+ /**
+ * @brief This member provides the futex state.
+ */
+ int state;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ NewlibReqFutexWake_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} NewlibReqFutexWake_Context;
+
+static NewlibReqFutexWake_Context
+ NewlibReqFutexWake_Instance;
+
+static const char * const NewlibReqFutexWake_PreDesc_Count[] = {
+ "NegativeOrZero",
+ "Positive",
+ "NA"
+};
+
+static const char * const * const NewlibReqFutexWake_PreDesc[] = {
+ NewlibReqFutexWake_PreDesc_Count,
+ NULL
+};
+
+typedef NewlibReqFutexWake_Context Context;
+
+static Context *ToContext( TQContext *tq_ctx )
+{
+ return RTEMS_CONTAINER_OF( tq_ctx, Context, tq_ctx );
+}
+
+static Status_Control Enqueue( TQContext *tq_ctx, TQWait wait )
+{
+ Context *ctx;
+ int count;
+ int eno;
+
+ ctx = ToContext( tq_ctx );
+
+ count = _Futex_Wake( &ctx->futex, -1 );
+ T_eq_int( count, 0 );
+
+ count = _Futex_Wake( &ctx->futex, 0 );
+ T_eq_int( count, 0 );
+
+ eno = _Futex_Wait( &ctx->futex, &ctx->state, 0 );
+ T_eq_int( eno, 0 );
+
+ return STATUS_BUILD( 0, eno );
+}
+
+static uint32_t Flush( TQContext *tq_ctx, uint32_t thread_count, bool all )
+{
+ Context *ctx;
+ int count;
+
+ (void) thread_count;
+
+ ctx = ToContext( tq_ctx );
+
+ if ( all ) {
+ count = _Futex_Wake( &ctx->futex, INT_MAX );
+ } else {
+ count = _Futex_Wake( &ctx->futex, 1 );
+ }
+
+ return (uint32_t) count;
+}
+
+static void NewlibReqFutexWake_Pre_Count_Prepare(
+ NewlibReqFutexWake_Context *ctx,
+ NewlibReqFutexWake_Pre_Count state
+)
+{
+ switch ( state ) {
+ case NewlibReqFutexWake_Pre_Count_NegativeOrZero: {
+ /*
+ * While the ``count`` parameter is less or equal to than zero.
+ */
+ /* This state is prepared by Enqueue() */
+ break;
+ }
+
+ case NewlibReqFutexWake_Pre_Count_Positive: {
+ /*
+ * While the ``count`` parameter is greater than zero.
+ */
+ /* This state is prepared by Flush() */
+ break;
+ }
+
+ case NewlibReqFutexWake_Pre_Count_NA:
+ break;
+ }
+}
+
+static void NewlibReqFutexWake_Post_Result_Check(
+ NewlibReqFutexWake_Context *ctx,
+ NewlibReqFutexWake_Post_Result state
+)
+{
+ switch ( state ) {
+ case NewlibReqFutexWake_Post_Result_Count: {
+ /*
+ * The return status of _Futex_Wake() shall be the count of threads
+ * extracted from the thread queue of the futex object.
+ */
+ /* This result is checked by Flush() */
+ break;
+ }
+
+ case NewlibReqFutexWake_Post_Result_NA:
+ break;
+ }
+}
+
+static void NewlibReqFutexWake_Post_Flush_Check(
+ NewlibReqFutexWake_Context *ctx,
+ NewlibReqFutexWake_Post_Flush state
+)
+{
+ switch ( state ) {
+ case NewlibReqFutexWake_Post_Flush_No: {
+ /*
+ * No thread shall be extracted from the thread queue of the futex
+ * object.
+ */
+ /* This state is checked by Enqueue() */
+ break;
+ }
+
+ case NewlibReqFutexWake_Post_Flush_Yes: {
+ /*
+ * The first count threads specified by the ``count`` parameter shall be
+ * extracted from the thread queue of the futex object in FIFO order.
+ */
+ ScoreTqReqFlushFifo_Run( &ctx->tq_ctx, true );
+ break;
+ }
+
+ case NewlibReqFutexWake_Post_Flush_NA:
+ break;
+ }
+}
+
+static void NewlibReqFutexWake_Setup( NewlibReqFutexWake_Context *ctx )
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->tq_ctx.discipline = TQ_FIFO;
+ ctx->tq_ctx.wait = TQ_WAIT_FOREVER;
+ ctx->tq_ctx.enqueue_prepare = TQDoNothing;
+ ctx->tq_ctx.enqueue = Enqueue;
+ ctx->tq_ctx.enqueue_done = TQDoNothing;
+ ctx->tq_ctx.flush = Flush;
+ ctx->tq_ctx.surrender = TQDoNothingSuccessfully;
+ ctx->tq_ctx.convert_status = TQConvertStatusPOSIX;
+ TQInitialize( &ctx->tq_ctx );
+}
+
+static void NewlibReqFutexWake_Setup_Wrap( void *arg )
+{
+ NewlibReqFutexWake_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ NewlibReqFutexWake_Setup( ctx );
+}
+
+static void NewlibReqFutexWake_Teardown( NewlibReqFutexWake_Context *ctx )
+{
+ TQDestroy( &ctx->tq_ctx );
+}
+
+static void NewlibReqFutexWake_Teardown_Wrap( void *arg )
+{
+ NewlibReqFutexWake_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ NewlibReqFutexWake_Teardown( ctx );
+}
+
+static void NewlibReqFutexWake_Prepare( NewlibReqFutexWake_Context *ctx )
+{
+ _Futex_Initialize( &ctx->futex );
+}
+
+static void NewlibReqFutexWake_Action( NewlibReqFutexWake_Context *ctx )
+{
+ /* The action is performed in the ``Flush`` post-condition ``All`` state. */
+}
+
+static void NewlibReqFutexWake_Cleanup( NewlibReqFutexWake_Context *ctx )
+{
+ _Futex_Destroy( &ctx->futex );
+}
+
+static const NewlibReqFutexWake_Entry
+NewlibReqFutexWake_Entries[] = {
+ { 0, 0, NewlibReqFutexWake_Post_Result_Count,
+ NewlibReqFutexWake_Post_Flush_No },
+ { 0, 0, NewlibReqFutexWake_Post_Result_Count,
+ NewlibReqFutexWake_Post_Flush_Yes }
+};
+
+static const uint8_t
+NewlibReqFutexWake_Map[] = {
+ 0, 1
+};
+
+static size_t NewlibReqFutexWake_Scope( void *arg, char *buf, size_t n )
+{
+ NewlibReqFutexWake_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( NewlibReqFutexWake_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture NewlibReqFutexWake_Fixture = {
+ .setup = NewlibReqFutexWake_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NewlibReqFutexWake_Teardown_Wrap,
+ .scope = NewlibReqFutexWake_Scope,
+ .initial_context = &NewlibReqFutexWake_Instance
+};
+
+static inline NewlibReqFutexWake_Entry NewlibReqFutexWake_PopEntry(
+ NewlibReqFutexWake_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return NewlibReqFutexWake_Entries[
+ NewlibReqFutexWake_Map[ index ]
+ ];
+}
+
+static void NewlibReqFutexWake_TestVariant( NewlibReqFutexWake_Context *ctx )
+{
+ NewlibReqFutexWake_Pre_Count_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ NewlibReqFutexWake_Action( ctx );
+ NewlibReqFutexWake_Post_Result_Check( ctx, ctx->Map.entry.Post_Result );
+ NewlibReqFutexWake_Post_Flush_Check( ctx, ctx->Map.entry.Post_Flush );
+}
+
+/**
+ * @fn void T_case_body_NewlibReqFutexWake( void )
+ */
+T_TEST_CASE_FIXTURE( NewlibReqFutexWake, &NewlibReqFutexWake_Fixture )
+{
+ NewlibReqFutexWake_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = NewlibReqFutexWake_Pre_Count_NegativeOrZero;
+ ctx->Map.pcs[ 0 ] < NewlibReqFutexWake_Pre_Count_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = NewlibReqFutexWake_PopEntry( ctx );
+ NewlibReqFutexWake_Prepare( ctx );
+ NewlibReqFutexWake_TestVariant( ctx );
+ NewlibReqFutexWake_Cleanup( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-intr-clear.c b/testsuites/validation/tc-intr-clear.c
index 8c4e1e1deb..b131b738fd 100644
--- a/testsuites/validation/tc-intr-clear.c
+++ b/testsuites/validation/tc-intr-clear.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsIntrReqClear
+ * @ingroup RtemsIntrReqClear
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -61,9 +61,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsIntrReqClear spec:/rtems/intr/req/clear
+ * @defgroup RtemsIntrReqClear spec:/rtems/intr/req/clear
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationIntr
*
* @{
*/
@@ -134,6 +134,12 @@ typedef struct {
struct {
/**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 2 ];
+
+ /**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 2 ];
@@ -560,13 +566,23 @@ static inline RtemsIntrReqClear_Entry RtemsIntrReqClear_PopEntry(
];
}
+static void RtemsIntrReqClear_SetPreConditionStates(
+ RtemsIntrReqClear_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+
+ if ( ctx->Map.entry.Pre_CanClear_NA ) {
+ ctx->Map.pcs[ 1 ] = RtemsIntrReqClear_Pre_CanClear_NA;
+ } else {
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ }
+}
+
static void RtemsIntrReqClear_TestVariant( RtemsIntrReqClear_Context *ctx )
{
RtemsIntrReqClear_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] );
- RtemsIntrReqClear_Pre_CanClear_Prepare(
- ctx,
- ctx->Map.entry.Pre_CanClear_NA ? RtemsIntrReqClear_Pre_CanClear_NA : ctx->Map.pcs[ 1 ]
- );
+ RtemsIntrReqClear_Pre_CanClear_Prepare( ctx, ctx->Map.pcs[ 1 ] );
RtemsIntrReqClear_Action( ctx );
RtemsIntrReqClear_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
RtemsIntrReqClear_Post_Cleared_Check( ctx, ctx->Map.entry.Post_Cleared );
@@ -584,16 +600,17 @@ T_TEST_CASE_FIXTURE( RtemsIntrReqClear, &RtemsIntrReqClear_Fixture )
ctx->Map.index = 0;
for (
- ctx->Map.pcs[ 0 ] = RtemsIntrReqClear_Pre_Vector_Valid;
- ctx->Map.pcs[ 0 ] < RtemsIntrReqClear_Pre_Vector_NA;
- ++ctx->Map.pcs[ 0 ]
+ ctx->Map.pci[ 0 ] = RtemsIntrReqClear_Pre_Vector_Valid;
+ ctx->Map.pci[ 0 ] < RtemsIntrReqClear_Pre_Vector_NA;
+ ++ctx->Map.pci[ 0 ]
) {
for (
- ctx->Map.pcs[ 1 ] = RtemsIntrReqClear_Pre_CanClear_Yes;
- ctx->Map.pcs[ 1 ] < RtemsIntrReqClear_Pre_CanClear_NA;
- ++ctx->Map.pcs[ 1 ]
+ ctx->Map.pci[ 1 ] = RtemsIntrReqClear_Pre_CanClear_Yes;
+ ctx->Map.pci[ 1 ] < RtemsIntrReqClear_Pre_CanClear_NA;
+ ++ctx->Map.pci[ 1 ]
) {
ctx->Map.entry = RtemsIntrReqClear_PopEntry( ctx );
+ RtemsIntrReqClear_SetPreConditionStates( ctx );
RtemsIntrReqClear_TestVariant( ctx );
}
}
diff --git a/testsuites/validation/tc-intr-entry-install.c b/testsuites/validation/tc-intr-entry-install.c
index 37583249aa..58c7989dbe 100644
--- a/testsuites/validation/tc-intr-entry-install.c
+++ b/testsuites/validation/tc-intr-entry-install.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsIntrReqEntryInstall
+ * @ingroup RtemsIntrReqEntryInstall
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -60,10 +60,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsIntrReqEntryInstall \
- * spec:/rtems/intr/req/entry-install
+ * @defgroup RtemsIntrReqEntryInstall spec:/rtems/intr/req/entry-install
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationIntr
*
* @{
*/
@@ -174,9 +173,14 @@ typedef struct {
bool initialized_during_setup;
/**
- * @brief If this member is true, then an interrupt occurred.
+ * @brief This member provides a counter for handler invocations.
*/
- bool interrupt_occurred;
+ uint32_t handler_counter;
+
+ /**
+ * @brief This member provides a counter snapshot for each entry.
+ */
+ uint32_t counter_by_entry[ 3 ];
/**
* @brief This member provides the vector number of a testable interrupt
@@ -185,6 +189,12 @@ typedef struct {
rtems_vector_number test_vector;
/**
+ * @brief If this member is true, then the testable interrupt vector was
+ * enabled at the test case begin.
+ */
+ bool test_vector_was_enabled;
+
+ /**
* @brief This member provides the attributes of the testable interrupt
* vector.
*/
@@ -262,7 +272,7 @@ typedef struct {
/**
* @brief This member specifies if the ``entry`` parameter value.
*/
- rtems_interrupt_entry *entry;;
+ rtems_interrupt_entry *entry;
/**
* @brief This member contains the return value of the
@@ -272,6 +282,12 @@ typedef struct {
struct {
/**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 8 ];
+
+ /**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 8 ];
@@ -409,29 +425,63 @@ static void Install(
ctx->other_installed = true;
}
-static void OtherRoutine( void *arg )
+static void Routine( Context *ctx, uint32_t counter )
{
- Context *ctx;
rtems_status_code sc;
- (void) arg;
- ctx = T_fixture_context();
- sc = rtems_interrupt_vector_disable( ctx->test_vector );
- T_rsc_success( sc );
+ ctx->handler_counter = counter;
+
+ if ( !ctx->attributes.cleared_by_acknowledge ) {
+ sc = ClearSoftwareInterrupt( ctx->test_vector );
+ T_rsc_success( sc );
+ }
- ctx->interrupt_occurred = true;
+ if ( counter > 3 ) {
+ sc = rtems_interrupt_vector_disable( ctx->test_vector );
+ T_rsc_success( sc );
+ }
}
static void EntryRoutine( void *arg )
{
- T_eq_ptr( arg, &entry_arg );
- OtherRoutine( NULL );
+ Context *ctx;
+ uint32_t counter;
+
+ ctx = T_fixture_context();
+ counter = ctx->handler_counter + 1;
+
+ if ( arg == &other_arg ) {
+ ctx->counter_by_entry[ 1 ] = counter;
+ } else {
+ ctx->counter_by_entry[ 0 ] = counter;
+ T_eq_ptr( arg, &entry_arg );
+ }
+
+ Routine( ctx, counter );
+}
+
+static void OtherRoutine( void *arg )
+{
+ Context *ctx;
+ uint32_t counter;
+
+ (void) arg;
+ ctx = T_fixture_context();
+ counter = ctx->handler_counter + 1;
+ ctx->counter_by_entry[ 1 ] = counter;
+ Routine( ctx, counter );
}
static void ThirdRoutine( void *arg )
{
+ Context *ctx;
+ uint32_t counter;
+
+ ctx = T_fixture_context();
+ counter = ctx->handler_counter + 1;
+ ctx->counter_by_entry[ 2 ] = counter;
T_eq_ptr( arg, &third_arg );
- OtherRoutine( NULL );
+ Routine( ctx, counter );
}
static void InstallThird( Context *ctx )
@@ -469,7 +519,7 @@ static void Action( void *arg )
T_rsc_success( sc );
bsp_interrupt_set_handler_unique(
- BSP_INTERRUPT_HANDLER_TABLE_SIZE,
+ BSP_INTERRUPT_DISPATCH_TABLE_SIZE,
ctx->initialized
);
@@ -480,7 +530,7 @@ static void Action( void *arg )
);
bsp_interrupt_set_handler_unique(
- BSP_INTERRUPT_HANDLER_TABLE_SIZE,
+ BSP_INTERRUPT_DISPATCH_TABLE_SIZE,
ctx->initialized_during_setup
);
@@ -489,6 +539,11 @@ static void Action( void *arg )
&ctx->enabled_after
);
T_rsc_success( sc );
+
+ if ( ctx->status == RTEMS_SUCCESSFUL ) {
+ sc = RaiseSoftwareInterrupt( ctx->test_vector );
+ T_rsc_success( sc );
+ }
}
static void VisitInstalled(
@@ -940,7 +995,7 @@ static void RtemsIntrReqEntryInstall_Post_Enable_Check(
* The enabled status of the interrupt vector specified by ``vector``
* shall not be modified by the rtems_interrupt_entry_install() call.
*/
- if ( !ctx->interrupt_occurred ) {
+ if ( ctx->handler_counter == 0 ) {
T_eq( ctx->enabled_before, ctx->enabled_after );
}
break;
@@ -950,9 +1005,7 @@ static void RtemsIntrReqEntryInstall_Post_Enable_Check(
/*
* The interrupt vector specified by ``vector`` shall be enabled.
*/
- if ( ctx->attributes.can_enable ) {
- T_true( ctx->enabled_after || ctx->interrupt_occurred );
- }
+ T_true( ctx->enabled_after || ctx->handler_counter > 3 );
break;
}
@@ -960,10 +1013,13 @@ static void RtemsIntrReqEntryInstall_Post_Enable_Check(
/*
* The interrupt vector specified by ``vector`` may be enabled.
*/
- /* The comment of pre-condition ``CanEnable`` for the ``Yes`` state. */
- if ( ctx->attributes.can_enable ) {
- T_true( ctx->enabled_after || ctx->interrupt_occurred );
- }
+ /*
+ * Interrupt vectors which cannot be enabled are not selected as a
+ * testable interrupt vector by GetTestableInterruptVector(), so this
+ * path is not validated by this test. See also comment for
+ * ``CanEnable`` pre-condition state ``Yes``.
+ */
+ T_true( ctx->enabled_after || ctx->handler_counter > 3 );
break;
}
@@ -973,8 +1029,11 @@ static void RtemsIntrReqEntryInstall_Post_Enable_Check(
*/
/*
* Interrupt vectors which cannot be enabled are not selected as a
- * testable interrupt vector by GetTestableInterruptVector().
+ * testable interrupt vector by GetTestableInterruptVector(), so this
+ * path is not validated by this test. See also comment for
+ * ``CanEnable`` pre-condition state ``Yes``.
*/
+ T_true( ctx->enabled_after || ctx->handler_counter > 3 );
break;
}
@@ -998,6 +1057,24 @@ static void RtemsIntrReqEntryInstall_Post_Installed_Check(
);
T_rsc_success( sc );
+ if ( ctx->status == RTEMS_SUCCESSFUL ) {
+ uint32_t counter;
+
+ counter = 1;
+
+ if ( ctx->other_installed ) {
+ T_eq_u32( ctx->counter_by_entry[ 1 ], counter );
+ ++counter;
+ }
+
+ if ( ctx->third_installed ) {
+ T_eq_u32( ctx->counter_by_entry[ 2 ], counter );
+ ++counter;
+ }
+
+ T_eq_u32( ctx->counter_by_entry[ 0 ], counter );
+ }
+
switch ( state ) {
case RtemsIntrReqEntryInstall_Post_Installed_No: {
/*
@@ -1038,10 +1115,18 @@ static void RtemsIntrReqEntryInstall_Setup(
RtemsIntrReqEntryInstall_Context *ctx
)
{
+ rtems_interrupt_attributes required = {
+ .can_raise = true
+ };
rtems_status_code sc;
ctx->initialized_during_setup = bsp_interrupt_is_initialized();
- ctx->test_vector = GetTestableInterruptVector();
+ ctx->test_vector = GetTestableInterruptVector( &required );
+ ctx->test_vector_was_enabled = false;
+ (void) rtems_interrupt_vector_is_enabled(
+ ctx->test_vector,
+ &ctx->test_vector_was_enabled
+ );
sc = rtems_interrupt_get_attributes( ctx->test_vector, &ctx->attributes );
T_rsc_success( sc );
}
@@ -1055,11 +1140,35 @@ static void RtemsIntrReqEntryInstall_Setup_Wrap( void *arg )
RtemsIntrReqEntryInstall_Setup( ctx );
}
+static void RtemsIntrReqEntryInstall_Teardown(
+ RtemsIntrReqEntryInstall_Context *ctx
+)
+{
+ if ( ctx->test_vector_was_enabled ) {
+ (void) rtems_interrupt_vector_enable( ctx->test_vector );
+ }
+}
+
+static void RtemsIntrReqEntryInstall_Teardown_Wrap( void *arg )
+{
+ RtemsIntrReqEntryInstall_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsIntrReqEntryInstall_Teardown( ctx );
+}
+
static void RtemsIntrReqEntryInstall_Prepare(
RtemsIntrReqEntryInstall_Context *ctx
)
{
- ctx->interrupt_occurred = false;
+ size_t i;
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->counter_by_entry ); ++i ) {
+ ctx->counter_by_entry[ i ] = 0;
+ }
+
+ ctx->handler_counter = 0;
ctx->other_installed = false;
ctx->third_installed = false;
}
@@ -1236,7 +1345,7 @@ static size_t RtemsIntrReqEntryInstall_Scope( void *arg, char *buf, size_t n )
static T_fixture RtemsIntrReqEntryInstall_Fixture = {
.setup = RtemsIntrReqEntryInstall_Setup_Wrap,
.stop = NULL,
- .teardown = NULL,
+ .teardown = RtemsIntrReqEntryInstall_Teardown_Wrap,
.scope = RtemsIntrReqEntryInstall_Scope,
.initial_context = &RtemsIntrReqEntryInstall_Instance
};
@@ -1254,6 +1363,36 @@ static inline RtemsIntrReqEntryInstall_Entry RtemsIntrReqEntryInstall_PopEntry(
];
}
+static void RtemsIntrReqEntryInstall_SetPreConditionStates(
+ RtemsIntrReqEntryInstall_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+
+ if ( ctx->Map.entry.Pre_Routine_NA ) {
+ ctx->Map.pcs[ 3 ] = RtemsIntrReqEntryInstall_Pre_Routine_NA;
+ } else {
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ }
+
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+ ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
+
+ if ( ctx->Map.entry.Pre_CanEnable_NA ) {
+ ctx->Map.pcs[ 6 ] = RtemsIntrReqEntryInstall_Pre_CanEnable_NA;
+ } else {
+ ctx->Map.pcs[ 6 ] = ctx->Map.pci[ 6 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Installed_NA ) {
+ ctx->Map.pcs[ 7 ] = RtemsIntrReqEntryInstall_Pre_Installed_NA;
+ } else {
+ ctx->Map.pcs[ 7 ] = ctx->Map.pci[ 7 ];
+ }
+}
+
static void RtemsIntrReqEntryInstall_TestVariant(
RtemsIntrReqEntryInstall_Context *ctx
)
@@ -1261,20 +1400,11 @@ static void RtemsIntrReqEntryInstall_TestVariant(
RtemsIntrReqEntryInstall_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsIntrReqEntryInstall_Pre_Options_Prepare( ctx, ctx->Map.pcs[ 1 ] );
RtemsIntrReqEntryInstall_Pre_Entry_Prepare( ctx, ctx->Map.pcs[ 2 ] );
- RtemsIntrReqEntryInstall_Pre_Routine_Prepare(
- ctx,
- ctx->Map.entry.Pre_Routine_NA ? RtemsIntrReqEntryInstall_Pre_Routine_NA : ctx->Map.pcs[ 3 ]
- );
+ RtemsIntrReqEntryInstall_Pre_Routine_Prepare( ctx, ctx->Map.pcs[ 3 ] );
RtemsIntrReqEntryInstall_Pre_Init_Prepare( ctx, ctx->Map.pcs[ 4 ] );
RtemsIntrReqEntryInstall_Pre_ISR_Prepare( ctx, ctx->Map.pcs[ 5 ] );
- RtemsIntrReqEntryInstall_Pre_CanEnable_Prepare(
- ctx,
- ctx->Map.entry.Pre_CanEnable_NA ? RtemsIntrReqEntryInstall_Pre_CanEnable_NA : ctx->Map.pcs[ 6 ]
- );
- RtemsIntrReqEntryInstall_Pre_Installed_Prepare(
- ctx,
- ctx->Map.entry.Pre_Installed_NA ? RtemsIntrReqEntryInstall_Pre_Installed_NA : ctx->Map.pcs[ 7 ]
- );
+ RtemsIntrReqEntryInstall_Pre_CanEnable_Prepare( ctx, ctx->Map.pcs[ 6 ] );
+ RtemsIntrReqEntryInstall_Pre_Installed_Prepare( ctx, ctx->Map.pcs[ 7 ] );
RtemsIntrReqEntryInstall_Action( ctx );
RtemsIntrReqEntryInstall_Post_Status_Check(
ctx,
@@ -1305,46 +1435,47 @@ T_TEST_CASE_FIXTURE(
ctx->Map.index = 0;
for (
- ctx->Map.pcs[ 0 ] = RtemsIntrReqEntryInstall_Pre_Vector_Valid;
- ctx->Map.pcs[ 0 ] < RtemsIntrReqEntryInstall_Pre_Vector_NA;
- ++ctx->Map.pcs[ 0 ]
+ ctx->Map.pci[ 0 ] = RtemsIntrReqEntryInstall_Pre_Vector_Valid;
+ ctx->Map.pci[ 0 ] < RtemsIntrReqEntryInstall_Pre_Vector_NA;
+ ++ctx->Map.pci[ 0 ]
) {
for (
- ctx->Map.pcs[ 1 ] = RtemsIntrReqEntryInstall_Pre_Options_Unique;
- ctx->Map.pcs[ 1 ] < RtemsIntrReqEntryInstall_Pre_Options_NA;
- ++ctx->Map.pcs[ 1 ]
+ ctx->Map.pci[ 1 ] = RtemsIntrReqEntryInstall_Pre_Options_Unique;
+ ctx->Map.pci[ 1 ] < RtemsIntrReqEntryInstall_Pre_Options_NA;
+ ++ctx->Map.pci[ 1 ]
) {
for (
- ctx->Map.pcs[ 2 ] = RtemsIntrReqEntryInstall_Pre_Entry_Obj;
- ctx->Map.pcs[ 2 ] < RtemsIntrReqEntryInstall_Pre_Entry_NA;
- ++ctx->Map.pcs[ 2 ]
+ ctx->Map.pci[ 2 ] = RtemsIntrReqEntryInstall_Pre_Entry_Obj;
+ ctx->Map.pci[ 2 ] < RtemsIntrReqEntryInstall_Pre_Entry_NA;
+ ++ctx->Map.pci[ 2 ]
) {
for (
- ctx->Map.pcs[ 3 ] = RtemsIntrReqEntryInstall_Pre_Routine_Valid;
- ctx->Map.pcs[ 3 ] < RtemsIntrReqEntryInstall_Pre_Routine_NA;
- ++ctx->Map.pcs[ 3 ]
+ ctx->Map.pci[ 3 ] = RtemsIntrReqEntryInstall_Pre_Routine_Valid;
+ ctx->Map.pci[ 3 ] < RtemsIntrReqEntryInstall_Pre_Routine_NA;
+ ++ctx->Map.pci[ 3 ]
) {
for (
- ctx->Map.pcs[ 4 ] = RtemsIntrReqEntryInstall_Pre_Init_Yes;
- ctx->Map.pcs[ 4 ] < RtemsIntrReqEntryInstall_Pre_Init_NA;
- ++ctx->Map.pcs[ 4 ]
+ ctx->Map.pci[ 4 ] = RtemsIntrReqEntryInstall_Pre_Init_Yes;
+ ctx->Map.pci[ 4 ] < RtemsIntrReqEntryInstall_Pre_Init_NA;
+ ++ctx->Map.pci[ 4 ]
) {
for (
- ctx->Map.pcs[ 5 ] = RtemsIntrReqEntryInstall_Pre_ISR_Yes;
- ctx->Map.pcs[ 5 ] < RtemsIntrReqEntryInstall_Pre_ISR_NA;
- ++ctx->Map.pcs[ 5 ]
+ ctx->Map.pci[ 5 ] = RtemsIntrReqEntryInstall_Pre_ISR_Yes;
+ ctx->Map.pci[ 5 ] < RtemsIntrReqEntryInstall_Pre_ISR_NA;
+ ++ctx->Map.pci[ 5 ]
) {
for (
- ctx->Map.pcs[ 6 ] = RtemsIntrReqEntryInstall_Pre_CanEnable_Yes;
- ctx->Map.pcs[ 6 ] < RtemsIntrReqEntryInstall_Pre_CanEnable_NA;
- ++ctx->Map.pcs[ 6 ]
+ ctx->Map.pci[ 6 ] = RtemsIntrReqEntryInstall_Pre_CanEnable_Yes;
+ ctx->Map.pci[ 6 ] < RtemsIntrReqEntryInstall_Pre_CanEnable_NA;
+ ++ctx->Map.pci[ 6 ]
) {
for (
- ctx->Map.pcs[ 7 ] = RtemsIntrReqEntryInstall_Pre_Installed_None;
- ctx->Map.pcs[ 7 ] < RtemsIntrReqEntryInstall_Pre_Installed_NA;
- ++ctx->Map.pcs[ 7 ]
+ ctx->Map.pci[ 7 ] = RtemsIntrReqEntryInstall_Pre_Installed_None;
+ ctx->Map.pci[ 7 ] < RtemsIntrReqEntryInstall_Pre_Installed_NA;
+ ++ctx->Map.pci[ 7 ]
) {
ctx->Map.entry = RtemsIntrReqEntryInstall_PopEntry( ctx );
+ RtemsIntrReqEntryInstall_SetPreConditionStates( ctx );
RtemsIntrReqEntryInstall_Prepare( ctx );
RtemsIntrReqEntryInstall_TestVariant( ctx );
RtemsIntrReqEntryInstall_Cleanup( ctx );
diff --git a/testsuites/validation/tc-intr-entry-remove.c b/testsuites/validation/tc-intr-entry-remove.c
index 65cbbb28d3..01a72410e1 100644
--- a/testsuites/validation/tc-intr-entry-remove.c
+++ b/testsuites/validation/tc-intr-entry-remove.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsIntrReqEntryRemove
+ * @ingroup RtemsIntrReqEntryRemove
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -60,10 +60,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsIntrReqEntryRemove \
- * spec:/rtems/intr/req/entry-remove
+ * @defgroup RtemsIntrReqEntryRemove spec:/rtems/intr/req/entry-remove
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationIntr
*
* @{
*/
@@ -182,7 +181,7 @@ typedef struct {
/**
* @brief This member provides a counter incremented by EntryRoutine().
*/
- uint32_t entry_counter;;
+ uint32_t entry_counter;
/**
* @brief This member provides another rtems_interrupt_entry object.
@@ -234,6 +233,12 @@ typedef struct {
rtems_vector_number test_vector;
/**
+ * @brief If this member is true, then the testable interrupt vector was
+ * enabled at the test case begin.
+ */
+ bool test_vector_was_enabled;
+
+ /**
* @brief This member provides the attributes of the testable interrupt
* vector.
*/
@@ -280,7 +285,7 @@ typedef struct {
/**
* @brief This member specifies if the ``entry`` parameter value.
*/
- rtems_interrupt_entry *entry;;
+ rtems_interrupt_entry *entry;
/**
* @brief This member contains the return value of the
@@ -290,6 +295,12 @@ typedef struct {
struct {
/**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 9 ];
+
+ /**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 9 ];
@@ -467,14 +478,14 @@ static void Action( void *arg )
T_rsc_success( sc );
bsp_interrupt_set_handler_unique(
- BSP_INTERRUPT_HANDLER_TABLE_SIZE,
+ BSP_INTERRUPT_DISPATCH_TABLE_SIZE,
ctx->initialized
);
ctx->status = rtems_interrupt_entry_remove( ctx->vector, ctx->entry );
bsp_interrupt_set_handler_unique(
- BSP_INTERRUPT_HANDLER_TABLE_SIZE,
+ BSP_INTERRUPT_DISPATCH_TABLE_SIZE,
ctx->initialized_during_setup
);
@@ -1023,13 +1034,13 @@ static void RtemsIntrReqEntryRemove_Post_Installed_Check(
if ( expected_entries > 0 ) {
ctx->entry_counter = 0;
- bsp_interrupt_handler_dispatch( ctx->test_vector );
+ bsp_interrupt_handler_dispatch_unchecked( ctx->test_vector );
T_eq_u32( ctx->entry_counter, 0 );
} else {
rtems_interrupt_entry *first;
- first = bsp_interrupt_handler_table[
- bsp_interrupt_handler_index( ctx->test_vector )
+ first = bsp_interrupt_dispatch_table[
+ bsp_interrupt_dispatch_index( ctx->test_vector )
];
T_null( first );
}
@@ -1063,7 +1074,7 @@ static void RtemsIntrReqEntryRemove_Post_Installed_Check(
if ( ctx->installed ) {
ctx->entry_counter = 0;
- bsp_interrupt_handler_dispatch( ctx->test_vector );
+ bsp_interrupt_handler_dispatch_unchecked( ctx->test_vector );
T_eq_u32( ctx->entry_counter, 1 );
}
break;
@@ -1081,7 +1092,12 @@ static void RtemsIntrReqEntryRemove_Setup(
rtems_status_code sc;
ctx->initialized_during_setup = bsp_interrupt_is_initialized();
- ctx->test_vector = GetTestableInterruptVector();
+ ctx->test_vector = GetTestableInterruptVector( NULL );
+ ctx->test_vector_was_enabled = false;
+ (void) rtems_interrupt_vector_is_enabled(
+ ctx->test_vector,
+ &ctx->test_vector_was_enabled
+ );
sc = rtems_interrupt_get_attributes( ctx->test_vector, &ctx->attributes );
T_rsc_success( sc );
}
@@ -1095,6 +1111,24 @@ static void RtemsIntrReqEntryRemove_Setup_Wrap( void *arg )
RtemsIntrReqEntryRemove_Setup( ctx );
}
+static void RtemsIntrReqEntryRemove_Teardown(
+ RtemsIntrReqEntryRemove_Context *ctx
+)
+{
+ if ( ctx->test_vector_was_enabled ) {
+ (void) rtems_interrupt_vector_enable( ctx->test_vector );
+ }
+}
+
+static void RtemsIntrReqEntryRemove_Teardown_Wrap( void *arg )
+{
+ RtemsIntrReqEntryRemove_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsIntrReqEntryRemove_Teardown( ctx );
+}
+
static void RtemsIntrReqEntryRemove_Prepare(
RtemsIntrReqEntryRemove_Context *ctx
)
@@ -1286,7 +1320,7 @@ static size_t RtemsIntrReqEntryRemove_Scope( void *arg, char *buf, size_t n )
static T_fixture RtemsIntrReqEntryRemove_Fixture = {
.setup = RtemsIntrReqEntryRemove_Setup_Wrap,
.stop = NULL,
- .teardown = NULL,
+ .teardown = RtemsIntrReqEntryRemove_Teardown_Wrap,
.scope = RtemsIntrReqEntryRemove_Scope,
.initial_context = &RtemsIntrReqEntryRemove_Instance
};
@@ -1304,34 +1338,60 @@ static inline RtemsIntrReqEntryRemove_Entry RtemsIntrReqEntryRemove_PopEntry(
];
}
+static void RtemsIntrReqEntryRemove_SetPreConditionStates(
+ RtemsIntrReqEntryRemove_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+
+ if ( ctx->Map.entry.Pre_Routine_NA ) {
+ ctx->Map.pcs[ 2 ] = RtemsIntrReqEntryRemove_Pre_Routine_NA;
+ } else {
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ }
+
+ if ( ctx->Map.entry.Pre_EntryObj_NA ) {
+ ctx->Map.pcs[ 3 ] = RtemsIntrReqEntryRemove_Pre_EntryObj_NA;
+ } else {
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ }
+
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+ ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
+
+ if ( ctx->Map.entry.Pre_CanDisable_NA ) {
+ ctx->Map.pcs[ 6 ] = RtemsIntrReqEntryRemove_Pre_CanDisable_NA;
+ } else {
+ ctx->Map.pcs[ 6 ] = ctx->Map.pci[ 6 ];
+ }
+
+ if ( ctx->Map.entry.Pre_First_NA ) {
+ ctx->Map.pcs[ 7 ] = RtemsIntrReqEntryRemove_Pre_First_NA;
+ } else {
+ ctx->Map.pcs[ 7 ] = ctx->Map.pci[ 7 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Last_NA ) {
+ ctx->Map.pcs[ 8 ] = RtemsIntrReqEntryRemove_Pre_Last_NA;
+ } else {
+ ctx->Map.pcs[ 8 ] = ctx->Map.pci[ 8 ];
+ }
+}
+
static void RtemsIntrReqEntryRemove_TestVariant(
RtemsIntrReqEntryRemove_Context *ctx
)
{
RtemsIntrReqEntryRemove_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsIntrReqEntryRemove_Pre_Entry_Prepare( ctx, ctx->Map.pcs[ 1 ] );
- RtemsIntrReqEntryRemove_Pre_Routine_Prepare(
- ctx,
- ctx->Map.entry.Pre_Routine_NA ? RtemsIntrReqEntryRemove_Pre_Routine_NA : ctx->Map.pcs[ 2 ]
- );
- RtemsIntrReqEntryRemove_Pre_EntryObj_Prepare(
- ctx,
- ctx->Map.entry.Pre_EntryObj_NA ? RtemsIntrReqEntryRemove_Pre_EntryObj_NA : ctx->Map.pcs[ 3 ]
- );
+ RtemsIntrReqEntryRemove_Pre_Routine_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsIntrReqEntryRemove_Pre_EntryObj_Prepare( ctx, ctx->Map.pcs[ 3 ] );
RtemsIntrReqEntryRemove_Pre_Init_Prepare( ctx, ctx->Map.pcs[ 4 ] );
RtemsIntrReqEntryRemove_Pre_ISR_Prepare( ctx, ctx->Map.pcs[ 5 ] );
- RtemsIntrReqEntryRemove_Pre_CanDisable_Prepare(
- ctx,
- ctx->Map.entry.Pre_CanDisable_NA ? RtemsIntrReqEntryRemove_Pre_CanDisable_NA : ctx->Map.pcs[ 6 ]
- );
- RtemsIntrReqEntryRemove_Pre_First_Prepare(
- ctx,
- ctx->Map.entry.Pre_First_NA ? RtemsIntrReqEntryRemove_Pre_First_NA : ctx->Map.pcs[ 7 ]
- );
- RtemsIntrReqEntryRemove_Pre_Last_Prepare(
- ctx,
- ctx->Map.entry.Pre_Last_NA ? RtemsIntrReqEntryRemove_Pre_Last_NA : ctx->Map.pcs[ 8 ]
- );
+ RtemsIntrReqEntryRemove_Pre_CanDisable_Prepare( ctx, ctx->Map.pcs[ 6 ] );
+ RtemsIntrReqEntryRemove_Pre_First_Prepare( ctx, ctx->Map.pcs[ 7 ] );
+ RtemsIntrReqEntryRemove_Pre_Last_Prepare( ctx, ctx->Map.pcs[ 8 ] );
RtemsIntrReqEntryRemove_Action( ctx );
RtemsIntrReqEntryRemove_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
RtemsIntrReqEntryRemove_Post_Disabled_Check(
@@ -1359,51 +1419,52 @@ T_TEST_CASE_FIXTURE(
ctx->Map.index = 0;
for (
- ctx->Map.pcs[ 0 ] = RtemsIntrReqEntryRemove_Pre_Vector_Valid;
- ctx->Map.pcs[ 0 ] < RtemsIntrReqEntryRemove_Pre_Vector_NA;
- ++ctx->Map.pcs[ 0 ]
+ ctx->Map.pci[ 0 ] = RtemsIntrReqEntryRemove_Pre_Vector_Valid;
+ ctx->Map.pci[ 0 ] < RtemsIntrReqEntryRemove_Pre_Vector_NA;
+ ++ctx->Map.pci[ 0 ]
) {
for (
- ctx->Map.pcs[ 1 ] = RtemsIntrReqEntryRemove_Pre_Entry_Obj;
- ctx->Map.pcs[ 1 ] < RtemsIntrReqEntryRemove_Pre_Entry_NA;
- ++ctx->Map.pcs[ 1 ]
+ ctx->Map.pci[ 1 ] = RtemsIntrReqEntryRemove_Pre_Entry_Obj;
+ ctx->Map.pci[ 1 ] < RtemsIntrReqEntryRemove_Pre_Entry_NA;
+ ++ctx->Map.pci[ 1 ]
) {
for (
- ctx->Map.pcs[ 2 ] = RtemsIntrReqEntryRemove_Pre_Routine_Valid;
- ctx->Map.pcs[ 2 ] < RtemsIntrReqEntryRemove_Pre_Routine_NA;
- ++ctx->Map.pcs[ 2 ]
+ ctx->Map.pci[ 2 ] = RtemsIntrReqEntryRemove_Pre_Routine_Valid;
+ ctx->Map.pci[ 2 ] < RtemsIntrReqEntryRemove_Pre_Routine_NA;
+ ++ctx->Map.pci[ 2 ]
) {
for (
- ctx->Map.pcs[ 3 ] = RtemsIntrReqEntryRemove_Pre_EntryObj_Installed;
- ctx->Map.pcs[ 3 ] < RtemsIntrReqEntryRemove_Pre_EntryObj_NA;
- ++ctx->Map.pcs[ 3 ]
+ ctx->Map.pci[ 3 ] = RtemsIntrReqEntryRemove_Pre_EntryObj_Installed;
+ ctx->Map.pci[ 3 ] < RtemsIntrReqEntryRemove_Pre_EntryObj_NA;
+ ++ctx->Map.pci[ 3 ]
) {
for (
- ctx->Map.pcs[ 4 ] = RtemsIntrReqEntryRemove_Pre_Init_Yes;
- ctx->Map.pcs[ 4 ] < RtemsIntrReqEntryRemove_Pre_Init_NA;
- ++ctx->Map.pcs[ 4 ]
+ ctx->Map.pci[ 4 ] = RtemsIntrReqEntryRemove_Pre_Init_Yes;
+ ctx->Map.pci[ 4 ] < RtemsIntrReqEntryRemove_Pre_Init_NA;
+ ++ctx->Map.pci[ 4 ]
) {
for (
- ctx->Map.pcs[ 5 ] = RtemsIntrReqEntryRemove_Pre_ISR_Yes;
- ctx->Map.pcs[ 5 ] < RtemsIntrReqEntryRemove_Pre_ISR_NA;
- ++ctx->Map.pcs[ 5 ]
+ ctx->Map.pci[ 5 ] = RtemsIntrReqEntryRemove_Pre_ISR_Yes;
+ ctx->Map.pci[ 5 ] < RtemsIntrReqEntryRemove_Pre_ISR_NA;
+ ++ctx->Map.pci[ 5 ]
) {
for (
- ctx->Map.pcs[ 6 ] = RtemsIntrReqEntryRemove_Pre_CanDisable_Yes;
- ctx->Map.pcs[ 6 ] < RtemsIntrReqEntryRemove_Pre_CanDisable_NA;
- ++ctx->Map.pcs[ 6 ]
+ ctx->Map.pci[ 6 ] = RtemsIntrReqEntryRemove_Pre_CanDisable_Yes;
+ ctx->Map.pci[ 6 ] < RtemsIntrReqEntryRemove_Pre_CanDisable_NA;
+ ++ctx->Map.pci[ 6 ]
) {
for (
- ctx->Map.pcs[ 7 ] = RtemsIntrReqEntryRemove_Pre_First_Yes;
- ctx->Map.pcs[ 7 ] < RtemsIntrReqEntryRemove_Pre_First_NA;
- ++ctx->Map.pcs[ 7 ]
+ ctx->Map.pci[ 7 ] = RtemsIntrReqEntryRemove_Pre_First_Yes;
+ ctx->Map.pci[ 7 ] < RtemsIntrReqEntryRemove_Pre_First_NA;
+ ++ctx->Map.pci[ 7 ]
) {
for (
- ctx->Map.pcs[ 8 ] = RtemsIntrReqEntryRemove_Pre_Last_Yes;
- ctx->Map.pcs[ 8 ] < RtemsIntrReqEntryRemove_Pre_Last_NA;
- ++ctx->Map.pcs[ 8 ]
+ ctx->Map.pci[ 8 ] = RtemsIntrReqEntryRemove_Pre_Last_Yes;
+ ctx->Map.pci[ 8 ] < RtemsIntrReqEntryRemove_Pre_Last_NA;
+ ++ctx->Map.pci[ 8 ]
) {
ctx->Map.entry = RtemsIntrReqEntryRemove_PopEntry( ctx );
+ RtemsIntrReqEntryRemove_SetPreConditionStates( ctx );
RtemsIntrReqEntryRemove_Prepare( ctx );
RtemsIntrReqEntryRemove_TestVariant( ctx );
RtemsIntrReqEntryRemove_Cleanup( ctx );
diff --git a/testsuites/validation/tc-intr-get-affinity.c b/testsuites/validation/tc-intr-get-affinity.c
index 375a131a05..60509203b4 100644
--- a/testsuites/validation/tc-intr-get-affinity.c
+++ b/testsuites/validation/tc-intr-get-affinity.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsIntrReqGetAffinity
+ * @ingroup RtemsIntrReqGetAffinity
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -61,10 +61,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsIntrReqGetAffinity \
- * spec:/rtems/intr/req/get-affinity
+ * @defgroup RtemsIntrReqGetAffinity spec:/rtems/intr/req/get-affinity
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationIntr
*
* @{
*/
@@ -139,7 +138,7 @@ typedef struct {
* @brief This member provides the object referenced by the ``affinity``
* parameter.
*/
- cpu_set_t cpuset_obj[ 2 ];;
+ cpu_set_t cpuset_obj[ 2 ];
/**
* @brief This member contains the return value of the
@@ -165,6 +164,12 @@ typedef struct {
struct {
/**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 4 ];
+
+ /**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 4 ];
@@ -238,6 +243,9 @@ static void CheckGetAffinity(
rtems_status_code sc;
cpu_set_t set[ 2 ];
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Warray-bounds"
+
if ( attr->can_get_affinity ) {
CPU_ZERO_S( sizeof( ctx->cpuset_obj ), ctx->cpuset_obj );
} else {
@@ -259,6 +267,8 @@ static void CheckGetAffinity(
T_rsc( sc, RTEMS_UNSATISFIED );
T_true( CPU_EQUAL_S( sizeof( set ), ctx->cpuset_obj, set ) );
}
+
+ #pragma GCC diagnostic pop
}
static void RtemsIntrReqGetAffinity_Pre_Vector_Prepare(
@@ -559,6 +569,9 @@ static void RtemsIntrReqGetAffinity_Action(
ctx->vector = BSP_INTERRUPT_VECTOR_COUNT;
}
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Warray-bounds"
+
CPU_FILL_S( sizeof( ctx->cpuset_obj ), ctx->cpuset_obj );
ctx->status = rtems_interrupt_get_affinity(
@@ -577,6 +590,8 @@ static void RtemsIntrReqGetAffinity_Action(
}
T_true( CPU_EQUAL_S( sizeof( set ), ctx->cpuset_obj, set ) );
+
+ #pragma GCC diagnostic pop
}
}
@@ -642,6 +657,21 @@ static inline RtemsIntrReqGetAffinity_Entry RtemsIntrReqGetAffinity_PopEntry(
];
}
+static void RtemsIntrReqGetAffinity_SetPreConditionStates(
+ RtemsIntrReqGetAffinity_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+
+ if ( ctx->Map.entry.Pre_CanGetAffinity_NA ) {
+ ctx->Map.pcs[ 3 ] = RtemsIntrReqGetAffinity_Pre_CanGetAffinity_NA;
+ } else {
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ }
+}
+
static void RtemsIntrReqGetAffinity_TestVariant(
RtemsIntrReqGetAffinity_Context *ctx
)
@@ -649,10 +679,7 @@ static void RtemsIntrReqGetAffinity_TestVariant(
RtemsIntrReqGetAffinity_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsIntrReqGetAffinity_Pre_CPUSetSize_Prepare( ctx, ctx->Map.pcs[ 1 ] );
RtemsIntrReqGetAffinity_Pre_CPUSet_Prepare( ctx, ctx->Map.pcs[ 2 ] );
- RtemsIntrReqGetAffinity_Pre_CanGetAffinity_Prepare(
- ctx,
- ctx->Map.entry.Pre_CanGetAffinity_NA ? RtemsIntrReqGetAffinity_Pre_CanGetAffinity_NA : ctx->Map.pcs[ 3 ]
- );
+ RtemsIntrReqGetAffinity_Pre_CanGetAffinity_Prepare( ctx, ctx->Map.pcs[ 3 ] );
RtemsIntrReqGetAffinity_Action( ctx );
RtemsIntrReqGetAffinity_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
RtemsIntrReqGetAffinity_Post_CPUSetObj_Check(
@@ -676,26 +703,27 @@ T_TEST_CASE_FIXTURE(
ctx->Map.index = 0;
for (
- ctx->Map.pcs[ 0 ] = RtemsIntrReqGetAffinity_Pre_Vector_Valid;
- ctx->Map.pcs[ 0 ] < RtemsIntrReqGetAffinity_Pre_Vector_NA;
- ++ctx->Map.pcs[ 0 ]
+ ctx->Map.pci[ 0 ] = RtemsIntrReqGetAffinity_Pre_Vector_Valid;
+ ctx->Map.pci[ 0 ] < RtemsIntrReqGetAffinity_Pre_Vector_NA;
+ ++ctx->Map.pci[ 0 ]
) {
for (
- ctx->Map.pcs[ 1 ] = RtemsIntrReqGetAffinity_Pre_CPUSetSize_Valid;
- ctx->Map.pcs[ 1 ] < RtemsIntrReqGetAffinity_Pre_CPUSetSize_NA;
- ++ctx->Map.pcs[ 1 ]
+ ctx->Map.pci[ 1 ] = RtemsIntrReqGetAffinity_Pre_CPUSetSize_Valid;
+ ctx->Map.pci[ 1 ] < RtemsIntrReqGetAffinity_Pre_CPUSetSize_NA;
+ ++ctx->Map.pci[ 1 ]
) {
for (
- ctx->Map.pcs[ 2 ] = RtemsIntrReqGetAffinity_Pre_CPUSet_Valid;
- ctx->Map.pcs[ 2 ] < RtemsIntrReqGetAffinity_Pre_CPUSet_NA;
- ++ctx->Map.pcs[ 2 ]
+ ctx->Map.pci[ 2 ] = RtemsIntrReqGetAffinity_Pre_CPUSet_Valid;
+ ctx->Map.pci[ 2 ] < RtemsIntrReqGetAffinity_Pre_CPUSet_NA;
+ ++ctx->Map.pci[ 2 ]
) {
for (
- ctx->Map.pcs[ 3 ] = RtemsIntrReqGetAffinity_Pre_CanGetAffinity_Yes;
- ctx->Map.pcs[ 3 ] < RtemsIntrReqGetAffinity_Pre_CanGetAffinity_NA;
- ++ctx->Map.pcs[ 3 ]
+ ctx->Map.pci[ 3 ] = RtemsIntrReqGetAffinity_Pre_CanGetAffinity_Yes;
+ ctx->Map.pci[ 3 ] < RtemsIntrReqGetAffinity_Pre_CanGetAffinity_NA;
+ ++ctx->Map.pci[ 3 ]
) {
ctx->Map.entry = RtemsIntrReqGetAffinity_PopEntry( ctx );
+ RtemsIntrReqGetAffinity_SetPreConditionStates( ctx );
RtemsIntrReqGetAffinity_TestVariant( ctx );
}
}
diff --git a/testsuites/validation/tc-intr-get-attributes.c b/testsuites/validation/tc-intr-get-attributes.c
index f64eef1563..4594c78a2e 100644
--- a/testsuites/validation/tc-intr-get-attributes.c
+++ b/testsuites/validation/tc-intr-get-attributes.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsIntrReqGetAttributes
+ * @ingroup RtemsIntrReqGetAttributes
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -59,10 +59,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsIntrReqGetAttributes \
- * spec:/rtems/intr/req/get-attributes
+ * @defgroup RtemsIntrReqGetAttributes spec:/rtems/intr/req/get-attributes
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationIntr
*
* @{
*/
@@ -119,7 +118,7 @@ typedef struct {
/**
* @brief This member specifies if the ``attributes`` parameter value.
*/
- rtems_interrupt_attributes *attributes;;
+ rtems_interrupt_attributes *attributes;
/**
* @brief This member contains the return value of the
diff --git a/testsuites/validation/tc-intr-handler-iterate.c b/testsuites/validation/tc-intr-handler-iterate.c
index 2014e829bf..fc3f498838 100644
--- a/testsuites/validation/tc-intr-handler-iterate.c
+++ b/testsuites/validation/tc-intr-handler-iterate.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsIntrReqHandlerIterate
+ * @ingroup RtemsIntrReqHandlerIterate
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -60,10 +60,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsIntrReqHandlerIterate \
- * spec:/rtems/intr/req/handler-iterate
+ * @defgroup RtemsIntrReqHandlerIterate spec:/rtems/intr/req/handler-iterate
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationIntr
*
* @{
*/
@@ -134,6 +133,12 @@ typedef struct {
rtems_vector_number test_vector;
/**
+ * @brief If this member is true, then the testable interrupt vector was
+ * enabled at the test case begin.
+ */
+ bool test_vector_was_enabled;
+
+ /**
* @brief If this member is true, then the service shall be initialized.
*/
bool initialized;
@@ -282,7 +287,7 @@ static void Action( void *arg )
ctx->visited_entries = 0;
bsp_interrupt_set_handler_unique(
- BSP_INTERRUPT_HANDLER_TABLE_SIZE,
+ BSP_INTERRUPT_DISPATCH_TABLE_SIZE,
ctx->initialized
);
@@ -293,7 +298,7 @@ static void Action( void *arg )
);
bsp_interrupt_set_handler_unique(
- BSP_INTERRUPT_HANDLER_TABLE_SIZE,
+ BSP_INTERRUPT_DISPATCH_TABLE_SIZE,
ctx->initialized_during_setup
);
}
@@ -505,7 +510,12 @@ static void RtemsIntrReqHandlerIterate_Setup(
rtems_status_code sc;
ctx->initialized_during_setup = bsp_interrupt_is_initialized();
- ctx->test_vector = GetTestableInterruptVector();
+ ctx->test_vector = GetTestableInterruptVector( NULL );
+ ctx->test_vector_was_enabled = false;
+ (void) rtems_interrupt_vector_is_enabled(
+ ctx->test_vector,
+ &ctx->test_vector_was_enabled
+ );
rtems_interrupt_entry_initialize(
&ctx->entry,
EntryRoutine,
@@ -529,6 +539,32 @@ static void RtemsIntrReqHandlerIterate_Setup_Wrap( void *arg )
RtemsIntrReqHandlerIterate_Setup( ctx );
}
+static void RtemsIntrReqHandlerIterate_Teardown(
+ RtemsIntrReqHandlerIterate_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ sc = rtems_interrupt_entry_remove(
+ ctx->test_vector,
+ &ctx->entry
+ );
+ T_rsc_success( sc );
+
+ if ( ctx->test_vector_was_enabled ) {
+ (void) rtems_interrupt_vector_enable( ctx->test_vector );
+ }
+}
+
+static void RtemsIntrReqHandlerIterate_Teardown_Wrap( void *arg )
+{
+ RtemsIntrReqHandlerIterate_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsIntrReqHandlerIterate_Teardown( ctx );
+}
+
static void RtemsIntrReqHandlerIterate_Action(
RtemsIntrReqHandlerIterate_Context *ctx
)
@@ -586,7 +622,7 @@ static size_t RtemsIntrReqHandlerIterate_Scope(
static T_fixture RtemsIntrReqHandlerIterate_Fixture = {
.setup = RtemsIntrReqHandlerIterate_Setup_Wrap,
.stop = NULL,
- .teardown = NULL,
+ .teardown = RtemsIntrReqHandlerIterate_Teardown_Wrap,
.scope = RtemsIntrReqHandlerIterate_Scope,
.initial_context = &RtemsIntrReqHandlerIterate_Instance
};
diff --git a/testsuites/validation/tc-intr-is-pending.c b/testsuites/validation/tc-intr-is-pending.c
index 4963827538..097e3d7a17 100644
--- a/testsuites/validation/tc-intr-is-pending.c
+++ b/testsuites/validation/tc-intr-is-pending.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsIntrReqIsPending
+ * @ingroup RtemsIntrReqIsPending
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -61,9 +61,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsIntrReqIsPending spec:/rtems/intr/req/is-pending
+ * @defgroup RtemsIntrReqIsPending spec:/rtems/intr/req/is-pending
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationIntr
*
* @{
*/
@@ -142,7 +142,7 @@ typedef struct {
/**
* @brief This member specifies if the ``pending`` parameter value.
*/
- bool *pending;;
+ bool *pending;
/**
* @brief This member contains the return value of the
@@ -152,6 +152,12 @@ typedef struct {
struct {
/**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 3 ];
+
+ /**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 3 ];
@@ -284,14 +290,21 @@ static void CheckIsPending(
if ( has_installed_entries ) {
/*
* We cannot test this vector thoroughly, since it is used by a device
- * driver.
+ * driver. It may be pending or not. For example in SMP configurations,
+ * it may be pending while being serviced right now on another processor.
*/
- T_false( IsPending( ctx ) );
+ (void) IsPending( ctx );
} else if ( !attr->is_maskable ) {
/* We can only safely test maskable interrupts */
T_false( IsPending( ctx ) );
+ } else if ( IsPending( ctx ) ) {
+ /*
+ * If there is already an interrupt pending, then it is probably raised
+ * by a peripheral which we cannot control.
+ */
} else if (
- attr->can_disable && ( attr->can_clear || attr->cleared_by_acknowledge )
+ attr->can_raise && attr->can_disable &&
+ ( attr->can_clear || attr->cleared_by_acknowledge )
) {
rtems_interrupt_entry entry;
rtems_interrupt_level level;
@@ -307,19 +320,21 @@ static void CheckIsPending(
T_rsc_success( sc );
if ( !IsPending( ctx) && ( attr->can_enable || IsEnabled( ctx ) ) ) {
- if ( attr->can_disable ) {
- Disable( ctx );
- Raise( ctx );
- T_true( IsPending( ctx ) );
-
- sc = rtems_interrupt_vector_enable( ctx->vector );
- T_rsc_success( sc );
-
- while ( ctx->interrupt_count < 1 ) {
- /* Wait */
- }
- } else {
- ++ctx->interrupt_count;
+ Disable( ctx );
+ Raise( ctx );
+
+ /*
+ * Some interrupt controllers will signal a pending interrupt if it is
+ * disabled (for example ARM GIC), others will not signal a pending
+ * interrupt if it is disabled (for example Freescale/NXP MPIC).
+ */
+ (void) IsPending( ctx );
+
+ sc = rtems_interrupt_vector_enable( ctx->vector );
+ T_rsc_success( sc );
+
+ while ( ctx->interrupt_count < 1 ) {
+ /* Wait */
}
rtems_interrupt_local_disable( level );
@@ -593,16 +608,27 @@ static inline RtemsIntrReqIsPending_Entry RtemsIntrReqIsPending_PopEntry(
];
}
+static void RtemsIntrReqIsPending_SetPreConditionStates(
+ RtemsIntrReqIsPending_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+
+ if ( ctx->Map.entry.Pre_IsPending_NA ) {
+ ctx->Map.pcs[ 2 ] = RtemsIntrReqIsPending_Pre_IsPending_NA;
+ } else {
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ }
+}
+
static void RtemsIntrReqIsPending_TestVariant(
RtemsIntrReqIsPending_Context *ctx
)
{
RtemsIntrReqIsPending_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsIntrReqIsPending_Pre_Pending_Prepare( ctx, ctx->Map.pcs[ 1 ] );
- RtemsIntrReqIsPending_Pre_IsPending_Prepare(
- ctx,
- ctx->Map.entry.Pre_IsPending_NA ? RtemsIntrReqIsPending_Pre_IsPending_NA : ctx->Map.pcs[ 2 ]
- );
+ RtemsIntrReqIsPending_Pre_IsPending_Prepare( ctx, ctx->Map.pcs[ 2 ] );
RtemsIntrReqIsPending_Action( ctx );
RtemsIntrReqIsPending_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
RtemsIntrReqIsPending_Post_IsPending_Check(
@@ -623,21 +649,22 @@ T_TEST_CASE_FIXTURE( RtemsIntrReqIsPending, &RtemsIntrReqIsPending_Fixture )
ctx->Map.index = 0;
for (
- ctx->Map.pcs[ 0 ] = RtemsIntrReqIsPending_Pre_Vector_Valid;
- ctx->Map.pcs[ 0 ] < RtemsIntrReqIsPending_Pre_Vector_NA;
- ++ctx->Map.pcs[ 0 ]
+ ctx->Map.pci[ 0 ] = RtemsIntrReqIsPending_Pre_Vector_Valid;
+ ctx->Map.pci[ 0 ] < RtemsIntrReqIsPending_Pre_Vector_NA;
+ ++ctx->Map.pci[ 0 ]
) {
for (
- ctx->Map.pcs[ 1 ] = RtemsIntrReqIsPending_Pre_Pending_Obj;
- ctx->Map.pcs[ 1 ] < RtemsIntrReqIsPending_Pre_Pending_NA;
- ++ctx->Map.pcs[ 1 ]
+ ctx->Map.pci[ 1 ] = RtemsIntrReqIsPending_Pre_Pending_Obj;
+ ctx->Map.pci[ 1 ] < RtemsIntrReqIsPending_Pre_Pending_NA;
+ ++ctx->Map.pci[ 1 ]
) {
for (
- ctx->Map.pcs[ 2 ] = RtemsIntrReqIsPending_Pre_IsPending_Yes;
- ctx->Map.pcs[ 2 ] < RtemsIntrReqIsPending_Pre_IsPending_NA;
- ++ctx->Map.pcs[ 2 ]
+ ctx->Map.pci[ 2 ] = RtemsIntrReqIsPending_Pre_IsPending_Yes;
+ ctx->Map.pci[ 2 ] < RtemsIntrReqIsPending_Pre_IsPending_NA;
+ ++ctx->Map.pci[ 2 ]
) {
ctx->Map.entry = RtemsIntrReqIsPending_PopEntry( ctx );
+ RtemsIntrReqIsPending_SetPreConditionStates( ctx );
RtemsIntrReqIsPending_TestVariant( ctx );
}
}
diff --git a/testsuites/validation/tc-intr-non-smp.c b/testsuites/validation/tc-intr-non-smp.c
new file mode 100644
index 0000000000..ce34571298
--- /dev/null
+++ b/testsuites/validation/tc-intr-non-smp.c
@@ -0,0 +1,170 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsIntrValIntrNonSmp
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsIntrValIntrNonSmp spec:/rtems/intr/val/intr-non-smp
+ *
+ * @ingroup TestsuitesValidationNonSmp
+ *
+ * @brief Tests some @ref RTEMSAPIClassicIntr interfaces.
+ *
+ * This test case performs the following actions:
+ *
+ * - Validate some interrupt lock macros.
+ *
+ * - Check that RTEMS_INTERRUPT_LOCK_DECLARE() expands to white space only.
+ *
+ * - Check that RTEMS_INTERRUPT_LOCK_DEFINE() expands to white space only.
+ *
+ * - Check that RTEMS_INTERRUPT_LOCK_MEMBER() expands to white space only.
+ *
+ * - Check that RTEMS_INTERRUPT_LOCK_REFERENCE() expands to white space only.
+ *
+ * - Check that rtems_interrupt_lock_destroy() expands to white space only.
+ *
+ * - Check that RTEMS_INTERRUPT_LOCK_INITIALIZER() expands to an empty
+ * structure initializer.
+ *
+ * - Check that rtems_interrupt_lock_initialize() expands to white space
+ * only.
+ *
+ * - Check that rtems_interrupt_lock_acquire_isr() expands to a code block
+ * which marks the second parameter as used.
+ *
+ * - Check that rtems_interrupt_lock_release_isr() expands to a code block
+ * which marks the second parameter as used.
+ *
+ * @{
+ */
+
+/**
+ * @brief Validate some interrupt lock macros.
+ */
+static void RtemsIntrValIntrNonSmp_Action_0( void )
+{
+ const char *s;
+
+ /*
+ * Check that RTEMS_INTERRUPT_LOCK_DECLARE() expands to white space only.
+ */
+ s = RTEMS_XSTRING( RTEMS_INTERRUPT_LOCK_DECLARE( x, y ) );
+ T_true( IsWhiteSpaceOnly( s ) );
+
+ /*
+ * Check that RTEMS_INTERRUPT_LOCK_DEFINE() expands to white space only.
+ */
+ s = RTEMS_XSTRING( RTEMS_INTERRUPT_LOCK_DEFINE( x, y, z ) );
+ T_true( IsWhiteSpaceOnly( s ) );
+
+ /*
+ * Check that RTEMS_INTERRUPT_LOCK_MEMBER() expands to white space only.
+ */
+ s = RTEMS_XSTRING( RTEMS_INTERRUPT_LOCK_MEMBER( x ) );
+ T_true( IsWhiteSpaceOnly( s ) );
+
+ /*
+ * Check that RTEMS_INTERRUPT_LOCK_REFERENCE() expands to white space only.
+ */
+ s = RTEMS_XSTRING( RTEMS_INTERRUPT_LOCK_REFERENCE( x, y ) );
+ T_true( IsWhiteSpaceOnly( s ) );
+
+ /*
+ * Check that rtems_interrupt_lock_destroy() expands to white space only.
+ */
+ s = RTEMS_XSTRING( rtems_interrupt_lock_destroy( x ) );
+ T_true( IsWhiteSpaceOnly( s ) );
+
+ /*
+ * Check that RTEMS_INTERRUPT_LOCK_INITIALIZER() expands to an empty
+ * structure initializer.
+ */
+ s = RTEMS_XSTRING( RTEMS_INTERRUPT_LOCK_INITIALIZER( x ) );
+ T_true( IsEqualIgnoreWhiteSpace( s, "{}" ) );
+
+ /*
+ * Check that rtems_interrupt_lock_initialize() expands to white space only.
+ */
+ s = RTEMS_XSTRING( rtems_interrupt_lock_initialize( x, y ) );
+ T_true( IsWhiteSpaceOnly( s ) );
+
+ /*
+ * Check that rtems_interrupt_lock_acquire_isr() expands to a code block
+ * which marks the second parameter as used.
+ */
+ s = RTEMS_XSTRING( rtems_interrupt_lock_acquire_isr( x, y ) );
+ T_true( IsEqualIgnoreWhiteSpace( s, "do{(void)y;}while(0)" ) );
+
+ /*
+ * Check that rtems_interrupt_lock_release_isr() expands to a code block
+ * which marks the second parameter as used.
+ */
+ s = RTEMS_XSTRING( rtems_interrupt_lock_release_isr( x, y ) );
+ T_true( IsEqualIgnoreWhiteSpace( s, "do{(void)y;}while(0)" ) );
+}
+
+/**
+ * @fn void T_case_body_RtemsIntrValIntrNonSmp( void )
+ */
+T_TEST_CASE( RtemsIntrValIntrNonSmp )
+{
+ RtemsIntrValIntrNonSmp_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-intr-raise-on.c b/testsuites/validation/tc-intr-raise-on.c
index efe468aebd..d4298463b6 100644
--- a/testsuites/validation/tc-intr-raise-on.c
+++ b/testsuites/validation/tc-intr-raise-on.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsIntrReqRaiseOn
+ * @ingroup RtemsIntrReqRaiseOn
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -61,9 +61,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsIntrReqRaiseOn spec:/rtems/intr/req/raise-on
+ * @defgroup RtemsIntrReqRaiseOn spec:/rtems/intr/req/raise-on
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationIntr
*
* @{
*/
@@ -154,6 +154,12 @@ typedef struct {
struct {
/**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 3 ];
+
+ /**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 3 ];
@@ -332,21 +338,21 @@ static void CheckRaiseOn(
T_rsc_success( sc );
if ( !IsPending( ctx) && ( attr->can_enable || IsEnabled( ctx ) ) ) {
- T_false( IsPending( ctx ) );
+ Disable( ctx );
+ RaiseOn( ctx );
- if ( attr->can_disable ) {
- Disable( ctx );
- RaiseOn( ctx );
- T_true( IsPending( ctx ) );
+ /*
+ * Some interrupt controllers will signal a pending interrupt if it is
+ * disabled (for example ARM GIC), others will not signal a pending
+ * interrupt if it is disabled (for example Freescale/NXP MPIC).
+ */
+ (void) IsPending( ctx );
- sc = rtems_interrupt_vector_enable( ctx->vector );
- T_rsc_success( sc );
+ sc = rtems_interrupt_vector_enable( ctx->vector );
+ T_rsc_success( sc );
- while ( ctx->interrupt_count < 1 ) {
- /* Wait */
- }
- } else {
- ++ctx->interrupt_count;
+ while ( ctx->interrupt_count < 1 ) {
+ /* Wait */
}
T_false( IsPending( ctx ) );
@@ -672,14 +678,25 @@ static inline RtemsIntrReqRaiseOn_Entry RtemsIntrReqRaiseOn_PopEntry(
];
}
+static void RtemsIntrReqRaiseOn_SetPreConditionStates(
+ RtemsIntrReqRaiseOn_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+
+ if ( ctx->Map.entry.Pre_CanRaiseOn_NA ) {
+ ctx->Map.pcs[ 2 ] = RtemsIntrReqRaiseOn_Pre_CanRaiseOn_NA;
+ } else {
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ }
+}
+
static void RtemsIntrReqRaiseOn_TestVariant( RtemsIntrReqRaiseOn_Context *ctx )
{
RtemsIntrReqRaiseOn_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsIntrReqRaiseOn_Pre_CPU_Prepare( ctx, ctx->Map.pcs[ 1 ] );
- RtemsIntrReqRaiseOn_Pre_CanRaiseOn_Prepare(
- ctx,
- ctx->Map.entry.Pre_CanRaiseOn_NA ? RtemsIntrReqRaiseOn_Pre_CanRaiseOn_NA : ctx->Map.pcs[ 2 ]
- );
+ RtemsIntrReqRaiseOn_Pre_CanRaiseOn_Prepare( ctx, ctx->Map.pcs[ 2 ] );
RtemsIntrReqRaiseOn_Action( ctx );
RtemsIntrReqRaiseOn_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
RtemsIntrReqRaiseOn_Post_Pending_Check( ctx, ctx->Map.entry.Post_Pending );
@@ -697,19 +714,19 @@ T_TEST_CASE_FIXTURE( RtemsIntrReqRaiseOn, &RtemsIntrReqRaiseOn_Fixture )
ctx->Map.index = 0;
for (
- ctx->Map.pcs[ 0 ] = RtemsIntrReqRaiseOn_Pre_Vector_Valid;
- ctx->Map.pcs[ 0 ] < RtemsIntrReqRaiseOn_Pre_Vector_NA;
- ++ctx->Map.pcs[ 0 ]
+ ctx->Map.pci[ 0 ] = RtemsIntrReqRaiseOn_Pre_Vector_Valid;
+ ctx->Map.pci[ 0 ] < RtemsIntrReqRaiseOn_Pre_Vector_NA;
+ ++ctx->Map.pci[ 0 ]
) {
for (
- ctx->Map.pcs[ 1 ] = RtemsIntrReqRaiseOn_Pre_CPU_Online;
- ctx->Map.pcs[ 1 ] < RtemsIntrReqRaiseOn_Pre_CPU_NA;
- ++ctx->Map.pcs[ 1 ]
+ ctx->Map.pci[ 1 ] = RtemsIntrReqRaiseOn_Pre_CPU_Online;
+ ctx->Map.pci[ 1 ] < RtemsIntrReqRaiseOn_Pre_CPU_NA;
+ ++ctx->Map.pci[ 1 ]
) {
for (
- ctx->Map.pcs[ 2 ] = RtemsIntrReqRaiseOn_Pre_CanRaiseOn_Yes;
- ctx->Map.pcs[ 2 ] < RtemsIntrReqRaiseOn_Pre_CanRaiseOn_NA;
- ++ctx->Map.pcs[ 2 ]
+ ctx->Map.pci[ 2 ] = RtemsIntrReqRaiseOn_Pre_CanRaiseOn_Yes;
+ ctx->Map.pci[ 2 ] < RtemsIntrReqRaiseOn_Pre_CanRaiseOn_NA;
+ ++ctx->Map.pci[ 2 ]
) {
ctx->Map.entry = RtemsIntrReqRaiseOn_PopEntry( ctx );
@@ -717,6 +734,7 @@ T_TEST_CASE_FIXTURE( RtemsIntrReqRaiseOn, &RtemsIntrReqRaiseOn_Fixture )
continue;
}
+ RtemsIntrReqRaiseOn_SetPreConditionStates( ctx );
RtemsIntrReqRaiseOn_TestVariant( ctx );
}
}
diff --git a/testsuites/validation/tc-intr-raise.c b/testsuites/validation/tc-intr-raise.c
index 81e8f8e856..1faa48fc79 100644
--- a/testsuites/validation/tc-intr-raise.c
+++ b/testsuites/validation/tc-intr-raise.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsIntrReqRaise
+ * @ingroup RtemsIntrReqRaise
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -61,9 +61,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsIntrReqRaise spec:/rtems/intr/req/raise
+ * @defgroup RtemsIntrReqRaise spec:/rtems/intr/req/raise
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationIntr
*
* @{
*/
@@ -134,6 +134,12 @@ typedef struct {
struct {
/**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 2 ];
+
+ /**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 2 ];
@@ -304,21 +310,21 @@ static void CheckRaise(
T_rsc_success( sc );
if ( !IsPending( ctx) && ( attr->can_enable || IsEnabled( ctx ) ) ) {
- T_false( IsPending( ctx ) );
+ Disable( ctx );
+ Raise( ctx );
- if ( attr->can_disable ) {
- Disable( ctx );
- Raise( ctx );
- T_true( IsPending( ctx ) );
+ /*
+ * Some interrupt controllers will signal a pending interrupt if it is
+ * disabled (for example ARM GIC), others will not signal a pending
+ * interrupt if it is disabled (for example Freescale/NXP MPIC).
+ */
+ (void) IsPending( ctx );
- sc = rtems_interrupt_vector_enable( ctx->vector );
- T_rsc_success( sc );
+ sc = rtems_interrupt_vector_enable( ctx->vector );
+ T_rsc_success( sc );
- while ( ctx->interrupt_count < 1 ) {
- /* Wait */
- }
- } else {
- ++ctx->interrupt_count;
+ while ( ctx->interrupt_count < 1 ) {
+ /* Wait */
}
T_false( IsPending( ctx ) );
@@ -550,13 +556,23 @@ static inline RtemsIntrReqRaise_Entry RtemsIntrReqRaise_PopEntry(
];
}
+static void RtemsIntrReqRaise_SetPreConditionStates(
+ RtemsIntrReqRaise_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+
+ if ( ctx->Map.entry.Pre_CanRaise_NA ) {
+ ctx->Map.pcs[ 1 ] = RtemsIntrReqRaise_Pre_CanRaise_NA;
+ } else {
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ }
+}
+
static void RtemsIntrReqRaise_TestVariant( RtemsIntrReqRaise_Context *ctx )
{
RtemsIntrReqRaise_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] );
- RtemsIntrReqRaise_Pre_CanRaise_Prepare(
- ctx,
- ctx->Map.entry.Pre_CanRaise_NA ? RtemsIntrReqRaise_Pre_CanRaise_NA : ctx->Map.pcs[ 1 ]
- );
+ RtemsIntrReqRaise_Pre_CanRaise_Prepare( ctx, ctx->Map.pcs[ 1 ] );
RtemsIntrReqRaise_Action( ctx );
RtemsIntrReqRaise_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
RtemsIntrReqRaise_Post_Pending_Check( ctx, ctx->Map.entry.Post_Pending );
@@ -574,16 +590,17 @@ T_TEST_CASE_FIXTURE( RtemsIntrReqRaise, &RtemsIntrReqRaise_Fixture )
ctx->Map.index = 0;
for (
- ctx->Map.pcs[ 0 ] = RtemsIntrReqRaise_Pre_Vector_Valid;
- ctx->Map.pcs[ 0 ] < RtemsIntrReqRaise_Pre_Vector_NA;
- ++ctx->Map.pcs[ 0 ]
+ ctx->Map.pci[ 0 ] = RtemsIntrReqRaise_Pre_Vector_Valid;
+ ctx->Map.pci[ 0 ] < RtemsIntrReqRaise_Pre_Vector_NA;
+ ++ctx->Map.pci[ 0 ]
) {
for (
- ctx->Map.pcs[ 1 ] = RtemsIntrReqRaise_Pre_CanRaise_Yes;
- ctx->Map.pcs[ 1 ] < RtemsIntrReqRaise_Pre_CanRaise_NA;
- ++ctx->Map.pcs[ 1 ]
+ ctx->Map.pci[ 1 ] = RtemsIntrReqRaise_Pre_CanRaise_Yes;
+ ctx->Map.pci[ 1 ] < RtemsIntrReqRaise_Pre_CanRaise_NA;
+ ++ctx->Map.pci[ 1 ]
) {
ctx->Map.entry = RtemsIntrReqRaise_PopEntry( ctx );
+ RtemsIntrReqRaise_SetPreConditionStates( ctx );
RtemsIntrReqRaise_TestVariant( ctx );
}
}
diff --git a/testsuites/validation/tc-intr-set-affinity.c b/testsuites/validation/tc-intr-set-affinity.c
index a2a6a45e09..3354681b47 100644
--- a/testsuites/validation/tc-intr-set-affinity.c
+++ b/testsuites/validation/tc-intr-set-affinity.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsIntrReqSetAffinity
+ * @ingroup RtemsIntrReqSetAffinity
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021, 2022 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -60,10 +60,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsIntrReqSetAffinity \
- * spec:/rtems/intr/req/set-affinity
+ * @defgroup RtemsIntrReqSetAffinity spec:/rtems/intr/req/set-affinity
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationIntr
*
* @{
*/
@@ -75,11 +74,23 @@ typedef enum {
} RtemsIntrReqSetAffinity_Pre_Vector;
typedef enum {
- RtemsIntrReqSetAffinity_Pre_CPUSetKind_Valid,
- RtemsIntrReqSetAffinity_Pre_CPUSetKind_Huge,
- RtemsIntrReqSetAffinity_Pre_CPUSetKind_Askew,
- RtemsIntrReqSetAffinity_Pre_CPUSetKind_NA
-} RtemsIntrReqSetAffinity_Pre_CPUSetKind;
+ RtemsIntrReqSetAffinity_Pre_CPUSetSize_Askew,
+ RtemsIntrReqSetAffinity_Pre_CPUSetSize_Normal,
+ RtemsIntrReqSetAffinity_Pre_CPUSetSize_Huge,
+ RtemsIntrReqSetAffinity_Pre_CPUSetSize_NA
+} RtemsIntrReqSetAffinity_Pre_CPUSetSize;
+
+typedef enum {
+ RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Valid,
+ RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Empty,
+ RtemsIntrReqSetAffinity_Pre_CPUSetOnline_NA
+} RtemsIntrReqSetAffinity_Pre_CPUSetOnline;
+
+typedef enum {
+ RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NotZero,
+ RtemsIntrReqSetAffinity_Pre_CPUSetHuge_Zero,
+ RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NA
+} RtemsIntrReqSetAffinity_Pre_CPUSetHuge;
typedef enum {
RtemsIntrReqSetAffinity_Pre_CPUSet_Valid,
@@ -103,7 +114,7 @@ typedef enum {
} RtemsIntrReqSetAffinity_Post_Status;
typedef enum {
- RtemsIntrReqSetAffinity_Post_SetAffinity_Yes,
+ RtemsIntrReqSetAffinity_Post_SetAffinity_Set,
RtemsIntrReqSetAffinity_Post_SetAffinity_Nop,
RtemsIntrReqSetAffinity_Post_SetAffinity_NA
} RtemsIntrReqSetAffinity_Post_SetAffinity;
@@ -111,7 +122,9 @@ typedef enum {
typedef struct {
uint16_t Skip : 1;
uint16_t Pre_Vector_NA : 1;
- uint16_t Pre_CPUSetKind_NA : 1;
+ uint16_t Pre_CPUSetSize_NA : 1;
+ uint16_t Pre_CPUSetOnline_NA : 1;
+ uint16_t Pre_CPUSetHuge_NA : 1;
uint16_t Pre_CPUSet_NA : 1;
uint16_t Pre_CanSetAffinity_NA : 1;
uint16_t Post_Status : 3;
@@ -162,9 +175,15 @@ typedef struct {
struct {
/**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 6 ];
+
+ /**
* @brief This member defines the pre-condition states for the next action.
*/
- size_t pcs[ 4 ];
+ size_t pcs[ 6 ];
/**
* @brief If this member is true, then the test action loop is executed.
@@ -198,10 +217,22 @@ static const char * const RtemsIntrReqSetAffinity_PreDesc_Vector[] = {
"NA"
};
-static const char * const RtemsIntrReqSetAffinity_PreDesc_CPUSetKind[] = {
- "Valid",
- "Huge",
+static const char * const RtemsIntrReqSetAffinity_PreDesc_CPUSetSize[] = {
"Askew",
+ "Normal",
+ "Huge",
+ "NA"
+};
+
+static const char * const RtemsIntrReqSetAffinity_PreDesc_CPUSetOnline[] = {
+ "Valid",
+ "Empty",
+ "NA"
+};
+
+static const char * const RtemsIntrReqSetAffinity_PreDesc_CPUSetHuge[] = {
+ "NotZero",
+ "Zero",
"NA"
};
@@ -219,7 +250,9 @@ static const char * const RtemsIntrReqSetAffinity_PreDesc_CanSetAffinity[] = {
static const char * const * const RtemsIntrReqSetAffinity_PreDesc[] = {
RtemsIntrReqSetAffinity_PreDesc_Vector,
- RtemsIntrReqSetAffinity_PreDesc_CPUSetKind,
+ RtemsIntrReqSetAffinity_PreDesc_CPUSetSize,
+ RtemsIntrReqSetAffinity_PreDesc_CPUSetOnline,
+ RtemsIntrReqSetAffinity_PreDesc_CPUSetHuge,
RtemsIntrReqSetAffinity_PreDesc_CPUSet,
RtemsIntrReqSetAffinity_PreDesc_CanSetAffinity,
NULL
@@ -295,43 +328,107 @@ static void RtemsIntrReqSetAffinity_Pre_Vector_Prepare(
}
}
-static void RtemsIntrReqSetAffinity_Pre_CPUSetKind_Prepare(
+static void RtemsIntrReqSetAffinity_Pre_CPUSetSize_Prepare(
RtemsIntrReqSetAffinity_Context *ctx,
- RtemsIntrReqSetAffinity_Pre_CPUSetKind state
+ RtemsIntrReqSetAffinity_Pre_CPUSetSize state
)
{
switch ( state ) {
- case RtemsIntrReqSetAffinity_Pre_CPUSetKind_Valid: {
+ case RtemsIntrReqSetAffinity_Pre_CPUSetSize_Askew: {
+ /*
+ * While the ``affinity_size`` parameter is not an integral multiple of
+ * the size of long.
+ */
+ ctx->cpusetsize = SIZE_MAX;
+ break;
+ }
+
+ case RtemsIntrReqSetAffinity_Pre_CPUSetSize_Normal: {
/*
* While the ``affinity_size`` parameter is an integral multiple of the
- * size of long, while the ``affinity_size`` and ``affinity`` parameter
- * specify a processor set which is within the implementation limits.
+ * size of long, while the ``affinity_size`` parameter is less than or
+ * equal to the maximum processor set size storable in the system.
*/
ctx->cpusetsize = sizeof( ctx->cpuset_obj[ 0 ] );
break;
}
- case RtemsIntrReqSetAffinity_Pre_CPUSetKind_Huge: {
+ case RtemsIntrReqSetAffinity_Pre_CPUSetSize_Huge: {
/*
* While the ``affinity_size`` parameter is an integral multiple of the
- * size of long, while the ``affinity_size`` and ``affinity`` parameter
- * specify a processor set which exceeds the implementation limits.
+ * size of long, while the ``affinity_size`` parameter is greater than
+ * the maximum processor set size storable in the system.
*/
ctx->cpusetsize = sizeof( ctx->cpuset_obj );
+ break;
+ }
+
+ case RtemsIntrReqSetAffinity_Pre_CPUSetSize_NA:
+ break;
+ }
+}
+
+static void RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Prepare(
+ RtemsIntrReqSetAffinity_Context *ctx,
+ RtemsIntrReqSetAffinity_Pre_CPUSetOnline state
+)
+{
+ switch ( state ) {
+ case RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Valid: {
+ /*
+ * While the intersection of the processor set specified by the
+ * ``affinity_size`` and ``affinity`` parameters and the set of online
+ * processors is not empty, while the intersection of the processor set
+ * specified by the ``affinity_size`` and ``affinity`` parameters and the
+ * set of online processors is a processor affinity set supported by the
+ * interrupt vector.
+ */
+ /* Already prepared */
+ break;
+ }
+
+ case RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Empty: {
+ /*
+ * While the intersection of the processor set specified by the
+ * ``affinity_size`` and ``affinity`` parameters and the set of online
+ * processors is empty.
+ */
CPU_ZERO( &ctx->cpuset_obj[ 0 ] );
break;
}
- case RtemsIntrReqSetAffinity_Pre_CPUSetKind_Askew: {
+ case RtemsIntrReqSetAffinity_Pre_CPUSetOnline_NA:
+ break;
+ }
+}
+
+static void RtemsIntrReqSetAffinity_Pre_CPUSetHuge_Prepare(
+ RtemsIntrReqSetAffinity_Context *ctx,
+ RtemsIntrReqSetAffinity_Pre_CPUSetHuge state
+)
+{
+ switch ( state ) {
+ case RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NotZero: {
/*
- * While the ``affinity_size`` parameter is not an integral multiple of
- * the size of long.
+ * While the processor set specified by the ``affinity_size`` and
+ * ``affinity`` parameters contains at least one processor which is not
+ * storable in a processor set supported by the system.
*/
- ctx->cpusetsize = SIZE_MAX;
+ /* Already prepared */
+ break;
+ }
+
+ case RtemsIntrReqSetAffinity_Pre_CPUSetHuge_Zero: {
+ /*
+ * While the processor set specified by the ``affinity_size`` and
+ * ``affinity`` parameters contains no processor which is not storable in
+ * a processor set supported by the system.
+ */
+ CPU_ZERO( &ctx->cpuset_obj[ 1 ] );
break;
}
- case RtemsIntrReqSetAffinity_Pre_CPUSetKind_NA:
+ case RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NA:
break;
}
}
@@ -455,7 +552,7 @@ static void RtemsIntrReqSetAffinity_Post_SetAffinity_Check(
)
{
switch ( state ) {
- case RtemsIntrReqSetAffinity_Post_SetAffinity_Yes: {
+ case RtemsIntrReqSetAffinity_Post_SetAffinity_Set: {
/*
* The affinity set of the interrupt specified by ``vector`` shall be set
* to the processor set specified by ``affinity_size`` and ``affinity``
@@ -513,7 +610,7 @@ static void RtemsIntrReqSetAffinity_Action(
if (
ctx->valid_vector && ctx->cpusetsize == sizeof( ctx->cpuset_obj[ 0 ] ) &&
- ctx->cpuset == &ctx->cpuset_obj[ 0 ]
+ ctx->cpuset == &ctx->cpuset_obj[ 0 ] && !CPU_EMPTY( &ctx->cpuset_obj[ 0 ] )
) {
for (
ctx->vector = 0;
@@ -532,6 +629,7 @@ static void RtemsIntrReqSetAffinity_Action(
T_rsc_success( sc );
CheckSetAffinity( ctx, &attr );
+ ctx->status = RTEMS_SUCCESSFUL;
}
} else {
cpu_set_t set;
@@ -539,6 +637,8 @@ static void RtemsIntrReqSetAffinity_Action(
CPU_ZERO( &set );
CPU_ZERO( &set2 );
+ CPU_SET( 0, &set );
+ CPU_SET( 0, &set2 );
if ( ctx->valid_vector ) {
ctx->vector = ctx->some_vector;
@@ -549,7 +649,9 @@ static void RtemsIntrReqSetAffinity_Action(
ctx->vector = BSP_INTERRUPT_VECTOR_COUNT;
}
- CPU_ZERO( &ctx->cpuset_obj[ 0 ] );
+ if ( !CPU_EMPTY( &ctx->cpuset_obj[ 0 ] ) ) {
+ CPU_COPY( &set, &ctx->cpuset_obj[ 0 ] );
+ }
ctx->status = rtems_interrupt_set_affinity(
ctx->vector,
@@ -567,23 +669,34 @@ static void RtemsIntrReqSetAffinity_Action(
static const RtemsIntrReqSetAffinity_Entry
RtemsIntrReqSetAffinity_Entries[] = {
- { 0, 0, 0, 0, 0, RtemsIntrReqSetAffinity_Post_Status_InvAddr,
+ { 0, 0, 0, 1, 1, 0, 0, RtemsIntrReqSetAffinity_Post_Status_InvAddr,
+ RtemsIntrReqSetAffinity_Post_SetAffinity_Nop },
+ { 0, 0, 0, 1, 1, 0, 1, RtemsIntrReqSetAffinity_Post_Status_InvAddr,
+ RtemsIntrReqSetAffinity_Post_SetAffinity_Nop },
+ { 0, 0, 0, 1, 1, 0, 1, RtemsIntrReqSetAffinity_Post_Status_InvId,
RtemsIntrReqSetAffinity_Post_SetAffinity_Nop },
- { 0, 0, 0, 0, 1, RtemsIntrReqSetAffinity_Post_Status_InvId,
- RtemsIntrReqSetAffinity_Post_SetAffinity_NA },
- { 0, 0, 0, 0, 1, RtemsIntrReqSetAffinity_Post_Status_InvAddr,
- RtemsIntrReqSetAffinity_Post_SetAffinity_NA },
- { 0, 0, 0, 0, 0, RtemsIntrReqSetAffinity_Post_Status_InvNum,
+ { 0, 0, 0, 0, 1, 0, 0, RtemsIntrReqSetAffinity_Post_Status_InvNum,
RtemsIntrReqSetAffinity_Post_SetAffinity_Nop },
- { 0, 0, 0, 0, 0, RtemsIntrReqSetAffinity_Post_Status_Ok,
- RtemsIntrReqSetAffinity_Post_SetAffinity_Yes },
- { 0, 0, 0, 0, 0, RtemsIntrReqSetAffinity_Post_Status_Unsat,
+ { 0, 0, 0, 1, 0, 0, 1, RtemsIntrReqSetAffinity_Post_Status_InvId,
+ RtemsIntrReqSetAffinity_Post_SetAffinity_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsIntrReqSetAffinity_Post_Status_InvNum,
+ RtemsIntrReqSetAffinity_Post_SetAffinity_Nop },
+ { 0, 0, 0, 0, 1, 0, 0, RtemsIntrReqSetAffinity_Post_Status_Ok,
+ RtemsIntrReqSetAffinity_Post_SetAffinity_Set },
+ { 0, 0, 0, 0, 1, 0, 0, RtemsIntrReqSetAffinity_Post_Status_Unsat,
+ RtemsIntrReqSetAffinity_Post_SetAffinity_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsIntrReqSetAffinity_Post_Status_Ok,
+ RtemsIntrReqSetAffinity_Post_SetAffinity_Set },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsIntrReqSetAffinity_Post_Status_Unsat,
RtemsIntrReqSetAffinity_Post_SetAffinity_Nop }
};
static const uint8_t
RtemsIntrReqSetAffinity_Map[] = {
- 4, 5, 0, 0, 3, 3, 0, 0, 3, 3, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2
+ 3, 3, 0, 0, 3, 3, 0, 0, 3, 3, 0, 0, 3, 3, 0, 0, 6, 7, 0, 0, 6, 7, 0, 0, 3, 3,
+ 0, 0, 3, 3, 0, 0, 8, 9, 0, 0, 8, 9, 0, 0, 5, 5, 0, 0, 5, 5, 0, 0, 2, 2, 1, 1,
+ 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2,
+ 1, 1, 4, 4, 1, 1, 4, 4, 1, 1, 4, 4, 1, 1, 4, 4, 1, 1
};
static size_t RtemsIntrReqSetAffinity_Scope( void *arg, char *buf, size_t n )
@@ -625,17 +738,44 @@ static inline RtemsIntrReqSetAffinity_Entry RtemsIntrReqSetAffinity_PopEntry(
];
}
+static void RtemsIntrReqSetAffinity_SetPreConditionStates(
+ RtemsIntrReqSetAffinity_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+
+ if ( ctx->Map.entry.Pre_CPUSetOnline_NA ) {
+ ctx->Map.pcs[ 2 ] = RtemsIntrReqSetAffinity_Pre_CPUSetOnline_NA;
+ } else {
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ }
+
+ if ( ctx->Map.entry.Pre_CPUSetHuge_NA ) {
+ ctx->Map.pcs[ 3 ] = RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NA;
+ } else {
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ }
+
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+
+ if ( ctx->Map.entry.Pre_CanSetAffinity_NA ) {
+ ctx->Map.pcs[ 5 ] = RtemsIntrReqSetAffinity_Pre_CanSetAffinity_NA;
+ } else {
+ ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
+ }
+}
+
static void RtemsIntrReqSetAffinity_TestVariant(
RtemsIntrReqSetAffinity_Context *ctx
)
{
RtemsIntrReqSetAffinity_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] );
- RtemsIntrReqSetAffinity_Pre_CPUSetKind_Prepare( ctx, ctx->Map.pcs[ 1 ] );
- RtemsIntrReqSetAffinity_Pre_CPUSet_Prepare( ctx, ctx->Map.pcs[ 2 ] );
- RtemsIntrReqSetAffinity_Pre_CanSetAffinity_Prepare(
- ctx,
- ctx->Map.entry.Pre_CanSetAffinity_NA ? RtemsIntrReqSetAffinity_Pre_CanSetAffinity_NA : ctx->Map.pcs[ 3 ]
- );
+ RtemsIntrReqSetAffinity_Pre_CPUSetSize_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsIntrReqSetAffinity_Pre_CPUSetHuge_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsIntrReqSetAffinity_Pre_CPUSet_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsIntrReqSetAffinity_Pre_CanSetAffinity_Prepare( ctx, ctx->Map.pcs[ 5 ] );
RtemsIntrReqSetAffinity_Action( ctx );
RtemsIntrReqSetAffinity_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
RtemsIntrReqSetAffinity_Post_SetAffinity_Check(
@@ -659,28 +799,41 @@ T_TEST_CASE_FIXTURE(
ctx->Map.index = 0;
for (
- ctx->Map.pcs[ 0 ] = RtemsIntrReqSetAffinity_Pre_Vector_Valid;
- ctx->Map.pcs[ 0 ] < RtemsIntrReqSetAffinity_Pre_Vector_NA;
- ++ctx->Map.pcs[ 0 ]
+ ctx->Map.pci[ 0 ] = RtemsIntrReqSetAffinity_Pre_Vector_Valid;
+ ctx->Map.pci[ 0 ] < RtemsIntrReqSetAffinity_Pre_Vector_NA;
+ ++ctx->Map.pci[ 0 ]
) {
for (
- ctx->Map.pcs[ 1 ] = RtemsIntrReqSetAffinity_Pre_CPUSetKind_Valid;
- ctx->Map.pcs[ 1 ] < RtemsIntrReqSetAffinity_Pre_CPUSetKind_NA;
- ++ctx->Map.pcs[ 1 ]
+ ctx->Map.pci[ 1 ] = RtemsIntrReqSetAffinity_Pre_CPUSetSize_Askew;
+ ctx->Map.pci[ 1 ] < RtemsIntrReqSetAffinity_Pre_CPUSetSize_NA;
+ ++ctx->Map.pci[ 1 ]
) {
for (
- ctx->Map.pcs[ 2 ] = RtemsIntrReqSetAffinity_Pre_CPUSet_Valid;
- ctx->Map.pcs[ 2 ] < RtemsIntrReqSetAffinity_Pre_CPUSet_NA;
- ++ctx->Map.pcs[ 2 ]
+ ctx->Map.pci[ 2 ] = RtemsIntrReqSetAffinity_Pre_CPUSetOnline_Valid;
+ ctx->Map.pci[ 2 ] < RtemsIntrReqSetAffinity_Pre_CPUSetOnline_NA;
+ ++ctx->Map.pci[ 2 ]
) {
for (
- ctx->Map.pcs[ 3 ] = RtemsIntrReqSetAffinity_Pre_CanSetAffinity_Yes;
- ctx->Map.pcs[ 3 ] < RtemsIntrReqSetAffinity_Pre_CanSetAffinity_NA;
- ++ctx->Map.pcs[ 3 ]
+ ctx->Map.pci[ 3 ] = RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NotZero;
+ ctx->Map.pci[ 3 ] < RtemsIntrReqSetAffinity_Pre_CPUSetHuge_NA;
+ ++ctx->Map.pci[ 3 ]
) {
- ctx->Map.entry = RtemsIntrReqSetAffinity_PopEntry( ctx );
- RtemsIntrReqSetAffinity_Prepare( ctx );
- RtemsIntrReqSetAffinity_TestVariant( ctx );
+ for (
+ ctx->Map.pci[ 4 ] = RtemsIntrReqSetAffinity_Pre_CPUSet_Valid;
+ ctx->Map.pci[ 4 ] < RtemsIntrReqSetAffinity_Pre_CPUSet_NA;
+ ++ctx->Map.pci[ 4 ]
+ ) {
+ for (
+ ctx->Map.pci[ 5 ] = RtemsIntrReqSetAffinity_Pre_CanSetAffinity_Yes;
+ ctx->Map.pci[ 5 ] < RtemsIntrReqSetAffinity_Pre_CanSetAffinity_NA;
+ ++ctx->Map.pci[ 5 ]
+ ) {
+ ctx->Map.entry = RtemsIntrReqSetAffinity_PopEntry( ctx );
+ RtemsIntrReqSetAffinity_SetPreConditionStates( ctx );
+ RtemsIntrReqSetAffinity_Prepare( ctx );
+ RtemsIntrReqSetAffinity_TestVariant( ctx );
+ }
+ }
}
}
}
diff --git a/testsuites/validation/tc-intr-smp-only.c b/testsuites/validation/tc-intr-smp-only.c
new file mode 100644
index 0000000000..4d1f64b699
--- /dev/null
+++ b/testsuites/validation/tc-intr-smp-only.c
@@ -0,0 +1,225 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsIntrValIntrSmpOnly
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsIntrValIntrSmpOnly spec:/rtems/intr/val/intr-smp-only
+ *
+ * @ingroup TestsuitesValidationSmpOnly0
+ *
+ * @brief Tests some @ref RTEMSAPIClassicIntr directives.
+ *
+ * This test case performs the following actions:
+ *
+ * - Validate the interrupt lock directives.
+ *
+ * - Check that RTEMS_INTERRUPT_LOCK_REFERENCE() expanded to a lock reference
+ * definition. Check that the lock is available after static
+ * initialization.
+ *
+ * - Check that the lock is available after initialization.
+ *
+ * - Check that maskable interrupts are disabled before the call to
+ * rtems_interrupt_lock_interrupt_disable() and disabled afterwards.
+ *
+ * - Check that the maskable interrupt status is not changed by the
+ * rtems_interrupt_lock_acquire_isr() call. Check that the lock is no
+ * longer available.
+ *
+ * - Check that the maskable interrupt status is restored by the call to
+ * rtems_interrupt_lock_release() according to the ``_lock_context``
+ * parameter. Check that the lock is available afterwards.
+ *
+ * - Check that the maskable interrupt status is not changed by the
+ * rtems_interrupt_lock_destroy() call.
+ *
+ * - Initialize the lock using rtems_interrupt_lock_initialize(). Check that
+ * the lock is available after initialization.
+ *
+ * - Check that maskable interrupts are disabled before the call to
+ * rtems_interrupt_lock_acquire() and disabled afterwards. Check that the
+ * lock is no longer available.
+ *
+ * - Check that the maskable interrupt status is restored by the call to
+ * rtems_interrupt_lock_release() according to the ``_lock_context``
+ * parameter. Check that the lock is available afterwards.
+ *
+ * - Check that the maskable interrupt status is not changed by the
+ * rtems_interrupt_lock_destroy() call.
+ *
+ * @{
+ */
+
+RTEMS_INTERRUPT_LOCK_DECLARE( static, the_lock )
+RTEMS_INTERRUPT_LOCK_DEFINE( static, the_lock, "name " )
+
+/**
+ * @brief Validate the interrupt lock directives.
+ */
+static void RtemsIntrValIntrSmpOnly_Action_0( void )
+{
+ struct {
+ int a;
+ RTEMS_INTERRUPT_LOCK_MEMBER( member )
+ int b;
+ } lock = {
+ .member = RTEMS_INTERRUPT_LOCK_INITIALIZER( "name" )
+ };
+
+ RTEMS_INTERRUPT_LOCK_REFERENCE( ref, &the_lock )
+ rtems_interrupt_lock_context lock_context;
+
+ /*
+ * Check that RTEMS_INTERRUPT_LOCK_REFERENCE() expanded to a lock reference
+ * definition. Check that the lock is available after static initialization.
+ */
+ T_true( ISRLockIsAvailable( ref ) );
+
+ /*
+ * Check that the lock is available after initialization.
+ */
+ T_true( ISRLockIsAvailable( &lock.member ) );
+
+ /*
+ * Check that maskable interrupts are disabled before the call to
+ * rtems_interrupt_lock_interrupt_disable() and disabled afterwards.
+ */
+ T_true( AreInterruptsEnabled() );
+ T_true( ISRLockIsAvailable( &lock.member ) );
+ rtems_interrupt_lock_interrupt_disable( &lock_context );
+ T_false( AreInterruptsEnabled() );
+ T_true( ISRLockIsAvailable( &lock.member ) );
+
+ /*
+ * Check that the maskable interrupt status is not changed by the
+ * rtems_interrupt_lock_acquire_isr() call. Check that the lock is no longer
+ * available.
+ */
+ T_false( AreInterruptsEnabled() );
+ T_true( ISRLockIsAvailable( &lock.member ) );
+ rtems_interrupt_lock_acquire_isr( &lock.member, &lock_context );
+ T_false( AreInterruptsEnabled() );
+ T_false( ISRLockIsAvailable( &lock.member ) );
+
+ /*
+ * Check that the maskable interrupt status is restored by the call to
+ * rtems_interrupt_lock_release() according to the ``_lock_context``
+ * parameter. Check that the lock is available afterwards.
+ */
+ T_false( AreInterruptsEnabled() );
+ T_false( ISRLockIsAvailable( &lock.member ) );
+ rtems_interrupt_lock_release( &lock.member, &lock_context );
+ T_true( AreInterruptsEnabled() );
+ T_true( ISRLockIsAvailable( &lock.member ) );
+
+ /*
+ * Check that the maskable interrupt status is not changed by the
+ * rtems_interrupt_lock_destroy() call.
+ */
+ T_true( AreInterruptsEnabled() );
+ rtems_interrupt_lock_destroy( &lock.member );
+ T_true( AreInterruptsEnabled() );
+
+ /*
+ * Initialize the lock using rtems_interrupt_lock_initialize(). Check that
+ * the lock is available after initialization.
+ */
+ rtems_interrupt_lock_initialize( &lock.member, "name" );
+ T_true( ISRLockIsAvailable( &lock.member ) );
+
+ /*
+ * Check that maskable interrupts are disabled before the call to
+ * rtems_interrupt_lock_acquire() and disabled afterwards. Check that the
+ * lock is no longer available.
+ */
+ T_true( AreInterruptsEnabled() );
+ T_true( ISRLockIsAvailable( &lock.member ) );
+ rtems_interrupt_lock_acquire( &lock.member, &lock_context );
+ T_false( AreInterruptsEnabled() );
+ T_false( ISRLockIsAvailable( &lock.member ) );
+
+ /*
+ * Check that the maskable interrupt status is restored by the call to
+ * rtems_interrupt_lock_release() according to the ``_lock_context``
+ * parameter. Check that the lock is available afterwards.
+ */
+ T_false( AreInterruptsEnabled() );
+ T_false( ISRLockIsAvailable( &lock.member ) );
+ rtems_interrupt_lock_release( &lock.member, &lock_context );
+ T_true( AreInterruptsEnabled() );
+ T_true( ISRLockIsAvailable( &lock.member ) );
+
+ /*
+ * Check that the maskable interrupt status is not changed by the
+ * rtems_interrupt_lock_destroy() call.
+ */
+ T_true( AreInterruptsEnabled() );
+ rtems_interrupt_lock_destroy( &lock.member );
+ T_true( AreInterruptsEnabled() );
+}
+
+/**
+ * @fn void T_case_body_RtemsIntrValIntrSmpOnly( void )
+ */
+T_TEST_CASE( RtemsIntrValIntrSmpOnly )
+{
+ RtemsIntrValIntrSmpOnly_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-intr-vector-disable.c b/testsuites/validation/tc-intr-vector-disable.c
index fea05a257a..013befeff8 100644
--- a/testsuites/validation/tc-intr-vector-disable.c
+++ b/testsuites/validation/tc-intr-vector-disable.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsIntrReqVectorDisable
+ * @ingroup RtemsIntrReqVectorDisable
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -61,10 +61,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsIntrReqVectorDisable \
- * spec:/rtems/intr/req/vector-disable
+ * @defgroup RtemsIntrReqVectorDisable spec:/rtems/intr/req/vector-disable
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationIntr
*
* @{
*/
@@ -139,6 +138,12 @@ typedef struct {
struct {
/**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 3 ];
+
+ /**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 3 ];
@@ -594,19 +599,32 @@ RtemsIntrReqVectorDisable_PopEntry( RtemsIntrReqVectorDisable_Context *ctx )
];
}
+static void RtemsIntrReqVectorDisable_SetPreConditionStates(
+ RtemsIntrReqVectorDisable_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+
+ if ( ctx->Map.entry.Pre_IsEnabled_NA ) {
+ ctx->Map.pcs[ 1 ] = RtemsIntrReqVectorDisable_Pre_IsEnabled_NA;
+ } else {
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ }
+
+ if ( ctx->Map.entry.Pre_CanDisable_NA ) {
+ ctx->Map.pcs[ 2 ] = RtemsIntrReqVectorDisable_Pre_CanDisable_NA;
+ } else {
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ }
+}
+
static void RtemsIntrReqVectorDisable_TestVariant(
RtemsIntrReqVectorDisable_Context *ctx
)
{
RtemsIntrReqVectorDisable_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] );
- RtemsIntrReqVectorDisable_Pre_IsEnabled_Prepare(
- ctx,
- ctx->Map.entry.Pre_IsEnabled_NA ? RtemsIntrReqVectorDisable_Pre_IsEnabled_NA : ctx->Map.pcs[ 1 ]
- );
- RtemsIntrReqVectorDisable_Pre_CanDisable_Prepare(
- ctx,
- ctx->Map.entry.Pre_CanDisable_NA ? RtemsIntrReqVectorDisable_Pre_CanDisable_NA : ctx->Map.pcs[ 2 ]
- );
+ RtemsIntrReqVectorDisable_Pre_IsEnabled_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsIntrReqVectorDisable_Pre_CanDisable_Prepare( ctx, ctx->Map.pcs[ 2 ] );
RtemsIntrReqVectorDisable_Action( ctx );
RtemsIntrReqVectorDisable_Post_Status_Check(
ctx,
@@ -633,21 +651,22 @@ T_TEST_CASE_FIXTURE(
ctx->Map.index = 0;
for (
- ctx->Map.pcs[ 0 ] = RtemsIntrReqVectorDisable_Pre_Vector_Valid;
- ctx->Map.pcs[ 0 ] < RtemsIntrReqVectorDisable_Pre_Vector_NA;
- ++ctx->Map.pcs[ 0 ]
+ ctx->Map.pci[ 0 ] = RtemsIntrReqVectorDisable_Pre_Vector_Valid;
+ ctx->Map.pci[ 0 ] < RtemsIntrReqVectorDisable_Pre_Vector_NA;
+ ++ctx->Map.pci[ 0 ]
) {
for (
- ctx->Map.pcs[ 1 ] = RtemsIntrReqVectorDisable_Pre_IsEnabled_Yes;
- ctx->Map.pcs[ 1 ] < RtemsIntrReqVectorDisable_Pre_IsEnabled_NA;
- ++ctx->Map.pcs[ 1 ]
+ ctx->Map.pci[ 1 ] = RtemsIntrReqVectorDisable_Pre_IsEnabled_Yes;
+ ctx->Map.pci[ 1 ] < RtemsIntrReqVectorDisable_Pre_IsEnabled_NA;
+ ++ctx->Map.pci[ 1 ]
) {
for (
- ctx->Map.pcs[ 2 ] = RtemsIntrReqVectorDisable_Pre_CanDisable_Yes;
- ctx->Map.pcs[ 2 ] < RtemsIntrReqVectorDisable_Pre_CanDisable_NA;
- ++ctx->Map.pcs[ 2 ]
+ ctx->Map.pci[ 2 ] = RtemsIntrReqVectorDisable_Pre_CanDisable_Yes;
+ ctx->Map.pci[ 2 ] < RtemsIntrReqVectorDisable_Pre_CanDisable_NA;
+ ++ctx->Map.pci[ 2 ]
) {
ctx->Map.entry = RtemsIntrReqVectorDisable_PopEntry( ctx );
+ RtemsIntrReqVectorDisable_SetPreConditionStates( ctx );
RtemsIntrReqVectorDisable_TestVariant( ctx );
}
}
diff --git a/testsuites/validation/tc-intr-vector-enable.c b/testsuites/validation/tc-intr-vector-enable.c
index c0d985a9d0..91993fb8d4 100644
--- a/testsuites/validation/tc-intr-vector-enable.c
+++ b/testsuites/validation/tc-intr-vector-enable.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsIntrReqVectorEnable
+ * @ingroup RtemsIntrReqVectorEnable
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -61,10 +61,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsIntrReqVectorEnable \
- * spec:/rtems/intr/req/vector-enable
+ * @defgroup RtemsIntrReqVectorEnable spec:/rtems/intr/req/vector-enable
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationIntr
*
* @{
*/
@@ -139,6 +138,12 @@ typedef struct {
struct {
/**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 3 ];
+
+ /**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 3 ];
@@ -362,7 +367,7 @@ static void RtemsIntrReqVectorEnable_Pre_IsEnabled_Prepare(
case RtemsIntrReqVectorEnable_Pre_IsEnabled_No: {
/*
* While the interrupt vector associated with the ``vector`` parameter is
- * enabled.
+ * disabled.
*/
/*
* This pre-condition depends on the attributes of an interrupt vector,
@@ -600,19 +605,32 @@ static inline RtemsIntrReqVectorEnable_Entry RtemsIntrReqVectorEnable_PopEntry(
];
}
+static void RtemsIntrReqVectorEnable_SetPreConditionStates(
+ RtemsIntrReqVectorEnable_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+
+ if ( ctx->Map.entry.Pre_IsEnabled_NA ) {
+ ctx->Map.pcs[ 1 ] = RtemsIntrReqVectorEnable_Pre_IsEnabled_NA;
+ } else {
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ }
+
+ if ( ctx->Map.entry.Pre_CanEnable_NA ) {
+ ctx->Map.pcs[ 2 ] = RtemsIntrReqVectorEnable_Pre_CanEnable_NA;
+ } else {
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ }
+}
+
static void RtemsIntrReqVectorEnable_TestVariant(
RtemsIntrReqVectorEnable_Context *ctx
)
{
RtemsIntrReqVectorEnable_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] );
- RtemsIntrReqVectorEnable_Pre_IsEnabled_Prepare(
- ctx,
- ctx->Map.entry.Pre_IsEnabled_NA ? RtemsIntrReqVectorEnable_Pre_IsEnabled_NA : ctx->Map.pcs[ 1 ]
- );
- RtemsIntrReqVectorEnable_Pre_CanEnable_Prepare(
- ctx,
- ctx->Map.entry.Pre_CanEnable_NA ? RtemsIntrReqVectorEnable_Pre_CanEnable_NA : ctx->Map.pcs[ 2 ]
- );
+ RtemsIntrReqVectorEnable_Pre_IsEnabled_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsIntrReqVectorEnable_Pre_CanEnable_Prepare( ctx, ctx->Map.pcs[ 2 ] );
RtemsIntrReqVectorEnable_Action( ctx );
RtemsIntrReqVectorEnable_Post_Status_Check(
ctx,
@@ -639,21 +657,22 @@ T_TEST_CASE_FIXTURE(
ctx->Map.index = 0;
for (
- ctx->Map.pcs[ 0 ] = RtemsIntrReqVectorEnable_Pre_Vector_Valid;
- ctx->Map.pcs[ 0 ] < RtemsIntrReqVectorEnable_Pre_Vector_NA;
- ++ctx->Map.pcs[ 0 ]
+ ctx->Map.pci[ 0 ] = RtemsIntrReqVectorEnable_Pre_Vector_Valid;
+ ctx->Map.pci[ 0 ] < RtemsIntrReqVectorEnable_Pre_Vector_NA;
+ ++ctx->Map.pci[ 0 ]
) {
for (
- ctx->Map.pcs[ 1 ] = RtemsIntrReqVectorEnable_Pre_IsEnabled_Yes;
- ctx->Map.pcs[ 1 ] < RtemsIntrReqVectorEnable_Pre_IsEnabled_NA;
- ++ctx->Map.pcs[ 1 ]
+ ctx->Map.pci[ 1 ] = RtemsIntrReqVectorEnable_Pre_IsEnabled_Yes;
+ ctx->Map.pci[ 1 ] < RtemsIntrReqVectorEnable_Pre_IsEnabled_NA;
+ ++ctx->Map.pci[ 1 ]
) {
for (
- ctx->Map.pcs[ 2 ] = RtemsIntrReqVectorEnable_Pre_CanEnable_Yes;
- ctx->Map.pcs[ 2 ] < RtemsIntrReqVectorEnable_Pre_CanEnable_NA;
- ++ctx->Map.pcs[ 2 ]
+ ctx->Map.pci[ 2 ] = RtemsIntrReqVectorEnable_Pre_CanEnable_Yes;
+ ctx->Map.pci[ 2 ] < RtemsIntrReqVectorEnable_Pre_CanEnable_NA;
+ ++ctx->Map.pci[ 2 ]
) {
ctx->Map.entry = RtemsIntrReqVectorEnable_PopEntry( ctx );
+ RtemsIntrReqVectorEnable_SetPreConditionStates( ctx );
RtemsIntrReqVectorEnable_TestVariant( ctx );
}
}
diff --git a/testsuites/validation/tc-intr-vector-is-enabled.c b/testsuites/validation/tc-intr-vector-is-enabled.c
index de1d0c2ebb..d24ad3f602 100644
--- a/testsuites/validation/tc-intr-vector-is-enabled.c
+++ b/testsuites/validation/tc-intr-vector-is-enabled.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsIntrReqVectorIsEnabled
+ * @ingroup RtemsIntrReqVectorIsEnabled
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -61,10 +61,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsIntrReqVectorIsEnabled \
- * spec:/rtems/intr/req/vector-is-enabled
+ * @defgroup RtemsIntrReqVectorIsEnabled spec:/rtems/intr/req/vector-is-enabled
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationIntr
*
* @{
*/
@@ -144,7 +143,7 @@ typedef struct {
/**
* @brief This member specifies if the ``enabled`` parameter value.
*/
- bool *enabled;;
+ bool *enabled;
/**
* @brief This member contains the return value of the
@@ -154,6 +153,12 @@ typedef struct {
struct {
/**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 3 ];
+
+ /**
* @brief This member defines the pre-condition states for the next action.
*/
size_t pcs[ 3 ];
@@ -584,16 +589,27 @@ RtemsIntrReqVectorIsEnabled_PopEntry(
];
}
+static void RtemsIntrReqVectorIsEnabled_SetPreConditionStates(
+ RtemsIntrReqVectorIsEnabled_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+
+ if ( ctx->Map.entry.Pre_IsEnabled_NA ) {
+ ctx->Map.pcs[ 2 ] = RtemsIntrReqVectorIsEnabled_Pre_IsEnabled_NA;
+ } else {
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ }
+}
+
static void RtemsIntrReqVectorIsEnabled_TestVariant(
RtemsIntrReqVectorIsEnabled_Context *ctx
)
{
RtemsIntrReqVectorIsEnabled_Pre_Vector_Prepare( ctx, ctx->Map.pcs[ 0 ] );
RtemsIntrReqVectorIsEnabled_Pre_Enabled_Prepare( ctx, ctx->Map.pcs[ 1 ] );
- RtemsIntrReqVectorIsEnabled_Pre_IsEnabled_Prepare(
- ctx,
- ctx->Map.entry.Pre_IsEnabled_NA ? RtemsIntrReqVectorIsEnabled_Pre_IsEnabled_NA : ctx->Map.pcs[ 2 ]
- );
+ RtemsIntrReqVectorIsEnabled_Pre_IsEnabled_Prepare( ctx, ctx->Map.pcs[ 2 ] );
RtemsIntrReqVectorIsEnabled_Action( ctx );
RtemsIntrReqVectorIsEnabled_Post_Status_Check(
ctx,
@@ -620,21 +636,22 @@ T_TEST_CASE_FIXTURE(
ctx->Map.index = 0;
for (
- ctx->Map.pcs[ 0 ] = RtemsIntrReqVectorIsEnabled_Pre_Vector_Valid;
- ctx->Map.pcs[ 0 ] < RtemsIntrReqVectorIsEnabled_Pre_Vector_NA;
- ++ctx->Map.pcs[ 0 ]
+ ctx->Map.pci[ 0 ] = RtemsIntrReqVectorIsEnabled_Pre_Vector_Valid;
+ ctx->Map.pci[ 0 ] < RtemsIntrReqVectorIsEnabled_Pre_Vector_NA;
+ ++ctx->Map.pci[ 0 ]
) {
for (
- ctx->Map.pcs[ 1 ] = RtemsIntrReqVectorIsEnabled_Pre_Enabled_Obj;
- ctx->Map.pcs[ 1 ] < RtemsIntrReqVectorIsEnabled_Pre_Enabled_NA;
- ++ctx->Map.pcs[ 1 ]
+ ctx->Map.pci[ 1 ] = RtemsIntrReqVectorIsEnabled_Pre_Enabled_Obj;
+ ctx->Map.pci[ 1 ] < RtemsIntrReqVectorIsEnabled_Pre_Enabled_NA;
+ ++ctx->Map.pci[ 1 ]
) {
for (
- ctx->Map.pcs[ 2 ] = RtemsIntrReqVectorIsEnabled_Pre_IsEnabled_Yes;
- ctx->Map.pcs[ 2 ] < RtemsIntrReqVectorIsEnabled_Pre_IsEnabled_NA;
- ++ctx->Map.pcs[ 2 ]
+ ctx->Map.pci[ 2 ] = RtemsIntrReqVectorIsEnabled_Pre_IsEnabled_Yes;
+ ctx->Map.pci[ 2 ] < RtemsIntrReqVectorIsEnabled_Pre_IsEnabled_NA;
+ ++ctx->Map.pci[ 2 ]
) {
ctx->Map.entry = RtemsIntrReqVectorIsEnabled_PopEntry( ctx );
+ RtemsIntrReqVectorIsEnabled_SetPreConditionStates( ctx );
RtemsIntrReqVectorIsEnabled_TestVariant( ctx );
}
}
diff --git a/testsuites/validation/tc-intr.c b/testsuites/validation/tc-intr.c
new file mode 100644
index 0000000000..72ac626c97
--- /dev/null
+++ b/testsuites/validation/tc-intr.c
@@ -0,0 +1,286 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsIntrValIntr
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/irq-extension.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsIntrValIntr spec:/rtems/intr/val/intr
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests some @ref RTEMSAPIClassicIntr directives.
+ *
+ * This test case performs the following actions:
+ *
+ * - Validate rtems_interrupt_local_disable() and
+ * rtems_interrupt_local_enable().
+ *
+ * - Check that maskable interrupts are enabled before the call to
+ * rtems_interrupt_local_disable() and disabled afterwards.
+ *
+ * - Check that maskable interrupts are disabled before the call to
+ * rtems_interrupt_local_disable() and disabled afterwards.
+ *
+ * - Check that the maskable interrupt status is restored by the call to
+ * rtems_interrupt_local_enable() according to the ``_isr_cookie``
+ * parameter. In this case maskable interrupts are still disabled
+ * afterwards.
+ *
+ * - Check that the maskable interrupt status is restored by the call to
+ * rtems_interrupt_local_enable() according to the ``_isr_cookie``
+ * parameter. In this case maskable interrupts are enabled afterwards.
+ *
+ * - Validate the interrupt lock directives.
+ *
+ * - Check that maskable interrupts are disabled before the call to
+ * rtems_interrupt_lock_interrupt_disable() and disabled afterwards.
+ *
+ * - Check that the maskable interrupt status is not changed by the
+ * rtems_interrupt_lock_acquire_isr() call.
+ *
+ * - Check that the maskable interrupt status is restored by the call to
+ * rtems_interrupt_lock_release() according to the ``_lock_context``
+ * parameter.
+ *
+ * - Check that maskable interrupts are disabled before the call to
+ * rtems_interrupt_lock_acquire() and disabled afterwards.
+ *
+ * - Check that the maskable interrupt status is restored by the call to
+ * rtems_interrupt_lock_release() according to the ``_lock_context``
+ * parameter.
+ *
+ * - Check that the maskable interrupt status is not changed by the
+ * rtems_interrupt_lock_destroy() call.
+ *
+ * - Validate the interrupt entry initialization.
+ *
+ * - Check that the entry is properly initialized by
+ * RTEMS_INTERRUPT_ENTRY_INITIALIZER().
+ *
+ * - Call rtems_interrupt_entry_initialize(). Check that the entry is
+ * properly initialized by rtems_interrupt_entry_initialize().
+ *
+ * @{
+ */
+
+static void EntryRoutine( void *arg )
+{
+ (void) arg;
+}
+
+static void EntryRoutine2( void *arg )
+{
+ (void) arg;
+}
+
+/**
+ * @brief Validate rtems_interrupt_local_disable() and
+ * rtems_interrupt_local_enable().
+ */
+static void RtemsIntrValIntr_Action_0( void )
+{
+ rtems_interrupt_level level;
+ rtems_interrupt_level level_2;
+
+ /*
+ * Check that maskable interrupts are enabled before the call to
+ * rtems_interrupt_local_disable() and disabled afterwards.
+ */
+ T_true( AreInterruptsEnabled() );
+ rtems_interrupt_local_disable( level );
+ T_false( AreInterruptsEnabled() );
+
+ /*
+ * Check that maskable interrupts are disabled before the call to
+ * rtems_interrupt_local_disable() and disabled afterwards.
+ */
+ T_false( AreInterruptsEnabled() );
+ rtems_interrupt_local_disable( level_2 );
+ T_false( AreInterruptsEnabled() );
+
+ /*
+ * Check that the maskable interrupt status is restored by the call to
+ * rtems_interrupt_local_enable() according to the ``_isr_cookie`` parameter.
+ * In this case maskable interrupts are still disabled afterwards.
+ */
+ T_false( AreInterruptsEnabled() );
+ rtems_interrupt_local_enable( level_2 );
+ T_false( AreInterruptsEnabled() );
+
+ /*
+ * Check that the maskable interrupt status is restored by the call to
+ * rtems_interrupt_local_enable() according to the ``_isr_cookie`` parameter.
+ * In this case maskable interrupts are enabled afterwards.
+ */
+ T_false( AreInterruptsEnabled() );
+ rtems_interrupt_local_enable( level );
+ T_true( AreInterruptsEnabled() );
+}
+
+/**
+ * @brief Validate the interrupt lock directives.
+ */
+static void RtemsIntrValIntr_Action_1( void )
+{
+ RTEMS_INTERRUPT_LOCK_DEFINE( , lock, "name" );
+ rtems_interrupt_lock_context lock_context;
+
+ /*
+ * Check that maskable interrupts are disabled before the call to
+ * rtems_interrupt_lock_interrupt_disable() and disabled afterwards.
+ */
+ T_true( AreInterruptsEnabled() );
+ rtems_interrupt_lock_interrupt_disable( &lock_context );
+ T_false( AreInterruptsEnabled() );
+
+ /*
+ * Check that the maskable interrupt status is not changed by the
+ * rtems_interrupt_lock_acquire_isr() call.
+ */
+ T_false( AreInterruptsEnabled() );
+ rtems_interrupt_lock_acquire_isr( &lock, &lock_context );
+ T_false( AreInterruptsEnabled() );
+
+ /*
+ * Check that the maskable interrupt status is restored by the call to
+ * rtems_interrupt_lock_release() according to the ``_lock_context``
+ * parameter.
+ */
+ T_false( AreInterruptsEnabled() );
+ rtems_interrupt_lock_release( &lock, &lock_context );
+ T_true( AreInterruptsEnabled() );
+
+ /*
+ * Check that maskable interrupts are disabled before the call to
+ * rtems_interrupt_lock_acquire() and disabled afterwards.
+ */
+ T_true( AreInterruptsEnabled() );
+ rtems_interrupt_lock_acquire( &lock, &lock_context );
+ T_false( AreInterruptsEnabled() );
+
+ /*
+ * Check that the maskable interrupt status is restored by the call to
+ * rtems_interrupt_lock_release() according to the ``_lock_context``
+ * parameter.
+ */
+ T_false( AreInterruptsEnabled() );
+ rtems_interrupt_lock_release( &lock, &lock_context );
+ T_true( AreInterruptsEnabled() );
+
+ /*
+ * Check that the maskable interrupt status is not changed by the
+ * rtems_interrupt_lock_destroy() call.
+ */
+ T_true( AreInterruptsEnabled() );
+ rtems_interrupt_lock_destroy( &lock );
+ T_true( AreInterruptsEnabled() );
+}
+
+/**
+ * @brief Validate the interrupt entry initialization.
+ */
+static void RtemsIntrValIntr_Action_2( void )
+{
+ int entry_arg;
+ int entry_arg_2;
+ const char entry_info[] = "1";
+ const char entry_info_2[] = "1";
+ rtems_interrupt_entry entry = RTEMS_INTERRUPT_ENTRY_INITIALIZER(
+ EntryRoutine,
+ &entry_arg,
+ entry_info
+ );
+
+ /*
+ * Check that the entry is properly initialized by
+ * RTEMS_INTERRUPT_ENTRY_INITIALIZER().
+ */
+ T_eq_ptr( entry.handler, EntryRoutine );
+ T_eq_ptr( entry.arg, &entry_arg );
+ T_eq_ptr( entry.next, NULL );
+ T_eq_ptr( entry.info, entry_info );
+
+ /*
+ * Call rtems_interrupt_entry_initialize(). Check that the entry is properly
+ * initialized by rtems_interrupt_entry_initialize().
+ */
+ entry.next = &entry;
+ rtems_interrupt_entry_initialize(
+ &entry,
+ EntryRoutine2,
+ &entry_arg_2,
+ entry_info_2
+ );
+ T_eq_ptr( entry.handler, EntryRoutine2 );
+ T_eq_ptr( entry.arg, &entry_arg_2 );
+ T_eq_ptr( entry.next, NULL );
+ T_eq_ptr( entry.info, entry_info_2 );
+}
+
+/**
+ * @fn void T_case_body_RtemsIntrValIntr( void )
+ */
+T_TEST_CASE( RtemsIntrValIntr )
+{
+ RtemsIntrValIntr_Action_0();
+ RtemsIntrValIntr_Action_1();
+ RtemsIntrValIntr_Action_2();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-io-getchark.c b/testsuites/validation/tc-io-getchark.c
new file mode 100644
index 0000000000..20aede7fd9
--- /dev/null
+++ b/testsuites/validation/tc-io-getchark.c
@@ -0,0 +1,328 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsIoReqGetchark
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/bspIo.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsIoReqGetchark spec:/rtems/io/req/getchark
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsIoReqGetchark_Pre_PollChar_Valid,
+ RtemsIoReqGetchark_Pre_PollChar_Null,
+ RtemsIoReqGetchark_Pre_PollChar_NA
+} RtemsIoReqGetchark_Pre_PollChar;
+
+typedef enum {
+ RtemsIoReqGetchark_Post_Result_PollChar,
+ RtemsIoReqGetchark_Post_Result_MinusOne,
+ RtemsIoReqGetchark_Post_Result_NA
+} RtemsIoReqGetchark_Post_Result;
+
+typedef enum {
+ RtemsIoReqGetchark_Post_Calls_Once,
+ RtemsIoReqGetchark_Post_Calls_NA
+} RtemsIoReqGetchark_Post_Calls;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_PollChar_NA : 1;
+ uint8_t Post_Result : 2;
+ uint8_t Post_Calls : 1;
+} RtemsIoReqGetchark_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/io/req/getchark test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the character input count.
+ */
+ size_t input_count;
+
+ /**
+ * @brief This member specifies the value for BSP_poll_char.
+ */
+ BSP_polling_getchar_function_type poll_char;
+
+ /**
+ * @brief This member contains the return value of the getchark() call.
+ */
+ int result;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsIoReqGetchark_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsIoReqGetchark_Context;
+
+static RtemsIoReqGetchark_Context
+ RtemsIoReqGetchark_Instance;
+
+static const char * const RtemsIoReqGetchark_PreDesc_PollChar[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsIoReqGetchark_PreDesc[] = {
+ RtemsIoReqGetchark_PreDesc_PollChar,
+ NULL
+};
+
+typedef RtemsIoReqGetchark_Context Context;
+
+static int PollChar( void )
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+ ++ctx->input_count;
+
+ return 123;
+}
+
+static void RtemsIoReqGetchark_Pre_PollChar_Prepare(
+ RtemsIoReqGetchark_Context *ctx,
+ RtemsIoReqGetchark_Pre_PollChar state
+)
+{
+ switch ( state ) {
+ case RtemsIoReqGetchark_Pre_PollChar_Valid: {
+ /*
+ * While BSP_poll_char references a function.
+ */
+ ctx->poll_char = PollChar;
+ break;
+ }
+
+ case RtemsIoReqGetchark_Pre_PollChar_Null: {
+ /*
+ * While BSP_poll_char is equal to NULL.
+ */
+ ctx->poll_char = NULL;
+ break;
+ }
+
+ case RtemsIoReqGetchark_Pre_PollChar_NA:
+ break;
+ }
+}
+
+static void RtemsIoReqGetchark_Post_Result_Check(
+ RtemsIoReqGetchark_Context *ctx,
+ RtemsIoReqGetchark_Post_Result state
+)
+{
+ switch ( state ) {
+ case RtemsIoReqGetchark_Post_Result_PollChar: {
+ /*
+ * The return value of getchark() shall be the return value of the
+ * function referenced by BSP_poll_char.
+ */
+ T_eq_int( ctx->result, 123 );
+ break;
+ }
+
+ case RtemsIoReqGetchark_Post_Result_MinusOne: {
+ /*
+ * The return value of getchark() shall be minus one.
+ */
+ T_eq_int( ctx->result, -1 );
+ T_eq_u32( ctx->input_count, 0 );
+ break;
+ }
+
+ case RtemsIoReqGetchark_Post_Result_NA:
+ break;
+ }
+}
+
+static void RtemsIoReqGetchark_Post_Calls_Check(
+ RtemsIoReqGetchark_Context *ctx,
+ RtemsIoReqGetchark_Post_Calls state
+)
+{
+ switch ( state ) {
+ case RtemsIoReqGetchark_Post_Calls_Once: {
+ /*
+ * The function referenced by BSP_poll_char shall be called exactly once
+ * to get the return value for getchark().
+ */
+ T_eq_u32( ctx->input_count, 1 );
+ break;
+ }
+
+ case RtemsIoReqGetchark_Post_Calls_NA:
+ break;
+ }
+}
+
+static void RtemsIoReqGetchark_Action( RtemsIoReqGetchark_Context *ctx )
+{
+ BSP_polling_getchar_function_type poll_char;
+
+ ctx->input_count = 0;
+ poll_char = BSP_poll_char;
+ BSP_poll_char = ctx->poll_char;
+ ctx->result = getchark();
+ BSP_poll_char = poll_char;
+}
+
+static const RtemsIoReqGetchark_Entry
+RtemsIoReqGetchark_Entries[] = {
+ { 0, 0, RtemsIoReqGetchark_Post_Result_PollChar,
+ RtemsIoReqGetchark_Post_Calls_Once },
+ { 0, 0, RtemsIoReqGetchark_Post_Result_MinusOne,
+ RtemsIoReqGetchark_Post_Calls_NA }
+};
+
+static const uint8_t
+RtemsIoReqGetchark_Map[] = {
+ 0, 1
+};
+
+static size_t RtemsIoReqGetchark_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsIoReqGetchark_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsIoReqGetchark_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsIoReqGetchark_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsIoReqGetchark_Scope,
+ .initial_context = &RtemsIoReqGetchark_Instance
+};
+
+static inline RtemsIoReqGetchark_Entry RtemsIoReqGetchark_PopEntry(
+ RtemsIoReqGetchark_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsIoReqGetchark_Entries[
+ RtemsIoReqGetchark_Map[ index ]
+ ];
+}
+
+static void RtemsIoReqGetchark_TestVariant( RtemsIoReqGetchark_Context *ctx )
+{
+ RtemsIoReqGetchark_Pre_PollChar_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsIoReqGetchark_Action( ctx );
+ RtemsIoReqGetchark_Post_Result_Check( ctx, ctx->Map.entry.Post_Result );
+ RtemsIoReqGetchark_Post_Calls_Check( ctx, ctx->Map.entry.Post_Calls );
+}
+
+/**
+ * @fn void T_case_body_RtemsIoReqGetchark( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsIoReqGetchark, &RtemsIoReqGetchark_Fixture )
+{
+ RtemsIoReqGetchark_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsIoReqGetchark_Pre_PollChar_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsIoReqGetchark_Pre_PollChar_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = RtemsIoReqGetchark_PopEntry( ctx );
+ RtemsIoReqGetchark_TestVariant( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-io-put-char.c b/testsuites/validation/tc-io-put-char.c
new file mode 100644
index 0000000000..671eed9835
--- /dev/null
+++ b/testsuites/validation/tc-io-put-char.c
@@ -0,0 +1,319 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsIoReqPutChar
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/bspIo.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsIoReqPutChar spec:/rtems/io/req/put-char
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsIoReqPutChar_Pre_Char_Nl,
+ RtemsIoReqPutChar_Pre_Char_Other,
+ RtemsIoReqPutChar_Pre_Char_NA
+} RtemsIoReqPutChar_Pre_Char;
+
+typedef enum {
+ RtemsIoReqPutChar_Post_Output_CrNl,
+ RtemsIoReqPutChar_Post_Output_Other,
+ RtemsIoReqPutChar_Post_Output_NA
+} RtemsIoReqPutChar_Post_Output;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Char_NA : 1;
+ uint8_t Post_Output : 2;
+} RtemsIoReqPutChar_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/io/req/put-char test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the character output.
+ */
+ int output[ 2 ];
+
+ /**
+ * @brief This member contains the character output count.
+ */
+ size_t output_count;
+
+ /**
+ * @brief This member specifies if the ``c`` parameter value.
+ */
+ int character;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsIoReqPutChar_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsIoReqPutChar_Context;
+
+static RtemsIoReqPutChar_Context
+ RtemsIoReqPutChar_Instance;
+
+static const char * const RtemsIoReqPutChar_PreDesc_Char[] = {
+ "Nl",
+ "Other",
+ "NA"
+};
+
+static const char * const * const RtemsIoReqPutChar_PreDesc[] = {
+ RtemsIoReqPutChar_PreDesc_Char,
+ NULL
+};
+
+typedef RtemsIoReqPutChar_Context Context;
+
+static void Output( int value )
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+
+ if ( ctx->output_count < RTEMS_ARRAY_SIZE( ctx->output ) ) {
+ ctx->output[ ctx->output_count ] = value;
+ }
+
+ ++ctx->output_count;
+}
+
+static void WrongOutput( char c )
+{
+ (void) c;
+ Output( -1 );
+}
+
+static void OutputChar( char c )
+{
+ BSP_output_char = WrongOutput;
+ Output( (unsigned char) c );
+}
+
+static void RtemsIoReqPutChar_Pre_Char_Prepare(
+ RtemsIoReqPutChar_Context *ctx,
+ RtemsIoReqPutChar_Pre_Char state
+)
+{
+ switch ( state ) {
+ case RtemsIoReqPutChar_Pre_Char_Nl: {
+ /*
+ * While the ``c`` parameter is equal to ``NL``.
+ */
+ ctx->character = '\n';
+ break;
+ }
+
+ case RtemsIoReqPutChar_Pre_Char_Other: {
+ /*
+ * While the ``c`` parameter is not equal to ``NL``.
+ */
+ ctx->character = 0xff;
+ break;
+ }
+
+ case RtemsIoReqPutChar_Pre_Char_NA:
+ break;
+ }
+}
+
+static void RtemsIoReqPutChar_Post_Output_Check(
+ RtemsIoReqPutChar_Context *ctx,
+ RtemsIoReqPutChar_Post_Output state
+)
+{
+ switch ( state ) {
+ case RtemsIoReqPutChar_Post_Output_CrNl: {
+ /*
+ * The function referenced by BSP_output_char shall be called with a
+ * ``CR`` character followed by a call with a ``NL`` character.
+ */
+ T_eq_int( ctx->output[ 0 ], (unsigned char) '\r' );
+ T_eq_int( ctx->output[ 1 ], (unsigned char) '\n' );
+ T_eq_sz( ctx->output_count, 2 );
+ break;
+ }
+
+ case RtemsIoReqPutChar_Post_Output_Other: {
+ /*
+ * The function referenced by BSP_output_char shall be called with the
+ * character specified by ``c``.
+ */
+ T_eq_int( ctx->output[ 0 ], 0xff );
+ T_eq_sz( ctx->output_count, 1 );
+ break;
+ }
+
+ case RtemsIoReqPutChar_Post_Output_NA:
+ break;
+ }
+}
+
+static void RtemsIoReqPutChar_Action( RtemsIoReqPutChar_Context *ctx )
+{
+ BSP_output_char_function_type output_char;
+
+ ctx->output[ 0 ] = -1;
+ ctx->output[ 1 ] = -1;
+ ctx->output_count = 0;
+ output_char = BSP_output_char;
+ BSP_output_char = OutputChar;
+ rtems_put_char( ctx->character, NULL );
+ BSP_output_char = output_char;
+}
+
+static const RtemsIoReqPutChar_Entry
+RtemsIoReqPutChar_Entries[] = {
+ { 0, 0, RtemsIoReqPutChar_Post_Output_CrNl },
+ { 0, 0, RtemsIoReqPutChar_Post_Output_Other }
+};
+
+static const uint8_t
+RtemsIoReqPutChar_Map[] = {
+ 0, 1
+};
+
+static size_t RtemsIoReqPutChar_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsIoReqPutChar_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsIoReqPutChar_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsIoReqPutChar_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsIoReqPutChar_Scope,
+ .initial_context = &RtemsIoReqPutChar_Instance
+};
+
+static inline RtemsIoReqPutChar_Entry RtemsIoReqPutChar_PopEntry(
+ RtemsIoReqPutChar_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsIoReqPutChar_Entries[
+ RtemsIoReqPutChar_Map[ index ]
+ ];
+}
+
+static void RtemsIoReqPutChar_TestVariant( RtemsIoReqPutChar_Context *ctx )
+{
+ RtemsIoReqPutChar_Pre_Char_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsIoReqPutChar_Action( ctx );
+ RtemsIoReqPutChar_Post_Output_Check( ctx, ctx->Map.entry.Post_Output );
+}
+
+/**
+ * @fn void T_case_body_RtemsIoReqPutChar( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsIoReqPutChar, &RtemsIoReqPutChar_Fixture )
+{
+ RtemsIoReqPutChar_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsIoReqPutChar_Pre_Char_Nl;
+ ctx->Map.pcs[ 0 ] < RtemsIoReqPutChar_Pre_Char_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = RtemsIoReqPutChar_PopEntry( ctx );
+ RtemsIoReqPutChar_TestVariant( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-io-putc.c b/testsuites/validation/tc-io-putc.c
new file mode 100644
index 0000000000..7b0efe2b17
--- /dev/null
+++ b/testsuites/validation/tc-io-putc.c
@@ -0,0 +1,319 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsIoReqPutc
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/bspIo.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsIoReqPutc spec:/rtems/io/req/putc
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsIoReqPutc_Pre_Char_Nl,
+ RtemsIoReqPutc_Pre_Char_Other,
+ RtemsIoReqPutc_Pre_Char_NA
+} RtemsIoReqPutc_Pre_Char;
+
+typedef enum {
+ RtemsIoReqPutc_Post_Output_CrNl,
+ RtemsIoReqPutc_Post_Output_Other,
+ RtemsIoReqPutc_Post_Output_NA
+} RtemsIoReqPutc_Post_Output;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Char_NA : 1;
+ uint8_t Post_Output : 2;
+} RtemsIoReqPutc_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/io/req/putc test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the character output.
+ */
+ int output[ 2 ];
+
+ /**
+ * @brief This member contains the character output count.
+ */
+ size_t output_count;
+
+ /**
+ * @brief This member specifies if the ``c`` parameter value.
+ */
+ char character;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsIoReqPutc_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsIoReqPutc_Context;
+
+static RtemsIoReqPutc_Context
+ RtemsIoReqPutc_Instance;
+
+static const char * const RtemsIoReqPutc_PreDesc_Char[] = {
+ "Nl",
+ "Other",
+ "NA"
+};
+
+static const char * const * const RtemsIoReqPutc_PreDesc[] = {
+ RtemsIoReqPutc_PreDesc_Char,
+ NULL
+};
+
+typedef RtemsIoReqPutc_Context Context;
+
+static void Output( int value )
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+
+ if ( ctx->output_count < RTEMS_ARRAY_SIZE( ctx->output ) ) {
+ ctx->output[ ctx->output_count ] = value;
+ }
+
+ ++ctx->output_count;
+}
+
+static void WrongOutput( char c )
+{
+ (void) c;
+ Output( -1 );
+}
+
+static void OutputChar( char c )
+{
+ BSP_output_char = WrongOutput;
+ Output( (unsigned char) c );
+}
+
+static void RtemsIoReqPutc_Pre_Char_Prepare(
+ RtemsIoReqPutc_Context *ctx,
+ RtemsIoReqPutc_Pre_Char state
+)
+{
+ switch ( state ) {
+ case RtemsIoReqPutc_Pre_Char_Nl: {
+ /*
+ * While the ``c`` parameter is equal to ``NL``.
+ */
+ ctx->character = '\n';
+ break;
+ }
+
+ case RtemsIoReqPutc_Pre_Char_Other: {
+ /*
+ * While the ``c`` parameter is not equal to ``NL``.
+ */
+ ctx->character = (char) 0xff;
+ break;
+ }
+
+ case RtemsIoReqPutc_Pre_Char_NA:
+ break;
+ }
+}
+
+static void RtemsIoReqPutc_Post_Output_Check(
+ RtemsIoReqPutc_Context *ctx,
+ RtemsIoReqPutc_Post_Output state
+)
+{
+ switch ( state ) {
+ case RtemsIoReqPutc_Post_Output_CrNl: {
+ /*
+ * The function referenced by BSP_output_char shall be called with a
+ * ``CR`` character followed by a call with a ``NL`` character.
+ */
+ T_eq_int( ctx->output[ 0 ], (unsigned char) '\r' );
+ T_eq_int( ctx->output[ 1 ], (unsigned char) '\n' );
+ T_eq_sz( ctx->output_count, 2 );
+ break;
+ }
+
+ case RtemsIoReqPutc_Post_Output_Other: {
+ /*
+ * The function referenced by BSP_output_char shall be called with the
+ * character specified by ``c``.
+ */
+ T_eq_int( ctx->output[ 0 ], 0xff );
+ T_eq_sz( ctx->output_count, 1 );
+ break;
+ }
+
+ case RtemsIoReqPutc_Post_Output_NA:
+ break;
+ }
+}
+
+static void RtemsIoReqPutc_Action( RtemsIoReqPutc_Context *ctx )
+{
+ BSP_output_char_function_type output_char;
+
+ ctx->output[ 0 ] = -1;
+ ctx->output[ 1 ] = -1;
+ ctx->output_count = 0;
+ output_char = BSP_output_char;
+ BSP_output_char = OutputChar;
+ rtems_putc( ctx->character );
+ BSP_output_char = output_char;
+}
+
+static const RtemsIoReqPutc_Entry
+RtemsIoReqPutc_Entries[] = {
+ { 0, 0, RtemsIoReqPutc_Post_Output_CrNl },
+ { 0, 0, RtemsIoReqPutc_Post_Output_Other }
+};
+
+static const uint8_t
+RtemsIoReqPutc_Map[] = {
+ 0, 1
+};
+
+static size_t RtemsIoReqPutc_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsIoReqPutc_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsIoReqPutc_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsIoReqPutc_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsIoReqPutc_Scope,
+ .initial_context = &RtemsIoReqPutc_Instance
+};
+
+static inline RtemsIoReqPutc_Entry RtemsIoReqPutc_PopEntry(
+ RtemsIoReqPutc_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsIoReqPutc_Entries[
+ RtemsIoReqPutc_Map[ index ]
+ ];
+}
+
+static void RtemsIoReqPutc_TestVariant( RtemsIoReqPutc_Context *ctx )
+{
+ RtemsIoReqPutc_Pre_Char_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsIoReqPutc_Action( ctx );
+ RtemsIoReqPutc_Post_Output_Check( ctx, ctx->Map.entry.Post_Output );
+}
+
+/**
+ * @fn void T_case_body_RtemsIoReqPutc( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsIoReqPutc, &RtemsIoReqPutc_Fixture )
+{
+ RtemsIoReqPutc_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsIoReqPutc_Pre_Char_Nl;
+ ctx->Map.pcs[ 0 ] < RtemsIoReqPutc_Pre_Char_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = RtemsIoReqPutc_PopEntry( ctx );
+ RtemsIoReqPutc_TestVariant( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-message-broadcast.c b/testsuites/validation/tc-message-broadcast.c
new file mode 100644
index 0000000000..01de6a99b3
--- /dev/null
+++ b/testsuites/validation/tc-message-broadcast.c
@@ -0,0 +1,1203 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsMessageReqBroadcast
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsMessageReqBroadcast spec:/rtems/message/req/broadcast
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsMessageReqBroadcast_Pre_SendBuffer_Valid,
+ RtemsMessageReqBroadcast_Pre_SendBuffer_Null,
+ RtemsMessageReqBroadcast_Pre_SendBuffer_NA
+} RtemsMessageReqBroadcast_Pre_SendBuffer;
+
+typedef enum {
+ RtemsMessageReqBroadcast_Pre_Count_Valid,
+ RtemsMessageReqBroadcast_Pre_Count_Null,
+ RtemsMessageReqBroadcast_Pre_Count_NA
+} RtemsMessageReqBroadcast_Pre_Count;
+
+typedef enum {
+ RtemsMessageReqBroadcast_Pre_Id_Valid,
+ RtemsMessageReqBroadcast_Pre_Id_Invalid,
+ RtemsMessageReqBroadcast_Pre_Id_NA
+} RtemsMessageReqBroadcast_Pre_Id;
+
+typedef enum {
+ RtemsMessageReqBroadcast_Pre_MsgSize_Zero,
+ RtemsMessageReqBroadcast_Pre_MsgSize_SomeSize,
+ RtemsMessageReqBroadcast_Pre_MsgSize_MaxSize,
+ RtemsMessageReqBroadcast_Pre_MsgSize_TooLarge,
+ RtemsMessageReqBroadcast_Pre_MsgSize_NA
+} RtemsMessageReqBroadcast_Pre_MsgSize;
+
+typedef enum {
+ RtemsMessageReqBroadcast_Pre_MsgQueue_Empty,
+ RtemsMessageReqBroadcast_Pre_MsgQueue_Several,
+ RtemsMessageReqBroadcast_Pre_MsgQueue_NA
+} RtemsMessageReqBroadcast_Pre_MsgQueue;
+
+typedef enum {
+ RtemsMessageReqBroadcast_Pre_Receivers_Waiting,
+ RtemsMessageReqBroadcast_Pre_Receivers_None,
+ RtemsMessageReqBroadcast_Pre_Receivers_NA
+} RtemsMessageReqBroadcast_Pre_Receivers;
+
+typedef enum {
+ RtemsMessageReqBroadcast_Pre_Storage_Nop,
+ RtemsMessageReqBroadcast_Pre_Storage_NA
+} RtemsMessageReqBroadcast_Pre_Storage;
+
+typedef enum {
+ RtemsMessageReqBroadcast_Post_Status_Ok,
+ RtemsMessageReqBroadcast_Post_Status_InvId,
+ RtemsMessageReqBroadcast_Post_Status_InvAddr,
+ RtemsMessageReqBroadcast_Post_Status_InvSize,
+ RtemsMessageReqBroadcast_Post_Status_NA
+} RtemsMessageReqBroadcast_Post_Status;
+
+typedef enum {
+ RtemsMessageReqBroadcast_Post_Count_Zero,
+ RtemsMessageReqBroadcast_Post_Count_Set,
+ RtemsMessageReqBroadcast_Post_Count_Nop,
+ RtemsMessageReqBroadcast_Post_Count_NA
+} RtemsMessageReqBroadcast_Post_Count;
+
+typedef enum {
+ RtemsMessageReqBroadcast_Post_MsgQueue_Nop,
+ RtemsMessageReqBroadcast_Post_MsgQueue_NA
+} RtemsMessageReqBroadcast_Post_MsgQueue;
+
+typedef enum {
+ RtemsMessageReqBroadcast_Post_Receivers_Unblocked,
+ RtemsMessageReqBroadcast_Post_Receivers_Nop,
+ RtemsMessageReqBroadcast_Post_Receivers_NA
+} RtemsMessageReqBroadcast_Post_Receivers;
+
+typedef enum {
+ RtemsMessageReqBroadcast_Post_RecSize_Message,
+ RtemsMessageReqBroadcast_Post_RecSize_Nop,
+ RtemsMessageReqBroadcast_Post_RecSize_NA
+} RtemsMessageReqBroadcast_Post_RecSize;
+
+typedef enum {
+ RtemsMessageReqBroadcast_Post_RecBuffer_Message,
+ RtemsMessageReqBroadcast_Post_RecBuffer_Nop,
+ RtemsMessageReqBroadcast_Post_RecBuffer_NA
+} RtemsMessageReqBroadcast_Post_RecBuffer;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_SendBuffer_NA : 1;
+ uint32_t Pre_Count_NA : 1;
+ uint32_t Pre_Id_NA : 1;
+ uint32_t Pre_MsgSize_NA : 1;
+ uint32_t Pre_MsgQueue_NA : 1;
+ uint32_t Pre_Receivers_NA : 1;
+ uint32_t Pre_Storage_NA : 1;
+ uint32_t Post_Status : 3;
+ uint32_t Post_Count : 2;
+ uint32_t Post_MsgQueue : 1;
+ uint32_t Post_Receivers : 2;
+ uint32_t Post_RecSize : 2;
+ uint32_t Post_RecBuffer : 2;
+} RtemsMessageReqBroadcast_Entry;
+
+#define MAXIMUM_PENDING_MESSAGES 3
+#define MAXIMUM_MESSAGE_SIZE 5
+#define NUMBER_OF_WORKERS 3
+
+/**
+ * @brief Test context for spec:/rtems/message/req/broadcast test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a valid ID of a message queue.
+ */
+ rtems_id message_queue_id;
+
+ /**
+ * @brief This member is used as storage area for the message queue.
+ */
+ RTEMS_MESSAGE_QUEUE_BUFFER( MAXIMUM_MESSAGE_SIZE )
+ storage_area[ MAXIMUM_PENDING_MESSAGES ];
+
+ /**
+ * @brief This member contains a buffer to receive messages from the queue.
+ */
+ uint8_t receive_buffer[ NUMBER_OF_WORKERS ][ MAXIMUM_MESSAGE_SIZE ];
+
+ /**
+ * @brief This member contains several buffers to receive a messages size.
+ */
+ size_t receive_size[ NUMBER_OF_WORKERS ];
+
+ /**
+ * @brief This member contains the returned status codes of the receivers.
+ */
+ rtems_status_code receive_status[ NUMBER_OF_WORKERS ];
+
+ /**
+ * @brief This member specifies the ``id`` parameter of the action.
+ */
+ rtems_id id_param;
+
+ /**
+ * @brief This member specifies the ``buffer`` parameter of the action.
+ */
+ const void *buffer_param;
+
+ /**
+ * @brief This member specifies the ``size`` parameter of the action.
+ */
+ size_t size_param;
+
+ /**
+ * @brief This member specifies the ``count`` parameter of the action.
+ */
+ uint32_t *count_param;
+
+ /**
+ * @brief This member contains the returned status code of the action.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member contains the value returned in parameter ``count`` of
+ * the action.
+ */
+ uint32_t count;
+
+ /**
+ * @brief This member contains the task identifiers of the worker tasks.
+ */
+ rtems_id worker_id[ NUMBER_OF_WORKERS ];
+
+ /**
+ * @brief This member contains a pointer to a function which is executed to
+ * check that the action has not changed the content of the message queue.
+ */
+ void (*check_msgq_unchanged)( void *ctx_in );
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 7 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsMessageReqBroadcast_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsMessageReqBroadcast_Context;
+
+static RtemsMessageReqBroadcast_Context
+ RtemsMessageReqBroadcast_Instance;
+
+static const char * const RtemsMessageReqBroadcast_PreDesc_SendBuffer[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsMessageReqBroadcast_PreDesc_Count[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsMessageReqBroadcast_PreDesc_Id[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsMessageReqBroadcast_PreDesc_MsgSize[] = {
+ "Zero",
+ "SomeSize",
+ "MaxSize",
+ "TooLarge",
+ "NA"
+};
+
+static const char * const RtemsMessageReqBroadcast_PreDesc_MsgQueue[] = {
+ "Empty",
+ "Several",
+ "NA"
+};
+
+static const char * const RtemsMessageReqBroadcast_PreDesc_Receivers[] = {
+ "Waiting",
+ "None",
+ "NA"
+};
+
+static const char * const RtemsMessageReqBroadcast_PreDesc_Storage[] = {
+ "Nop",
+ "NA"
+};
+
+static const char * const * const RtemsMessageReqBroadcast_PreDesc[] = {
+ RtemsMessageReqBroadcast_PreDesc_SendBuffer,
+ RtemsMessageReqBroadcast_PreDesc_Count,
+ RtemsMessageReqBroadcast_PreDesc_Id,
+ RtemsMessageReqBroadcast_PreDesc_MsgSize,
+ RtemsMessageReqBroadcast_PreDesc_MsgQueue,
+ RtemsMessageReqBroadcast_PreDesc_Receivers,
+ RtemsMessageReqBroadcast_PreDesc_Storage,
+ NULL
+};
+
+typedef RtemsMessageReqBroadcast_Context Context;
+static const rtems_interval TIMEOUT_TICKS = 1;
+static const rtems_event_set EVENT_RECEIVE = RTEMS_EVENT_17;
+static const uint8_t message[ MAXIMUM_MESSAGE_SIZE ] =
+ { 13, 42, 99, 222, 101 };
+static const uint8_t queued_message[] = { 200, 201, 202 };
+
+static void Receive( Context *ctx, size_t worker_index )
+{
+ ctx->receive_status[worker_index] = rtems_message_queue_receive(
+ ctx->message_queue_id,
+ ctx->receive_buffer[worker_index],
+ &ctx->receive_size[worker_index],
+ RTEMS_WAIT,
+ TIMEOUT_TICKS
+ );
+}
+
+static void WorkerTask( rtems_task_argument argument )
+{
+ static size_t worker_number = 0;
+ size_t worker_index = worker_number++;
+ Context *ctx = (Context *) argument;
+
+ while ( true ) {
+ ReceiveAnyEvents();
+ Receive( ctx, worker_index );
+ }
+}
+
+static void CheckForNoMessage(
+ Context *ctx,
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+)
+{
+ (void) ctx;
+ (void) message_buffer;
+ (void) message_size;
+ T_rsc( status, RTEMS_UNSATISFIED );
+}
+
+static void CheckForMessage(
+ Context *ctx,
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+)
+{
+ T_rsc_success( status );
+ T_eq_u32( message_size, ctx->size_param );
+ T_eq_mem( message_buffer, message, ctx->size_param );
+}
+
+static void CheckForQueuedMessage(
+ Context *ctx,
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+)
+{
+ (void) ctx;
+ T_rsc_success( status );
+ T_eq_u32( message_size, sizeof( queued_message ) );
+ T_eq_mem( message_buffer, queued_message, sizeof( queued_message ) );
+}
+
+static void PopMessage(
+ Context *ctx,
+ void (*check_fn)(
+ Context *ctx,
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+ )
+)
+{
+ rtems_status_code status;
+ uint8_t message_buffer[ MAXIMUM_MESSAGE_SIZE ];
+ size_t message_size;
+
+ status = rtems_message_queue_receive(
+ ctx->message_queue_id,
+ &message_buffer,
+ &message_size,
+ RTEMS_LOCAL | RTEMS_NO_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+
+ check_fn( ctx, status, message_buffer, message_size );
+}
+
+static void CheckForNoMessageInQueue( void *ctx_in )
+{
+ Context *ctx = ctx_in;
+ PopMessage( ctx, CheckForNoMessage );
+}
+
+static void CheckForSeveralMessagesInQueue( void *ctx_in )
+{
+ Context *ctx = ctx_in;
+ PopMessage( ctx, CheckForQueuedMessage );
+ PopMessage( ctx, CheckForQueuedMessage );
+ PopMessage( ctx, CheckForNoMessage );
+}
+
+static void SendMsg( Context *ctx )
+{
+ rtems_status_code status;
+
+ status = rtems_message_queue_send(
+ ctx->message_queue_id,
+ queued_message,
+ sizeof( queued_message )
+ );
+ T_rsc_success( status );
+}
+
+static void RtemsMessageReqBroadcast_Pre_SendBuffer_Prepare(
+ RtemsMessageReqBroadcast_Context *ctx,
+ RtemsMessageReqBroadcast_Pre_SendBuffer state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqBroadcast_Pre_SendBuffer_Valid: {
+ /*
+ * While the ``buffer`` parameter references a memory area where the
+ * message to be sent is stored.
+ */
+ ctx->buffer_param = &message;
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Pre_SendBuffer_Null: {
+ /*
+ * While the ``buffer`` parameter is NULL.
+ */
+ ctx->buffer_param = NULL;
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Pre_SendBuffer_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqBroadcast_Pre_Count_Prepare(
+ RtemsMessageReqBroadcast_Context *ctx,
+ RtemsMessageReqBroadcast_Pre_Count state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqBroadcast_Pre_Count_Valid: {
+ /*
+ * While the ``count`` parameter references an ``uint32_t`` object.
+ */
+ ctx->count_param = &ctx->count;
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Pre_Count_Null: {
+ /*
+ * While the ``count`` parameter is NULL.
+ */
+ ctx->count_param = NULL;
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Pre_Count_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqBroadcast_Pre_Id_Prepare(
+ RtemsMessageReqBroadcast_Context *ctx,
+ RtemsMessageReqBroadcast_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqBroadcast_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter is valid.
+ */
+ ctx->id_param = ctx->message_queue_id;
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is invalid.
+ */
+ ctx->id_param = RTEMS_ID_NONE;
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqBroadcast_Pre_MsgSize_Prepare(
+ RtemsMessageReqBroadcast_Context *ctx,
+ RtemsMessageReqBroadcast_Pre_MsgSize state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqBroadcast_Pre_MsgSize_Zero: {
+ /*
+ * While the ``size`` parameter is 0.
+ */
+ ctx->size_param = 0;
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Pre_MsgSize_SomeSize: {
+ /*
+ * While the ``size`` parameter has a value between 0 and the maximum
+ * message size.
+ */
+ ctx->size_param = MAXIMUM_MESSAGE_SIZE / 2 + 1;
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Pre_MsgSize_MaxSize: {
+ /*
+ * While the ``size`` parameter has a value of the maximum message size.
+ */
+ ctx->size_param = MAXIMUM_MESSAGE_SIZE;
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Pre_MsgSize_TooLarge: {
+ /*
+ * While the ``size`` parameter has a value greater than the maximum
+ * message size.
+ */
+ ctx->size_param = MAXIMUM_MESSAGE_SIZE + 1;
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Pre_MsgSize_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqBroadcast_Pre_MsgQueue_Prepare(
+ RtemsMessageReqBroadcast_Context *ctx,
+ RtemsMessageReqBroadcast_Pre_MsgQueue state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqBroadcast_Pre_MsgQueue_Empty: {
+ /*
+ * While there is no message in the message queue.
+ */
+ /* Message queue is already empty. */
+ ctx->check_msgq_unchanged = CheckForNoMessageInQueue;
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Pre_MsgQueue_Several: {
+ /*
+ * While there are messages in the message queue.
+ */
+ SendMsg( ctx );
+ SendMsg( ctx );
+ ctx->check_msgq_unchanged = CheckForSeveralMessagesInQueue;
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Pre_MsgQueue_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqBroadcast_Pre_Receivers_Prepare(
+ RtemsMessageReqBroadcast_Context *ctx,
+ RtemsMessageReqBroadcast_Pre_Receivers state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqBroadcast_Pre_Receivers_Waiting: {
+ /*
+ * While one or more receivers are waiting to receive a message.
+ */
+ size_t i;
+ for ( i = 0; i < NUMBER_OF_WORKERS; ++i ) {
+ SendEvents( ctx->worker_id[i], EVENT_RECEIVE );
+ }
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Pre_Receivers_None: {
+ /*
+ * While no receiver is waiting to receive a message.
+ */
+ /* There is already no receiver waiting. */
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Pre_Receivers_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqBroadcast_Pre_Storage_Prepare(
+ RtemsMessageReqBroadcast_Context *ctx,
+ RtemsMessageReqBroadcast_Pre_Storage state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqBroadcast_Pre_Storage_Nop: {
+ /*
+ * While the memory area to which a pointer is provided as member
+ * storage_area of type rtems_message_queue_config when the message queue
+ * is constructed by rtems_message_queue_construct() is altered only by
+ * the RTEMS operating system.
+ */
+ /* Only a requirement text. */
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Pre_Storage_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqBroadcast_Post_Status_Check(
+ RtemsMessageReqBroadcast_Context *ctx,
+ RtemsMessageReqBroadcast_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqBroadcast_Post_Status_Ok: {
+ /*
+ * The return status of rtems_message_queue_broadcast() shall be
+ * RTEMS_SUCCESSFUL
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Post_Status_InvId: {
+ /*
+ * The return status of rtems_message_queue_broadcast() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_message_queue_broadcast() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Post_Status_InvSize: {
+ /*
+ * The return status of rtems_message_queue_broadcast() shall be
+ * RTEMS_INVALID_SIZE.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_SIZE );
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqBroadcast_Post_Count_Check(
+ RtemsMessageReqBroadcast_Context *ctx,
+ RtemsMessageReqBroadcast_Post_Count state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqBroadcast_Post_Count_Zero: {
+ /*
+ * The value of the object referenced by the ``count`` parameter shall be
+ * set to 0 after the return of the rtems_message_queue_broadcast() call.
+ */
+ T_eq_u32( ctx->count, 0 );
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Post_Count_Set: {
+ /*
+ * The value of the object referenced by the ``count`` parameter shall be
+ * set to the number of tasks unblocked (see unblock) by the call to
+ * directive rtems_message_queue_broadcast() after the return of the
+ * rtems_message_queue_broadcast() call.
+ */
+ T_eq_u32( ctx->count, NUMBER_OF_WORKERS );
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Post_Count_Nop: {
+ /*
+ * The value of the object referenced by the ``count`` parameter in past
+ * call to rtems_message_queue_broadcast() shall not be accessed by the
+ * rtems_message_queue_broadcast() call (see also Nop).
+ */
+ T_eq_u32( ctx->count, UINT8_MAX );
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Post_Count_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqBroadcast_Post_MsgQueue_Check(
+ RtemsMessageReqBroadcast_Context *ctx,
+ RtemsMessageReqBroadcast_Post_MsgQueue state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqBroadcast_Post_MsgQueue_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in the past call to
+ * rtems_message_queue_broadcast() shall not be accessed by that call
+ * (see also Nop).
+ */
+ ctx->check_msgq_unchanged( ctx );
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Post_MsgQueue_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqBroadcast_Post_Receivers_Check(
+ RtemsMessageReqBroadcast_Context *ctx,
+ RtemsMessageReqBroadcast_Post_Receivers state
+)
+{
+ size_t i;
+
+ switch ( state ) {
+ case RtemsMessageReqBroadcast_Post_Receivers_Unblocked: {
+ /*
+ * The call to the rtems_message_queue_broadcast() directive shall
+ * unblock all receivers waiting for a message at the message queue.
+ *
+ * Note: Currently, rtems_message_queue_broadcast() unblocks receivers in
+ * a none-atomic way. Meaning, it will not only unblock those receivers
+ * it finds waiting at the queue when rtems_message_queue_broadcast() is
+ * invoked but also any new receivers which start waiting for messages
+ * after rtems_message_queue_broadcast() is invoked and before it
+ * returns. This may lead to infinite unblocking loops.
+ */
+ for ( i = 0; i < NUMBER_OF_WORKERS; ++i ) {
+ T_rsc_success( ctx->receive_status[i] );
+ }
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Post_Receivers_Nop: {
+ /*
+ * The receivers waiting for a message at the message queue shall not be
+ * affected by the call to the rtems_message_queue_broadcast() directive.
+ */
+ for ( i = 0; i < NUMBER_OF_WORKERS; ++i ) {
+ T_rsc( ctx->receive_status[i], RTEMS_TIMEOUT );
+ }
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Post_Receivers_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqBroadcast_Post_RecSize_Check(
+ RtemsMessageReqBroadcast_Context *ctx,
+ RtemsMessageReqBroadcast_Post_RecSize state
+)
+{
+ size_t i;
+
+ switch ( state ) {
+ case RtemsMessageReqBroadcast_Post_RecSize_Message: {
+ /*
+ * The values of the objects referenced by the ``size`` parameter in all
+ * calls to rtems_message_queue_receive() which are unblocked (see
+ * unblock) by the rtems_message_queue_broadcast() call shall be set to
+ * the same value as provided by parameter ``size`` of the
+ * rtems_message_queue_broadcast() call after the return of the
+ * rtems_message_queue_broadcast() call.
+ */
+ for ( i = 0; i < NUMBER_OF_WORKERS; ++i ) {
+ CheckForMessage(
+ ctx,
+ ctx->receive_status[i],
+ ctx->receive_buffer[i],
+ ctx->receive_size[i]
+ );
+ }
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Post_RecSize_Nop: {
+ /*
+ * Objects referenced by the ``size`` parameter in past calls to
+ * rtems_message_queue_receive() shall not be accessed by the
+ * rtems_message_queue_broadcast() call (see also Nop).
+ */
+ for ( i = 0; i < NUMBER_OF_WORKERS; ++i ) {
+ T_eq_sz( ctx->receive_size[i], SIZE_MAX );
+ }
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Post_RecSize_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqBroadcast_Post_RecBuffer_Check(
+ RtemsMessageReqBroadcast_Context *ctx,
+ RtemsMessageReqBroadcast_Post_RecBuffer state
+)
+{
+ size_t w, i;
+
+ switch ( state ) {
+ case RtemsMessageReqBroadcast_Post_RecBuffer_Message: {
+ /*
+ * Bytes 0 till ``size`` - 1 of the object referenced by the ``buffer``
+ * parameter in all calls to rtems_message_queue_receive() which are
+ * unblocked (see unblock) by the rtems_message_queue_broadcast() call
+ * shall be set to the same values as bytes 0 till ``size`` - 1 of the
+ * object referenced by parameter ``buffer`` of the
+ * rtems_message_queue_broadcast() call after the return of the
+ * rtems_message_queue_receive() call.
+ */
+ for ( i = 0; i < NUMBER_OF_WORKERS; ++i ) {
+ CheckForMessage(
+ ctx,
+ ctx->receive_status[i],
+ ctx->receive_buffer[i],
+ ctx->receive_size[i]
+ );
+ }
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Post_RecBuffer_Nop: {
+ /*
+ * Objects referenced by the ``buffer`` parameter in past calls to
+ * rtems_message_queue_receive() shall not be accessed by the
+ * rtems_message_queue_broadcast() call (see also Nop).
+ */
+ for ( w = 0; w < NUMBER_OF_WORKERS; ++w ) {
+ for ( i = 0; i < MAXIMUM_MESSAGE_SIZE; ++i ) {
+ T_eq_u8( ctx->receive_buffer[w][i], UINT8_MAX );
+ }
+ }
+ break;
+ }
+
+ case RtemsMessageReqBroadcast_Post_RecBuffer_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqBroadcast_Setup(
+ RtemsMessageReqBroadcast_Context *ctx
+)
+{
+ size_t i;
+ SetSelfPriority( PRIO_NORMAL );
+
+ for ( i = 0; i < NUMBER_OF_WORKERS; ++i ) {
+ ctx->worker_id[i] = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id[i], WorkerTask, ctx );
+ }
+}
+
+static void RtemsMessageReqBroadcast_Setup_Wrap( void *arg )
+{
+ RtemsMessageReqBroadcast_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsMessageReqBroadcast_Setup( ctx );
+}
+
+static void RtemsMessageReqBroadcast_Teardown(
+ RtemsMessageReqBroadcast_Context *ctx
+)
+{
+ size_t i;
+
+ for ( i = 0; i < NUMBER_OF_WORKERS; ++i ) {
+ DeleteTask( ctx->worker_id[i] );
+ }
+ RestoreRunnerPriority();
+}
+
+static void RtemsMessageReqBroadcast_Teardown_Wrap( void *arg )
+{
+ RtemsMessageReqBroadcast_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsMessageReqBroadcast_Teardown( ctx );
+}
+
+static void RtemsMessageReqBroadcast_Prepare(
+ RtemsMessageReqBroadcast_Context *ctx
+)
+{
+ rtems_status_code status;
+ size_t i;
+
+ rtems_message_queue_config config = {
+ .name = rtems_build_name( 'M', 'S', 'G', 'Q' ),
+ .maximum_pending_messages = MAXIMUM_PENDING_MESSAGES,
+ .maximum_message_size = MAXIMUM_MESSAGE_SIZE,
+ .storage_area = ctx->storage_area,
+ .storage_size = sizeof( ctx->storage_area ),
+ .storage_free = NULL,
+ .attributes = RTEMS_DEFAULT_ATTRIBUTES
+ };
+
+ status = rtems_message_queue_construct(
+ &config,
+ &ctx->message_queue_id
+ );
+ T_rsc_success( status );
+
+ ctx->count = UINT8_MAX;
+ for ( i = 0; i < NUMBER_OF_WORKERS; ++i ) {
+ ctx->receive_size[i] = SIZE_MAX;
+ memset( ctx->receive_buffer[i], UINT8_MAX, MAXIMUM_MESSAGE_SIZE );
+ }
+}
+
+static void RtemsMessageReqBroadcast_Action(
+ RtemsMessageReqBroadcast_Context *ctx
+)
+{
+ ctx->status = rtems_message_queue_broadcast(
+ ctx->id_param,
+ ctx->buffer_param,
+ ctx->size_param,
+ ctx->count_param
+ );
+
+ FinalClockTick();
+}
+
+static void RtemsMessageReqBroadcast_Cleanup(
+ RtemsMessageReqBroadcast_Context *ctx
+)
+{
+ T_rsc_success( rtems_message_queue_delete( ctx->message_queue_id ) );
+}
+
+static const RtemsMessageReqBroadcast_Entry
+RtemsMessageReqBroadcast_Entries[] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqBroadcast_Post_Status_InvAddr,
+ RtemsMessageReqBroadcast_Post_Count_Nop,
+ RtemsMessageReqBroadcast_Post_MsgQueue_Nop,
+ RtemsMessageReqBroadcast_Post_Receivers_NA,
+ RtemsMessageReqBroadcast_Post_RecSize_NA,
+ RtemsMessageReqBroadcast_Post_RecBuffer_NA },
+ { 1, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqBroadcast_Post_Status_NA,
+ RtemsMessageReqBroadcast_Post_Count_NA,
+ RtemsMessageReqBroadcast_Post_MsgQueue_NA,
+ RtemsMessageReqBroadcast_Post_Receivers_NA,
+ RtemsMessageReqBroadcast_Post_RecSize_NA,
+ RtemsMessageReqBroadcast_Post_RecBuffer_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqBroadcast_Post_Status_InvAddr,
+ RtemsMessageReqBroadcast_Post_Count_Nop,
+ RtemsMessageReqBroadcast_Post_MsgQueue_Nop,
+ RtemsMessageReqBroadcast_Post_Receivers_Nop,
+ RtemsMessageReqBroadcast_Post_RecSize_Nop,
+ RtemsMessageReqBroadcast_Post_RecBuffer_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqBroadcast_Post_Status_InvId,
+ RtemsMessageReqBroadcast_Post_Count_Nop,
+ RtemsMessageReqBroadcast_Post_MsgQueue_Nop,
+ RtemsMessageReqBroadcast_Post_Receivers_NA,
+ RtemsMessageReqBroadcast_Post_RecSize_NA,
+ RtemsMessageReqBroadcast_Post_RecBuffer_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqBroadcast_Post_Status_Ok,
+ RtemsMessageReqBroadcast_Post_Count_Zero,
+ RtemsMessageReqBroadcast_Post_MsgQueue_Nop,
+ RtemsMessageReqBroadcast_Post_Receivers_NA,
+ RtemsMessageReqBroadcast_Post_RecSize_NA,
+ RtemsMessageReqBroadcast_Post_RecBuffer_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqBroadcast_Post_Status_InvId,
+ RtemsMessageReqBroadcast_Post_Count_Nop,
+ RtemsMessageReqBroadcast_Post_MsgQueue_Nop,
+ RtemsMessageReqBroadcast_Post_Receivers_Nop,
+ RtemsMessageReqBroadcast_Post_RecSize_Nop,
+ RtemsMessageReqBroadcast_Post_RecBuffer_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqBroadcast_Post_Status_Ok,
+ RtemsMessageReqBroadcast_Post_Count_Set,
+ RtemsMessageReqBroadcast_Post_MsgQueue_Nop,
+ RtemsMessageReqBroadcast_Post_Receivers_Unblocked,
+ RtemsMessageReqBroadcast_Post_RecSize_Message,
+ RtemsMessageReqBroadcast_Post_RecBuffer_Message },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqBroadcast_Post_Status_InvSize,
+ RtemsMessageReqBroadcast_Post_Count_Nop,
+ RtemsMessageReqBroadcast_Post_MsgQueue_Nop,
+ RtemsMessageReqBroadcast_Post_Receivers_NA,
+ RtemsMessageReqBroadcast_Post_RecSize_NA,
+ RtemsMessageReqBroadcast_Post_RecBuffer_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqBroadcast_Post_Status_InvSize,
+ RtemsMessageReqBroadcast_Post_Count_Nop,
+ RtemsMessageReqBroadcast_Post_MsgQueue_Nop,
+ RtemsMessageReqBroadcast_Post_Receivers_Nop,
+ RtemsMessageReqBroadcast_Post_RecSize_Nop,
+ RtemsMessageReqBroadcast_Post_RecBuffer_Nop }
+};
+
+static const uint8_t
+RtemsMessageReqBroadcast_Map[] = {
+ 6, 4, 1, 4, 6, 4, 1, 4, 6, 4, 1, 4, 8, 7, 1, 7, 5, 3, 1, 3, 5, 3, 1, 3, 5, 3,
+ 1, 3, 5, 3, 1, 3, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0,
+ 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0,
+ 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0,
+ 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 1, 0
+};
+
+static size_t RtemsMessageReqBroadcast_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsMessageReqBroadcast_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsMessageReqBroadcast_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsMessageReqBroadcast_Fixture = {
+ .setup = RtemsMessageReqBroadcast_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsMessageReqBroadcast_Teardown_Wrap,
+ .scope = RtemsMessageReqBroadcast_Scope,
+ .initial_context = &RtemsMessageReqBroadcast_Instance
+};
+
+static inline RtemsMessageReqBroadcast_Entry RtemsMessageReqBroadcast_PopEntry(
+ RtemsMessageReqBroadcast_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsMessageReqBroadcast_Entries[
+ RtemsMessageReqBroadcast_Map[ index ]
+ ];
+}
+
+static void RtemsMessageReqBroadcast_TestVariant(
+ RtemsMessageReqBroadcast_Context *ctx
+)
+{
+ RtemsMessageReqBroadcast_Pre_SendBuffer_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsMessageReqBroadcast_Pre_Count_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsMessageReqBroadcast_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsMessageReqBroadcast_Pre_MsgSize_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsMessageReqBroadcast_Pre_MsgQueue_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsMessageReqBroadcast_Pre_Receivers_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsMessageReqBroadcast_Pre_Storage_Prepare( ctx, ctx->Map.pcs[ 6 ] );
+ RtemsMessageReqBroadcast_Action( ctx );
+ RtemsMessageReqBroadcast_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ RtemsMessageReqBroadcast_Post_Count_Check( ctx, ctx->Map.entry.Post_Count );
+ RtemsMessageReqBroadcast_Post_MsgQueue_Check(
+ ctx,
+ ctx->Map.entry.Post_MsgQueue
+ );
+ RtemsMessageReqBroadcast_Post_Receivers_Check(
+ ctx,
+ ctx->Map.entry.Post_Receivers
+ );
+ RtemsMessageReqBroadcast_Post_RecSize_Check(
+ ctx,
+ ctx->Map.entry.Post_RecSize
+ );
+ RtemsMessageReqBroadcast_Post_RecBuffer_Check(
+ ctx,
+ ctx->Map.entry.Post_RecBuffer
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsMessageReqBroadcast( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsMessageReqBroadcast,
+ &RtemsMessageReqBroadcast_Fixture
+)
+{
+ RtemsMessageReqBroadcast_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsMessageReqBroadcast_Pre_SendBuffer_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsMessageReqBroadcast_Pre_SendBuffer_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsMessageReqBroadcast_Pre_Count_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsMessageReqBroadcast_Pre_Count_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsMessageReqBroadcast_Pre_Id_Valid;
+ ctx->Map.pcs[ 2 ] < RtemsMessageReqBroadcast_Pre_Id_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsMessageReqBroadcast_Pre_MsgSize_Zero;
+ ctx->Map.pcs[ 3 ] < RtemsMessageReqBroadcast_Pre_MsgSize_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = RtemsMessageReqBroadcast_Pre_MsgQueue_Empty;
+ ctx->Map.pcs[ 4 ] < RtemsMessageReqBroadcast_Pre_MsgQueue_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 5 ] = RtemsMessageReqBroadcast_Pre_Receivers_Waiting;
+ ctx->Map.pcs[ 5 ] < RtemsMessageReqBroadcast_Pre_Receivers_NA;
+ ++ctx->Map.pcs[ 5 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 6 ] = RtemsMessageReqBroadcast_Pre_Storage_Nop;
+ ctx->Map.pcs[ 6 ] < RtemsMessageReqBroadcast_Pre_Storage_NA;
+ ++ctx->Map.pcs[ 6 ]
+ ) {
+ ctx->Map.entry = RtemsMessageReqBroadcast_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsMessageReqBroadcast_Prepare( ctx );
+ RtemsMessageReqBroadcast_TestVariant( ctx );
+ RtemsMessageReqBroadcast_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-message-construct-errors.c b/testsuites/validation/tc-message-construct-errors.c
deleted file mode 100644
index 570160b947..0000000000
--- a/testsuites/validation/tc-message-construct-errors.c
+++ /dev/null
@@ -1,932 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/**
- * @file
- *
- * @ingroup RTEMSTestCaseRtemsMessageReqConstructErrors
- */
-
-/*
- * Copyright (C) 2020, 2021 embedded brains GmbH (http://www.embedded-brains.de)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * This file is part of the RTEMS quality process and was automatically
- * generated. If you find something that needs to be fixed or
- * worded better please post a report or patch to an RTEMS mailing list
- * or raise a bug report:
- *
- * https://www.rtems.org/bugs.html
- *
- * For information on updating and regenerating please refer to the How-To
- * section in the Software Requirements Engineering chapter of the
- * RTEMS Software Engineering manual. The manual is provided as a part of
- * a release. For development sources please refer to the online
- * documentation at:
- *
- * https://docs.rtems.org
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems.h>
-#include <string.h>
-
-#include "tx-support.h"
-
-#include <rtems/test.h>
-
-/**
- * @defgroup RTEMSTestCaseRtemsMessageReqConstructErrors \
- * spec:/rtems/message/req/construct-errors
- *
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
- *
- * @{
- */
-
-typedef enum {
- RtemsMessageReqConstructErrors_Pre_Config_Valid,
- RtemsMessageReqConstructErrors_Pre_Config_Null,
- RtemsMessageReqConstructErrors_Pre_Config_NA
-} RtemsMessageReqConstructErrors_Pre_Config;
-
-typedef enum {
- RtemsMessageReqConstructErrors_Pre_Name_Valid,
- RtemsMessageReqConstructErrors_Pre_Name_Invalid,
- RtemsMessageReqConstructErrors_Pre_Name_NA
-} RtemsMessageReqConstructErrors_Pre_Name;
-
-typedef enum {
- RtemsMessageReqConstructErrors_Pre_Id_Id,
- RtemsMessageReqConstructErrors_Pre_Id_Null,
- RtemsMessageReqConstructErrors_Pre_Id_NA
-} RtemsMessageReqConstructErrors_Pre_Id;
-
-typedef enum {
- RtemsMessageReqConstructErrors_Pre_MaxPending_Valid,
- RtemsMessageReqConstructErrors_Pre_MaxPending_Zero,
- RtemsMessageReqConstructErrors_Pre_MaxPending_Big,
- RtemsMessageReqConstructErrors_Pre_MaxPending_NA
-} RtemsMessageReqConstructErrors_Pre_MaxPending;
-
-typedef enum {
- RtemsMessageReqConstructErrors_Pre_MaxSize_Valid,
- RtemsMessageReqConstructErrors_Pre_MaxSize_Zero,
- RtemsMessageReqConstructErrors_Pre_MaxSize_Big,
- RtemsMessageReqConstructErrors_Pre_MaxSize_NA
-} RtemsMessageReqConstructErrors_Pre_MaxSize;
-
-typedef enum {
- RtemsMessageReqConstructErrors_Pre_Free_Yes,
- RtemsMessageReqConstructErrors_Pre_Free_No,
- RtemsMessageReqConstructErrors_Pre_Free_NA
-} RtemsMessageReqConstructErrors_Pre_Free;
-
-typedef enum {
- RtemsMessageReqConstructErrors_Pre_Area_Valid,
- RtemsMessageReqConstructErrors_Pre_Area_Null,
- RtemsMessageReqConstructErrors_Pre_Area_NA
-} RtemsMessageReqConstructErrors_Pre_Area;
-
-typedef enum {
- RtemsMessageReqConstructErrors_Pre_AreaSize_Valid,
- RtemsMessageReqConstructErrors_Pre_AreaSize_Invalid,
- RtemsMessageReqConstructErrors_Pre_AreaSize_NA
-} RtemsMessageReqConstructErrors_Pre_AreaSize;
-
-typedef enum {
- RtemsMessageReqConstructErrors_Post_Status_Ok,
- RtemsMessageReqConstructErrors_Post_Status_InvAddr,
- RtemsMessageReqConstructErrors_Post_Status_InvName,
- RtemsMessageReqConstructErrors_Post_Status_InvNum,
- RtemsMessageReqConstructErrors_Post_Status_InvSize,
- RtemsMessageReqConstructErrors_Post_Status_TooMany,
- RtemsMessageReqConstructErrors_Post_Status_Unsat,
- RtemsMessageReqConstructErrors_Post_Status_NA
-} RtemsMessageReqConstructErrors_Post_Status;
-
-typedef enum {
- RtemsMessageReqConstructErrors_Post_Name_Valid,
- RtemsMessageReqConstructErrors_Post_Name_Invalid,
- RtemsMessageReqConstructErrors_Post_Name_NA
-} RtemsMessageReqConstructErrors_Post_Name;
-
-typedef enum {
- RtemsMessageReqConstructErrors_Post_IdVar_Set,
- RtemsMessageReqConstructErrors_Post_IdVar_Nop,
- RtemsMessageReqConstructErrors_Post_IdVar_NA
-} RtemsMessageReqConstructErrors_Post_IdVar;
-
-/**
- * @brief Test context for spec:/rtems/message/req/construct-errors test case.
- */
-typedef struct {
- rtems_status_code status;
-
- const rtems_message_queue_config *config;
-
- rtems_message_queue_config config_value;
-
- rtems_id *id;
-
- rtems_id id_value;
-
- void *seized_objects;
-
- /**
- * @brief This member defines the pre-condition states for the next action.
- */
- size_t pcs[ 8 ];
-
- /**
- * @brief This member indicates if the test action loop is currently
- * executed.
- */
- bool in_action_loop;
-} RtemsMessageReqConstructErrors_Context;
-
-static RtemsMessageReqConstructErrors_Context
- RtemsMessageReqConstructErrors_Instance;
-
-static const char * const RtemsMessageReqConstructErrors_PreDesc_Config[] = {
- "Valid",
- "Null",
- "NA"
-};
-
-static const char * const RtemsMessageReqConstructErrors_PreDesc_Name[] = {
- "Valid",
- "Invalid",
- "NA"
-};
-
-static const char * const RtemsMessageReqConstructErrors_PreDesc_Id[] = {
- "Id",
- "Null",
- "NA"
-};
-
-static const char * const RtemsMessageReqConstructErrors_PreDesc_MaxPending[] = {
- "Valid",
- "Zero",
- "Big",
- "NA"
-};
-
-static const char * const RtemsMessageReqConstructErrors_PreDesc_MaxSize[] = {
- "Valid",
- "Zero",
- "Big",
- "NA"
-};
-
-static const char * const RtemsMessageReqConstructErrors_PreDesc_Free[] = {
- "Yes",
- "No",
- "NA"
-};
-
-static const char * const RtemsMessageReqConstructErrors_PreDesc_Area[] = {
- "Valid",
- "Null",
- "NA"
-};
-
-static const char * const RtemsMessageReqConstructErrors_PreDesc_AreaSize[] = {
- "Valid",
- "Invalid",
- "NA"
-};
-
-static const char * const * const RtemsMessageReqConstructErrors_PreDesc[] = {
- RtemsMessageReqConstructErrors_PreDesc_Config,
- RtemsMessageReqConstructErrors_PreDesc_Name,
- RtemsMessageReqConstructErrors_PreDesc_Id,
- RtemsMessageReqConstructErrors_PreDesc_MaxPending,
- RtemsMessageReqConstructErrors_PreDesc_MaxSize,
- RtemsMessageReqConstructErrors_PreDesc_Free,
- RtemsMessageReqConstructErrors_PreDesc_Area,
- RtemsMessageReqConstructErrors_PreDesc_AreaSize,
- NULL
-};
-
-#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
-
-#define MAX_MESSAGE_QUEUES 4
-
-#define MAX_PENDING_MESSAGES 1
-
-#define MAX_MESSAGE_SIZE 1
-
-static RTEMS_MESSAGE_QUEUE_BUFFER( MAX_MESSAGE_SIZE )
- buffers_to_seize[ MAX_MESSAGE_QUEUES ][ MAX_PENDING_MESSAGES ];
-
-static RTEMS_MESSAGE_QUEUE_BUFFER( MAX_MESSAGE_SIZE )
- buffers[ MAX_PENDING_MESSAGES ];
-
-static rtems_status_code Create( void *arg, uint32_t *id )
-{
- rtems_message_queue_config config;
- size_t *i;
-
- i = arg;
- T_quiet_lt_sz( *i, MAX_MESSAGE_QUEUES );
-
- memset( &config, 0, sizeof( config ) );
- config.name = rtems_build_name( 'S', 'I', 'Z', 'E' );
- config.maximum_pending_messages = MAX_PENDING_MESSAGES;
- config.maximum_message_size = MAX_MESSAGE_SIZE;
- config.storage_size = sizeof( buffers_to_seize[ *i ] );
- config.storage_area = buffers_to_seize[ *i ];
- config.attributes = RTEMS_DEFAULT_ATTRIBUTES;
-
- ++(*i);
-
- return rtems_message_queue_construct( &config, id );
-}
-
-static void RtemsMessageReqConstructErrors_Pre_Config_Prepare(
- RtemsMessageReqConstructErrors_Context *ctx,
- RtemsMessageReqConstructErrors_Pre_Config state
-)
-{
- switch ( state ) {
- case RtemsMessageReqConstructErrors_Pre_Config_Valid: {
- /*
- * While the ``config`` parameter references an object of type
- * rtems_message_queue_config.
- */
- ctx->config = &ctx->config_value;
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_Config_Null: {
- /*
- * While the ``config`` parameter is NULL.
- */
- ctx->config = NULL;
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_Config_NA:
- break;
- }
-}
-
-static void RtemsMessageReqConstructErrors_Pre_Name_Prepare(
- RtemsMessageReqConstructErrors_Context *ctx,
- RtemsMessageReqConstructErrors_Pre_Name state
-)
-{
- switch ( state ) {
- case RtemsMessageReqConstructErrors_Pre_Name_Valid: {
- /*
- * While the name of the message queue configuration is valid.
- */
- ctx->config_value.name = NAME;
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_Name_Invalid: {
- /*
- * While the name of the message queue configuration is invalid.
- */
- ctx->config_value.name = 0;
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_Name_NA:
- break;
- }
-}
-
-static void RtemsMessageReqConstructErrors_Pre_Id_Prepare(
- RtemsMessageReqConstructErrors_Context *ctx,
- RtemsMessageReqConstructErrors_Pre_Id state
-)
-{
- switch ( state ) {
- case RtemsMessageReqConstructErrors_Pre_Id_Id: {
- /*
- * While the ``id`` parameter references an object of type rtems_id.
- */
- ctx->id = &ctx->id_value;
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_Id_Null: {
- /*
- * While the ``id`` parameter is NULL.
- */
- ctx->id = NULL;
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_Id_NA:
- break;
- }
-}
-
-static void RtemsMessageReqConstructErrors_Pre_MaxPending_Prepare(
- RtemsMessageReqConstructErrors_Context *ctx,
- RtemsMessageReqConstructErrors_Pre_MaxPending state
-)
-{
- switch ( state ) {
- case RtemsMessageReqConstructErrors_Pre_MaxPending_Valid: {
- /*
- * While the maximum number of pending messages of the message queue
- * configuration is valid.
- */
- ctx->config_value.maximum_pending_messages = MAX_PENDING_MESSAGES;
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_MaxPending_Zero: {
- /*
- * While the maximum number of pending messages of the message queue
- * configuration is zero.
- */
- ctx->config_value.maximum_pending_messages = 0;
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_MaxPending_Big: {
- /*
- * While the maximum number of pending messages of the message queue
- * configuration is big enough so that a calculation to get the message
- * buffer storage area size overflows.
- */
- ctx->config_value.maximum_pending_messages = UINT32_MAX;
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_MaxPending_NA:
- break;
- }
-}
-
-static void RtemsMessageReqConstructErrors_Pre_MaxSize_Prepare(
- RtemsMessageReqConstructErrors_Context *ctx,
- RtemsMessageReqConstructErrors_Pre_MaxSize state
-)
-{
- switch ( state ) {
- case RtemsMessageReqConstructErrors_Pre_MaxSize_Valid: {
- /*
- * While the maximum message size of the message queue configuration is
- * valid.
- */
- if ( ctx->config_value.maximum_pending_messages == UINT32_MAX ) {
- /*
- * At least on 64-bit systems we need a bit of help to ensure that we
- * meet the Big state of the MaxPending pre-condition. The following
- * message size is valid with respect to calculations involving only
- * the message size.
- */
- ctx->config_value.maximum_message_size = SIZE_MAX - sizeof( uintptr_t ) +
- 1 - sizeof( CORE_message_queue_Buffer );
- } else {
- ctx->config_value.maximum_message_size = MAX_MESSAGE_SIZE;
- }
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_MaxSize_Zero: {
- /*
- * While the maximum message size of the message queue configuration is
- * zero.
- */
- ctx->config_value.maximum_message_size = 0;
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_MaxSize_Big: {
- /*
- * While the maximum message size of the message queue configuration is
- * big enough so that a calculation to get the message buffer storage
- * area size overflows.
- */
- ctx->config_value.maximum_message_size = SIZE_MAX;
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_MaxSize_NA:
- break;
- }
-}
-
-static void RtemsMessageReqConstructErrors_Pre_Free_Prepare(
- RtemsMessageReqConstructErrors_Context *ctx,
- RtemsMessageReqConstructErrors_Pre_Free state
-)
-{
- size_t i;
-
- switch ( state ) {
- case RtemsMessageReqConstructErrors_Pre_Free_Yes: {
- /*
- * While the system has at least one inactive message queue object
- * available.
- */
- /* Nothing to do */
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_Free_No: {
- /*
- * While the system has no inactive message queue object available.
- */
- i = 0;
- ctx->seized_objects = T_seize_objects( Create, &i );
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_Free_NA:
- break;
- }
-}
-
-static void RtemsMessageReqConstructErrors_Pre_Area_Prepare(
- RtemsMessageReqConstructErrors_Context *ctx,
- RtemsMessageReqConstructErrors_Pre_Area state
-)
-{
- switch ( state ) {
- case RtemsMessageReqConstructErrors_Pre_Area_Valid: {
- /*
- * While the message buffer storage area begin pointer of the message
- * queue configuration is valid.
- */
- ctx->config_value.storage_area = buffers;
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_Area_Null: {
- /*
- * While the message buffer storage area begin pointer of the message
- * queue configuration is NULL.
- */
- ctx->config_value.storage_area = NULL;
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_Area_NA:
- break;
- }
-}
-
-static void RtemsMessageReqConstructErrors_Pre_AreaSize_Prepare(
- RtemsMessageReqConstructErrors_Context *ctx,
- RtemsMessageReqConstructErrors_Pre_AreaSize state
-)
-{
- switch ( state ) {
- case RtemsMessageReqConstructErrors_Pre_AreaSize_Valid: {
- /*
- * While the message buffer storage area size of the message queue
- * configuration is valid.
- */
- ctx->config_value.storage_size = sizeof( buffers );
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_AreaSize_Invalid: {
- /*
- * While the message buffer storage area size of the message queue
- * configuration is invalid.
- */
- ctx->config_value.storage_size = SIZE_MAX;
- break;
- }
-
- case RtemsMessageReqConstructErrors_Pre_AreaSize_NA:
- break;
- }
-}
-
-static void RtemsMessageReqConstructErrors_Post_Status_Check(
- RtemsMessageReqConstructErrors_Context *ctx,
- RtemsMessageReqConstructErrors_Post_Status state
-)
-{
- switch ( state ) {
- case RtemsMessageReqConstructErrors_Post_Status_Ok: {
- /*
- * The return status of rtems_message_queue_construct() shall be
- * RTEMS_SUCCESSFUL.
- */
- T_rsc_success( ctx->status );
- break;
- }
-
- case RtemsMessageReqConstructErrors_Post_Status_InvAddr: {
- /*
- * The return status of rtems_message_queue_construct() shall be
- * RTEMS_INVALID_ADDRESS.
- */
- T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
- break;
- }
-
- case RtemsMessageReqConstructErrors_Post_Status_InvName: {
- /*
- * The return status of rtems_message_queue_construct() shall be
- * RTEMS_INVALID_NAME.
- */
- T_rsc( ctx->status, RTEMS_INVALID_NAME );
- break;
- }
-
- case RtemsMessageReqConstructErrors_Post_Status_InvNum: {
- /*
- * The return status of rtems_message_queue_construct() shall be
- * RTEMS_INVALID_NUMBER.
- */
- T_rsc( ctx->status, RTEMS_INVALID_NUMBER );
- break;
- }
-
- case RtemsMessageReqConstructErrors_Post_Status_InvSize: {
- /*
- * The return status of rtems_message_queue_construct() shall be
- * RTEMS_INVALID_SIZE.
- */
- T_rsc( ctx->status, RTEMS_INVALID_SIZE );
- break;
- }
-
- case RtemsMessageReqConstructErrors_Post_Status_TooMany: {
- /*
- * The return status of rtems_message_queue_construct() shall be
- * RTEMS_TOO_MANY.
- */
- T_rsc( ctx->status, RTEMS_TOO_MANY );
- break;
- }
-
- case RtemsMessageReqConstructErrors_Post_Status_Unsat: {
- /*
- * The return status of rtems_message_queue_construct() shall be
- * RTEMS_UNSATISFIED.
- */
- T_rsc( ctx->status, RTEMS_UNSATISFIED );
- break;
- }
-
- case RtemsMessageReqConstructErrors_Post_Status_NA:
- break;
- }
-}
-
-static void RtemsMessageReqConstructErrors_Post_Name_Check(
- RtemsMessageReqConstructErrors_Context *ctx,
- RtemsMessageReqConstructErrors_Post_Name state
-)
-{
- rtems_status_code sc;
- rtems_id id;
-
- switch ( state ) {
- case RtemsMessageReqConstructErrors_Post_Name_Valid: {
- /*
- * The unique object name shall identify the message queue constructed by
- * the rtems_message_queue_construct() call.
- */
- id = 0;
- sc = rtems_message_queue_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
- T_rsc_success( sc );
- T_eq_u32( id, ctx->id_value );
- break;
- }
-
- case RtemsMessageReqConstructErrors_Post_Name_Invalid: {
- /*
- * The unique object name shall not identify a message queue.
- */
- sc = rtems_message_queue_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
- T_rsc( sc, RTEMS_INVALID_NAME );
- break;
- }
-
- case RtemsMessageReqConstructErrors_Post_Name_NA:
- break;
- }
-}
-
-static void RtemsMessageReqConstructErrors_Post_IdVar_Check(
- RtemsMessageReqConstructErrors_Context *ctx,
- RtemsMessageReqConstructErrors_Post_IdVar state
-)
-{
- switch ( state ) {
- case RtemsMessageReqConstructErrors_Post_IdVar_Set: {
- /*
- * The value of the object referenced by the ``id`` parameter shall be
- * set to the object identifier of the constructed message queue after
- * the return of the rtems_message_queue_construct() call.
- */
- T_eq_ptr( ctx->id, &ctx->id_value );
- T_ne_u32( ctx->id_value, INVALID_ID );
- break;
- }
-
- case RtemsMessageReqConstructErrors_Post_IdVar_Nop: {
- /*
- * Objects referenced by the ``id`` parameter in past calls to
- * rtems_message_queue_construct() shall not be accessed by the
- * rtems_message_queue_construct() call.
- */
- T_eq_u32( ctx->id_value, INVALID_ID );
- break;
- }
-
- case RtemsMessageReqConstructErrors_Post_IdVar_NA:
- break;
- }
-}
-
-static void RtemsMessageReqConstructErrors_Prepare(
- RtemsMessageReqConstructErrors_Context *ctx
-)
-{
- ctx->id_value = INVALID_ID;
- memset( &ctx->config_value, 0, sizeof( ctx->config_value ) );
-}
-
-static void RtemsMessageReqConstructErrors_Action(
- RtemsMessageReqConstructErrors_Context *ctx
-)
-{
- ctx->status = rtems_message_queue_construct( ctx->config, ctx->id );
-}
-
-static void RtemsMessageReqConstructErrors_Cleanup(
- RtemsMessageReqConstructErrors_Context *ctx
-)
-{
- if ( ctx->id_value != INVALID_ID ) {
- rtems_status_code sc;
-
- sc = rtems_message_queue_delete( ctx->id_value );
- T_rsc_success( sc );
-
- ctx->id_value = INVALID_ID;
- }
-
- T_surrender_objects( &ctx->seized_objects, rtems_message_queue_delete );
-}
-
-typedef struct {
- uint16_t Skip : 1;
- uint16_t Pre_Config_NA : 1;
- uint16_t Pre_Name_NA : 1;
- uint16_t Pre_Id_NA : 1;
- uint16_t Pre_MaxPending_NA : 1;
- uint16_t Pre_MaxSize_NA : 1;
- uint16_t Pre_Free_NA : 1;
- uint16_t Pre_Area_NA : 1;
- uint16_t Pre_AreaSize_NA : 1;
- uint16_t Post_Status : 3;
- uint16_t Post_Name : 2;
- uint16_t Post_IdVar : 2;
-} RtemsMessageReqConstructErrors_Entry;
-
-static const RtemsMessageReqConstructErrors_Entry
-RtemsMessageReqConstructErrors_Entries[] = {
- { 0, 0, 0, 0, 0, 0, 0, 0, 0,
- RtemsMessageReqConstructErrors_Post_Status_InvAddr,
- RtemsMessageReqConstructErrors_Post_Name_Invalid,
- RtemsMessageReqConstructErrors_Post_IdVar_Nop },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0,
- RtemsMessageReqConstructErrors_Post_Status_InvName,
- RtemsMessageReqConstructErrors_Post_Name_Invalid,
- RtemsMessageReqConstructErrors_Post_IdVar_Nop },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0,
- RtemsMessageReqConstructErrors_Post_Status_InvNum,
- RtemsMessageReqConstructErrors_Post_Name_Invalid,
- RtemsMessageReqConstructErrors_Post_IdVar_Nop },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0,
- RtemsMessageReqConstructErrors_Post_Status_InvSize,
- RtemsMessageReqConstructErrors_Post_Name_Invalid,
- RtemsMessageReqConstructErrors_Post_IdVar_Nop },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0,
- RtemsMessageReqConstructErrors_Post_Status_TooMany,
- RtemsMessageReqConstructErrors_Post_Name_Invalid,
- RtemsMessageReqConstructErrors_Post_IdVar_Nop },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0,
- RtemsMessageReqConstructErrors_Post_Status_Unsat,
- RtemsMessageReqConstructErrors_Post_Name_Invalid,
- RtemsMessageReqConstructErrors_Post_IdVar_Nop },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqConstructErrors_Post_Status_Ok,
- RtemsMessageReqConstructErrors_Post_Name_Valid,
- RtemsMessageReqConstructErrors_Post_IdVar_Set }
-};
-
-static const uint8_t
-RtemsMessageReqConstructErrors_Map[] = {
- 6, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 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, 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, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0
-};
-
-static size_t RtemsMessageReqConstructErrors_Scope(
- void *arg,
- char *buf,
- size_t n
-)
-{
- RtemsMessageReqConstructErrors_Context *ctx;
-
- ctx = arg;
-
- if ( ctx->in_action_loop ) {
- return T_get_scope(
- RtemsMessageReqConstructErrors_PreDesc,
- buf,
- n,
- ctx->pcs
- );
- }
-
- return 0;
-}
-
-static T_fixture RtemsMessageReqConstructErrors_Fixture = {
- .setup = NULL,
- .stop = NULL,
- .teardown = NULL,
- .scope = RtemsMessageReqConstructErrors_Scope,
- .initial_context = &RtemsMessageReqConstructErrors_Instance
-};
-
-static inline RtemsMessageReqConstructErrors_Entry
-RtemsMessageReqConstructErrors_GetEntry( size_t index )
-{
- return RtemsMessageReqConstructErrors_Entries[
- RtemsMessageReqConstructErrors_Map[ index ]
- ];
-}
-
-/**
- * @fn void T_case_body_RtemsMessageReqConstructErrors( void )
- */
-T_TEST_CASE_FIXTURE(
- RtemsMessageReqConstructErrors,
- &RtemsMessageReqConstructErrors_Fixture
-)
-{
- RtemsMessageReqConstructErrors_Context *ctx;
- size_t index;
-
- ctx = T_fixture_context();
- ctx->in_action_loop = true;
- index = 0;
-
- for (
- ctx->pcs[ 0 ] = RtemsMessageReqConstructErrors_Pre_Config_Valid;
- ctx->pcs[ 0 ] < RtemsMessageReqConstructErrors_Pre_Config_NA;
- ++ctx->pcs[ 0 ]
- ) {
- for (
- ctx->pcs[ 1 ] = RtemsMessageReqConstructErrors_Pre_Name_Valid;
- ctx->pcs[ 1 ] < RtemsMessageReqConstructErrors_Pre_Name_NA;
- ++ctx->pcs[ 1 ]
- ) {
- for (
- ctx->pcs[ 2 ] = RtemsMessageReqConstructErrors_Pre_Id_Id;
- ctx->pcs[ 2 ] < RtemsMessageReqConstructErrors_Pre_Id_NA;
- ++ctx->pcs[ 2 ]
- ) {
- for (
- ctx->pcs[ 3 ] = RtemsMessageReqConstructErrors_Pre_MaxPending_Valid;
- ctx->pcs[ 3 ] < RtemsMessageReqConstructErrors_Pre_MaxPending_NA;
- ++ctx->pcs[ 3 ]
- ) {
- for (
- ctx->pcs[ 4 ] = RtemsMessageReqConstructErrors_Pre_MaxSize_Valid;
- ctx->pcs[ 4 ] < RtemsMessageReqConstructErrors_Pre_MaxSize_NA;
- ++ctx->pcs[ 4 ]
- ) {
- for (
- ctx->pcs[ 5 ] = RtemsMessageReqConstructErrors_Pre_Free_Yes;
- ctx->pcs[ 5 ] < RtemsMessageReqConstructErrors_Pre_Free_NA;
- ++ctx->pcs[ 5 ]
- ) {
- for (
- ctx->pcs[ 6 ] = RtemsMessageReqConstructErrors_Pre_Area_Valid;
- ctx->pcs[ 6 ] < RtemsMessageReqConstructErrors_Pre_Area_NA;
- ++ctx->pcs[ 6 ]
- ) {
- for (
- ctx->pcs[ 7 ] = RtemsMessageReqConstructErrors_Pre_AreaSize_Valid;
- ctx->pcs[ 7 ] < RtemsMessageReqConstructErrors_Pre_AreaSize_NA;
- ++ctx->pcs[ 7 ]
- ) {
- RtemsMessageReqConstructErrors_Entry entry;
-
- entry = RtemsMessageReqConstructErrors_GetEntry( index );
- ++index;
-
- RtemsMessageReqConstructErrors_Prepare( ctx );
- RtemsMessageReqConstructErrors_Pre_Config_Prepare(
- ctx,
- ctx->pcs[ 0 ]
- );
- RtemsMessageReqConstructErrors_Pre_Name_Prepare(
- ctx,
- ctx->pcs[ 1 ]
- );
- RtemsMessageReqConstructErrors_Pre_Id_Prepare(
- ctx,
- ctx->pcs[ 2 ]
- );
- RtemsMessageReqConstructErrors_Pre_MaxPending_Prepare(
- ctx,
- ctx->pcs[ 3 ]
- );
- RtemsMessageReqConstructErrors_Pre_MaxSize_Prepare(
- ctx,
- ctx->pcs[ 4 ]
- );
- RtemsMessageReqConstructErrors_Pre_Free_Prepare(
- ctx,
- ctx->pcs[ 5 ]
- );
- RtemsMessageReqConstructErrors_Pre_Area_Prepare(
- ctx,
- ctx->pcs[ 6 ]
- );
- RtemsMessageReqConstructErrors_Pre_AreaSize_Prepare(
- ctx,
- ctx->pcs[ 7 ]
- );
- RtemsMessageReqConstructErrors_Action( ctx );
- RtemsMessageReqConstructErrors_Post_Status_Check(
- ctx,
- entry.Post_Status
- );
- RtemsMessageReqConstructErrors_Post_Name_Check(
- ctx,
- entry.Post_Name
- );
- RtemsMessageReqConstructErrors_Post_IdVar_Check(
- ctx,
- entry.Post_IdVar
- );
- RtemsMessageReqConstructErrors_Cleanup( ctx );
- }
- }
- }
- }
- }
- }
- }
- }
-}
-
-/** @} */
diff --git a/testsuites/validation/tc-message-construct.c b/testsuites/validation/tc-message-construct.c
new file mode 100644
index 0000000000..316849ba68
--- /dev/null
+++ b/testsuites/validation/tc-message-construct.c
@@ -0,0 +1,1058 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsMessageReqConstruct
+ */
+
+/*
+ * Copyright (C) 2020, 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsMessageReqConstruct spec:/rtems/message/req/construct
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsMessageReqConstruct_Pre_Config_Valid,
+ RtemsMessageReqConstruct_Pre_Config_Null,
+ RtemsMessageReqConstruct_Pre_Config_NA
+} RtemsMessageReqConstruct_Pre_Config;
+
+typedef enum {
+ RtemsMessageReqConstruct_Pre_Name_Valid,
+ RtemsMessageReqConstruct_Pre_Name_Invalid,
+ RtemsMessageReqConstruct_Pre_Name_NA
+} RtemsMessageReqConstruct_Pre_Name;
+
+typedef enum {
+ RtemsMessageReqConstruct_Pre_Id_Id,
+ RtemsMessageReqConstruct_Pre_Id_Null,
+ RtemsMessageReqConstruct_Pre_Id_NA
+} RtemsMessageReqConstruct_Pre_Id;
+
+typedef enum {
+ RtemsMessageReqConstruct_Pre_MaxPending_Valid,
+ RtemsMessageReqConstruct_Pre_MaxPending_Zero,
+ RtemsMessageReqConstruct_Pre_MaxPending_Big,
+ RtemsMessageReqConstruct_Pre_MaxPending_NA
+} RtemsMessageReqConstruct_Pre_MaxPending;
+
+typedef enum {
+ RtemsMessageReqConstruct_Pre_MaxSize_Valid,
+ RtemsMessageReqConstruct_Pre_MaxSize_Zero,
+ RtemsMessageReqConstruct_Pre_MaxSize_Big,
+ RtemsMessageReqConstruct_Pre_MaxSize_NA
+} RtemsMessageReqConstruct_Pre_MaxSize;
+
+typedef enum {
+ RtemsMessageReqConstruct_Pre_Free_Yes,
+ RtemsMessageReqConstruct_Pre_Free_No,
+ RtemsMessageReqConstruct_Pre_Free_NA
+} RtemsMessageReqConstruct_Pre_Free;
+
+typedef enum {
+ RtemsMessageReqConstruct_Pre_Area_Valid,
+ RtemsMessageReqConstruct_Pre_Area_Null,
+ RtemsMessageReqConstruct_Pre_Area_NA
+} RtemsMessageReqConstruct_Pre_Area;
+
+typedef enum {
+ RtemsMessageReqConstruct_Pre_AreaSize_Valid,
+ RtemsMessageReqConstruct_Pre_AreaSize_Invalid,
+ RtemsMessageReqConstruct_Pre_AreaSize_NA
+} RtemsMessageReqConstruct_Pre_AreaSize;
+
+typedef enum {
+ RtemsMessageReqConstruct_Pre_StorageFree_Null,
+ RtemsMessageReqConstruct_Pre_StorageFree_Handler,
+ RtemsMessageReqConstruct_Pre_StorageFree_NA
+} RtemsMessageReqConstruct_Pre_StorageFree;
+
+typedef enum {
+ RtemsMessageReqConstruct_Post_Status_Ok,
+ RtemsMessageReqConstruct_Post_Status_InvAddr,
+ RtemsMessageReqConstruct_Post_Status_InvName,
+ RtemsMessageReqConstruct_Post_Status_InvNum,
+ RtemsMessageReqConstruct_Post_Status_InvSize,
+ RtemsMessageReqConstruct_Post_Status_TooMany,
+ RtemsMessageReqConstruct_Post_Status_Unsat,
+ RtemsMessageReqConstruct_Post_Status_NA
+} RtemsMessageReqConstruct_Post_Status;
+
+typedef enum {
+ RtemsMessageReqConstruct_Post_Name_Valid,
+ RtemsMessageReqConstruct_Post_Name_Invalid,
+ RtemsMessageReqConstruct_Post_Name_NA
+} RtemsMessageReqConstruct_Post_Name;
+
+typedef enum {
+ RtemsMessageReqConstruct_Post_IdObj_Set,
+ RtemsMessageReqConstruct_Post_IdObj_Nop,
+ RtemsMessageReqConstruct_Post_IdObj_NA
+} RtemsMessageReqConstruct_Post_IdObj;
+
+typedef enum {
+ RtemsMessageReqConstruct_Post_StorageFree_Free,
+ RtemsMessageReqConstruct_Post_StorageFree_Nop,
+ RtemsMessageReqConstruct_Post_StorageFree_NA
+} RtemsMessageReqConstruct_Post_StorageFree;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_Config_NA : 1;
+ uint32_t Pre_Name_NA : 1;
+ uint32_t Pre_Id_NA : 1;
+ uint32_t Pre_MaxPending_NA : 1;
+ uint32_t Pre_MaxSize_NA : 1;
+ uint32_t Pre_Free_NA : 1;
+ uint32_t Pre_Area_NA : 1;
+ uint32_t Pre_AreaSize_NA : 1;
+ uint32_t Pre_StorageFree_NA : 1;
+ uint32_t Post_Status : 3;
+ uint32_t Post_Name : 2;
+ uint32_t Post_IdObj : 2;
+ uint32_t Post_StorageFree : 2;
+} RtemsMessageReqConstruct_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/message/req/construct test case.
+ */
+typedef struct {
+ rtems_status_code status;
+
+ const rtems_message_queue_config *config;
+
+ rtems_message_queue_config config_obj;
+
+ rtems_id *id;
+
+ rtems_id id_obj;
+
+ void *seized_objects;
+
+ uint32_t storage_free_counter;
+
+ uint32_t expected_storage_free_counter;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 9 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsMessageReqConstruct_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsMessageReqConstruct_Context;
+
+static RtemsMessageReqConstruct_Context
+ RtemsMessageReqConstruct_Instance;
+
+static const char * const RtemsMessageReqConstruct_PreDesc_Config[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsMessageReqConstruct_PreDesc_Name[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsMessageReqConstruct_PreDesc_Id[] = {
+ "Id",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsMessageReqConstruct_PreDesc_MaxPending[] = {
+ "Valid",
+ "Zero",
+ "Big",
+ "NA"
+};
+
+static const char * const RtemsMessageReqConstruct_PreDesc_MaxSize[] = {
+ "Valid",
+ "Zero",
+ "Big",
+ "NA"
+};
+
+static const char * const RtemsMessageReqConstruct_PreDesc_Free[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsMessageReqConstruct_PreDesc_Area[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsMessageReqConstruct_PreDesc_AreaSize[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsMessageReqConstruct_PreDesc_StorageFree[] = {
+ "Null",
+ "Handler",
+ "NA"
+};
+
+static const char * const * const RtemsMessageReqConstruct_PreDesc[] = {
+ RtemsMessageReqConstruct_PreDesc_Config,
+ RtemsMessageReqConstruct_PreDesc_Name,
+ RtemsMessageReqConstruct_PreDesc_Id,
+ RtemsMessageReqConstruct_PreDesc_MaxPending,
+ RtemsMessageReqConstruct_PreDesc_MaxSize,
+ RtemsMessageReqConstruct_PreDesc_Free,
+ RtemsMessageReqConstruct_PreDesc_Area,
+ RtemsMessageReqConstruct_PreDesc_AreaSize,
+ RtemsMessageReqConstruct_PreDesc_StorageFree,
+ NULL
+};
+
+#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+#define MAX_MESSAGE_QUEUES 4
+
+#define MAX_PENDING_MESSAGES 1
+
+#define MAX_MESSAGE_SIZE 1
+
+typedef RtemsMessageReqConstruct_Context Context;
+
+static RTEMS_MESSAGE_QUEUE_BUFFER( MAX_MESSAGE_SIZE )
+ buffers_to_seize[ MAX_MESSAGE_QUEUES ][ MAX_PENDING_MESSAGES ];
+
+static RTEMS_MESSAGE_QUEUE_BUFFER( MAX_MESSAGE_SIZE )
+ buffers[ MAX_PENDING_MESSAGES ];
+
+static rtems_status_code Create( void *arg, uint32_t *id )
+{
+ rtems_message_queue_config config;
+ size_t *i;
+
+ i = arg;
+ T_quiet_lt_sz( *i, MAX_MESSAGE_QUEUES );
+
+ memset( &config, 0, sizeof( config ) );
+ config.name = rtems_build_name( 'S', 'I', 'Z', 'E' );
+ config.maximum_pending_messages = MAX_PENDING_MESSAGES;
+ config.maximum_message_size = MAX_MESSAGE_SIZE;
+ config.storage_size = sizeof( buffers_to_seize[ *i ] );
+ config.storage_area = buffers_to_seize[ *i ];
+ config.attributes = RTEMS_DEFAULT_ATTRIBUTES;
+
+ ++(*i);
+
+ return rtems_message_queue_construct( &config, id );
+}
+
+static void StorageFree( void *ptr )
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+ T_eq_ptr( ptr, buffers );
+ ++ctx->storage_free_counter;
+}
+
+static void RtemsMessageReqConstruct_Pre_Config_Prepare(
+ RtemsMessageReqConstruct_Context *ctx,
+ RtemsMessageReqConstruct_Pre_Config state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqConstruct_Pre_Config_Valid: {
+ /*
+ * While the ``config`` parameter references an object of type
+ * rtems_message_queue_config.
+ */
+ ctx->config = &ctx->config_obj;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_Config_Null: {
+ /*
+ * While the ``config`` parameter is NULL.
+ */
+ ctx->config = NULL;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_Config_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqConstruct_Pre_Name_Prepare(
+ RtemsMessageReqConstruct_Context *ctx,
+ RtemsMessageReqConstruct_Pre_Name state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqConstruct_Pre_Name_Valid: {
+ /*
+ * While the name of the message queue configuration is valid.
+ */
+ ctx->config_obj.name = NAME;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_Name_Invalid: {
+ /*
+ * While the name of the message queue configuration is invalid.
+ */
+ ctx->config_obj.name = 0;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_Name_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqConstruct_Pre_Id_Prepare(
+ RtemsMessageReqConstruct_Context *ctx,
+ RtemsMessageReqConstruct_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqConstruct_Pre_Id_Id: {
+ /*
+ * While the ``id`` parameter references an object of type rtems_id.
+ */
+ ctx->id = &ctx->id_obj;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_Id_Null: {
+ /*
+ * While the ``id`` parameter is NULL.
+ */
+ ctx->id = NULL;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqConstruct_Pre_MaxPending_Prepare(
+ RtemsMessageReqConstruct_Context *ctx,
+ RtemsMessageReqConstruct_Pre_MaxPending state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqConstruct_Pre_MaxPending_Valid: {
+ /*
+ * While the maximum number of pending messages of the message queue
+ * configuration is valid.
+ */
+ ctx->config_obj.maximum_pending_messages = MAX_PENDING_MESSAGES;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_MaxPending_Zero: {
+ /*
+ * While the maximum number of pending messages of the message queue
+ * configuration is zero.
+ */
+ ctx->config_obj.maximum_pending_messages = 0;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_MaxPending_Big: {
+ /*
+ * While the maximum number of pending messages of the message queue
+ * configuration is big enough so that a calculation to get the message
+ * buffer storage area size overflows.
+ */
+ ctx->config_obj.maximum_pending_messages = UINT32_MAX;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_MaxPending_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqConstruct_Pre_MaxSize_Prepare(
+ RtemsMessageReqConstruct_Context *ctx,
+ RtemsMessageReqConstruct_Pre_MaxSize state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqConstruct_Pre_MaxSize_Valid: {
+ /*
+ * While the maximum message size of the message queue configuration is
+ * valid.
+ */
+ if ( ctx->config_obj.maximum_pending_messages == UINT32_MAX ) {
+ /*
+ * At least on 64-bit systems we need a bit of help to ensure that we
+ * meet the Big state of the MaxPending pre-condition. The following
+ * message size is valid with respect to calculations involving only
+ * the message size.
+ */
+ ctx->config_obj.maximum_message_size = SIZE_MAX - sizeof( uintptr_t ) +
+ 1 - sizeof( CORE_message_queue_Buffer );
+ } else {
+ ctx->config_obj.maximum_message_size = MAX_MESSAGE_SIZE;
+ }
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_MaxSize_Zero: {
+ /*
+ * While the maximum message size of the message queue configuration is
+ * zero.
+ */
+ ctx->config_obj.maximum_message_size = 0;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_MaxSize_Big: {
+ /*
+ * While the maximum message size of the message queue configuration is
+ * big enough so that a calculation to get the message buffer storage
+ * area size overflows.
+ */
+ ctx->config_obj.maximum_message_size = SIZE_MAX;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_MaxSize_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqConstruct_Pre_Free_Prepare(
+ RtemsMessageReqConstruct_Context *ctx,
+ RtemsMessageReqConstruct_Pre_Free state
+)
+{
+ size_t i;
+
+ switch ( state ) {
+ case RtemsMessageReqConstruct_Pre_Free_Yes: {
+ /*
+ * While the system has at least one inactive message queue object
+ * available.
+ */
+ /* Nothing to do */
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_Free_No: {
+ /*
+ * While the system has no inactive message queue object available.
+ */
+ i = 0;
+ ctx->seized_objects = T_seize_objects( Create, &i );
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_Free_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqConstruct_Pre_Area_Prepare(
+ RtemsMessageReqConstruct_Context *ctx,
+ RtemsMessageReqConstruct_Pre_Area state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqConstruct_Pre_Area_Valid: {
+ /*
+ * While the message buffer storage area begin pointer of the message
+ * queue configuration is valid.
+ */
+ ctx->config_obj.storage_area = buffers;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_Area_Null: {
+ /*
+ * While the message buffer storage area begin pointer of the message
+ * queue configuration is NULL.
+ */
+ ctx->config_obj.storage_area = NULL;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_Area_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqConstruct_Pre_AreaSize_Prepare(
+ RtemsMessageReqConstruct_Context *ctx,
+ RtemsMessageReqConstruct_Pre_AreaSize state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqConstruct_Pre_AreaSize_Valid: {
+ /*
+ * While the message buffer storage area size of the message queue
+ * configuration is valid.
+ */
+ ctx->config_obj.storage_size = sizeof( buffers );
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_AreaSize_Invalid: {
+ /*
+ * While the message buffer storage area size of the message queue
+ * configuration is invalid.
+ */
+ ctx->config_obj.storage_size = SIZE_MAX;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_AreaSize_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqConstruct_Pre_StorageFree_Prepare(
+ RtemsMessageReqConstruct_Context *ctx,
+ RtemsMessageReqConstruct_Pre_StorageFree state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqConstruct_Pre_StorageFree_Null: {
+ /*
+ * While the storage free member of the message queue configuration is
+ * equal to NULL.
+ */
+ ctx->config_obj.storage_free = NULL;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_StorageFree_Handler: {
+ /*
+ * While the storage free member of the message queue configuration
+ * references a storage free handler.
+ */
+ ctx->config_obj.storage_free = StorageFree;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Pre_StorageFree_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqConstruct_Post_Status_Check(
+ RtemsMessageReqConstruct_Context *ctx,
+ RtemsMessageReqConstruct_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqConstruct_Post_Status_Ok: {
+ /*
+ * The return status of rtems_message_queue_construct() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_message_queue_construct() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Post_Status_InvName: {
+ /*
+ * The return status of rtems_message_queue_construct() shall be
+ * RTEMS_INVALID_NAME.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Post_Status_InvNum: {
+ /*
+ * The return status of rtems_message_queue_construct() shall be
+ * RTEMS_INVALID_NUMBER.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NUMBER );
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Post_Status_InvSize: {
+ /*
+ * The return status of rtems_message_queue_construct() shall be
+ * RTEMS_INVALID_SIZE.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_SIZE );
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Post_Status_TooMany: {
+ /*
+ * The return status of rtems_message_queue_construct() shall be
+ * RTEMS_TOO_MANY.
+ */
+ T_rsc( ctx->status, RTEMS_TOO_MANY );
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Post_Status_Unsat: {
+ /*
+ * The return status of rtems_message_queue_construct() shall be
+ * RTEMS_UNSATISFIED.
+ */
+ T_rsc( ctx->status, RTEMS_UNSATISFIED );
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqConstruct_Post_Name_Check(
+ RtemsMessageReqConstruct_Context *ctx,
+ RtemsMessageReqConstruct_Post_Name state
+)
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ switch ( state ) {
+ case RtemsMessageReqConstruct_Post_Name_Valid: {
+ /*
+ * The unique object name shall identify the message queue constructed by
+ * the rtems_message_queue_construct() call.
+ */
+ id = 0;
+ sc = rtems_message_queue_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc_success( sc );
+ T_eq_u32( id, ctx->id_obj );
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Post_Name_Invalid: {
+ /*
+ * The unique object name shall not identify a message queue.
+ */
+ sc = rtems_message_queue_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc( sc, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Post_Name_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqConstruct_Post_IdObj_Check(
+ RtemsMessageReqConstruct_Context *ctx,
+ RtemsMessageReqConstruct_Post_IdObj state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqConstruct_Post_IdObj_Set: {
+ /*
+ * The value of the object referenced by the ``id`` parameter shall be
+ * set to the object identifier of the constructed message queue after
+ * the return of the rtems_message_queue_construct() call.
+ */
+ T_eq_ptr( ctx->id, &ctx->id_obj );
+ T_ne_u32( ctx->id_obj, INVALID_ID );
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Post_IdObj_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past calls to
+ * rtems_message_queue_construct() shall not be accessed by the
+ * rtems_message_queue_construct() call.
+ */
+ T_eq_u32( ctx->id_obj, INVALID_ID );
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Post_IdObj_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqConstruct_Post_StorageFree_Check(
+ RtemsMessageReqConstruct_Context *ctx,
+ RtemsMessageReqConstruct_Post_StorageFree state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqConstruct_Post_StorageFree_Free: {
+ /*
+ * The storage free handler of the message queue configuration specified
+ * by the ``config`` parameter shall be used to free the message queue
+ * storage area.
+ */
+ ctx->expected_storage_free_counter = 1;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Post_StorageFree_Nop: {
+ /*
+ * No operation shall be performed to free the message queue storage
+ * area.
+ */
+ ctx->expected_storage_free_counter = 0;
+ break;
+ }
+
+ case RtemsMessageReqConstruct_Post_StorageFree_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqConstruct_Prepare(
+ RtemsMessageReqConstruct_Context *ctx
+)
+{
+ ctx->id_obj = INVALID_ID;
+ ctx->storage_free_counter = 0;
+ ctx->expected_storage_free_counter = UINT32_MAX;
+ memset( &ctx->config_obj, 0, sizeof( ctx->config_obj ) );
+}
+
+static void RtemsMessageReqConstruct_Action(
+ RtemsMessageReqConstruct_Context *ctx
+)
+{
+ ctx->status = rtems_message_queue_construct( ctx->config, ctx->id );
+}
+
+static void RtemsMessageReqConstruct_Cleanup(
+ RtemsMessageReqConstruct_Context *ctx
+)
+{
+ if ( ctx->id_obj != INVALID_ID ) {
+ rtems_status_code sc;
+
+ sc = rtems_message_queue_delete( ctx->id_obj );
+ T_rsc_success( sc );
+
+ T_eq_u32( ctx->storage_free_counter, ctx->expected_storage_free_counter );
+ } else {
+ T_eq_u32( ctx->storage_free_counter, 0 );
+ }
+
+ T_surrender_objects( &ctx->seized_objects, rtems_message_queue_delete );
+}
+
+static const RtemsMessageReqConstruct_Entry
+RtemsMessageReqConstruct_Entries[] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqConstruct_Post_Status_InvAddr,
+ RtemsMessageReqConstruct_Post_Name_Invalid,
+ RtemsMessageReqConstruct_Post_IdObj_Nop,
+ RtemsMessageReqConstruct_Post_StorageFree_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqConstruct_Post_Status_InvName,
+ RtemsMessageReqConstruct_Post_Name_Invalid,
+ RtemsMessageReqConstruct_Post_IdObj_Nop,
+ RtemsMessageReqConstruct_Post_StorageFree_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqConstruct_Post_Status_InvNum,
+ RtemsMessageReqConstruct_Post_Name_Invalid,
+ RtemsMessageReqConstruct_Post_IdObj_Nop,
+ RtemsMessageReqConstruct_Post_StorageFree_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqConstruct_Post_Status_InvSize,
+ RtemsMessageReqConstruct_Post_Name_Invalid,
+ RtemsMessageReqConstruct_Post_IdObj_Nop,
+ RtemsMessageReqConstruct_Post_StorageFree_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqConstruct_Post_Status_TooMany,
+ RtemsMessageReqConstruct_Post_Name_Invalid,
+ RtemsMessageReqConstruct_Post_IdObj_Nop,
+ RtemsMessageReqConstruct_Post_StorageFree_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqConstruct_Post_Status_Unsat,
+ RtemsMessageReqConstruct_Post_Name_Invalid,
+ RtemsMessageReqConstruct_Post_IdObj_Nop,
+ RtemsMessageReqConstruct_Post_StorageFree_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqConstruct_Post_Status_Ok,
+ RtemsMessageReqConstruct_Post_Name_Valid,
+ RtemsMessageReqConstruct_Post_IdObj_Set,
+ RtemsMessageReqConstruct_Post_StorageFree_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqConstruct_Post_Status_Ok,
+ RtemsMessageReqConstruct_Post_Name_Valid,
+ RtemsMessageReqConstruct_Post_IdObj_Set,
+ RtemsMessageReqConstruct_Post_StorageFree_Free }
+};
+
+static const uint8_t
+RtemsMessageReqConstruct_Map[] = {
+ 6, 7, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0
+};
+
+static size_t RtemsMessageReqConstruct_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsMessageReqConstruct_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsMessageReqConstruct_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsMessageReqConstruct_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsMessageReqConstruct_Scope,
+ .initial_context = &RtemsMessageReqConstruct_Instance
+};
+
+static inline RtemsMessageReqConstruct_Entry RtemsMessageReqConstruct_PopEntry(
+ RtemsMessageReqConstruct_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsMessageReqConstruct_Entries[
+ RtemsMessageReqConstruct_Map[ index ]
+ ];
+}
+
+static void RtemsMessageReqConstruct_TestVariant(
+ RtemsMessageReqConstruct_Context *ctx
+)
+{
+ RtemsMessageReqConstruct_Pre_Config_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsMessageReqConstruct_Pre_Name_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsMessageReqConstruct_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsMessageReqConstruct_Pre_MaxPending_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsMessageReqConstruct_Pre_MaxSize_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsMessageReqConstruct_Pre_Free_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsMessageReqConstruct_Pre_Area_Prepare( ctx, ctx->Map.pcs[ 6 ] );
+ RtemsMessageReqConstruct_Pre_AreaSize_Prepare( ctx, ctx->Map.pcs[ 7 ] );
+ RtemsMessageReqConstruct_Pre_StorageFree_Prepare( ctx, ctx->Map.pcs[ 8 ] );
+ RtemsMessageReqConstruct_Action( ctx );
+ RtemsMessageReqConstruct_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ RtemsMessageReqConstruct_Post_Name_Check( ctx, ctx->Map.entry.Post_Name );
+ RtemsMessageReqConstruct_Post_IdObj_Check( ctx, ctx->Map.entry.Post_IdObj );
+ RtemsMessageReqConstruct_Post_StorageFree_Check(
+ ctx,
+ ctx->Map.entry.Post_StorageFree
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsMessageReqConstruct( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsMessageReqConstruct,
+ &RtemsMessageReqConstruct_Fixture
+)
+{
+ RtemsMessageReqConstruct_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsMessageReqConstruct_Pre_Config_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsMessageReqConstruct_Pre_Config_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsMessageReqConstruct_Pre_Name_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsMessageReqConstruct_Pre_Name_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsMessageReqConstruct_Pre_Id_Id;
+ ctx->Map.pcs[ 2 ] < RtemsMessageReqConstruct_Pre_Id_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsMessageReqConstruct_Pre_MaxPending_Valid;
+ ctx->Map.pcs[ 3 ] < RtemsMessageReqConstruct_Pre_MaxPending_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = RtemsMessageReqConstruct_Pre_MaxSize_Valid;
+ ctx->Map.pcs[ 4 ] < RtemsMessageReqConstruct_Pre_MaxSize_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 5 ] = RtemsMessageReqConstruct_Pre_Free_Yes;
+ ctx->Map.pcs[ 5 ] < RtemsMessageReqConstruct_Pre_Free_NA;
+ ++ctx->Map.pcs[ 5 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 6 ] = RtemsMessageReqConstruct_Pre_Area_Valid;
+ ctx->Map.pcs[ 6 ] < RtemsMessageReqConstruct_Pre_Area_NA;
+ ++ctx->Map.pcs[ 6 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 7 ] = RtemsMessageReqConstruct_Pre_AreaSize_Valid;
+ ctx->Map.pcs[ 7 ] < RtemsMessageReqConstruct_Pre_AreaSize_NA;
+ ++ctx->Map.pcs[ 7 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 8 ] = RtemsMessageReqConstruct_Pre_StorageFree_Null;
+ ctx->Map.pcs[ 8 ] < RtemsMessageReqConstruct_Pre_StorageFree_NA;
+ ++ctx->Map.pcs[ 8 ]
+ ) {
+ ctx->Map.entry = RtemsMessageReqConstruct_PopEntry( ctx );
+ RtemsMessageReqConstruct_Prepare( ctx );
+ RtemsMessageReqConstruct_TestVariant( ctx );
+ RtemsMessageReqConstruct_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-message-delete.c b/testsuites/validation/tc-message-delete.c
new file mode 100644
index 0000000000..b0fa53be66
--- /dev/null
+++ b/testsuites/validation/tc-message-delete.c
@@ -0,0 +1,479 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsMessageReqDelete
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsMessageReqDelete spec:/rtems/message/req/delete
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsMessageReqDelete_Pre_Id_NoObj,
+ RtemsMessageReqDelete_Pre_Id_MsgQueue,
+ RtemsMessageReqDelete_Pre_Id_NA
+} RtemsMessageReqDelete_Pre_Id;
+
+typedef enum {
+ RtemsMessageReqDelete_Post_Status_Ok,
+ RtemsMessageReqDelete_Post_Status_InvId,
+ RtemsMessageReqDelete_Post_Status_NA
+} RtemsMessageReqDelete_Post_Status;
+
+typedef enum {
+ RtemsMessageReqDelete_Post_Name_Valid,
+ RtemsMessageReqDelete_Post_Name_Invalid,
+ RtemsMessageReqDelete_Post_Name_NA
+} RtemsMessageReqDelete_Post_Name;
+
+typedef enum {
+ RtemsMessageReqDelete_Post_Flush_Yes,
+ RtemsMessageReqDelete_Post_Flush_No,
+ RtemsMessageReqDelete_Post_Flush_NA
+} RtemsMessageReqDelete_Post_Flush;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Post_Status : 2;
+ uint8_t Post_Name : 2;
+ uint8_t Post_Flush : 2;
+} RtemsMessageReqDelete_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/message/req/delete test case.
+ */
+typedef struct {
+ rtems_id worker_id;
+
+ rtems_id message_queue_id;
+
+ uint32_t wait_done;
+
+ uint32_t wait_expected;
+
+ rtems_id id;
+
+ rtems_status_code status;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsMessageReqDelete_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsMessageReqDelete_Context;
+
+static RtemsMessageReqDelete_Context
+ RtemsMessageReqDelete_Instance;
+
+static const char * const RtemsMessageReqDelete_PreDesc_Id[] = {
+ "NoObj",
+ "MsgQueue",
+ "NA"
+};
+
+static const char * const * const RtemsMessageReqDelete_PreDesc[] = {
+ RtemsMessageReqDelete_PreDesc_Id,
+ NULL
+};
+
+#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+#define MAX_PENDING_MESSAGES 1
+
+#define MAX_MESSAGE_SIZE 1
+
+typedef RtemsMessageReqDelete_Context Context;
+
+static RTEMS_MESSAGE_QUEUE_BUFFER( MAX_MESSAGE_SIZE )
+ buffers[ MAX_PENDING_MESSAGES ];
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ while ( true ) {
+ rtems_status_code sc;
+ rtems_message_queue_config config;
+ char buffer[ MAX_MESSAGE_SIZE ];
+ size_t size;
+ rtems_task_priority prio;
+
+ memset( &config, 0, sizeof( config ) );
+ config.name = NAME;
+ config.maximum_pending_messages = MAX_PENDING_MESSAGES;
+ config.maximum_message_size = MAX_MESSAGE_SIZE;
+ config.storage_size = sizeof( buffers );
+ config.storage_area = buffers;
+ config.attributes = RTEMS_DEFAULT_ATTRIBUTES;
+
+ T_eq_u32( ctx->message_queue_id, 0 );
+
+ sc = rtems_message_queue_construct( &config, &ctx->message_queue_id );
+ T_rsc_success( sc );
+
+ size = SIZE_MAX;
+ sc = rtems_message_queue_receive(
+ ctx->message_queue_id,
+ buffer,
+ &size,
+ RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+ T_rsc( sc, RTEMS_OBJECT_WAS_DELETED );
+ T_eq_sz( size, SIZE_MAX );
+
+ ++ctx->wait_done;
+
+ prio = SetSelfPriority( PRIO_LOW );
+ T_eq_u32( prio, PRIO_HIGH );
+ }
+}
+
+static void RtemsMessageReqDelete_Pre_Id_Prepare(
+ RtemsMessageReqDelete_Context *ctx,
+ RtemsMessageReqDelete_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqDelete_Pre_Id_NoObj: {
+ /*
+ * While the ``id`` parameter is not associated with a message queue.
+ */
+ ctx->id = 0;
+ break;
+ }
+
+ case RtemsMessageReqDelete_Pre_Id_MsgQueue: {
+ /*
+ * While the ``id`` parameter is associated with a message queue.
+ */
+ ctx->id = ctx->message_queue_id;
+ break;
+ }
+
+ case RtemsMessageReqDelete_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqDelete_Post_Status_Check(
+ RtemsMessageReqDelete_Context *ctx,
+ RtemsMessageReqDelete_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqDelete_Post_Status_Ok: {
+ /*
+ * The return status of rtems_message_queue_delete() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ ctx->message_queue_id = 0;
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsMessageReqDelete_Post_Status_InvId: {
+ /*
+ * The return status of rtems_message_queue_delete() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsMessageReqDelete_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqDelete_Post_Name_Check(
+ RtemsMessageReqDelete_Context *ctx,
+ RtemsMessageReqDelete_Post_Name state
+)
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ switch ( state ) {
+ case RtemsMessageReqDelete_Post_Name_Valid: {
+ /*
+ * The unique object name shall identify a message queue.
+ */
+ id = 0;
+ sc = rtems_message_queue_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc_success( sc );
+ T_eq_u32( id, ctx->message_queue_id );
+ break;
+ }
+
+ case RtemsMessageReqDelete_Post_Name_Invalid: {
+ /*
+ * The unique object name shall not identify a message queue.
+ */
+ sc = rtems_message_queue_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc( sc, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsMessageReqDelete_Post_Name_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqDelete_Post_Flush_Check(
+ RtemsMessageReqDelete_Context *ctx,
+ RtemsMessageReqDelete_Post_Flush state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqDelete_Post_Flush_Yes: {
+ /*
+ * Tasks waiting at the message queue shall be unblocked.
+ */
+ ++ctx->wait_expected;
+ T_eq_u32( ctx->wait_done, ctx->wait_expected );
+ break;
+ }
+
+ case RtemsMessageReqDelete_Post_Flush_No: {
+ /*
+ * Tasks waiting at the message queue shall remain blocked.
+ */
+ T_eq_u32( ctx->wait_done, ctx->wait_expected );
+ break;
+ }
+
+ case RtemsMessageReqDelete_Post_Flush_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqDelete_Setup( RtemsMessageReqDelete_Context *ctx )
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+ SetSelfPriority( PRIO_NORMAL );
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+static void RtemsMessageReqDelete_Setup_Wrap( void *arg )
+{
+ RtemsMessageReqDelete_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsMessageReqDelete_Setup( ctx );
+}
+
+static void RtemsMessageReqDelete_Teardown(
+ RtemsMessageReqDelete_Context *ctx
+)
+{
+ DeleteTask( ctx->worker_id );
+ RestoreRunnerPriority();
+}
+
+static void RtemsMessageReqDelete_Teardown_Wrap( void *arg )
+{
+ RtemsMessageReqDelete_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsMessageReqDelete_Teardown( ctx );
+}
+
+static void RtemsMessageReqDelete_Prepare( RtemsMessageReqDelete_Context *ctx )
+{
+ rtems_task_priority prio;
+
+ prio = SetPriority( ctx->worker_id, PRIO_HIGH );
+ T_true( prio == PRIO_LOW || prio == PRIO_HIGH );
+}
+
+static void RtemsMessageReqDelete_Action( RtemsMessageReqDelete_Context *ctx )
+{
+ ctx->status = rtems_message_queue_delete( ctx->id );
+}
+
+static void RtemsMessageReqDelete_Cleanup( RtemsMessageReqDelete_Context *ctx )
+{
+ if ( ctx->message_queue_id != 0 ) {
+ rtems_status_code sc;
+
+ sc = rtems_message_queue_delete( ctx->message_queue_id );
+ T_rsc_success( sc );
+
+ ++ctx->wait_expected;
+ T_eq_u32( ctx->wait_done, ctx->wait_expected );
+
+ ctx->message_queue_id = 0;
+ }
+}
+
+static const RtemsMessageReqDelete_Entry
+RtemsMessageReqDelete_Entries[] = {
+ { 0, 0, RtemsMessageReqDelete_Post_Status_InvId,
+ RtemsMessageReqDelete_Post_Name_Valid, RtemsMessageReqDelete_Post_Flush_No },
+ { 0, 0, RtemsMessageReqDelete_Post_Status_Ok,
+ RtemsMessageReqDelete_Post_Name_Invalid,
+ RtemsMessageReqDelete_Post_Flush_Yes }
+};
+
+static const uint8_t
+RtemsMessageReqDelete_Map[] = {
+ 0, 1
+};
+
+static size_t RtemsMessageReqDelete_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsMessageReqDelete_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsMessageReqDelete_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsMessageReqDelete_Fixture = {
+ .setup = RtemsMessageReqDelete_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsMessageReqDelete_Teardown_Wrap,
+ .scope = RtemsMessageReqDelete_Scope,
+ .initial_context = &RtemsMessageReqDelete_Instance
+};
+
+static inline RtemsMessageReqDelete_Entry RtemsMessageReqDelete_PopEntry(
+ RtemsMessageReqDelete_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsMessageReqDelete_Entries[
+ RtemsMessageReqDelete_Map[ index ]
+ ];
+}
+
+static void RtemsMessageReqDelete_TestVariant(
+ RtemsMessageReqDelete_Context *ctx
+)
+{
+ RtemsMessageReqDelete_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsMessageReqDelete_Action( ctx );
+ RtemsMessageReqDelete_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsMessageReqDelete_Post_Name_Check( ctx, ctx->Map.entry.Post_Name );
+ RtemsMessageReqDelete_Post_Flush_Check( ctx, ctx->Map.entry.Post_Flush );
+}
+
+/**
+ * @fn void T_case_body_RtemsMessageReqDelete( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsMessageReqDelete, &RtemsMessageReqDelete_Fixture )
+{
+ RtemsMessageReqDelete_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsMessageReqDelete_Pre_Id_NoObj;
+ ctx->Map.pcs[ 0 ] < RtemsMessageReqDelete_Pre_Id_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = RtemsMessageReqDelete_PopEntry( ctx );
+ RtemsMessageReqDelete_Prepare( ctx );
+ RtemsMessageReqDelete_TestVariant( ctx );
+ RtemsMessageReqDelete_Cleanup( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-message-flush-pending.c b/testsuites/validation/tc-message-flush-pending.c
new file mode 100644
index 0000000000..48ade108d0
--- /dev/null
+++ b/testsuites/validation/tc-message-flush-pending.c
@@ -0,0 +1,981 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsMessageReqFlushPending
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsMessageReqFlushPending spec:/rtems/message/req/flush-pending
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsMessageReqFlushPending_Pre_Count_Valid,
+ RtemsMessageReqFlushPending_Pre_Count_Null,
+ RtemsMessageReqFlushPending_Pre_Count_NA
+} RtemsMessageReqFlushPending_Pre_Count;
+
+typedef enum {
+ RtemsMessageReqFlushPending_Pre_Id_Valid,
+ RtemsMessageReqFlushPending_Pre_Id_Invalid,
+ RtemsMessageReqFlushPending_Pre_Id_NA
+} RtemsMessageReqFlushPending_Pre_Id;
+
+typedef enum {
+ RtemsMessageReqFlushPending_Pre_MsgQueue_Empty,
+ RtemsMessageReqFlushPending_Pre_MsgQueue_Several,
+ RtemsMessageReqFlushPending_Pre_MsgQueue_NA
+} RtemsMessageReqFlushPending_Pre_MsgQueue;
+
+typedef enum {
+ RtemsMessageReqFlushPending_Pre_Receivers_Waiting,
+ RtemsMessageReqFlushPending_Pre_Receivers_None,
+ RtemsMessageReqFlushPending_Pre_Receivers_NA
+} RtemsMessageReqFlushPending_Pre_Receivers;
+
+typedef enum {
+ RtemsMessageReqFlushPending_Pre_Directive_Flush,
+ RtemsMessageReqFlushPending_Pre_Directive_Pending,
+ RtemsMessageReqFlushPending_Pre_Directive_NA
+} RtemsMessageReqFlushPending_Pre_Directive;
+
+typedef enum {
+ RtemsMessageReqFlushPending_Pre_Storage_Nop,
+ RtemsMessageReqFlushPending_Pre_Storage_NA
+} RtemsMessageReqFlushPending_Pre_Storage;
+
+typedef enum {
+ RtemsMessageReqFlushPending_Post_Status_Ok,
+ RtemsMessageReqFlushPending_Post_Status_InvId,
+ RtemsMessageReqFlushPending_Post_Status_InvAddr,
+ RtemsMessageReqFlushPending_Post_Status_NA
+} RtemsMessageReqFlushPending_Post_Status;
+
+typedef enum {
+ RtemsMessageReqFlushPending_Post_Count_Zero,
+ RtemsMessageReqFlushPending_Post_Count_Set,
+ RtemsMessageReqFlushPending_Post_Count_Nop,
+ RtemsMessageReqFlushPending_Post_Count_NA
+} RtemsMessageReqFlushPending_Post_Count;
+
+typedef enum {
+ RtemsMessageReqFlushPending_Post_MsgQueue_Empty,
+ RtemsMessageReqFlushPending_Post_MsgQueue_Nop,
+ RtemsMessageReqFlushPending_Post_MsgQueue_NA
+} RtemsMessageReqFlushPending_Post_MsgQueue;
+
+typedef enum {
+ RtemsMessageReqFlushPending_Post_Receivers_Nop,
+ RtemsMessageReqFlushPending_Post_Receivers_NA
+} RtemsMessageReqFlushPending_Post_Receivers;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Count_NA : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_MsgQueue_NA : 1;
+ uint16_t Pre_Receivers_NA : 1;
+ uint16_t Pre_Directive_NA : 1;
+ uint16_t Pre_Storage_NA : 1;
+ uint16_t Post_Status : 2;
+ uint16_t Post_Count : 2;
+ uint16_t Post_MsgQueue : 2;
+ uint16_t Post_Receivers : 1;
+} RtemsMessageReqFlushPending_Entry;
+
+#define MAXIMUM_PENDING_MESSAGES 3
+#define MAXIMUM_MESSAGE_SIZE 5
+#define NUMBER_OF_WORKERS 3
+
+/**
+ * @brief Test context for spec:/rtems/message/req/flush-pending test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a valid ID of a message queue.
+ */
+ rtems_id message_queue_id;
+
+ /**
+ * @brief This member is used as storage area for the message queue.
+ */
+ RTEMS_MESSAGE_QUEUE_BUFFER( MAXIMUM_MESSAGE_SIZE )
+ storage_area[ MAXIMUM_PENDING_MESSAGES ];
+
+ /**
+ * @brief This member contains the returned status codes of the receivers.
+ */
+ rtems_status_code receive_status[ NUMBER_OF_WORKERS ];
+
+ /**
+ * @brief This member specifies the directive to be called as action.
+ *
+ * This is either rtems_message_queue_flush() or
+ * rtems_message_queue_get_number_pending().
+ */
+ rtems_status_code (*action)( rtems_id id, uint32_t *count );
+
+ /**
+ * @brief This member specifies the ``id`` parameter of the action.
+ */
+ rtems_id id_param;
+
+ /**
+ * @brief This member specifies the ``count`` parameter of the action.
+ */
+ uint32_t *count_param;
+
+ /**
+ * @brief This member contains the returned status code of the action.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member contains the value returned in parameter ``count`` of
+ * the action.
+ */
+ uint32_t count;
+
+ /**
+ * @brief This member contains the task identifiers of the worker tasks.
+ */
+ rtems_id worker_id[ NUMBER_OF_WORKERS ];
+
+ /**
+ * @brief This member contains a pointer to a function which is executed to
+ * check that the action has not changed the content of the message queue.
+ */
+ void (*check_msgq_unchanged)( void *ctx_in );
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 6 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsMessageReqFlushPending_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsMessageReqFlushPending_Context;
+
+static RtemsMessageReqFlushPending_Context
+ RtemsMessageReqFlushPending_Instance;
+
+static const char * const RtemsMessageReqFlushPending_PreDesc_Count[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsMessageReqFlushPending_PreDesc_Id[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsMessageReqFlushPending_PreDesc_MsgQueue[] = {
+ "Empty",
+ "Several",
+ "NA"
+};
+
+static const char * const RtemsMessageReqFlushPending_PreDesc_Receivers[] = {
+ "Waiting",
+ "None",
+ "NA"
+};
+
+static const char * const RtemsMessageReqFlushPending_PreDesc_Directive[] = {
+ "Flush",
+ "Pending",
+ "NA"
+};
+
+static const char * const RtemsMessageReqFlushPending_PreDesc_Storage[] = {
+ "Nop",
+ "NA"
+};
+
+static const char * const * const RtemsMessageReqFlushPending_PreDesc[] = {
+ RtemsMessageReqFlushPending_PreDesc_Count,
+ RtemsMessageReqFlushPending_PreDesc_Id,
+ RtemsMessageReqFlushPending_PreDesc_MsgQueue,
+ RtemsMessageReqFlushPending_PreDesc_Receivers,
+ RtemsMessageReqFlushPending_PreDesc_Directive,
+ RtemsMessageReqFlushPending_PreDesc_Storage,
+ NULL
+};
+
+typedef RtemsMessageReqFlushPending_Context Context;
+static const uint32_t NUMBER_OF_PENDING_MESSAGES = 2;
+static const rtems_interval TIMEOUT_TICKS = 1;
+static const rtems_event_set EVENT_RECEIVE = RTEMS_EVENT_17;
+static const uint8_t queued_message[] = { 200, 201, 202 };
+
+static void Receive( Context *ctx, size_t worker_index )
+{
+ size_t size;
+ uint8_t buffer[ MAXIMUM_MESSAGE_SIZE ];
+
+ ctx->receive_status[worker_index] = rtems_message_queue_receive(
+ ctx->message_queue_id,
+ buffer,
+ &size,
+ RTEMS_WAIT,
+ TIMEOUT_TICKS
+ );
+}
+
+static void WorkerTask( rtems_task_argument argument )
+{
+ static size_t worker_number = 0;
+ size_t worker_index = worker_number++;
+ Context *ctx = (Context *) argument;
+
+ while ( true ) {
+ ReceiveAnyEvents();
+ Receive( ctx, worker_index );
+ }
+}
+
+static void CheckForNoMessage(
+ Context *ctx,
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+)
+{
+ (void) ctx;
+ (void) message_buffer;
+ (void) message_size;
+ T_rsc( status, RTEMS_UNSATISFIED );
+}
+
+static void CheckForQueuedMessage(
+ Context *ctx,
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+)
+{
+ (void) ctx;
+ T_rsc_success( status );
+ T_eq_u32( message_size, sizeof( queued_message ) );
+ T_eq_mem( message_buffer, queued_message, sizeof( queued_message ) );
+}
+
+static void PopMessage(
+ Context *ctx,
+ void (*check_fn)(
+ Context *ctx,
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+ )
+)
+{
+ rtems_status_code status;
+ uint8_t message_buffer[ MAXIMUM_MESSAGE_SIZE ];
+ size_t message_size;
+
+ status = rtems_message_queue_receive(
+ ctx->message_queue_id,
+ &message_buffer,
+ &message_size,
+ RTEMS_LOCAL | RTEMS_NO_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+
+ check_fn( ctx, status, message_buffer, message_size );
+}
+
+static void CheckForNoMessageInQueue( void *ctx_in )
+{
+ Context *ctx = ctx_in;
+ PopMessage( ctx, CheckForNoMessage );
+}
+
+static void CheckForSeveralMessagesInQueue( void *ctx_in )
+{
+ Context *ctx = ctx_in;
+ uint32_t i;
+ for ( i = 0; i < NUMBER_OF_PENDING_MESSAGES; ++i ) {
+ PopMessage( ctx, CheckForQueuedMessage );
+ }
+ PopMessage( ctx, CheckForNoMessage );
+}
+
+static void SendMsg( Context *ctx )
+{
+ rtems_status_code status;
+
+ status = rtems_message_queue_send(
+ ctx->message_queue_id,
+ queued_message,
+ sizeof( queued_message )
+ );
+ T_rsc_success( status );
+}
+
+static void RtemsMessageReqFlushPending_Pre_Count_Prepare(
+ RtemsMessageReqFlushPending_Context *ctx,
+ RtemsMessageReqFlushPending_Pre_Count state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqFlushPending_Pre_Count_Valid: {
+ /*
+ * While the ``count`` parameter references an ``uint32_t`` object.
+ */
+ ctx->count_param = &ctx->count;
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Pre_Count_Null: {
+ /*
+ * While the ``count`` parameter is NULL.
+ */
+ ctx->count_param = NULL;
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Pre_Count_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqFlushPending_Pre_Id_Prepare(
+ RtemsMessageReqFlushPending_Context *ctx,
+ RtemsMessageReqFlushPending_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqFlushPending_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter is valid.
+ */
+ ctx->id_param = ctx->message_queue_id;
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is invalid.
+ */
+ ctx->id_param = RTEMS_ID_NONE;
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqFlushPending_Pre_MsgQueue_Prepare(
+ RtemsMessageReqFlushPending_Context *ctx,
+ RtemsMessageReqFlushPending_Pre_MsgQueue state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqFlushPending_Pre_MsgQueue_Empty: {
+ /*
+ * While there is no message in the message queue.
+ */
+ /* Message queue is already empty. */
+ ctx->check_msgq_unchanged = CheckForNoMessageInQueue;
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Pre_MsgQueue_Several: {
+ /*
+ * While there are messages in the message queue.
+ */
+ uint32_t i;
+ for ( i = 0; i < NUMBER_OF_PENDING_MESSAGES; ++i ) {
+ SendMsg( ctx );
+ }
+ ctx->check_msgq_unchanged = CheckForSeveralMessagesInQueue;
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Pre_MsgQueue_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqFlushPending_Pre_Receivers_Prepare(
+ RtemsMessageReqFlushPending_Context *ctx,
+ RtemsMessageReqFlushPending_Pre_Receivers state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqFlushPending_Pre_Receivers_Waiting: {
+ /*
+ * While one or more receivers are waiting to receive a message.
+ */
+ size_t i;
+ for ( i = 0; i < NUMBER_OF_WORKERS; ++i ) {
+ SendEvents( ctx->worker_id[i], EVENT_RECEIVE );
+ }
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Pre_Receivers_None: {
+ /*
+ * While no receiver is waiting to receive a message.
+ */
+ /* There is already no receiver waiting. */
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Pre_Receivers_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqFlushPending_Pre_Directive_Prepare(
+ RtemsMessageReqFlushPending_Context *ctx,
+ RtemsMessageReqFlushPending_Pre_Directive state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqFlushPending_Pre_Directive_Flush: {
+ /*
+ * While the directive rtems_message_queue_flush() is called.
+ */
+ ctx->action = rtems_message_queue_flush;
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Pre_Directive_Pending: {
+ /*
+ * While the directive rtems_message_queue_get_number_pending() is
+ * called.
+ */
+ ctx->action = rtems_message_queue_get_number_pending;
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Pre_Directive_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqFlushPending_Pre_Storage_Prepare(
+ RtemsMessageReqFlushPending_Context *ctx,
+ RtemsMessageReqFlushPending_Pre_Storage state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqFlushPending_Pre_Storage_Nop: {
+ /*
+ * While the memory area to which a pointer is provided as member
+ * storage_area of type rtems_message_queue_config when the message queue
+ * is constructed by rtems_message_queue_construct() is altered only by
+ * the RTEMS operating system.
+ */
+ /* Only a requirement text. */
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Pre_Storage_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqFlushPending_Post_Status_Check(
+ RtemsMessageReqFlushPending_Context *ctx,
+ RtemsMessageReqFlushPending_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqFlushPending_Post_Status_Ok: {
+ /*
+ * The return status of the called directive (rtems_message_queue_flush()
+ * or rtems_message_queue_get_number_pending()) shall be RTEMS_SUCCESSFUL
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Post_Status_InvId: {
+ /*
+ * The return status of the called directive (rtems_message_queue_flush()
+ * or rtems_message_queue_get_number_pending()) shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Post_Status_InvAddr: {
+ /*
+ * The return status of the called directive (rtems_message_queue_flush()
+ * or rtems_message_queue_get_number_pending()) shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqFlushPending_Post_Count_Check(
+ RtemsMessageReqFlushPending_Context *ctx,
+ RtemsMessageReqFlushPending_Post_Count state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqFlushPending_Post_Count_Zero: {
+ /*
+ * The value of the object referenced by the ``count`` parameter shall be
+ * 0 after the return of the rtems_message_queue_flush() or
+ * rtems_message_queue_get_number_pending() call.
+ */
+ T_eq_u32( ctx->count, 0 );
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Post_Count_Set: {
+ /*
+ * The rtems_message_queue_get_number_pending() directive shall set the
+ * value of the object referenced by the ``count`` parameter to the
+ * number of messages present in the message queue at a point in time
+ * during the single execution of the
+ * rtems_message_queue_get_number_pending() directive.
+ *
+ * The rtems_message_queue_flush() directive shall set the value of the
+ * object referenced by the ``count`` parameter to the number of messages
+ * it removed from the message queue during the single execution of the
+ * rtems_message_queue_flush() directive.
+ */
+ T_eq_u32( ctx->count, NUMBER_OF_PENDING_MESSAGES );
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Post_Count_Nop: {
+ /*
+ * The value of the object referenced by the ``count`` parameter in past
+ * call to rtems_message_queue_flush() or
+ * rtems_message_queue_get_number_pending() shall not be accessed by the
+ * rtems_message_queue_flush() or
+ * rtems_message_queue_get_number_pending() call (see also Nop).
+ */
+ T_eq_u32( ctx->count, UINT8_MAX );
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Post_Count_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqFlushPending_Post_MsgQueue_Check(
+ RtemsMessageReqFlushPending_Context *ctx,
+ RtemsMessageReqFlushPending_Post_MsgQueue state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqFlushPending_Post_MsgQueue_Empty: {
+ /*
+ * The message queue shall contain no messages after the last call to
+ * ``id``.
+ */
+ PopMessage( ctx, CheckForNoMessage );
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Post_MsgQueue_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in the past call to
+ * rtems_message_queue_flush() or
+ * rtems_message_queue_get_number_pending() shall not be changed by that
+ * call (see also Nop).
+ */
+ ctx->check_msgq_unchanged( ctx );
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Post_MsgQueue_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqFlushPending_Post_Receivers_Check(
+ RtemsMessageReqFlushPending_Context *ctx,
+ RtemsMessageReqFlushPending_Post_Receivers state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqFlushPending_Post_Receivers_Nop: {
+ /*
+ * The receivers waiting for a message at the message queue shall not be
+ * affected by the call to the rtems_message_queue_flush() or
+ * rtems_message_queue_get_number_pending() directive.
+ */
+ size_t i;
+ for ( i = 0; i < NUMBER_OF_WORKERS; ++i ) {
+ T_rsc( ctx->receive_status[i], RTEMS_TIMEOUT );
+ }
+ break;
+ }
+
+ case RtemsMessageReqFlushPending_Post_Receivers_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqFlushPending_Setup(
+ RtemsMessageReqFlushPending_Context *ctx
+)
+{
+ size_t i;
+ SetSelfPriority( PRIO_NORMAL );
+
+ for ( i = 0; i < NUMBER_OF_WORKERS; ++i ) {
+ ctx->worker_id[i] = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id[i], WorkerTask, ctx );
+ }
+}
+
+static void RtemsMessageReqFlushPending_Setup_Wrap( void *arg )
+{
+ RtemsMessageReqFlushPending_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsMessageReqFlushPending_Setup( ctx );
+}
+
+static void RtemsMessageReqFlushPending_Teardown(
+ RtemsMessageReqFlushPending_Context *ctx
+)
+{
+ size_t i;
+
+ for ( i = 0; i < NUMBER_OF_WORKERS; ++i ) {
+ DeleteTask( ctx->worker_id[i] );
+ }
+ RestoreRunnerPriority();
+}
+
+static void RtemsMessageReqFlushPending_Teardown_Wrap( void *arg )
+{
+ RtemsMessageReqFlushPending_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsMessageReqFlushPending_Teardown( ctx );
+}
+
+static void RtemsMessageReqFlushPending_Prepare(
+ RtemsMessageReqFlushPending_Context *ctx
+)
+{
+ rtems_status_code status;
+
+ rtems_message_queue_config config = {
+ .name = rtems_build_name( 'M', 'S', 'G', 'Q' ),
+ .maximum_pending_messages = MAXIMUM_PENDING_MESSAGES,
+ .maximum_message_size = MAXIMUM_MESSAGE_SIZE,
+ .storage_area = ctx->storage_area,
+ .storage_size = sizeof( ctx->storage_area ),
+ .storage_free = NULL,
+ .attributes = RTEMS_DEFAULT_ATTRIBUTES
+ };
+
+ status = rtems_message_queue_construct(
+ &config,
+ &ctx->message_queue_id
+ );
+ T_rsc_success( status );
+
+ ctx->count = UINT8_MAX;
+}
+
+static void RtemsMessageReqFlushPending_Action(
+ RtemsMessageReqFlushPending_Context *ctx
+)
+{
+ ctx->status = (ctx->action)(
+ ctx->id_param,
+ ctx->count_param
+ );
+
+ FinalClockTick();
+}
+
+static void RtemsMessageReqFlushPending_Cleanup(
+ RtemsMessageReqFlushPending_Context *ctx
+)
+{
+ T_rsc_success( rtems_message_queue_delete( ctx->message_queue_id ) );
+}
+
+static const RtemsMessageReqFlushPending_Entry
+RtemsMessageReqFlushPending_Entries[] = {
+ { 1, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_NA,
+ RtemsMessageReqFlushPending_Post_Count_NA,
+ RtemsMessageReqFlushPending_Post_MsgQueue_NA,
+ RtemsMessageReqFlushPending_Post_Receivers_NA },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_InvAddr,
+ RtemsMessageReqFlushPending_Post_Count_Nop,
+ RtemsMessageReqFlushPending_Post_MsgQueue_Nop,
+ RtemsMessageReqFlushPending_Post_Receivers_NA },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_InvId,
+ RtemsMessageReqFlushPending_Post_Count_Nop,
+ RtemsMessageReqFlushPending_Post_MsgQueue_Nop,
+ RtemsMessageReqFlushPending_Post_Receivers_NA },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_InvAddr,
+ RtemsMessageReqFlushPending_Post_Count_Nop,
+ RtemsMessageReqFlushPending_Post_MsgQueue_Nop,
+ RtemsMessageReqFlushPending_Post_Receivers_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_InvId,
+ RtemsMessageReqFlushPending_Post_Count_Nop,
+ RtemsMessageReqFlushPending_Post_MsgQueue_Nop,
+ RtemsMessageReqFlushPending_Post_Receivers_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_Ok,
+ RtemsMessageReqFlushPending_Post_Count_Zero,
+ RtemsMessageReqFlushPending_Post_MsgQueue_Empty,
+ RtemsMessageReqFlushPending_Post_Receivers_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_Ok,
+ RtemsMessageReqFlushPending_Post_Count_Zero,
+ RtemsMessageReqFlushPending_Post_MsgQueue_Nop,
+ RtemsMessageReqFlushPending_Post_Receivers_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_Ok,
+ RtemsMessageReqFlushPending_Post_Count_Zero,
+ RtemsMessageReqFlushPending_Post_MsgQueue_Empty,
+ RtemsMessageReqFlushPending_Post_Receivers_NA },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_Ok,
+ RtemsMessageReqFlushPending_Post_Count_Zero,
+ RtemsMessageReqFlushPending_Post_MsgQueue_Nop,
+ RtemsMessageReqFlushPending_Post_Receivers_NA },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_Ok,
+ RtemsMessageReqFlushPending_Post_Count_Set,
+ RtemsMessageReqFlushPending_Post_MsgQueue_Empty,
+ RtemsMessageReqFlushPending_Post_Receivers_NA },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqFlushPending_Post_Status_Ok,
+ RtemsMessageReqFlushPending_Post_Count_Set,
+ RtemsMessageReqFlushPending_Post_MsgQueue_Nop,
+ RtemsMessageReqFlushPending_Post_Receivers_NA }
+};
+
+static const uint8_t
+RtemsMessageReqFlushPending_Map[] = {
+ 5, 6, 7, 8, 0, 0, 9, 10, 4, 4, 2, 2, 0, 0, 2, 2, 3, 3, 1, 1, 0, 0, 1, 1, 3,
+ 3, 1, 1, 0, 0, 1, 1
+};
+
+static size_t RtemsMessageReqFlushPending_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ RtemsMessageReqFlushPending_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsMessageReqFlushPending_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsMessageReqFlushPending_Fixture = {
+ .setup = RtemsMessageReqFlushPending_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsMessageReqFlushPending_Teardown_Wrap,
+ .scope = RtemsMessageReqFlushPending_Scope,
+ .initial_context = &RtemsMessageReqFlushPending_Instance
+};
+
+static inline RtemsMessageReqFlushPending_Entry
+RtemsMessageReqFlushPending_PopEntry(
+ RtemsMessageReqFlushPending_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsMessageReqFlushPending_Entries[
+ RtemsMessageReqFlushPending_Map[ index ]
+ ];
+}
+
+static void RtemsMessageReqFlushPending_TestVariant(
+ RtemsMessageReqFlushPending_Context *ctx
+)
+{
+ RtemsMessageReqFlushPending_Pre_Count_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsMessageReqFlushPending_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsMessageReqFlushPending_Pre_MsgQueue_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsMessageReqFlushPending_Pre_Receivers_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsMessageReqFlushPending_Pre_Directive_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsMessageReqFlushPending_Pre_Storage_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsMessageReqFlushPending_Action( ctx );
+ RtemsMessageReqFlushPending_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ RtemsMessageReqFlushPending_Post_Count_Check(
+ ctx,
+ ctx->Map.entry.Post_Count
+ );
+ RtemsMessageReqFlushPending_Post_MsgQueue_Check(
+ ctx,
+ ctx->Map.entry.Post_MsgQueue
+ );
+ RtemsMessageReqFlushPending_Post_Receivers_Check(
+ ctx,
+ ctx->Map.entry.Post_Receivers
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsMessageReqFlushPending( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsMessageReqFlushPending,
+ &RtemsMessageReqFlushPending_Fixture
+)
+{
+ RtemsMessageReqFlushPending_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsMessageReqFlushPending_Pre_Count_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsMessageReqFlushPending_Pre_Count_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsMessageReqFlushPending_Pre_Id_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsMessageReqFlushPending_Pre_Id_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsMessageReqFlushPending_Pre_MsgQueue_Empty;
+ ctx->Map.pcs[ 2 ] < RtemsMessageReqFlushPending_Pre_MsgQueue_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsMessageReqFlushPending_Pre_Receivers_Waiting;
+ ctx->Map.pcs[ 3 ] < RtemsMessageReqFlushPending_Pre_Receivers_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = RtemsMessageReqFlushPending_Pre_Directive_Flush;
+ ctx->Map.pcs[ 4 ] < RtemsMessageReqFlushPending_Pre_Directive_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 5 ] = RtemsMessageReqFlushPending_Pre_Storage_Nop;
+ ctx->Map.pcs[ 5 ] < RtemsMessageReqFlushPending_Pre_Storage_NA;
+ ++ctx->Map.pcs[ 5 ]
+ ) {
+ ctx->Map.entry = RtemsMessageReqFlushPending_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsMessageReqFlushPending_Prepare( ctx );
+ RtemsMessageReqFlushPending_TestVariant( ctx );
+ RtemsMessageReqFlushPending_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-message-ident.c b/testsuites/validation/tc-message-ident.c
new file mode 100644
index 0000000000..dc3ed119a6
--- /dev/null
+++ b/testsuites/validation/tc-message-ident.c
@@ -0,0 +1,129 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsMessageValIdent
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-object-ident.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsMessageValIdent spec:/rtems/message/val/ident
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Test the rtems_message_queue_ident() directive.
+ *
+ * This test case performs the following actions:
+ *
+ * - Run the generic object identification tests for Classic API message queue
+ * class objects defined by spec:/rtems/req/ident.
+ *
+ * @{
+ */
+
+#define NAME_LOCAL_OBJECT rtems_build_name( 'M', 'E', 'S', 'Q' )
+
+static RTEMS_MESSAGE_QUEUE_BUFFER( 1 ) ClassicMessageIdentBuffers[ 1 ];
+
+static rtems_message_queue_config ClassicObjectIdentConfig = {
+ .name = NAME_LOCAL_OBJECT,
+ .maximum_pending_messages = RTEMS_ARRAY_SIZE( ClassicMessageIdentBuffers ),
+ .maximum_message_size = 1,
+ .storage_area = ClassicMessageIdentBuffers,
+ .storage_size = sizeof( ClassicMessageIdentBuffers ),
+ .attributes = RTEMS_DEFAULT_ATTRIBUTES
+};
+
+static rtems_status_code ClassicMessageIdentAction(
+ rtems_name name,
+ uint32_t node,
+ rtems_id *id
+)
+{
+ return rtems_message_queue_ident( name, node, id );
+}
+
+/**
+ * @brief Run the generic object identification tests for Classic API message
+ * queue class objects defined by spec:/rtems/req/ident.
+ */
+static void RtemsMessageValIdent_Action_0( void )
+{
+ rtems_status_code sc;
+ rtems_id id_local_object;
+
+ sc = rtems_message_queue_construct(
+ &ClassicObjectIdentConfig,
+ &id_local_object
+ );
+ T_assert_rsc_success( sc );
+
+ RtemsReqIdent_Run(
+ id_local_object,
+ NAME_LOCAL_OBJECT,
+ ClassicMessageIdentAction
+ );
+
+ sc = rtems_message_queue_delete( id_local_object );
+ T_rsc_success( sc );
+}
+
+/**
+ * @fn void T_case_body_RtemsMessageValIdent( void )
+ */
+T_TEST_CASE( RtemsMessageValIdent )
+{
+ RtemsMessageValIdent_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-message-macros.c b/testsuites/validation/tc-message-macros.c
new file mode 100644
index 0000000000..b3c37b1963
--- /dev/null
+++ b/testsuites/validation/tc-message-macros.c
@@ -0,0 +1,147 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsMessageValMessageMacros
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsMessageValMessageMacros \
+ * spec:/rtems/message/val/message-macros
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests the macros of the @ref RTEMSAPIClassicMessage.
+ *
+ * This test case performs the following actions:
+ *
+ * - Check the RTEMS_MESSAGE_QUEUE_BUFFER() macro.
+ *
+ * - Check that the object defined by the RTEMS_MESSAGE_QUEUE_BUFFER()
+ * expression has the desired size. rtems_message_queue_construct() will
+ * return RTEMS_UNSATISFIED instead of RTEMS_SUCCESSFUL if the object
+ * defined by the RTEMS_MESSAGE_QUEUE_BUFFER() expression has incorrect
+ * size.
+ *
+ * @{
+ */
+
+/**
+ * @brief Check the RTEMS_MESSAGE_QUEUE_BUFFER() macro.
+ */
+static void RtemsMessageValMessageMacros_Action_0( void )
+{
+ rtems_status_code status;
+ rtems_id id;
+
+ static const uint32_t maximum_pending_messages_0 = 1;
+ static const size_t maximum_message_size_0 = 1;
+ RTEMS_MESSAGE_QUEUE_BUFFER( maximum_message_size_0 )
+ storage_area_0[ maximum_pending_messages_0 ];
+ rtems_message_queue_config config_0 = {
+ .name = rtems_build_name( 'M', 'S', 'G', '0' ),
+ .maximum_pending_messages = maximum_pending_messages_0,
+ .maximum_message_size = maximum_message_size_0,
+ .storage_area = storage_area_0,
+ .storage_size = sizeof( storage_area_0 ),
+ .storage_free = NULL,
+ .attributes = RTEMS_DEFAULT_OPTIONS
+ };
+
+ static const uint32_t maximum_pending_messages_1 = 3;
+ static const size_t maximum_message_size_1 = 5;
+ RTEMS_MESSAGE_QUEUE_BUFFER( maximum_message_size_1 )
+ storage_area_1[ maximum_pending_messages_1 ];
+ rtems_message_queue_config config_1 = {
+ .name = rtems_build_name( 'M', 'S', 'G', '1' ),
+ .maximum_pending_messages = maximum_pending_messages_1,
+ .maximum_message_size = maximum_message_size_1,
+ .storage_area = storage_area_1,
+ .storage_size = sizeof( storage_area_1 ),
+ .storage_free = NULL,
+ .attributes = RTEMS_DEFAULT_OPTIONS
+ };
+
+ /*
+ * Check that the object defined by the RTEMS_MESSAGE_QUEUE_BUFFER()
+ * expression has the desired size. rtems_message_queue_construct() will
+ * return RTEMS_UNSATISFIED instead of RTEMS_SUCCESSFUL if the object defined
+ * by the RTEMS_MESSAGE_QUEUE_BUFFER() expression has incorrect size.
+ */
+ status = rtems_message_queue_construct(
+ &config_0,
+ &id
+ );
+ T_step_rsc_success( 0, status );
+ T_step_rsc_success( 1, rtems_message_queue_delete( id ) );
+
+ status = rtems_message_queue_construct(
+ &config_1,
+ &id
+ );
+ T_step_rsc_success( 2, status );
+ T_step_rsc_success( 3, rtems_message_queue_delete( id ) );
+}
+
+/**
+ * @fn void T_case_body_RtemsMessageValMessageMacros( void )
+ */
+T_TEST_CASE( RtemsMessageValMessageMacros )
+{
+ T_plan( 4 );
+
+ RtemsMessageValMessageMacros_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-message-performance.c b/testsuites/validation/tc-message-performance.c
new file mode 100644
index 0000000000..c01570b772
--- /dev/null
+++ b/testsuites/validation/tc-message-performance.c
@@ -0,0 +1,946 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsMessageValPerf
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsMessageValPerf spec:/rtems/message/val/perf
+ *
+ * @ingroup TestsuitesPerformanceNoClock0
+ *
+ * @brief This test case provides a context to run @ref RTEMSAPIClassicMessage
+ * performance tests.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/rtems/message/val/perf test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides a message queue identifier.
+ */
+ rtems_id queue_id;
+
+ /**
+ * @brief This member provides a message to send.
+ */
+ long message;
+
+ /**
+ * @brief This member provides a worker identifier.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member provides a status code.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member references the measure runtime context.
+ */
+ T_measure_runtime_context *context;
+
+ /**
+ * @brief This member provides the measure runtime request.
+ */
+ T_measure_runtime_request request;
+
+ /**
+ * @brief This member provides an optional measurement begin time point.
+ */
+ T_ticks begin;
+
+ /**
+ * @brief This member provides an optional measurement end time point.
+ */
+ T_ticks end;
+} RtemsMessageValPerf_Context;
+
+static RtemsMessageValPerf_Context
+ RtemsMessageValPerf_Instance;
+
+#define MAXIMUM_PENDING_MESSAGES 1
+
+#define MAXIMUM_MESSAGE_SIZE 8
+
+#define EVENT_END RTEMS_EVENT_0
+
+#define EVENT_SEND RTEMS_EVENT_1
+
+#define EVENT_SEND_END RTEMS_EVENT_2
+
+#define EVENT_RECEIVE RTEMS_EVENT_3
+
+#define EVENT_RECEIVE_END RTEMS_EVENT_4
+
+typedef RtemsMessageValPerf_Context Context;
+
+static RTEMS_MESSAGE_QUEUE_BUFFER( MAXIMUM_MESSAGE_SIZE )
+ storage_area[ MAXIMUM_PENDING_MESSAGES ];
+
+rtems_message_queue_config config = {
+ .name = OBJECT_NAME,
+ .maximum_pending_messages = MAXIMUM_PENDING_MESSAGES,
+ .maximum_message_size = MAXIMUM_MESSAGE_SIZE,
+ .storage_area = storage_area,
+ .storage_size = sizeof( storage_area )
+};
+
+static void Send( const Context *ctx, rtems_event_set events )
+{
+ SendEvents( ctx->worker_id, events );
+}
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ while ( true ) {
+ rtems_event_set events;
+ rtems_status_code sc;
+ T_ticks ticks;
+
+ sc = rtems_event_receive(
+ RTEMS_ALL_EVENTS,
+ RTEMS_EVENT_ANY | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &events
+ );
+ ticks = T_tick();
+ T_quiet_rsc_success( sc );
+
+ if ( ( events & EVENT_END ) != 0 ) {
+ ctx->end = ticks;
+ }
+
+ if ( ( events & EVENT_SEND ) != 0 ) {
+ sc = rtems_message_queue_send(
+ ctx->queue_id,
+ &ctx->message,
+ sizeof( ctx->message )
+ );
+ ticks = T_tick();
+ T_quiet_rsc_success( sc );
+
+ if ( ( events & EVENT_SEND_END ) != 0 ) {
+ ctx->end = ticks;
+ }
+ }
+
+ if ( ( events & EVENT_RECEIVE ) != 0 ) {
+ long message;
+ size_t size;
+
+ sc = rtems_message_queue_receive(
+ ctx->queue_id,
+ &message,
+ &size,
+ RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+ ticks = T_tick();
+ T_quiet_rsc_success( sc );
+
+ if ( ( events & EVENT_RECEIVE_END ) != 0 ) {
+ ctx->end = ticks;
+ }
+ }
+ }
+}
+
+static void RtemsMessageValPerf_Setup_Context(
+ RtemsMessageValPerf_Context *ctx
+)
+{
+ T_measure_runtime_config config;
+
+ memset( &config, 0, sizeof( config ) );
+ config.sample_count = 100;
+ ctx->request.arg = ctx;
+ ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES;
+ ctx->context = T_measure_runtime_create( &config );
+ T_assert_not_null( ctx->context );
+}
+
+/**
+ * @brief Create a message queue and a worker task.
+ */
+static void RtemsMessageValPerf_Setup( RtemsMessageValPerf_Context *ctx )
+{
+ rtems_status_code sc;
+
+ SetSelfPriority( PRIO_NORMAL );
+
+ sc = rtems_message_queue_construct( &config, &ctx->queue_id );
+ T_rsc_success( sc );
+
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+static void RtemsMessageValPerf_Setup_Wrap( void *arg )
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsMessageValPerf_Setup_Context( ctx );
+ RtemsMessageValPerf_Setup( ctx );
+}
+
+/**
+ * @brief Delete the worker task and the message queue.
+ */
+static void RtemsMessageValPerf_Teardown( RtemsMessageValPerf_Context *ctx )
+{
+ rtems_status_code sc;
+
+ DeleteTask( ctx->worker_id );
+
+ sc = rtems_message_queue_delete( ctx->queue_id );
+ T_rsc_success( sc );
+
+ RestoreRunnerPriority();
+}
+
+static void RtemsMessageValPerf_Teardown_Wrap( void *arg )
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsMessageValPerf_Teardown( ctx );
+}
+
+static T_fixture RtemsMessageValPerf_Fixture = {
+ .setup = RtemsMessageValPerf_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsMessageValPerf_Teardown_Wrap,
+ .scope = NULL,
+ .initial_context = &RtemsMessageValPerf_Instance
+};
+
+/**
+ * @defgroup RtemsMessageReqPerfReceiveTry \
+ * spec:/rtems/message/req/perf-receive-try
+ *
+ * @{
+ */
+
+/**
+ * @brief Try to receive a message.
+ */
+static void RtemsMessageReqPerfReceiveTry_Body(
+ RtemsMessageValPerf_Context *ctx
+)
+{
+ uint64_t message;
+ size_t size;
+
+ ctx->status = rtems_message_queue_receive(
+ ctx->queue_id,
+ &message,
+ &size,
+ RTEMS_NO_WAIT,
+ 0
+ );
+}
+
+static void RtemsMessageReqPerfReceiveTry_Body_Wrap( void *arg )
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsMessageReqPerfReceiveTry_Body( ctx );
+}
+
+/**
+ * @brief Discard samples interrupted by a clock tick.
+ */
+static bool RtemsMessageReqPerfReceiveTry_Teardown(
+ RtemsMessageValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc( ctx->status, RTEMS_UNSATISFIED );
+
+ return tic == toc;
+}
+
+static bool RtemsMessageReqPerfReceiveTry_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsMessageReqPerfReceiveTry_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/** @} */
+
+/**
+ * @defgroup RtemsMessageReqPerfReceiveWaitForever \
+ * spec:/rtems/message/req/perf-receive-wait-forever
+ *
+ * @{
+ */
+
+/**
+ * @brief Schedule a message send.
+ */
+static void RtemsMessageReqPerfReceiveWaitForever_Setup(
+ RtemsMessageValPerf_Context *ctx
+)
+{
+ SetPriority( ctx->worker_id, PRIO_LOW );
+ Send( ctx, EVENT_END | EVENT_SEND );
+}
+
+static void RtemsMessageReqPerfReceiveWaitForever_Setup_Wrap( void *arg )
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsMessageReqPerfReceiveWaitForever_Setup( ctx );
+}
+
+/**
+ * @brief Receive a message. Wait forever.
+ */
+static void RtemsMessageReqPerfReceiveWaitForever_Body(
+ RtemsMessageValPerf_Context *ctx
+)
+{
+ uint64_t message;
+ size_t size;
+
+ ctx->begin = T_tick();
+ ctx->status = rtems_message_queue_receive(
+ ctx->queue_id,
+ &message,
+ &size,
+ RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+}
+
+static void RtemsMessageReqPerfReceiveWaitForever_Body_Wrap( void *arg )
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsMessageReqPerfReceiveWaitForever_Body( ctx );
+}
+
+/**
+ * @brief Set the measured runtime. Restore the worker priority. Discard
+ * samples interrupted by a clock tick.
+ */
+static bool RtemsMessageReqPerfReceiveWaitForever_Teardown(
+ RtemsMessageValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+ SetPriority( ctx->worker_id, PRIO_HIGH );
+
+ return tic == toc;
+}
+
+static bool RtemsMessageReqPerfReceiveWaitForever_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsMessageReqPerfReceiveWaitForever_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/** @} */
+
+/**
+ * @defgroup RtemsMessageReqPerfReceiveWaitTimed \
+ * spec:/rtems/message/req/perf-receive-wait-timed
+ *
+ * @{
+ */
+
+/**
+ * @brief Schedule a message send.
+ */
+static void RtemsMessageReqPerfReceiveWaitTimed_Setup(
+ RtemsMessageValPerf_Context *ctx
+)
+{
+ SetPriority( ctx->worker_id, PRIO_LOW );
+ Send( ctx, EVENT_END | EVENT_SEND );
+}
+
+static void RtemsMessageReqPerfReceiveWaitTimed_Setup_Wrap( void *arg )
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsMessageReqPerfReceiveWaitTimed_Setup( ctx );
+}
+
+/**
+ * @brief Receive a message. Wait with a timeout.
+ */
+static void RtemsMessageReqPerfReceiveWaitTimed_Body(
+ RtemsMessageValPerf_Context *ctx
+)
+{
+ uint64_t message;
+ size_t size;
+
+ ctx->begin = T_tick();
+ ctx->status = rtems_message_queue_receive(
+ ctx->queue_id,
+ &message,
+ &size,
+ RTEMS_WAIT,
+ UINT32_MAX
+ );
+}
+
+static void RtemsMessageReqPerfReceiveWaitTimed_Body_Wrap( void *arg )
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsMessageReqPerfReceiveWaitTimed_Body( ctx );
+}
+
+/**
+ * @brief Set the measured runtime. Restore the worker priority. Discard
+ * samples interrupted by a clock tick.
+ */
+static bool RtemsMessageReqPerfReceiveWaitTimed_Teardown(
+ RtemsMessageValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+ SetPriority( ctx->worker_id, PRIO_HIGH );
+
+ return tic == toc;
+}
+
+static bool RtemsMessageReqPerfReceiveWaitTimed_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsMessageReqPerfReceiveWaitTimed_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/** @} */
+
+/**
+ * @defgroup RtemsMessageReqPerfSend spec:/rtems/message/req/perf-send
+ *
+ * @{
+ */
+
+/**
+ * @brief Send a message.
+ */
+static void RtemsMessageReqPerfSend_Body( RtemsMessageValPerf_Context *ctx )
+{
+ ctx->status = rtems_message_queue_send(
+ ctx->queue_id,
+ &ctx->message,
+ sizeof( ctx->message )
+ );
+}
+
+static void RtemsMessageReqPerfSend_Body_Wrap( void *arg )
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsMessageReqPerfSend_Body( ctx );
+}
+
+/**
+ * @brief Flush the message queue. Discard samples interrupted by a clock
+ * tick.
+ */
+static bool RtemsMessageReqPerfSend_Teardown(
+ RtemsMessageValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ rtems_status_code sc;
+ uint32_t count;
+
+ T_quiet_rsc_success( ctx->status );
+
+ sc = rtems_message_queue_flush( ctx->queue_id, &count );
+ T_quiet_rsc_success( sc );
+ T_quiet_eq_u32( count, 1 );
+
+ return tic == toc;
+}
+
+static bool RtemsMessageReqPerfSend_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsMessageReqPerfSend_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/** @} */
+
+/**
+ * @defgroup RtemsMessageReqPerfSendOther \
+ * spec:/rtems/message/req/perf-send-other
+ *
+ * @{
+ */
+
+/**
+ * @brief Let the worker wait on the message queue.
+ */
+static void RtemsMessageReqPerfSendOther_Setup(
+ RtemsMessageValPerf_Context *ctx
+)
+{
+ Send( ctx, EVENT_RECEIVE );
+ SetPriority( ctx->worker_id, PRIO_LOW );
+}
+
+static void RtemsMessageReqPerfSendOther_Setup_Wrap( void *arg )
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsMessageReqPerfSendOther_Setup( ctx );
+}
+
+/**
+ * @brief Send a message.
+ */
+static void RtemsMessageReqPerfSendOther_Body(
+ RtemsMessageValPerf_Context *ctx
+)
+{
+ ctx->status = rtems_message_queue_send(
+ ctx->queue_id,
+ &ctx->message,
+ sizeof( ctx->message )
+ );
+}
+
+static void RtemsMessageReqPerfSendOther_Body_Wrap( void *arg )
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsMessageReqPerfSendOther_Body( ctx );
+}
+
+/**
+ * @brief Restore the worker priority. Discard samples interrupted by a clock
+ * tick.
+ */
+static bool RtemsMessageReqPerfSendOther_Teardown(
+ RtemsMessageValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ SetPriority( ctx->worker_id, PRIO_HIGH );
+
+ return tic == toc;
+}
+
+static bool RtemsMessageReqPerfSendOther_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsMessageReqPerfSendOther_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/** @} */
+
+#if defined(RTEMS_SMP)
+/**
+ * @defgroup RtemsMessageReqPerfSendOtherCpu \
+ * spec:/rtems/message/req/perf-send-other-cpu
+ *
+ * @{
+ */
+
+/**
+ * @brief Move worker to scheduler B.
+ */
+static void RtemsMessageReqPerfSendOtherCpu_Prepare(
+ RtemsMessageValPerf_Context *ctx
+)
+{
+ SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+}
+
+/**
+ * @brief Let the worker wait on the message queue.
+ */
+static void RtemsMessageReqPerfSendOtherCpu_Setup(
+ RtemsMessageValPerf_Context *ctx
+)
+{
+ Send( ctx, EVENT_RECEIVE | EVENT_RECEIVE_END );
+ WaitForNextTask( 1, ctx->worker_id );
+}
+
+static void RtemsMessageReqPerfSendOtherCpu_Setup_Wrap( void *arg )
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsMessageReqPerfSendOtherCpu_Setup( ctx );
+}
+
+/**
+ * @brief Send a message.
+ */
+static void RtemsMessageReqPerfSendOtherCpu_Body(
+ RtemsMessageValPerf_Context *ctx
+)
+{
+ ctx->begin = T_tick();
+ ctx->status = rtems_message_queue_send(
+ ctx->queue_id,
+ &ctx->message,
+ sizeof( ctx->message )
+ );
+}
+
+static void RtemsMessageReqPerfSendOtherCpu_Body_Wrap( void *arg )
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsMessageReqPerfSendOtherCpu_Body( ctx );
+}
+
+/**
+ * @brief Make sure the worker waits for the next event. Set the measured
+ * runtime. Discard samples interrupted by a clock tick.
+ */
+static bool RtemsMessageReqPerfSendOtherCpu_Teardown(
+ RtemsMessageValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ WaitForNextTask( 1, ctx->worker_id );
+ *delta = ctx->end - ctx->begin;
+
+ return tic == toc;
+}
+
+static bool RtemsMessageReqPerfSendOtherCpu_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsMessageReqPerfSendOtherCpu_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/**
+ * @brief Move worker to scheduler A.
+ */
+static void RtemsMessageReqPerfSendOtherCpu_Cleanup(
+ RtemsMessageValPerf_Context *ctx
+)
+{
+ SetScheduler( ctx->worker_id, SCHEDULER_A_ID, PRIO_HIGH );
+}
+
+/** @} */
+#endif
+
+/**
+ * @defgroup RtemsMessageReqPerfSendPreempt \
+ * spec:/rtems/message/req/perf-send-preempt
+ *
+ * @{
+ */
+
+/**
+ * @brief Let the worker wait on the message queue.
+ */
+static void RtemsMessageReqPerfSendPreempt_Setup(
+ RtemsMessageValPerf_Context *ctx
+)
+{
+ Send( ctx, EVENT_RECEIVE | EVENT_RECEIVE_END );
+}
+
+static void RtemsMessageReqPerfSendPreempt_Setup_Wrap( void *arg )
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsMessageReqPerfSendPreempt_Setup( ctx );
+}
+
+/**
+ * @brief Send a message.
+ */
+static void RtemsMessageReqPerfSendPreempt_Body(
+ RtemsMessageValPerf_Context *ctx
+)
+{
+ ctx->begin = T_tick();
+ ctx->status = rtems_message_queue_send(
+ ctx->queue_id,
+ &ctx->message,
+ sizeof( ctx->message )
+ );
+}
+
+static void RtemsMessageReqPerfSendPreempt_Body_Wrap( void *arg )
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsMessageReqPerfSendPreempt_Body( ctx );
+}
+
+/**
+ * @brief Set the measured runtime. Discard samples interrupted by a clock
+ * tick.
+ */
+static bool RtemsMessageReqPerfSendPreempt_Teardown(
+ RtemsMessageValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+
+ return tic == toc;
+}
+
+static bool RtemsMessageReqPerfSendPreempt_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsMessageReqPerfSendPreempt_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/** @} */
+
+/**
+ * @fn void T_case_body_RtemsMessageValPerf( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsMessageValPerf, &RtemsMessageValPerf_Fixture )
+{
+ RtemsMessageValPerf_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ ctx->request.name = "RtemsMessageReqPerfReceiveTry";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsMessageReqPerfReceiveTry_Body_Wrap;
+ ctx->request.teardown = RtemsMessageReqPerfReceiveTry_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ ctx->request.name = "RtemsMessageReqPerfReceiveWaitForever";
+ ctx->request.setup = RtemsMessageReqPerfReceiveWaitForever_Setup_Wrap;
+ ctx->request.body = RtemsMessageReqPerfReceiveWaitForever_Body_Wrap;
+ ctx->request.teardown = RtemsMessageReqPerfReceiveWaitForever_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ ctx->request.name = "RtemsMessageReqPerfReceiveWaitTimed";
+ ctx->request.setup = RtemsMessageReqPerfReceiveWaitTimed_Setup_Wrap;
+ ctx->request.body = RtemsMessageReqPerfReceiveWaitTimed_Body_Wrap;
+ ctx->request.teardown = RtemsMessageReqPerfReceiveWaitTimed_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ ctx->request.name = "RtemsMessageReqPerfSend";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsMessageReqPerfSend_Body_Wrap;
+ ctx->request.teardown = RtemsMessageReqPerfSend_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ ctx->request.name = "RtemsMessageReqPerfSendOther";
+ ctx->request.setup = RtemsMessageReqPerfSendOther_Setup_Wrap;
+ ctx->request.body = RtemsMessageReqPerfSendOther_Body_Wrap;
+ ctx->request.teardown = RtemsMessageReqPerfSendOther_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ #if defined(RTEMS_SMP)
+ RtemsMessageReqPerfSendOtherCpu_Prepare( ctx );
+ ctx->request.name = "RtemsMessageReqPerfSendOtherCpu";
+ ctx->request.setup = RtemsMessageReqPerfSendOtherCpu_Setup_Wrap;
+ ctx->request.body = RtemsMessageReqPerfSendOtherCpu_Body_Wrap;
+ ctx->request.teardown = RtemsMessageReqPerfSendOtherCpu_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsMessageReqPerfSendOtherCpu_Cleanup( ctx );
+ #endif
+
+ ctx->request.name = "RtemsMessageReqPerfSendPreempt";
+ ctx->request.setup = RtemsMessageReqPerfSendPreempt_Setup_Wrap;
+ ctx->request.body = RtemsMessageReqPerfSendPreempt_Body_Wrap;
+ ctx->request.teardown = RtemsMessageReqPerfSendPreempt_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-message-receive.c b/testsuites/validation/tc-message-receive.c
new file mode 100644
index 0000000000..944512eaa8
--- /dev/null
+++ b/testsuites/validation/tc-message-receive.c
@@ -0,0 +1,1473 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsMessageReqReceive
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/score/statesimpl.h>
+
+#include "tr-tq-enqueue-fifo.h"
+#include "tr-tq-enqueue-priority.h"
+#include "tx-support.h"
+#include "tx-thread-queue.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsMessageReqReceive spec:/rtems/message/req/receive
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsMessageReqReceive_Pre_Buffer_Valid,
+ RtemsMessageReqReceive_Pre_Buffer_Null,
+ RtemsMessageReqReceive_Pre_Buffer_NA
+} RtemsMessageReqReceive_Pre_Buffer;
+
+typedef enum {
+ RtemsMessageReqReceive_Pre_Size_Valid,
+ RtemsMessageReqReceive_Pre_Size_Null,
+ RtemsMessageReqReceive_Pre_Size_NA
+} RtemsMessageReqReceive_Pre_Size;
+
+typedef enum {
+ RtemsMessageReqReceive_Pre_Id_Valid,
+ RtemsMessageReqReceive_Pre_Id_Invalid,
+ RtemsMessageReqReceive_Pre_Id_NA
+} RtemsMessageReqReceive_Pre_Id;
+
+typedef enum {
+ RtemsMessageReqReceive_Pre_DuringWait_Nop,
+ RtemsMessageReqReceive_Pre_DuringWait_Deleted,
+ RtemsMessageReqReceive_Pre_DuringWait_NA
+} RtemsMessageReqReceive_Pre_DuringWait;
+
+typedef enum {
+ RtemsMessageReqReceive_Pre_TaskQueue_Fifo,
+ RtemsMessageReqReceive_Pre_TaskQueue_Priority,
+ RtemsMessageReqReceive_Pre_TaskQueue_NA
+} RtemsMessageReqReceive_Pre_TaskQueue;
+
+typedef enum {
+ RtemsMessageReqReceive_Pre_Wait_No,
+ RtemsMessageReqReceive_Pre_Wait_Timeout,
+ RtemsMessageReqReceive_Pre_Wait_Forever,
+ RtemsMessageReqReceive_Pre_Wait_NA
+} RtemsMessageReqReceive_Pre_Wait;
+
+typedef enum {
+ RtemsMessageReqReceive_Pre_MsgQueue_Empty,
+ RtemsMessageReqReceive_Pre_MsgQueue_One,
+ RtemsMessageReqReceive_Pre_MsgQueue_Several,
+ RtemsMessageReqReceive_Pre_MsgQueue_NA
+} RtemsMessageReqReceive_Pre_MsgQueue;
+
+typedef enum {
+ RtemsMessageReqReceive_Pre_Storage_Nop,
+ RtemsMessageReqReceive_Pre_Storage_NA
+} RtemsMessageReqReceive_Pre_Storage;
+
+typedef enum {
+ RtemsMessageReqReceive_Post_Status_Ok,
+ RtemsMessageReqReceive_Post_Status_InvId,
+ RtemsMessageReqReceive_Post_Status_InvAddr,
+ RtemsMessageReqReceive_Post_Status_Unsat,
+ RtemsMessageReqReceive_Post_Status_Timeout,
+ RtemsMessageReqReceive_Post_Status_Deleted,
+ RtemsMessageReqReceive_Post_Status_NA
+} RtemsMessageReqReceive_Post_Status;
+
+typedef enum {
+ RtemsMessageReqReceive_Post_Delay_None,
+ RtemsMessageReqReceive_Post_Delay_Ticks,
+ RtemsMessageReqReceive_Post_Delay_Forever,
+ RtemsMessageReqReceive_Post_Delay_NA
+} RtemsMessageReqReceive_Post_Delay;
+
+typedef enum {
+ RtemsMessageReqReceive_Post_Size_First,
+ RtemsMessageReqReceive_Post_Size_Nop,
+ RtemsMessageReqReceive_Post_Size_NA
+} RtemsMessageReqReceive_Post_Size;
+
+typedef enum {
+ RtemsMessageReqReceive_Post_Msg_First,
+ RtemsMessageReqReceive_Post_Msg_Nop,
+ RtemsMessageReqReceive_Post_Msg_NA
+} RtemsMessageReqReceive_Post_Msg;
+
+typedef enum {
+ RtemsMessageReqReceive_Post_MsgQueue_Empty,
+ RtemsMessageReqReceive_Post_MsgQueue_OneLess,
+ RtemsMessageReqReceive_Post_MsgQueue_Nop,
+ RtemsMessageReqReceive_Post_MsgQueue_NA
+} RtemsMessageReqReceive_Post_MsgQueue;
+
+typedef enum {
+ RtemsMessageReqReceive_Post_Tasks_Fifo,
+ RtemsMessageReqReceive_Post_Tasks_Priority,
+ RtemsMessageReqReceive_Post_Tasks_NA
+} RtemsMessageReqReceive_Post_Tasks;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_Buffer_NA : 1;
+ uint32_t Pre_Size_NA : 1;
+ uint32_t Pre_Id_NA : 1;
+ uint32_t Pre_DuringWait_NA : 1;
+ uint32_t Pre_TaskQueue_NA : 1;
+ uint32_t Pre_Wait_NA : 1;
+ uint32_t Pre_MsgQueue_NA : 1;
+ uint32_t Pre_Storage_NA : 1;
+ uint32_t Post_Status : 3;
+ uint32_t Post_Delay : 2;
+ uint32_t Post_Size : 2;
+ uint32_t Post_Msg : 2;
+ uint32_t Post_MsgQueue : 2;
+ uint32_t Post_Tasks : 2;
+} RtemsMessageReqReceive_Entry;
+
+#define MAXIMUM_PENDING_MESSAGES 3
+#define MAXIMUM_MESSAGE_SIZE 5
+
+/**
+ * @brief Test context for spec:/rtems/message/req/receive test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the thread queue test context.
+ */
+ TQContext tq_ctx;
+
+ /**
+ * @brief This member specifies the attribute set of the message queue.
+ */
+ rtems_attribute attribute_set;
+
+ /**
+ * @brief This member is used as storage area for the message queue.
+ */
+ RTEMS_MESSAGE_QUEUE_BUFFER( MAXIMUM_MESSAGE_SIZE )
+ storage_area[ MAXIMUM_PENDING_MESSAGES];
+
+ /**
+ * @brief This member contains always the same arbitrary number ``magic``.
+ *
+ * It is used for run-time type checking.
+ */
+ uint32_t magic;
+
+ /**
+ * @brief This member contains a number which is sent as next message.
+ */
+ uint8_t send_msg_counter;
+
+ /**
+ * @brief This member contains a buffer to receive messages from the queue.
+ */
+ uint8_t receive_buffer[ MAXIMUM_MESSAGE_SIZE ];
+
+ /**
+ * @brief This member contains a buffer to receive the messages size.
+ */
+ size_t receive_size;
+
+ /**
+ * @brief This member specifies the ``id`` parameter for the action.
+ */
+ rtems_id id_param;
+
+ /**
+ * @brief This member specifies the ``buffer`` parameter for the action.
+ */
+ void *buffer_param;
+
+ /**
+ * @brief This member specifies the ``size`` parameter for the action.
+ */
+ size_t *size_param;
+
+ /**
+ * @brief This member specifies the ``option_set`` parameter for the action.
+ */
+ rtems_option option_set_param;
+
+ /**
+ * @brief This member specifies the ``timeout`` parameter for the action.
+ */
+ rtems_interval timeout_param;
+
+ /**
+ * @brief This member contains the returned status code of the action.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member contains the duration of the action in ticks.
+ */
+ uint32_t action_duration;
+
+ /**
+ * @brief This member contains the task identifier of the main task.
+ */
+ rtems_id task_id;
+
+ /**
+ * @brief This member contains the task identifier of the worker task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member contains a pointer to a function which is executed
+ * while the worker is waiting to receive a message (`delete(), nop()``).
+ */
+ void (*concurrent_activity)( void *ctx_in );
+
+ /**
+ * @brief This member contains a pointer to a function which is executed to
+ * check that the action has not changed the content of the message queue.
+ */
+ void (*check_msgq_unchanged)( void *ctx_in );
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 8 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsMessageReqReceive_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsMessageReqReceive_Context;
+
+static RtemsMessageReqReceive_Context
+ RtemsMessageReqReceive_Instance;
+
+static const char * const RtemsMessageReqReceive_PreDesc_Buffer[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsMessageReqReceive_PreDesc_Size[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsMessageReqReceive_PreDesc_Id[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsMessageReqReceive_PreDesc_DuringWait[] = {
+ "Nop",
+ "Deleted",
+ "NA"
+};
+
+static const char * const RtemsMessageReqReceive_PreDesc_TaskQueue[] = {
+ "Fifo",
+ "Priority",
+ "NA"
+};
+
+static const char * const RtemsMessageReqReceive_PreDesc_Wait[] = {
+ "No",
+ "Timeout",
+ "Forever",
+ "NA"
+};
+
+static const char * const RtemsMessageReqReceive_PreDesc_MsgQueue[] = {
+ "Empty",
+ "One",
+ "Several",
+ "NA"
+};
+
+static const char * const RtemsMessageReqReceive_PreDesc_Storage[] = {
+ "Nop",
+ "NA"
+};
+
+static const char * const * const RtemsMessageReqReceive_PreDesc[] = {
+ RtemsMessageReqReceive_PreDesc_Buffer,
+ RtemsMessageReqReceive_PreDesc_Size,
+ RtemsMessageReqReceive_PreDesc_Id,
+ RtemsMessageReqReceive_PreDesc_DuringWait,
+ RtemsMessageReqReceive_PreDesc_TaskQueue,
+ RtemsMessageReqReceive_PreDesc_Wait,
+ RtemsMessageReqReceive_PreDesc_MsgQueue,
+ RtemsMessageReqReceive_PreDesc_Storage,
+ NULL
+};
+
+typedef RtemsMessageReqReceive_Context Context;
+static const uint32_t magic = 0xA55CA3D1; /* an arbitrary number */
+static const rtems_interval timeout_ticks = 3;
+static const rtems_event_set wake_main_task_event = RTEMS_EVENT_17;
+
+static void DoAction( void *ctx_in )
+{
+ Context *ctx = ctx_in;
+ ctx->status = rtems_message_queue_receive(
+ ctx->id_param,
+ ctx->buffer_param,
+ ctx->size_param,
+ ctx->option_set_param,
+ ctx->timeout_param
+ );
+}
+
+static void WorkerTask( rtems_task_argument argument )
+{
+ Context *ctx = (Context *) argument;
+ if ( ctx != NULL ) {
+ T_assert_eq_u32( ctx->magic, magic ); /* Run-time type check */
+ DoAction( ctx );
+ T_rsc_success( rtems_event_send( ctx->task_id, wake_main_task_event ) );
+ }
+ T_rsc_success( rtems_task_suspend( RTEMS_SELF ) );
+}
+
+static void WorkerDoAction( void *ctx_in )
+{
+ rtems_status_code status;
+ Context *ctx = ctx_in;
+ T_assert_eq_u32( ctx->magic, magic ); /* Run-time type check */
+ status = rtems_task_restart( ctx->worker_id, (rtems_task_argument) ctx );
+ T_rsc_success( status );
+}
+
+static uint32_t WaitForWorker( Context *ctx )
+{
+ uint32_t ticks_to_wait = timeout_ticks + 1;
+ rtems_status_code status;
+ rtems_event_set event_set;
+
+ for ( ; ticks_to_wait > 0; --ticks_to_wait ) {
+ /* Check whether the worker finished executing the action */
+ status = rtems_event_receive(
+ RTEMS_PENDING_EVENTS,
+ RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
+ RTEMS_NO_TIMEOUT,
+ &event_set
+ );
+ T_rsc_success( status );
+
+ if ( ( event_set & wake_main_task_event ) == wake_main_task_event ) {
+ break;
+ }
+ TimecounterTick();
+ }
+
+ if ( ctx->timeout_param != RTEMS_NO_TIMEOUT ) {
+ /* Wait till the worker task finishes */
+ status = rtems_event_receive(
+ wake_main_task_event,
+ RTEMS_DEFAULT_OPTIONS,
+ RTEMS_NO_TIMEOUT,
+ &event_set
+ );
+ T_rsc_success( status );
+ }
+
+ return timeout_ticks + 1 - ticks_to_wait;
+}
+
+static void MessageQueueSetup( Context *ctx )
+{
+ rtems_status_code status;
+ /* Sanity check: Make sure the message queue does not exist, yet. */
+ T_assert_eq_u32( ctx->tq_ctx.thread_queue_id, RTEMS_ID_NONE );
+ rtems_message_queue_config config = {
+ .name = rtems_build_name( 'M', 'S', 'G', 'Q' ),
+ .maximum_pending_messages = MAXIMUM_PENDING_MESSAGES,
+ .maximum_message_size = MAXIMUM_MESSAGE_SIZE,
+ .storage_area = ctx->storage_area,
+ .storage_size = sizeof( ctx->storage_area ),
+ .storage_free = NULL,
+ .attributes = ctx->attribute_set
+ };
+
+ status = rtems_message_queue_construct(
+ &config,
+ &ctx->tq_ctx.thread_queue_id
+ );
+ T_rsc_success( status );
+
+ if ( ctx->id_param != RTEMS_ID_NONE ) {
+ ctx->id_param = ctx->tq_ctx.thread_queue_id;
+ }
+}
+
+static void MessageQueueTeardown( Context *ctx )
+{
+ rtems_status_code status;
+ if ( ctx->tq_ctx.thread_queue_id != RTEMS_ID_NONE ) {
+ status = rtems_message_queue_delete( ctx->tq_ctx.thread_queue_id );
+ T_rsc_success( status );
+ ctx->tq_ctx.thread_queue_id = RTEMS_ID_NONE;
+ }
+}
+
+static void CheckForNoMessage(
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+)
+{
+ (void) message_buffer;
+ (void) message_size;
+ T_rsc( status, RTEMS_UNSATISFIED );
+}
+
+static void CheckForFirstMessage(
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+)
+{
+ T_rsc_success( status );
+ T_eq_u32( message_size, 1 );
+ T_eq_u8( message_buffer[0], 0 );
+}
+
+static void CheckForSecondMessage(
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+)
+{
+ T_rsc_success( status );
+ T_eq_u32( message_size, 3 );
+ T_eq_u8( message_buffer[0], 1 );
+ T_eq_u8( message_buffer[1], 1 );
+ T_eq_u8( message_buffer[2], 1 );
+}
+
+static void CheckForThirdMessage(
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+)
+{
+ T_rsc_success( status );
+ T_eq_u32( message_size, 5 );
+ T_eq_u8( message_buffer[0], 2 );
+ T_eq_u8( message_buffer[1], 2 );
+ T_eq_u8( message_buffer[2], 2 );
+ T_eq_u8( message_buffer[3], 2 );
+ T_eq_u8( message_buffer[4], 2 );
+}
+
+static void PopMessage(
+ Context *ctx,
+ void (*check_fn)(
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+ )
+)
+{
+ rtems_status_code status;
+ uint8_t message_buffer[ MAXIMUM_MESSAGE_SIZE ];
+ size_t message_size;
+
+ status = rtems_message_queue_receive(
+ ctx->tq_ctx.thread_queue_id,
+ &message_buffer,
+ &message_size,
+ RTEMS_LOCAL | RTEMS_NO_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+
+ check_fn( status, message_buffer, message_size );
+}
+
+static void CheckForNoMessageInQueue( void *ctx_in )
+{
+ Context *ctx = ctx_in;
+ T_assert_eq_u32( ctx->magic, magic ); /* Run-time type check */
+ PopMessage( ctx, CheckForNoMessage );
+}
+
+static void CheckForOneMessageInQueue( void *ctx_in )
+{
+ Context *ctx = ctx_in;
+ T_assert_eq_u32( ctx->magic, magic ); /* Run-time type check */
+ PopMessage( ctx, CheckForFirstMessage );
+ PopMessage( ctx, CheckForNoMessage );
+}
+
+static void CheckForSeveralMessagesInQueue( void *ctx_in )
+{
+ Context *ctx = ctx_in;
+ T_assert_eq_u32( ctx->magic, magic ); /* Run-time type check */
+ PopMessage( ctx, CheckForFirstMessage );
+ PopMessage( ctx, CheckForSecondMessage );
+ PopMessage( ctx, CheckForThirdMessage );
+ PopMessage( ctx, CheckForNoMessage );
+}
+
+static void MessageQueueNop( void *ctx_in )
+{
+ (void) ctx_in;
+}
+
+static void MessageQueueDelete( void *ctx_in )
+{
+ Context *ctx = ctx_in;
+ T_assert_eq_u32( ctx->magic, magic ); /* Run-time type check */
+ MessageQueueTeardown( ctx );
+}
+
+static Context *ToContext( TQContext *tqctx )
+{
+ Context *ctx = RTEMS_CONTAINER_OF( tqctx, Context, tq_ctx );
+ T_assert_eq_u32( ctx->magic, magic ); /* Run-time type check */
+ return ctx;
+}
+
+static Status_Control ReceiveMsg( TQContext *tqctx, TQWait wait )
+{
+ Context *ctx = ToContext( tqctx );
+ rtems_status_code status;
+ rtems_option option_set;
+ rtems_interval timeout;
+
+ switch ( wait ) {
+ case TQ_WAIT_FOREVER:
+ option_set = RTEMS_WAIT;
+ timeout = RTEMS_NO_TIMEOUT;
+ break;
+ case TQ_WAIT_TIMED:
+ option_set = RTEMS_WAIT;
+ timeout = UINT32_MAX;
+ break;
+ default:
+ option_set = RTEMS_NO_WAIT;
+ timeout = 0;
+ break;
+ }
+
+ status = rtems_message_queue_receive(
+ ctx->tq_ctx.thread_queue_id,
+ ctx->receive_buffer,
+ &ctx->receive_size,
+ option_set,
+ timeout
+ );
+
+ return STATUS_BUILD( status, 0 );
+}
+
+static void SendMsg( TQContext *tqctx )
+{
+ Context *ctx = ToContext( tqctx );
+ rtems_status_code status;
+ uint8_t msg[ MAXIMUM_MESSAGE_SIZE ];
+
+ memset( msg, ctx->send_msg_counter, MAXIMUM_MESSAGE_SIZE );
+ status = rtems_message_queue_send(
+ ctx->tq_ctx.thread_queue_id,
+ msg,
+ ( ctx->send_msg_counter * 2 ) % MAXIMUM_MESSAGE_SIZE + 1
+ );
+ T_rsc_success( status );
+ ++ctx->send_msg_counter;
+}
+
+static void EnqueuePrepare( TQContext *tqctx )
+{
+ Status_Control status;
+
+ /* Check that the message queue is empty */
+ status = TQEnqueue( tqctx, TQ_NO_WAIT );
+ T_eq_int( status, STATUS_BUILD( RTEMS_UNSATISFIED, 0 ) );
+}
+
+static void EnqueueDone( TQContext *tqctx )
+{
+ uint32_t i;
+
+ for ( i = 0; i < tqctx->how_many; ++i ) {
+ SendMsg( tqctx );
+ }
+}
+
+static void RtemsMessageReqReceive_Pre_Buffer_Prepare(
+ RtemsMessageReqReceive_Context *ctx,
+ RtemsMessageReqReceive_Pre_Buffer state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqReceive_Pre_Buffer_Valid: {
+ /*
+ * While the ``buffer`` parameter references a memory area able to store
+ * a message up to the maximum size permitted in this message queue.
+ */
+ ctx->buffer_param = ctx->receive_buffer;
+ break;
+ }
+
+ case RtemsMessageReqReceive_Pre_Buffer_Null: {
+ /*
+ * While the ``buffer`` parameter is NULL.
+ */
+ ctx->buffer_param = NULL;
+ break;
+ }
+
+ case RtemsMessageReqReceive_Pre_Buffer_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqReceive_Pre_Size_Prepare(
+ RtemsMessageReqReceive_Context *ctx,
+ RtemsMessageReqReceive_Pre_Size state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqReceive_Pre_Size_Valid: {
+ /*
+ * While the ``size`` parameter references an object of type ``size_t``.
+ */
+ ctx->size_param = &ctx->receive_size;
+ break;
+ }
+
+ case RtemsMessageReqReceive_Pre_Size_Null: {
+ /*
+ * While the ``size`` parameter is NULL.
+ */
+ ctx->size_param = NULL;
+ break;
+ }
+
+ case RtemsMessageReqReceive_Pre_Size_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqReceive_Pre_Id_Prepare(
+ RtemsMessageReqReceive_Context *ctx,
+ RtemsMessageReqReceive_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqReceive_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter is valid.
+ */
+ ctx->id_param = 1;
+ break;
+ }
+
+ case RtemsMessageReqReceive_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is invalid.
+ */
+ ctx->id_param = RTEMS_ID_NONE;
+ break;
+ }
+
+ case RtemsMessageReqReceive_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqReceive_Pre_DuringWait_Prepare(
+ RtemsMessageReqReceive_Context *ctx,
+ RtemsMessageReqReceive_Pre_DuringWait state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqReceive_Pre_DuringWait_Nop: {
+ /*
+ * While no rtems_message_queue_delete() directive is called successfully
+ * on the message queue during the time one or more tasks are waiting to
+ * receive messages.
+ */
+ ctx->concurrent_activity = MessageQueueNop;
+ break;
+ }
+
+ case RtemsMessageReqReceive_Pre_DuringWait_Deleted: {
+ /*
+ * While rtems_message_queue_delete() is called successfully on the
+ * message queue while one or more tasks are waiting to receive messages.
+ */
+ ctx->concurrent_activity = MessageQueueDelete;
+ break;
+ }
+
+ case RtemsMessageReqReceive_Pre_DuringWait_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqReceive_Pre_TaskQueue_Prepare(
+ RtemsMessageReqReceive_Context *ctx,
+ RtemsMessageReqReceive_Pre_TaskQueue state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqReceive_Pre_TaskQueue_Fifo: {
+ /*
+ * While the member attributes of type rtems_message_queue_config
+ * contains value RTEMS_FIFO when the message queue is constructed.
+ *
+ * Note: RTEMS_GLOBAL is not part of the space profile because no remote
+ * nodes are supported.
+ */
+ ctx->attribute_set = RTEMS_LOCAL | RTEMS_FIFO;
+ break;
+ }
+
+ case RtemsMessageReqReceive_Pre_TaskQueue_Priority: {
+ /*
+ * While the member attributes of type rtems_message_queue_config
+ * contains value RTEMS_PRIORITY when the message queue is constructed.
+ *
+ * Note: RTEMS_GLOBAL is not part of the space profile because no remote
+ * nodes are supported.
+ */
+ ctx->attribute_set = RTEMS_LOCAL | RTEMS_PRIORITY;
+ break;
+ }
+
+ case RtemsMessageReqReceive_Pre_TaskQueue_NA:
+ break;
+ }
+
+ MessageQueueSetup( ctx );
+}
+
+static void RtemsMessageReqReceive_Pre_Wait_Prepare(
+ RtemsMessageReqReceive_Context *ctx,
+ RtemsMessageReqReceive_Pre_Wait state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqReceive_Pre_Wait_No: {
+ /*
+ * While the ``option_set`` parameter indicates the RTEMS_NO_WAIT option.
+ */
+ ctx->tq_ctx.wait = TQ_NO_WAIT;
+ ctx->option_set_param = RTEMS_NO_WAIT;
+ ctx->timeout_param = 1; /* 0 would be RTEMS_NO_TIMEOUT */
+ break;
+ }
+
+ case RtemsMessageReqReceive_Pre_Wait_Timeout: {
+ /*
+ * While the ``option_set`` parameter indicates the RTEMS_WAIT option,
+ * while the ``timeout`` parameter is not equal to RTEMS_NO_TIMEOUT.
+ */
+ ctx->tq_ctx.wait = TQ_WAIT_TIMED;
+ ctx->option_set_param = RTEMS_WAIT;
+ ctx->timeout_param = timeout_ticks;
+ break;
+ }
+
+ case RtemsMessageReqReceive_Pre_Wait_Forever: {
+ /*
+ * While the ``option_set`` parameter indicates the RTEMS_WAIT option,
+ * while the ``timeout`` parameter is equal to RTEMS_NO_TIMEOUT.
+ */
+ ctx->tq_ctx.wait = TQ_WAIT_FOREVER;
+ ctx->option_set_param = RTEMS_WAIT;
+ ctx->timeout_param = RTEMS_NO_TIMEOUT;
+ break;
+ }
+
+ case RtemsMessageReqReceive_Pre_Wait_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqReceive_Pre_MsgQueue_Prepare(
+ RtemsMessageReqReceive_Context *ctx,
+ RtemsMessageReqReceive_Pre_MsgQueue state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqReceive_Pre_MsgQueue_Empty: {
+ /*
+ * While there is no message in the message queue.
+ */
+ /* Message queue is already empty. */
+ ctx->check_msgq_unchanged = CheckForNoMessageInQueue;
+ break;
+ }
+
+ case RtemsMessageReqReceive_Pre_MsgQueue_One: {
+ /*
+ * While there is exactly one message in the message queue.
+ */
+ SendMsg( &( ctx->tq_ctx ) );
+ ctx->check_msgq_unchanged = CheckForOneMessageInQueue;
+ break;
+ }
+
+ case RtemsMessageReqReceive_Pre_MsgQueue_Several: {
+ /*
+ * While there are more than one message in the message queue.
+ */
+ SendMsg( &( ctx->tq_ctx ) );
+ SendMsg( &( ctx->tq_ctx ) );
+ SendMsg( &( ctx->tq_ctx ) );
+ ctx->check_msgq_unchanged = CheckForSeveralMessagesInQueue;
+ break;
+ }
+
+ case RtemsMessageReqReceive_Pre_MsgQueue_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqReceive_Pre_Storage_Prepare(
+ RtemsMessageReqReceive_Context *ctx,
+ RtemsMessageReqReceive_Pre_Storage state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqReceive_Pre_Storage_Nop: {
+ /*
+ * While the memory area to which a pointer is provided as member
+ * storage_area of type rtems_message_queue_config when the message queue
+ * is constructed by rtems_message_queue_construct() is altered only by
+ * the RTEMS operating system.
+ */
+ /* Only a requirement text. */
+ break;
+ }
+
+ case RtemsMessageReqReceive_Pre_Storage_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqReceive_Post_Status_Check(
+ RtemsMessageReqReceive_Context *ctx,
+ RtemsMessageReqReceive_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqReceive_Post_Status_Ok: {
+ /*
+ * The return status of rtems_message_queue_receive() shall be
+ * RTEMS_SUCCESSFUL
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_Status_InvId: {
+ /*
+ * The return status of rtems_message_queue_receive() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_message_queue_receive() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_Status_Unsat: {
+ /*
+ * The return status of rtems_message_queue_receive() shall be
+ * RTEMS_UNSATISFIED.
+ */
+ T_rsc( ctx->status, RTEMS_UNSATISFIED );
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_Status_Timeout: {
+ /*
+ * The return status of rtems_message_queue_receive() shall be
+ * RTEMS_TIMEOUT.
+ */
+ T_rsc( ctx->status, RTEMS_TIMEOUT );
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_Status_Deleted: {
+ /*
+ * The return status of rtems_message_queue_receive() shall be
+ * RTEMS_OBJECT_WAS_DELETED.
+ */
+ T_rsc( ctx->status, RTEMS_OBJECT_WAS_DELETED );
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqReceive_Post_Delay_Check(
+ RtemsMessageReqReceive_Context *ctx,
+ RtemsMessageReqReceive_Post_Delay state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqReceive_Post_Delay_None: {
+ /*
+ * The rtems_message_queue_receive() call shall return immediately.
+ */
+ T_eq_u32( ctx->action_duration, 0 );
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_Delay_Ticks: {
+ /*
+ * The rtems_message_queue_receive() call shall return after the timeout
+ * period in ticks.
+ */
+ T_eq_u32( ctx->action_duration, timeout_ticks );
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_Delay_Forever: {
+ /*
+ * The rtems_message_queue_receive() call shall not return.
+ */
+ T_gt_u32( ctx->action_duration, timeout_ticks );
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_Delay_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqReceive_Post_Size_Check(
+ RtemsMessageReqReceive_Context *ctx,
+ RtemsMessageReqReceive_Post_Size state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqReceive_Post_Size_First: {
+ /*
+ * The value of the object referenced by the ``size`` parameter shall be
+ * set to the size of the first message (the same value as provided by
+ * parameter ``size`` of the rtems_message_queue_send() or
+ * rtems_message_queue_urgent() directive which added the message to the
+ * queue) after the return of the rtems_message_queue_receive() call.
+ */
+ CheckForFirstMessage(
+ ctx->status,
+ ctx->receive_buffer,
+ ctx->receive_size
+ );
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_Size_Nop: {
+ /*
+ * Objects referenced by the ``size`` parameter in past calls to
+ * rtems_message_queue_receive() shall not be accessed by the
+ * rtems_message_queue_receive() call (see also Nop).
+ */
+ T_eq_sz( ctx->receive_size, SIZE_MAX );
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_Size_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqReceive_Post_Msg_Check(
+ RtemsMessageReqReceive_Context *ctx,
+ RtemsMessageReqReceive_Post_Msg state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqReceive_Post_Msg_First: {
+ /*
+ * The bytes 0 till ``size`` - 1 of the object referenced by the
+ * ``option_set`` parameter shall contain a copy of the content of the
+ * first message (all bytes unchanged and in the same order as provided
+ * by parameter ``buffer`` of the rtems_message_queue_send() or
+ * rtems_message_queue_urgent() directive which added the message to the
+ * queue) after the return of the rtems_message_queue_receive() call.
+ */
+ CheckForFirstMessage(
+ ctx->status,
+ ctx->receive_buffer,
+ ctx->receive_size
+ );
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_Msg_Nop: {
+ /*
+ * Objects referenced by the ``option_set`` parameter in past calls to
+ * rtems_message_queue_receive() shall not be accessed by the
+ * rtems_message_queue_receive() call (see also Nop).
+ */
+ int i;
+ for ( i = 0; i < MAXIMUM_MESSAGE_SIZE; ++i ) {
+ T_eq_u8( ctx->receive_buffer[i], UINT8_MAX );
+ }
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_Msg_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqReceive_Post_MsgQueue_Check(
+ RtemsMessageReqReceive_Context *ctx,
+ RtemsMessageReqReceive_Post_MsgQueue state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqReceive_Post_MsgQueue_Empty: {
+ /*
+ * The message queue shall be empty after the return of the
+ * rtems_message_queue_receive() call.
+ */
+ PopMessage( ctx, CheckForNoMessage );
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_MsgQueue_OneLess: {
+ /*
+ * The first message shall be removed from the message queue after the
+ * return of the rtems_message_queue_receive() call.
+ */
+ PopMessage( ctx, CheckForSecondMessage );
+ PopMessage( ctx, CheckForThirdMessage );
+ PopMessage( ctx, CheckForNoMessage );
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_MsgQueue_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past calls to
+ * rtems_message_queue_receive() shall not be accessed by the
+ * rtems_message_queue_receive() call (see also Nop).
+ */
+ ctx->check_msgq_unchanged( ctx );
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_MsgQueue_NA:
+ break;
+ }
+
+ MessageQueueTeardown( ctx );
+}
+
+static void RtemsMessageReqReceive_Post_Tasks_Check(
+ RtemsMessageReqReceive_Context *ctx,
+ RtemsMessageReqReceive_Post_Tasks state
+)
+{
+ MessageQueueSetup( ctx );
+
+ switch ( state ) {
+ case RtemsMessageReqReceive_Post_Tasks_Fifo: {
+ /*
+ * Where the thread queue uses the FIFO discipline, the calling thread
+ * shall be enqueued in FIFO order.
+ */
+ ScoreTqReqEnqueueFifo_Run( &ctx->tq_ctx );
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_Tasks_Priority: {
+ /*
+ * Where the thread queue uses the priority discipline, the calling
+ * thread shall be enqueued in priority order.
+ */
+ ScoreTqReqEnqueuePriority_Run( &ctx->tq_ctx );
+ break;
+ }
+
+ case RtemsMessageReqReceive_Post_Tasks_NA:
+ break;
+ }
+
+ MessageQueueTeardown( ctx );
+}
+
+static void RtemsMessageReqReceive_Setup( RtemsMessageReqReceive_Context *ctx )
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->magic = magic;
+ ctx->tq_ctx.enqueue = ReceiveMsg;
+ ctx->tq_ctx.surrender = TQDoNothingSuccessfully;
+ ctx->tq_ctx.convert_status = TQConvertStatusClassic;
+ ctx->tq_ctx.enqueue_prepare = EnqueuePrepare;
+ ctx->tq_ctx.enqueue_done = EnqueueDone;
+ TQInitialize( &ctx->tq_ctx );
+
+ /*
+ * ctx->tq_ctx.thread_queue_id = RTEMS_ID_NONE indicates that the message
+ * queue does currently not exist. A message queue is created
+ * two times in a row in a single test cycle. First after the attributes
+ * are set in the preconditions. That queue is used for all tests of
+ * usual message queue requirements. Second a message queue is recreated
+ * in the tasks post-conditions for the tests of the task queue.
+ * To avoid an accidentally creation of a second
+ * message queue without the first being deleted prior,
+ * ctx->tq_ctx.thread_queue_id is checked for being RTEMS_ID_NONE before
+ * any message queue is created - a run-time sanity check.
+ */
+ ctx->tq_ctx.thread_queue_id = RTEMS_ID_NONE;
+ ctx->task_id = rtems_task_self();
+
+ /* Note: TQInitialize() will assign the "main" task priority PRIO_NORMAL */
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, WorkerTask, NULL );
+}
+
+static void RtemsMessageReqReceive_Setup_Wrap( void *arg )
+{
+ RtemsMessageReqReceive_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsMessageReqReceive_Setup( ctx );
+}
+
+static void RtemsMessageReqReceive_Teardown(
+ RtemsMessageReqReceive_Context *ctx
+)
+{
+ DeleteTask( ctx->worker_id );
+ TQDestroy( &ctx->tq_ctx );
+ (void) PollAnyEvents();
+}
+
+static void RtemsMessageReqReceive_Teardown_Wrap( void *arg )
+{
+ RtemsMessageReqReceive_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsMessageReqReceive_Teardown( ctx );
+}
+
+static void RtemsMessageReqReceive_Prepare(
+ RtemsMessageReqReceive_Context *ctx
+)
+{
+ /* Clean away pending events - happens after RTEMS_WAIT + RTEMS_NO_TIMEOUT */
+ (void) PollAnyEvents();
+
+ ctx->send_msg_counter = 0;
+ ctx->receive_size = SIZE_MAX;
+ memset( ctx->receive_buffer, UINT8_MAX, MAXIMUM_MESSAGE_SIZE );
+}
+
+static void RtemsMessageReqReceive_Action(
+ RtemsMessageReqReceive_Context *ctx
+)
+{
+ WorkerDoAction( ctx );
+ ctx->concurrent_activity( ctx );
+ ctx->action_duration = WaitForWorker( ctx );
+}
+
+static const RtemsMessageReqReceive_Entry
+RtemsMessageReqReceive_Entries[] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqReceive_Post_Status_InvAddr,
+ RtemsMessageReqReceive_Post_Delay_None,
+ RtemsMessageReqReceive_Post_Size_Nop, RtemsMessageReqReceive_Post_Msg_Nop,
+ RtemsMessageReqReceive_Post_MsgQueue_Nop,
+ RtemsMessageReqReceive_Post_Tasks_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqReceive_Post_Status_InvAddr,
+ RtemsMessageReqReceive_Post_Delay_None,
+ RtemsMessageReqReceive_Post_Size_Nop, RtemsMessageReqReceive_Post_Msg_Nop,
+ RtemsMessageReqReceive_Post_MsgQueue_NA,
+ RtemsMessageReqReceive_Post_Tasks_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqReceive_Post_Status_InvId,
+ RtemsMessageReqReceive_Post_Delay_None,
+ RtemsMessageReqReceive_Post_Size_Nop, RtemsMessageReqReceive_Post_Msg_Nop,
+ RtemsMessageReqReceive_Post_MsgQueue_Nop,
+ RtemsMessageReqReceive_Post_Tasks_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqReceive_Post_Status_InvId,
+ RtemsMessageReqReceive_Post_Delay_None,
+ RtemsMessageReqReceive_Post_Size_Nop, RtemsMessageReqReceive_Post_Msg_Nop,
+ RtemsMessageReqReceive_Post_MsgQueue_NA,
+ RtemsMessageReqReceive_Post_Tasks_NA },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqReceive_Post_Status_NA,
+ RtemsMessageReqReceive_Post_Delay_NA, RtemsMessageReqReceive_Post_Size_NA,
+ RtemsMessageReqReceive_Post_Msg_NA,
+ RtemsMessageReqReceive_Post_MsgQueue_NA,
+ RtemsMessageReqReceive_Post_Tasks_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqReceive_Post_Status_Ok,
+ RtemsMessageReqReceive_Post_Delay_None,
+ RtemsMessageReqReceive_Post_Size_First,
+ RtemsMessageReqReceive_Post_Msg_First,
+ RtemsMessageReqReceive_Post_MsgQueue_Empty,
+ RtemsMessageReqReceive_Post_Tasks_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqReceive_Post_Status_Ok,
+ RtemsMessageReqReceive_Post_Delay_None,
+ RtemsMessageReqReceive_Post_Size_First,
+ RtemsMessageReqReceive_Post_Msg_First,
+ RtemsMessageReqReceive_Post_MsgQueue_OneLess,
+ RtemsMessageReqReceive_Post_Tasks_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqReceive_Post_Status_Deleted,
+ RtemsMessageReqReceive_Post_Delay_None,
+ RtemsMessageReqReceive_Post_Size_Nop, RtemsMessageReqReceive_Post_Msg_Nop,
+ RtemsMessageReqReceive_Post_MsgQueue_NA,
+ RtemsMessageReqReceive_Post_Tasks_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqReceive_Post_Status_Unsat,
+ RtemsMessageReqReceive_Post_Delay_None,
+ RtemsMessageReqReceive_Post_Size_Nop, RtemsMessageReqReceive_Post_Msg_Nop,
+ RtemsMessageReqReceive_Post_MsgQueue_Nop,
+ RtemsMessageReqReceive_Post_Tasks_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqReceive_Post_Status_Timeout,
+ RtemsMessageReqReceive_Post_Delay_Ticks,
+ RtemsMessageReqReceive_Post_Size_Nop, RtemsMessageReqReceive_Post_Msg_Nop,
+ RtemsMessageReqReceive_Post_MsgQueue_Nop,
+ RtemsMessageReqReceive_Post_Tasks_Fifo },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqReceive_Post_Status_NA,
+ RtemsMessageReqReceive_Post_Delay_Forever,
+ RtemsMessageReqReceive_Post_Size_Nop, RtemsMessageReqReceive_Post_Msg_Nop,
+ RtemsMessageReqReceive_Post_MsgQueue_Nop,
+ RtemsMessageReqReceive_Post_Tasks_Fifo },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqReceive_Post_Status_Timeout,
+ RtemsMessageReqReceive_Post_Delay_Ticks,
+ RtemsMessageReqReceive_Post_Size_Nop, RtemsMessageReqReceive_Post_Msg_Nop,
+ RtemsMessageReqReceive_Post_MsgQueue_Nop,
+ RtemsMessageReqReceive_Post_Tasks_Priority },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqReceive_Post_Status_NA,
+ RtemsMessageReqReceive_Post_Delay_Forever,
+ RtemsMessageReqReceive_Post_Size_Nop, RtemsMessageReqReceive_Post_Msg_Nop,
+ RtemsMessageReqReceive_Post_MsgQueue_Nop,
+ RtemsMessageReqReceive_Post_Tasks_Priority }
+};
+
+static const uint8_t
+RtemsMessageReqReceive_Map[] = {
+ 8, 5, 6, 9, 5, 6, 10, 5, 6, 8, 5, 6, 11, 5, 6, 12, 5, 6, 4, 4, 4, 7, 4, 4, 7,
+ 4, 4, 4, 4, 4, 7, 4, 4, 7, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1
+};
+
+static size_t RtemsMessageReqReceive_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsMessageReqReceive_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsMessageReqReceive_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsMessageReqReceive_Fixture = {
+ .setup = RtemsMessageReqReceive_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsMessageReqReceive_Teardown_Wrap,
+ .scope = RtemsMessageReqReceive_Scope,
+ .initial_context = &RtemsMessageReqReceive_Instance
+};
+
+static inline RtemsMessageReqReceive_Entry RtemsMessageReqReceive_PopEntry(
+ RtemsMessageReqReceive_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsMessageReqReceive_Entries[
+ RtemsMessageReqReceive_Map[ index ]
+ ];
+}
+
+static void RtemsMessageReqReceive_TestVariant(
+ RtemsMessageReqReceive_Context *ctx
+)
+{
+ RtemsMessageReqReceive_Pre_Buffer_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsMessageReqReceive_Pre_Size_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsMessageReqReceive_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsMessageReqReceive_Pre_DuringWait_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsMessageReqReceive_Pre_TaskQueue_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsMessageReqReceive_Pre_Wait_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsMessageReqReceive_Pre_MsgQueue_Prepare( ctx, ctx->Map.pcs[ 6 ] );
+ RtemsMessageReqReceive_Pre_Storage_Prepare( ctx, ctx->Map.pcs[ 7 ] );
+ RtemsMessageReqReceive_Action( ctx );
+ RtemsMessageReqReceive_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsMessageReqReceive_Post_Delay_Check( ctx, ctx->Map.entry.Post_Delay );
+ RtemsMessageReqReceive_Post_Size_Check( ctx, ctx->Map.entry.Post_Size );
+ RtemsMessageReqReceive_Post_Msg_Check( ctx, ctx->Map.entry.Post_Msg );
+ RtemsMessageReqReceive_Post_MsgQueue_Check(
+ ctx,
+ ctx->Map.entry.Post_MsgQueue
+ );
+ RtemsMessageReqReceive_Post_Tasks_Check( ctx, ctx->Map.entry.Post_Tasks );
+}
+
+/**
+ * @fn void T_case_body_RtemsMessageReqReceive( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsMessageReqReceive, &RtemsMessageReqReceive_Fixture )
+{
+ RtemsMessageReqReceive_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsMessageReqReceive_Pre_Buffer_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsMessageReqReceive_Pre_Buffer_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsMessageReqReceive_Pre_Size_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsMessageReqReceive_Pre_Size_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsMessageReqReceive_Pre_Id_Valid;
+ ctx->Map.pcs[ 2 ] < RtemsMessageReqReceive_Pre_Id_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsMessageReqReceive_Pre_DuringWait_Nop;
+ ctx->Map.pcs[ 3 ] < RtemsMessageReqReceive_Pre_DuringWait_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = RtemsMessageReqReceive_Pre_TaskQueue_Fifo;
+ ctx->Map.pcs[ 4 ] < RtemsMessageReqReceive_Pre_TaskQueue_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 5 ] = RtemsMessageReqReceive_Pre_Wait_No;
+ ctx->Map.pcs[ 5 ] < RtemsMessageReqReceive_Pre_Wait_NA;
+ ++ctx->Map.pcs[ 5 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 6 ] = RtemsMessageReqReceive_Pre_MsgQueue_Empty;
+ ctx->Map.pcs[ 6 ] < RtemsMessageReqReceive_Pre_MsgQueue_NA;
+ ++ctx->Map.pcs[ 6 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 7 ] = RtemsMessageReqReceive_Pre_Storage_Nop;
+ ctx->Map.pcs[ 7 ] < RtemsMessageReqReceive_Pre_Storage_NA;
+ ++ctx->Map.pcs[ 7 ]
+ ) {
+ ctx->Map.entry = RtemsMessageReqReceive_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsMessageReqReceive_Prepare( ctx );
+ RtemsMessageReqReceive_TestVariant( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-message-urgent-send.c b/testsuites/validation/tc-message-urgent-send.c
new file mode 100644
index 0000000000..e7364f108d
--- /dev/null
+++ b/testsuites/validation/tc-message-urgent-send.c
@@ -0,0 +1,1166 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsMessageReqUrgentSend
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsMessageReqUrgentSend spec:/rtems/message/req/urgent-send
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsMessageReqUrgentSend_Pre_Buffer_Valid,
+ RtemsMessageReqUrgentSend_Pre_Buffer_Null,
+ RtemsMessageReqUrgentSend_Pre_Buffer_NA
+} RtemsMessageReqUrgentSend_Pre_Buffer;
+
+typedef enum {
+ RtemsMessageReqUrgentSend_Pre_Id_Valid,
+ RtemsMessageReqUrgentSend_Pre_Id_Invalid,
+ RtemsMessageReqUrgentSend_Pre_Id_NA
+} RtemsMessageReqUrgentSend_Pre_Id;
+
+typedef enum {
+ RtemsMessageReqUrgentSend_Pre_Size_Zero,
+ RtemsMessageReqUrgentSend_Pre_Size_SomeSize,
+ RtemsMessageReqUrgentSend_Pre_Size_MaxSize,
+ RtemsMessageReqUrgentSend_Pre_Size_TooLarge,
+ RtemsMessageReqUrgentSend_Pre_Size_NA
+} RtemsMessageReqUrgentSend_Pre_Size;
+
+typedef enum {
+ RtemsMessageReqUrgentSend_Pre_MsgQueue_Empty,
+ RtemsMessageReqUrgentSend_Pre_MsgQueue_One,
+ RtemsMessageReqUrgentSend_Pre_MsgQueue_Several,
+ RtemsMessageReqUrgentSend_Pre_MsgQueue_Full,
+ RtemsMessageReqUrgentSend_Pre_MsgQueue_NA
+} RtemsMessageReqUrgentSend_Pre_MsgQueue;
+
+typedef enum {
+ RtemsMessageReqUrgentSend_Pre_Receiver_Waiting,
+ RtemsMessageReqUrgentSend_Pre_Receiver_No,
+ RtemsMessageReqUrgentSend_Pre_Receiver_NA
+} RtemsMessageReqUrgentSend_Pre_Receiver;
+
+typedef enum {
+ RtemsMessageReqUrgentSend_Pre_Directive_Send,
+ RtemsMessageReqUrgentSend_Pre_Directive_Urgent,
+ RtemsMessageReqUrgentSend_Pre_Directive_NA
+} RtemsMessageReqUrgentSend_Pre_Directive;
+
+typedef enum {
+ RtemsMessageReqUrgentSend_Pre_Storage_Nop,
+ RtemsMessageReqUrgentSend_Pre_Storage_NA
+} RtemsMessageReqUrgentSend_Pre_Storage;
+
+typedef enum {
+ RtemsMessageReqUrgentSend_Post_Status_Ok,
+ RtemsMessageReqUrgentSend_Post_Status_InvId,
+ RtemsMessageReqUrgentSend_Post_Status_InvAddr,
+ RtemsMessageReqUrgentSend_Post_Status_InvSize,
+ RtemsMessageReqUrgentSend_Post_Status_TooMany,
+ RtemsMessageReqUrgentSend_Post_Status_NA
+} RtemsMessageReqUrgentSend_Post_Status;
+
+typedef enum {
+ RtemsMessageReqUrgentSend_Post_MsgQueue_Empty,
+ RtemsMessageReqUrgentSend_Post_MsgQueue_One,
+ RtemsMessageReqUrgentSend_Post_MsgQueue_Prepend,
+ RtemsMessageReqUrgentSend_Post_MsgQueue_Append,
+ RtemsMessageReqUrgentSend_Post_MsgQueue_Nop,
+ RtemsMessageReqUrgentSend_Post_MsgQueue_NA
+} RtemsMessageReqUrgentSend_Post_MsgQueue;
+
+typedef enum {
+ RtemsMessageReqUrgentSend_Post_Receiver_GotMsg,
+ RtemsMessageReqUrgentSend_Post_Receiver_Waiting,
+ RtemsMessageReqUrgentSend_Post_Receiver_NA
+} RtemsMessageReqUrgentSend_Post_Receiver;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Buffer_NA : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_Size_NA : 1;
+ uint16_t Pre_MsgQueue_NA : 1;
+ uint16_t Pre_Receiver_NA : 1;
+ uint16_t Pre_Directive_NA : 1;
+ uint16_t Pre_Storage_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_MsgQueue : 3;
+ uint16_t Post_Receiver : 2;
+} RtemsMessageReqUrgentSend_Entry;
+
+#define MAXIMUM_PENDING_MESSAGES 3
+#define MAXIMUM_MESSAGE_SIZE 5
+
+/**
+ * @brief Test context for spec:/rtems/message/req/urgent-send test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a valid ID of a message queue.
+ */
+ rtems_id message_queue_id;
+
+ /**
+ * @brief This member is used as storage area for the message queue.
+ */
+ RTEMS_MESSAGE_QUEUE_BUFFER( MAXIMUM_MESSAGE_SIZE )
+ storage_area[ MAXIMUM_PENDING_MESSAGES];
+
+ /**
+ * @brief This member contains always the same arbitrary number ``magic``.
+ *
+ * It is used for run-time type checking.
+ */
+ uint32_t magic;
+
+ /**
+ * @brief This member contains a number which is sent as next message.
+ */
+ uint8_t send_msg_counter;
+
+ /**
+ * @brief This member contains a buffer to receive messages from the queue.
+ */
+ uint8_t receive_buffer[ MAXIMUM_MESSAGE_SIZE ];
+
+ /**
+ * @brief This member contains a buffer to receive the messages size.
+ */
+ size_t receive_size;
+
+ /**
+ * @brief This member contains the returned status code of the receiver.
+ */
+ rtems_status_code receive_status;
+
+ /**
+ * @brief This member indicates whether the a receiver task should be started
+ * to receive a message.
+ */
+ bool is_receiver_waiting;
+
+ /**
+ * @brief This member contains the message to be sent by the action.
+ */
+ uint8_t send_message[ MAXIMUM_MESSAGE_SIZE ];
+
+ /**
+ * @brief This member specifies the directive to be called as action.
+ *
+ * This is either rtems_message_queue_send() or rtems_message_queue_urgent().
+ */
+ rtems_status_code (*action)( rtems_id id, const void *buffer, size_t size );
+
+ /**
+ * @brief This member specifies the ``id`` parameter for the action.
+ */
+ rtems_id id_param;
+
+ /**
+ * @brief This member specifies the ``buffer`` parameter for the action.
+ */
+ void *buffer_param;
+
+ /**
+ * @brief This member specifies the ``size`` parameter for the action.
+ */
+ size_t size_param;
+
+ /**
+ * @brief This member contains the returned status code of the action.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member contains the task identifier of the worker task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member contains a pointer to a function which is executed to
+ * check that the action has not changed the content of the message queue.
+ */
+ void (*check_msgq_unchanged)( void *ctx_in );
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 7 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsMessageReqUrgentSend_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsMessageReqUrgentSend_Context;
+
+static RtemsMessageReqUrgentSend_Context
+ RtemsMessageReqUrgentSend_Instance;
+
+static const char * const RtemsMessageReqUrgentSend_PreDesc_Buffer[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsMessageReqUrgentSend_PreDesc_Id[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsMessageReqUrgentSend_PreDesc_Size[] = {
+ "Zero",
+ "SomeSize",
+ "MaxSize",
+ "TooLarge",
+ "NA"
+};
+
+static const char * const RtemsMessageReqUrgentSend_PreDesc_MsgQueue[] = {
+ "Empty",
+ "One",
+ "Several",
+ "Full",
+ "NA"
+};
+
+static const char * const RtemsMessageReqUrgentSend_PreDesc_Receiver[] = {
+ "Waiting",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsMessageReqUrgentSend_PreDesc_Directive[] = {
+ "Send",
+ "Urgent",
+ "NA"
+};
+
+static const char * const RtemsMessageReqUrgentSend_PreDesc_Storage[] = {
+ "Nop",
+ "NA"
+};
+
+static const char * const * const RtemsMessageReqUrgentSend_PreDesc[] = {
+ RtemsMessageReqUrgentSend_PreDesc_Buffer,
+ RtemsMessageReqUrgentSend_PreDesc_Id,
+ RtemsMessageReqUrgentSend_PreDesc_Size,
+ RtemsMessageReqUrgentSend_PreDesc_MsgQueue,
+ RtemsMessageReqUrgentSend_PreDesc_Receiver,
+ RtemsMessageReqUrgentSend_PreDesc_Directive,
+ RtemsMessageReqUrgentSend_PreDesc_Storage,
+ NULL
+};
+
+typedef RtemsMessageReqUrgentSend_Context Context;
+static const uint32_t MAGIC = 0xA66FE31; /* an arbitrary number */
+static const rtems_interval TIMEOUT_TICKS = 1;
+static const rtems_event_set EVENT_RECEIVE = RTEMS_EVENT_17;
+
+static void Receive( Context *ctx )
+{
+ ctx->receive_status = rtems_message_queue_receive(
+ ctx->message_queue_id,
+ ctx->receive_buffer,
+ &ctx->receive_size,
+ RTEMS_WAIT,
+ TIMEOUT_TICKS
+ );
+}
+
+static void WorkerTask( rtems_task_argument argument )
+{
+ Context *ctx = (Context *) argument;
+
+ while ( true ) {
+ rtems_event_set events;
+
+ events = ReceiveAnyEvents();
+
+ if ( ( events & EVENT_RECEIVE ) != 0 ) {
+ Receive( ctx );
+ }
+ }
+}
+
+static void CheckForNoMessage(
+ Context *ctx,
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+)
+{
+ (void) ctx;
+ T_rsc( status, RTEMS_UNSATISFIED );
+}
+
+static void CheckForFirstMessage(
+ Context *ctx,
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+)
+{
+ (void) ctx;
+ T_rsc_success( status );
+ T_eq_u32( message_size, 1 );
+ T_eq_u8( message_buffer[0], 0 );
+}
+
+static void CheckForSecondMessage(
+ Context *ctx,
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+)
+{
+ (void) ctx;
+ T_rsc_success( status );
+ T_eq_u32( message_size, 3 );
+ T_eq_u8( message_buffer[0], 1 );
+ T_eq_u8( message_buffer[1], 1 );
+ T_eq_u8( message_buffer[2], 1 );
+}
+
+static void CheckForThirdMessage(
+ Context *ctx,
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+)
+{
+ (void) ctx;
+ T_rsc_success( status );
+ T_eq_u32( message_size, 5 );
+ T_eq_u8( message_buffer[0], 2 );
+ T_eq_u8( message_buffer[1], 2 );
+ T_eq_u8( message_buffer[2], 2 );
+ T_eq_u8( message_buffer[3], 2 );
+ T_eq_u8( message_buffer[4], 2 );
+}
+
+static void CheckForSendMessage(
+ Context *ctx,
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+)
+{
+ size_t i;
+ T_rsc_success( status );
+ T_eq_u32( message_size, ctx->size_param );
+ for ( i = 0; i < ctx->size_param; ++i ) {
+ T_eq_u8( message_buffer[i], ctx->send_message[i] );
+ }
+}
+
+static void PopMessage(
+ Context *ctx,
+ void (*check_fn)(
+ Context *ctx,
+ rtems_status_code status,
+ uint8_t *message_buffer,
+ size_t message_size
+ )
+)
+{
+ rtems_status_code status;
+ uint8_t message_buffer[ MAXIMUM_MESSAGE_SIZE ];
+ size_t message_size;
+
+ status = rtems_message_queue_receive(
+ ctx->message_queue_id,
+ &message_buffer,
+ &message_size,
+ RTEMS_LOCAL | RTEMS_NO_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+
+ check_fn( ctx, status, message_buffer, message_size );
+}
+
+static void CheckForNoMessageInQueue( void *ctx_in )
+{}
+
+static void CheckForOneMessageInQueue( void *ctx_in )
+{
+ Context *ctx = ctx_in;
+ T_assert_eq_u32( ctx->magic, MAGIC ); /* Run-time type check */
+ PopMessage( ctx, CheckForFirstMessage );
+}
+
+static void CheckForSeveralMessagesInQueue( void *ctx_in )
+{
+ Context *ctx = ctx_in;
+ T_assert_eq_u32( ctx->magic, MAGIC ); /* Run-time type check */
+ PopMessage( ctx, CheckForFirstMessage );
+ PopMessage( ctx, CheckForSecondMessage );
+}
+
+static void CheckForAllMessagesInQueue( void *ctx_in )
+{
+ Context *ctx = ctx_in;
+ T_assert_eq_u32( ctx->magic, MAGIC ); /* Run-time type check */
+ PopMessage( ctx, CheckForFirstMessage );
+ PopMessage( ctx, CheckForSecondMessage );
+ PopMessage( ctx, CheckForThirdMessage );
+}
+
+static void SendMsg( Context *ctx )
+{
+ rtems_status_code status;
+ uint8_t msg[ MAXIMUM_MESSAGE_SIZE ];
+
+ memset( msg, ctx->send_msg_counter, MAXIMUM_MESSAGE_SIZE );
+ status = rtems_message_queue_send(
+ ctx->message_queue_id,
+ msg,
+ ( ctx->send_msg_counter * 2 ) % MAXIMUM_MESSAGE_SIZE + 1
+ );
+ T_rsc_success( status );
+ ++ctx->send_msg_counter;
+}
+
+static void RtemsMessageReqUrgentSend_Pre_Buffer_Prepare(
+ RtemsMessageReqUrgentSend_Context *ctx,
+ RtemsMessageReqUrgentSend_Pre_Buffer state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqUrgentSend_Pre_Buffer_Valid: {
+ /*
+ * While the ``buffer`` parameter references a memory area where the
+ * message to be sent is stored.
+ */
+ uint8_t i;
+ for ( i = 0; i < MAXIMUM_MESSAGE_SIZE; ++i ) {
+ ctx->send_message[i] = 42 + i;
+ }
+ ctx->buffer_param = &ctx->send_message;
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Pre_Buffer_Null: {
+ /*
+ * While the ``buffer`` parameter is NULL.
+ */
+ ctx->buffer_param = NULL;
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Pre_Buffer_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqUrgentSend_Pre_Id_Prepare(
+ RtemsMessageReqUrgentSend_Context *ctx,
+ RtemsMessageReqUrgentSend_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqUrgentSend_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter is valid.
+ */
+ ctx->id_param = ctx->message_queue_id;
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is invalid.
+ */
+ ctx->id_param = RTEMS_ID_NONE;
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqUrgentSend_Pre_Size_Prepare(
+ RtemsMessageReqUrgentSend_Context *ctx,
+ RtemsMessageReqUrgentSend_Pre_Size state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqUrgentSend_Pre_Size_Zero: {
+ /*
+ * While the ``size`` parameter is 0.
+ */
+ ctx->size_param = 0;
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Pre_Size_SomeSize: {
+ /*
+ * While the ``size`` parameter has a value between 0 and the maximum
+ * message size.
+ */
+ ctx->size_param = MAXIMUM_MESSAGE_SIZE / 2 + 1;
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Pre_Size_MaxSize: {
+ /*
+ * While the ``size`` parameter has a value of the maximum message size.
+ */
+ ctx->size_param = MAXIMUM_MESSAGE_SIZE;
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Pre_Size_TooLarge: {
+ /*
+ * While the ``size`` parameter has a value greater than the maximum
+ * message size.
+ */
+ ctx->size_param = MAXIMUM_MESSAGE_SIZE + 1;
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Pre_Size_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqUrgentSend_Pre_MsgQueue_Prepare(
+ RtemsMessageReqUrgentSend_Context *ctx,
+ RtemsMessageReqUrgentSend_Pre_MsgQueue state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqUrgentSend_Pre_MsgQueue_Empty: {
+ /*
+ * While there is no message in the message queue.
+ */
+ /* Message queue is already empty. */
+ ctx->check_msgq_unchanged = CheckForNoMessageInQueue;
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Pre_MsgQueue_One: {
+ /*
+ * While there is exactly one message in the message queue.
+ */
+ SendMsg( ctx );
+ ctx->check_msgq_unchanged = CheckForOneMessageInQueue;
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Pre_MsgQueue_Several: {
+ /*
+ * While there are more than one and less than maximum pending messages
+ * in the message queue.
+ */
+ SendMsg( ctx );
+ SendMsg( ctx );
+ ctx->check_msgq_unchanged = CheckForSeveralMessagesInQueue;
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Pre_MsgQueue_Full: {
+ /*
+ * While there are maximum pending messages in the message queue.
+ */
+ SendMsg( ctx );
+ SendMsg( ctx );
+ SendMsg( ctx );
+ ctx->check_msgq_unchanged = CheckForAllMessagesInQueue;
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Pre_MsgQueue_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqUrgentSend_Pre_Receiver_Prepare(
+ RtemsMessageReqUrgentSend_Context *ctx,
+ RtemsMessageReqUrgentSend_Pre_Receiver state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqUrgentSend_Pre_Receiver_Waiting: {
+ /*
+ * While a receiver is waiting to receive a message.
+ */
+ ctx->is_receiver_waiting = true;
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Pre_Receiver_No: {
+ /*
+ * While no receiver is waiting to receive a message.
+ */
+ ctx->is_receiver_waiting = false;
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Pre_Receiver_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqUrgentSend_Pre_Directive_Prepare(
+ RtemsMessageReqUrgentSend_Context *ctx,
+ RtemsMessageReqUrgentSend_Pre_Directive state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqUrgentSend_Pre_Directive_Send: {
+ /*
+ * While the directive rtems_message_queue_send() is called.
+ */
+ ctx->action = rtems_message_queue_send;
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Pre_Directive_Urgent: {
+ /*
+ * While the directive rtems_message_queue_urgent() is called.
+ */
+ ctx->action = rtems_message_queue_urgent;
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Pre_Directive_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqUrgentSend_Pre_Storage_Prepare(
+ RtemsMessageReqUrgentSend_Context *ctx,
+ RtemsMessageReqUrgentSend_Pre_Storage state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqUrgentSend_Pre_Storage_Nop: {
+ /*
+ * While the memory area to which a pointer is provided as member
+ * storage_area of type rtems_message_queue_config when the message queue
+ * is constructed by rtems_message_queue_construct() is altered only by
+ * the RTEMS operating system.
+ */
+ /* Only a requirement text. */
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Pre_Storage_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqUrgentSend_Post_Status_Check(
+ RtemsMessageReqUrgentSend_Context *ctx,
+ RtemsMessageReqUrgentSend_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqUrgentSend_Post_Status_Ok: {
+ /*
+ * The return status of the called directive (rtems_message_queue_send()
+ * or rtems_message_queue_urgent()) shall be RTEMS_SUCCESSFUL
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Post_Status_InvId: {
+ /*
+ * The return status of the called directive (rtems_message_queue_send()
+ * or rtems_message_queue_urgent()) shall be RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Post_Status_InvAddr: {
+ /*
+ * The return status of the called directive (rtems_message_queue_send()
+ * or rtems_message_queue_urgent()) shall be RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Post_Status_InvSize: {
+ /*
+ * The return status of the called directive (rtems_message_queue_send()
+ * or rtems_message_queue_urgent()) shall be RTEMS_INVALID_SIZE.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_SIZE );
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Post_Status_TooMany: {
+ /*
+ * The return status of the called directive (rtems_message_queue_send()
+ * or rtems_message_queue_urgent()) shall be RTEMS_TOO_MANY.
+ */
+ T_rsc( ctx->status, RTEMS_TOO_MANY );
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqUrgentSend_Post_MsgQueue_Check(
+ RtemsMessageReqUrgentSend_Context *ctx,
+ RtemsMessageReqUrgentSend_Post_MsgQueue state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqUrgentSend_Post_MsgQueue_Empty: {
+ /*
+ * The message queue shall be empty after the return of the
+ * rtems_message_queue_send() or rtems_message_queue_urgent() call.
+ */
+ PopMessage( ctx, CheckForNoMessage );
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Post_MsgQueue_One: {
+ /*
+ * The message queue shall contain only the send message after the return
+ * of the rtems_message_queue_send() or rtems_message_queue_urgent()
+ * call.
+ */
+ PopMessage( ctx, CheckForSendMessage );
+ PopMessage( ctx, CheckForNoMessage );
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Post_MsgQueue_Prepend: {
+ /*
+ * The message queue shall contain the message send by the last call to
+ * rtems_message_queue_urgent() as first message followed by all the
+ * messages which were in the message queue before that call (in the same
+ * order and each message with the same content and size).
+ */
+ PopMessage( ctx, CheckForSendMessage );
+ ctx->check_msgq_unchanged( ctx );
+ PopMessage( ctx, CheckForNoMessage );
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Post_MsgQueue_Append: {
+ /*
+ * The message queue shall contain the message send by the last call to
+ * rtems_message_queue_send() as last message preceded by all the
+ * messages which were in the message queue before that call (in the same
+ * order and each message with the same content and size).
+ */
+ ctx->check_msgq_unchanged( ctx );
+ PopMessage( ctx, CheckForSendMessage );
+ PopMessage( ctx, CheckForNoMessage );
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Post_MsgQueue_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past call to
+ * rtems_message_queue_send() or rtems_message_queue_urgent() shall not
+ * be accessed by that call (see also Nop).
+ */
+ ctx->check_msgq_unchanged( ctx );
+ PopMessage( ctx, CheckForNoMessage );
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Post_MsgQueue_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqUrgentSend_Post_Receiver_Check(
+ RtemsMessageReqUrgentSend_Context *ctx,
+ RtemsMessageReqUrgentSend_Post_Receiver state
+)
+{
+ switch ( state ) {
+ case RtemsMessageReqUrgentSend_Post_Receiver_GotMsg: {
+ /*
+ * The receiver shall receive the message send by the last call to the
+ * rtems_message_queue_send() or rtems_message_queue_urgent() directive.
+ */
+ CheckForSendMessage(
+ ctx,
+ ctx->receive_status,
+ ctx->receive_buffer,
+ ctx->receive_size
+ );
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Post_Receiver_Waiting: {
+ /*
+ * The receiver shall still wait to receive a message after the last call
+ * to the rtems_message_queue_send() or rtems_message_queue_urgent()
+ * directive.
+ */
+ T_rsc( ctx->receive_status, RTEMS_TIMEOUT );
+ break;
+ }
+
+ case RtemsMessageReqUrgentSend_Post_Receiver_NA:
+ break;
+ }
+}
+
+static void RtemsMessageReqUrgentSend_Setup(
+ RtemsMessageReqUrgentSend_Context *ctx
+)
+{
+ ctx->magic = MAGIC;
+
+ SetSelfPriority( PRIO_NORMAL );
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, WorkerTask, ctx );
+}
+
+static void RtemsMessageReqUrgentSend_Setup_Wrap( void *arg )
+{
+ RtemsMessageReqUrgentSend_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsMessageReqUrgentSend_Setup( ctx );
+}
+
+static void RtemsMessageReqUrgentSend_Teardown(
+ RtemsMessageReqUrgentSend_Context *ctx
+)
+{
+ DeleteTask( ctx->worker_id );
+ RestoreRunnerPriority();
+}
+
+static void RtemsMessageReqUrgentSend_Teardown_Wrap( void *arg )
+{
+ RtemsMessageReqUrgentSend_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsMessageReqUrgentSend_Teardown( ctx );
+}
+
+static void RtemsMessageReqUrgentSend_Prepare(
+ RtemsMessageReqUrgentSend_Context *ctx
+)
+{
+ rtems_status_code status;
+
+ ctx->send_msg_counter = 0;
+
+ rtems_message_queue_config config = {
+ .name = rtems_build_name( 'M', 'S', 'G', 'Q' ),
+ .maximum_pending_messages = MAXIMUM_PENDING_MESSAGES,
+ .maximum_message_size = MAXIMUM_MESSAGE_SIZE,
+ .storage_area = ctx->storage_area,
+ .storage_size = sizeof( ctx->storage_area ),
+ .storage_free = NULL,
+ .attributes = RTEMS_DEFAULT_ATTRIBUTES
+ };
+
+ status = rtems_message_queue_construct(
+ &config,
+ &ctx->message_queue_id
+ );
+ T_rsc_success( status );
+}
+
+static void RtemsMessageReqUrgentSend_Action(
+ RtemsMessageReqUrgentSend_Context *ctx
+)
+{
+ if ( ctx->is_receiver_waiting ) {
+ SendEvents( ctx->worker_id, EVENT_RECEIVE );
+ }
+
+ ctx->status = (ctx->action)(
+ ctx->id_param,
+ ctx->buffer_param,
+ ctx->size_param
+ );
+
+ if ( ctx->is_receiver_waiting ) {
+ FinalClockTick();
+ }
+}
+
+static void RtemsMessageReqUrgentSend_Cleanup(
+ RtemsMessageReqUrgentSend_Context *ctx
+)
+{
+ T_rsc_success( rtems_message_queue_delete( ctx->message_queue_id ) );
+}
+
+static const RtemsMessageReqUrgentSend_Entry
+RtemsMessageReqUrgentSend_Entries[] = {
+ { 1, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_NA,
+ RtemsMessageReqUrgentSend_Post_MsgQueue_NA,
+ RtemsMessageReqUrgentSend_Post_Receiver_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_InvAddr,
+ RtemsMessageReqUrgentSend_Post_MsgQueue_Nop,
+ RtemsMessageReqUrgentSend_Post_Receiver_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_InvId,
+ RtemsMessageReqUrgentSend_Post_MsgQueue_Nop,
+ RtemsMessageReqUrgentSend_Post_Receiver_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_InvAddr,
+ RtemsMessageReqUrgentSend_Post_MsgQueue_Nop,
+ RtemsMessageReqUrgentSend_Post_Receiver_Waiting },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_InvSize,
+ RtemsMessageReqUrgentSend_Post_MsgQueue_Nop,
+ RtemsMessageReqUrgentSend_Post_Receiver_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_InvId,
+ RtemsMessageReqUrgentSend_Post_MsgQueue_Nop,
+ RtemsMessageReqUrgentSend_Post_Receiver_Waiting },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_Ok,
+ RtemsMessageReqUrgentSend_Post_MsgQueue_Empty,
+ RtemsMessageReqUrgentSend_Post_Receiver_GotMsg },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_Ok,
+ RtemsMessageReqUrgentSend_Post_MsgQueue_One,
+ RtemsMessageReqUrgentSend_Post_Receiver_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_Ok,
+ RtemsMessageReqUrgentSend_Post_MsgQueue_Append,
+ RtemsMessageReqUrgentSend_Post_Receiver_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_Ok,
+ RtemsMessageReqUrgentSend_Post_MsgQueue_Prepend,
+ RtemsMessageReqUrgentSend_Post_Receiver_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_TooMany,
+ RtemsMessageReqUrgentSend_Post_MsgQueue_Nop,
+ RtemsMessageReqUrgentSend_Post_Receiver_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsMessageReqUrgentSend_Post_Status_InvSize,
+ RtemsMessageReqUrgentSend_Post_MsgQueue_Nop,
+ RtemsMessageReqUrgentSend_Post_Receiver_Waiting }
+};
+
+static const uint8_t
+RtemsMessageReqUrgentSend_Map[] = {
+ 6, 6, 7, 7, 0, 0, 8, 9, 0, 0, 8, 9, 0, 0, 10, 10, 6, 6, 7, 7, 0, 0, 8, 9, 0,
+ 0, 8, 9, 0, 0, 10, 10, 6, 6, 7, 7, 0, 0, 8, 9, 0, 0, 8, 9, 0, 0, 10, 10, 11,
+ 11, 4, 4, 0, 0, 4, 4, 0, 0, 4, 4, 0, 0, 4, 4, 5, 5, 2, 2, 0, 0, 2, 2, 0, 0,
+ 2, 2, 0, 0, 2, 2, 5, 5, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 5, 5, 2, 2,
+ 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 5, 5, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2, 0, 0,
+ 2, 2, 3, 3, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 3, 3, 1, 1, 0, 0, 1, 1,
+ 0, 0, 1, 1, 0, 0, 1, 1, 3, 3, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 3, 3,
+ 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 3, 3, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
+ 0, 0, 1, 1, 3, 3, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 3, 3, 1, 1, 0, 0,
+ 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 3, 3, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1
+};
+
+static size_t RtemsMessageReqUrgentSend_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsMessageReqUrgentSend_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsMessageReqUrgentSend_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsMessageReqUrgentSend_Fixture = {
+ .setup = RtemsMessageReqUrgentSend_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsMessageReqUrgentSend_Teardown_Wrap,
+ .scope = RtemsMessageReqUrgentSend_Scope,
+ .initial_context = &RtemsMessageReqUrgentSend_Instance
+};
+
+static inline RtemsMessageReqUrgentSend_Entry
+RtemsMessageReqUrgentSend_PopEntry( RtemsMessageReqUrgentSend_Context *ctx )
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsMessageReqUrgentSend_Entries[
+ RtemsMessageReqUrgentSend_Map[ index ]
+ ];
+}
+
+static void RtemsMessageReqUrgentSend_TestVariant(
+ RtemsMessageReqUrgentSend_Context *ctx
+)
+{
+ RtemsMessageReqUrgentSend_Pre_Buffer_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsMessageReqUrgentSend_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsMessageReqUrgentSend_Pre_Size_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsMessageReqUrgentSend_Pre_MsgQueue_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsMessageReqUrgentSend_Pre_Receiver_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsMessageReqUrgentSend_Pre_Directive_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsMessageReqUrgentSend_Pre_Storage_Prepare( ctx, ctx->Map.pcs[ 6 ] );
+ RtemsMessageReqUrgentSend_Action( ctx );
+ RtemsMessageReqUrgentSend_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ RtemsMessageReqUrgentSend_Post_MsgQueue_Check(
+ ctx,
+ ctx->Map.entry.Post_MsgQueue
+ );
+ RtemsMessageReqUrgentSend_Post_Receiver_Check(
+ ctx,
+ ctx->Map.entry.Post_Receiver
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsMessageReqUrgentSend( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsMessageReqUrgentSend,
+ &RtemsMessageReqUrgentSend_Fixture
+)
+{
+ RtemsMessageReqUrgentSend_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsMessageReqUrgentSend_Pre_Buffer_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsMessageReqUrgentSend_Pre_Buffer_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsMessageReqUrgentSend_Pre_Id_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsMessageReqUrgentSend_Pre_Id_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsMessageReqUrgentSend_Pre_Size_Zero;
+ ctx->Map.pcs[ 2 ] < RtemsMessageReqUrgentSend_Pre_Size_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsMessageReqUrgentSend_Pre_MsgQueue_Empty;
+ ctx->Map.pcs[ 3 ] < RtemsMessageReqUrgentSend_Pre_MsgQueue_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = RtemsMessageReqUrgentSend_Pre_Receiver_Waiting;
+ ctx->Map.pcs[ 4 ] < RtemsMessageReqUrgentSend_Pre_Receiver_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 5 ] = RtemsMessageReqUrgentSend_Pre_Directive_Send;
+ ctx->Map.pcs[ 5 ] < RtemsMessageReqUrgentSend_Pre_Directive_NA;
+ ++ctx->Map.pcs[ 5 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 6 ] = RtemsMessageReqUrgentSend_Pre_Storage_Nop;
+ ctx->Map.pcs[ 6 ] < RtemsMessageReqUrgentSend_Pre_Storage_NA;
+ ++ctx->Map.pcs[ 6 ]
+ ) {
+ ctx->Map.entry = RtemsMessageReqUrgentSend_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsMessageReqUrgentSend_Prepare( ctx );
+ RtemsMessageReqUrgentSend_TestVariant( ctx );
+ RtemsMessageReqUrgentSend_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-modes.c b/testsuites/validation/tc-modes.c
new file mode 100644
index 0000000000..91d26e835c
--- /dev/null
+++ b/testsuites/validation/tc-modes.c
@@ -0,0 +1,363 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsModeValModes
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsModeValModes spec:/rtems/mode/val/modes
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests the task mode constants and function-like macros of the Classic
+ * API.
+ *
+ * This test case performs the following actions:
+ *
+ * - Validate the non-default task mode constants.
+ *
+ * - Check that RTEMS_NO_ASR is a power of two representable as an integer of
+ * type rtems_mode.
+ *
+ * - Check that RTEMS_NO_PREEMPT is a power of two representable as an
+ * integer of type rtems_mode.
+ *
+ * - Check that RTEMS_TIMESLICE is a power of two representable as an integer
+ * of type rtems_mode.
+ *
+ * - Validate the default task mode constants.
+ *
+ * - Check that RTEMS_ASR is equal to zero.
+ *
+ * - Check that RTEMS_DEFAULT_MODES is equal to zero.
+ *
+ * - Check that RTEMS_NO_TIMESLICE is equal to zero.
+ *
+ * - Check that RTEMS_PREEMPT is equal to zero.
+ *
+ * - Validate RTEMS_ALL_MODE_MASKS.
+ *
+ * - Check that the bitwise and of RTEMS_ASR_MASK and RTEMS_ALL_MODE_MASKS is
+ * equal to RTEMS_ASR_MASK.
+ *
+ * - Check that the bitwise and of RTEMS_PREEMPT_MASK and
+ * RTEMS_ALL_MODE_MASKS is equal to RTEMS_PREEMPT_MASK.
+ *
+ * - Check that the bitwise and of RTEMS_TIMESLICE_MASK and
+ * RTEMS_ALL_MODE_MASKS is equal to RTEMS_TIMESLICE_MASK.
+ *
+ * - Check that the bitwise and of RTEMS_INTERRUPT_MASK and
+ * RTEMS_ALL_MODE_MASKS is equal to RTEMS_INTERRUPT_MASK.
+ *
+ * - Validate the task mode mask constants except RTEMS_INTERRUPT_MASK.
+ *
+ * - Check that RTEMS_ASR_MASK is a power of two representable as an integer
+ * of type rtems_mode.
+ *
+ * - Check that RTEMS_PREEMPT_MASK is a power of two representable as an
+ * integer of type rtems_mode.
+ *
+ * - Check that RTEMS_TIMESLICE_MASK is a power of two representable as an
+ * integer of type rtems_mode.
+ *
+ * - Calculate the bitwise or of all task mode mask constants and 0xff.
+ *
+ * - Check that the count of set bits in the calculated value is equal to the
+ * count of task mode mask constants except RTEMS_INTERRUPT_MASK plus
+ * eight. Since each task mode mask constants except RTEMS_INTERRUPT_MASK
+ * is a power of two and the bitwise and of 0xff and RTEMS_INTERRUPT_MASK
+ * is equal to RTEMS_INTERRUPT_MASK this proves that each constant and 0xff
+ * has a unique value.
+ *
+ * - Calculate the bitwise or of all non-default task mode constants.
+ *
+ * - Check that the count of set bits in the calculated value is equal to the
+ * count of non-default task mode constants. Since each non-default task
+ * mode constants except is a power of this proves that each constant has a
+ * unique value.
+ *
+ * - Validate RTEMS_INTERRUPT_LEVEL().
+ *
+ * - Check the result of RTEMS_INTERRUPT_LEVEL() for a sample value.
+ *
+ * @{
+ */
+
+static bool IsPowerOfTwo( rtems_mode mode )
+{
+ return mode != 0 && ( mode & ( mode - 1 ) ) == 0;
+}
+
+static int PopCount( rtems_mode modes )
+{
+ int count;
+
+ count = 0;
+
+ while ( modes != 0 ) {
+ ++count;
+ modes &= modes - 1;
+ }
+
+ return count;
+}
+
+/**
+ * @brief Validate the non-default task mode constants.
+ */
+static void RtemsModeValModes_Action_0( void )
+{
+ /* No action */
+
+ /*
+ * Check that RTEMS_NO_ASR is a power of two representable as an integer of
+ * type rtems_mode.
+ */
+ T_step_true( 0, IsPowerOfTwo( RTEMS_NO_ASR ) );
+
+ /*
+ * Check that RTEMS_NO_PREEMPT is a power of two representable as an integer
+ * of type rtems_mode.
+ */
+ T_step_true( 1, IsPowerOfTwo( RTEMS_NO_PREEMPT ) );
+
+ /*
+ * Check that RTEMS_TIMESLICE is a power of two representable as an integer
+ * of type rtems_mode.
+ */
+ T_step_true( 2, IsPowerOfTwo( RTEMS_TIMESLICE ) );
+}
+
+/**
+ * @brief Validate the default task mode constants.
+ */
+static void RtemsModeValModes_Action_1( void )
+{
+ /* No action */
+
+ /*
+ * Check that RTEMS_ASR is equal to zero.
+ */
+ T_step_eq_u32( 3, RTEMS_ASR, 0 );
+
+ /*
+ * Check that RTEMS_DEFAULT_MODES is equal to zero.
+ */
+ T_step_eq_u32( 4, RTEMS_DEFAULT_MODES, 0 );
+
+ /*
+ * Check that RTEMS_NO_TIMESLICE is equal to zero.
+ */
+ T_step_eq_u32( 5, RTEMS_NO_TIMESLICE, 0 );
+
+ /*
+ * Check that RTEMS_PREEMPT is equal to zero.
+ */
+ T_step_eq_u32( 6, RTEMS_PREEMPT, 0 );
+}
+
+/**
+ * @brief Validate RTEMS_ALL_MODE_MASKS.
+ */
+static void RtemsModeValModes_Action_2( void )
+{
+ /* No action */
+
+ /*
+ * Check that the bitwise and of RTEMS_ASR_MASK and RTEMS_ALL_MODE_MASKS is
+ * equal to RTEMS_ASR_MASK.
+ */
+ T_step_eq_u32(
+ 7,
+ RTEMS_ASR_MASK & RTEMS_ALL_MODE_MASKS,
+ RTEMS_ASR_MASK
+ );
+
+ /*
+ * Check that the bitwise and of RTEMS_PREEMPT_MASK and RTEMS_ALL_MODE_MASKS
+ * is equal to RTEMS_PREEMPT_MASK.
+ */
+ T_step_eq_u32(
+ 8,
+ RTEMS_PREEMPT_MASK & RTEMS_ALL_MODE_MASKS,
+ RTEMS_PREEMPT_MASK
+ );
+
+ /*
+ * Check that the bitwise and of RTEMS_TIMESLICE_MASK and
+ * RTEMS_ALL_MODE_MASKS is equal to RTEMS_TIMESLICE_MASK.
+ */
+ T_step_eq_u32(
+ 9,
+ RTEMS_TIMESLICE_MASK & RTEMS_ALL_MODE_MASKS,
+ RTEMS_TIMESLICE_MASK
+ );
+
+ /*
+ * Check that the bitwise and of RTEMS_INTERRUPT_MASK and
+ * RTEMS_ALL_MODE_MASKS is equal to RTEMS_INTERRUPT_MASK.
+ */
+ T_step_eq_u32(
+ 10,
+ RTEMS_INTERRUPT_MASK & RTEMS_ALL_MODE_MASKS,
+ RTEMS_INTERRUPT_MASK
+ );
+}
+
+/**
+ * @brief Validate the task mode mask constants except RTEMS_INTERRUPT_MASK.
+ */
+static void RtemsModeValModes_Action_3( void )
+{
+ /* No action */
+
+ /*
+ * Check that RTEMS_ASR_MASK is a power of two representable as an integer of
+ * type rtems_mode.
+ */
+ T_step_true( 11, IsPowerOfTwo( RTEMS_ASR_MASK ) );
+
+ /*
+ * Check that RTEMS_PREEMPT_MASK is a power of two representable as an
+ * integer of type rtems_mode.
+ */
+ T_step_true( 12, IsPowerOfTwo( RTEMS_PREEMPT_MASK ) );
+
+ /*
+ * Check that RTEMS_TIMESLICE_MASK is a power of two representable as an
+ * integer of type rtems_mode.
+ */
+ T_step_true( 13, IsPowerOfTwo( RTEMS_TIMESLICE_MASK ) );
+}
+
+/**
+ * @brief Calculate the bitwise or of all task mode mask constants and 0xff.
+ */
+static void RtemsModeValModes_Action_4( void )
+{
+ rtems_mode modes;
+
+ modes = 0;
+ modes |= 0xff;
+ modes |= RTEMS_ASR_MASK;
+ modes |= RTEMS_PREEMPT_MASK;
+ modes |= RTEMS_TIMESLICE_MASK;
+
+ /*
+ * Check that the count of set bits in the calculated value is equal to the
+ * count of task mode mask constants except RTEMS_INTERRUPT_MASK plus eight.
+ * Since each task mode mask constants except RTEMS_INTERRUPT_MASK is a power
+ * of two and the bitwise and of 0xff and RTEMS_INTERRUPT_MASK is equal to
+ * RTEMS_INTERRUPT_MASK this proves that each constant and 0xff has a unique
+ * value.
+ */
+ T_step_eq_int( 14, PopCount( modes ), 11 );
+}
+
+/**
+ * @brief Calculate the bitwise or of all non-default task mode constants.
+ */
+static void RtemsModeValModes_Action_5( void )
+{
+ rtems_mode modes;
+
+ modes = 0;
+ modes |= RTEMS_NO_ASR;
+ modes |= RTEMS_NO_PREEMPT;
+ modes |= RTEMS_TIMESLICE;
+
+ /*
+ * Check that the count of set bits in the calculated value is equal to the
+ * count of non-default task mode constants. Since each non-default task
+ * mode constants except is a power of this proves that each constant has a
+ * unique value.
+ */
+ T_step_eq_int( 15, PopCount( modes ), 3 );
+}
+
+/**
+ * @brief Validate RTEMS_INTERRUPT_LEVEL().
+ */
+static void RtemsModeValModes_Action_6( void )
+{
+ /* Nothing to do */
+
+ /*
+ * Check the result of RTEMS_INTERRUPT_LEVEL() for a sample value.
+ */
+ T_step_eq_u32(
+ 16,
+ RTEMS_INTERRUPT_LEVEL( UINT32_MAX ),
+ RTEMS_INTERRUPT_MASK
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsModeValModes( void )
+ */
+T_TEST_CASE( RtemsModeValModes )
+{
+ T_plan( 17 );
+
+ RtemsModeValModes_Action_0();
+ RtemsModeValModes_Action_1();
+ RtemsModeValModes_Action_2();
+ RtemsModeValModes_Action_3();
+ RtemsModeValModes_Action_4();
+ RtemsModeValModes_Action_5();
+ RtemsModeValModes_Action_6();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-object.c b/testsuites/validation/tc-object.c
index 916c35aa95..6ee87dbf4e 100644
--- a/testsuites/validation/tc-object.c
+++ b/testsuites/validation/tc-object.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsObjectValObject
+ * @ingroup RtemsObjectValObject
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -57,24 +57,41 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsObjectValObject spec:/rtems/object/val/object
+ * @defgroup RtemsObjectValObject spec:/rtems/object/val/object
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidationNoClock0
*
- * @brief Tests the rtems_build_name() macro.
+ * @brief Tests some @ref RTEMSAPIClassicObject directives.
*
* This test case performs the following actions:
*
- * - Validate the results of rtems_build_name() for a sample set of parameters.
+ * - Validate the results of rtems_build_name() (function) and
+ * rtems_build_name() (macro) for a sample set of parameters.
*
* - Check that the accumulated name has the expected value.
*
+ * - Validate the result of rtems_object_get_local_node().
+ *
+ * - Check that the returned value is one.
+ *
* @{
*/
+static rtems_name BuildNameMacro( char c1, char c2, char c3, char c4 )
+{
+ return rtems_build_name( c1, c2, c3, c4 );
+}
+
+#undef rtems_build_name
+
+static rtems_name BuildName( char c1, char c2, char c3, char c4 )
+{
+ return rtems_build_name( c1, c2, c3, c4 );
+}
+
/**
- * @brief Validate the results of rtems_build_name() for a sample set of
- * parameters.
+ * @brief Validate the results of rtems_build_name() (function) and
+ * rtems_build_name() (macro) for a sample set of parameters.
*/
static void RtemsObjectValObject_Action_0( void )
{
@@ -123,13 +140,22 @@ static void RtemsObjectValObject_Action_0( void )
T_quiet_eq_u32( actual_name, expected_name )
accumulated_name += actual_name;
- actual_name = rtems_build_name(
+ actual_name = BuildName(
+ chars[ i ],
+ chars[ j ],
+ chars[ k ],
+ chars[ r ]
+ );
+ T_quiet_eq_u32( actual_name, expected_name );
+
+ actual_name = BuildNameMacro(
chars[ i ],
chars[ j ],
chars[ k ],
chars[ r ]
);
T_quiet_eq_u32( actual_name, expected_name );
+
accumulated_name += actual_name;
}
}
@@ -143,13 +169,29 @@ static void RtemsObjectValObject_Action_0( void )
}
/**
+ * @brief Validate the result of rtems_object_get_local_node().
+ */
+static void RtemsObjectValObject_Action_1( void )
+{
+ uint32_t node;
+
+ node = rtems_object_get_local_node();
+
+ /*
+ * Check that the returned value is one.
+ */
+ T_step_eq_u32( 1, node, 1 );
+}
+
+/**
* @fn void T_case_body_RtemsObjectValObject( void )
*/
T_TEST_CASE( RtemsObjectValObject )
{
- T_plan( 1 );
+ T_plan( 2 );
RtemsObjectValObject_Action_0();
+ RtemsObjectValObject_Action_1();
}
/** @} */
diff --git a/testsuites/validation/tc-options.c b/testsuites/validation/tc-options.c
new file mode 100644
index 0000000000..166b3b8b31
--- /dev/null
+++ b/testsuites/validation/tc-options.c
@@ -0,0 +1,202 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsOptionValOptions
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsOptionValOptions spec:/rtems/option/val/options
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests the option constants of the Classic API.
+ *
+ * This test case performs the following actions:
+ *
+ * - Validate the non-default option constants.
+ *
+ * - Check that RTEMS_EVENT_ANY is a power of two.
+ *
+ * - Check that RTEMS_NO_WAIT is a power of two.
+ *
+ * - Validate the default option constants.
+ *
+ * - Check that RTEMS_DEFAULT_OPTIONS is equal to zero.
+ *
+ * - Check that RTEMS_EVENT_ALL is equal to zero.
+ *
+ * - Check that RTEMS_WAIT is equal to zero.
+ *
+ * - Calculate the bitwise or of all non-default option constants.
+ *
+ * - Check that the count of set bits in the calculated value is equal to the
+ * count of non-default option constants. Since each non-default option
+ * constant is a power of two, this proves that each constant has a unique
+ * value.
+ *
+ * - Check the value of RTEMS_DEFAULT_OPTIONS.
+ *
+ * - Check RTEMS_DEFAULT_OPTIONS equals RTEMS_WAIT.
+ *
+ * @{
+ */
+
+static bool IsPowerOfTwo( rtems_option option )
+{
+ return option != 0 && ( option & ( option - 1 ) ) == 0;
+}
+
+static int PopCount( rtems_option options )
+{
+ int count;
+
+ count = 0;
+
+ while ( options != 0 ) {
+ ++count;
+ options &= options - 1;
+ }
+
+ return count;
+}
+
+/**
+ * @brief Validate the non-default option constants.
+ */
+static void RtemsOptionValOptions_Action_0( void )
+{
+ /* No action */
+
+ /*
+ * Check that RTEMS_EVENT_ANY is a power of two.
+ */
+ T_step_true( 0, IsPowerOfTwo( RTEMS_EVENT_ANY ) );
+
+ /*
+ * Check that RTEMS_NO_WAIT is a power of two.
+ */
+ T_step_true( 1, IsPowerOfTwo( RTEMS_NO_WAIT ) );
+}
+
+/**
+ * @brief Validate the default option constants.
+ */
+static void RtemsOptionValOptions_Action_1( void )
+{
+ /* No action */
+
+ /*
+ * Check that RTEMS_DEFAULT_OPTIONS is equal to zero.
+ */
+ T_step_eq_u32( 2, RTEMS_DEFAULT_OPTIONS, 0 );
+
+ /*
+ * Check that RTEMS_EVENT_ALL is equal to zero.
+ */
+ T_step_eq_u32( 3, RTEMS_EVENT_ALL, 0 );
+
+ /*
+ * Check that RTEMS_WAIT is equal to zero.
+ */
+ T_step_eq_u32( 4, RTEMS_WAIT, 0 );
+}
+
+/**
+ * @brief Calculate the bitwise or of all non-default option constants.
+ */
+static void RtemsOptionValOptions_Action_2( void )
+{
+ rtems_option options;
+
+ options = 0;
+ options |= RTEMS_EVENT_ANY;
+ options |= RTEMS_NO_WAIT;
+
+ /*
+ * Check that the count of set bits in the calculated value is equal to the
+ * count of non-default option constants. Since each non-default option
+ * constant is a power of two, this proves that each constant has a unique
+ * value.
+ */
+ T_step_eq_int( 5, PopCount( options ), 2 );
+}
+
+/**
+ * @brief Check the value of RTEMS_DEFAULT_OPTIONS.
+ */
+static void RtemsOptionValOptions_Action_3( void )
+{
+ /* No action */
+
+ /*
+ * Check RTEMS_DEFAULT_OPTIONS equals RTEMS_WAIT.
+ */
+ T_step_eq_int( 6, RTEMS_DEFAULT_OPTIONS, RTEMS_WAIT );
+}
+
+/**
+ * @fn void T_case_body_RtemsOptionValOptions( void )
+ */
+T_TEST_CASE( RtemsOptionValOptions )
+{
+ T_plan( 7 );
+
+ RtemsOptionValOptions_Action_0();
+ RtemsOptionValOptions_Action_1();
+ RtemsOptionValOptions_Action_2();
+ RtemsOptionValOptions_Action_3();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-part-create.c b/testsuites/validation/tc-part-create.c
new file mode 100644
index 0000000000..3e7389d98a
--- /dev/null
+++ b/testsuites/validation/tc-part-create.c
@@ -0,0 +1,791 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsPartReqCreate
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsPartReqCreate spec:/rtems/part/req/create
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsPartReqCreate_Pre_Name_Valid,
+ RtemsPartReqCreate_Pre_Name_Invalid,
+ RtemsPartReqCreate_Pre_Name_NA
+} RtemsPartReqCreate_Pre_Name;
+
+typedef enum {
+ RtemsPartReqCreate_Pre_Id_Valid,
+ RtemsPartReqCreate_Pre_Id_Null,
+ RtemsPartReqCreate_Pre_Id_NA
+} RtemsPartReqCreate_Pre_Id;
+
+typedef enum {
+ RtemsPartReqCreate_Pre_Start_Valid,
+ RtemsPartReqCreate_Pre_Start_Null,
+ RtemsPartReqCreate_Pre_Start_BadAlign,
+ RtemsPartReqCreate_Pre_Start_NA
+} RtemsPartReqCreate_Pre_Start;
+
+typedef enum {
+ RtemsPartReqCreate_Pre_Length_Valid,
+ RtemsPartReqCreate_Pre_Length_Zero,
+ RtemsPartReqCreate_Pre_Length_Invalid,
+ RtemsPartReqCreate_Pre_Length_NA
+} RtemsPartReqCreate_Pre_Length;
+
+typedef enum {
+ RtemsPartReqCreate_Pre_Size_Valid,
+ RtemsPartReqCreate_Pre_Size_Zero,
+ RtemsPartReqCreate_Pre_Size_Skew,
+ RtemsPartReqCreate_Pre_Size_Small,
+ RtemsPartReqCreate_Pre_Size_NA
+} RtemsPartReqCreate_Pre_Size;
+
+typedef enum {
+ RtemsPartReqCreate_Pre_Free_Yes,
+ RtemsPartReqCreate_Pre_Free_No,
+ RtemsPartReqCreate_Pre_Free_NA
+} RtemsPartReqCreate_Pre_Free;
+
+typedef enum {
+ RtemsPartReqCreate_Post_Status_Ok,
+ RtemsPartReqCreate_Post_Status_InvAddr,
+ RtemsPartReqCreate_Post_Status_InvName,
+ RtemsPartReqCreate_Post_Status_InvSize,
+ RtemsPartReqCreate_Post_Status_TooMany,
+ RtemsPartReqCreate_Post_Status_NA
+} RtemsPartReqCreate_Post_Status;
+
+typedef enum {
+ RtemsPartReqCreate_Post_Name_Valid,
+ RtemsPartReqCreate_Post_Name_Invalid,
+ RtemsPartReqCreate_Post_Name_NA
+} RtemsPartReqCreate_Post_Name;
+
+typedef enum {
+ RtemsPartReqCreate_Post_IdVar_Set,
+ RtemsPartReqCreate_Post_IdVar_Nop,
+ RtemsPartReqCreate_Post_IdVar_NA
+} RtemsPartReqCreate_Post_IdVar;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Name_NA : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_Start_NA : 1;
+ uint16_t Pre_Length_NA : 1;
+ uint16_t Pre_Size_NA : 1;
+ uint16_t Pre_Free_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_Name : 2;
+ uint16_t Post_IdVar : 2;
+} RtemsPartReqCreate_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/part/req/create test case.
+ */
+typedef struct {
+ void *seized_objects;
+
+ rtems_status_code status;
+
+ rtems_name name;
+
+ void *starting_address;
+
+ uintptr_t length;
+
+ size_t buffer_size;
+
+ rtems_attribute attribute_set;
+
+ rtems_id *id;
+
+ rtems_id id_value;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 6 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsPartReqCreate_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsPartReqCreate_Context;
+
+static RtemsPartReqCreate_Context
+ RtemsPartReqCreate_Instance;
+
+static const char * const RtemsPartReqCreate_PreDesc_Name[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsPartReqCreate_PreDesc_Id[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsPartReqCreate_PreDesc_Start[] = {
+ "Valid",
+ "Null",
+ "BadAlign",
+ "NA"
+};
+
+static const char * const RtemsPartReqCreate_PreDesc_Length[] = {
+ "Valid",
+ "Zero",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsPartReqCreate_PreDesc_Size[] = {
+ "Valid",
+ "Zero",
+ "Skew",
+ "Small",
+ "NA"
+};
+
+static const char * const RtemsPartReqCreate_PreDesc_Free[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsPartReqCreate_PreDesc[] = {
+ RtemsPartReqCreate_PreDesc_Name,
+ RtemsPartReqCreate_PreDesc_Id,
+ RtemsPartReqCreate_PreDesc_Start,
+ RtemsPartReqCreate_PreDesc_Length,
+ RtemsPartReqCreate_PreDesc_Size,
+ RtemsPartReqCreate_PreDesc_Free,
+ NULL
+};
+
+#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+#define MAX_PARTITIONS ( TEST_MAXIMUM_PARTITIONS + 1 )
+
+#define BUFFER_COUNT 2
+
+#define BUFFER_SIZE ( 2 * sizeof( void * ) )
+
+static RTEMS_ALIGNED( RTEMS_PARTITION_ALIGNMENT ) uint8_t
+ buffers_to_seize[ MAX_PARTITIONS ][ BUFFER_COUNT ][ BUFFER_SIZE ];
+
+static RTEMS_ALIGNED( RTEMS_PARTITION_ALIGNMENT ) uint8_t
+ buffers[ BUFFER_COUNT ][ BUFFER_SIZE ];
+
+static rtems_status_code Create( void *arg, uint32_t *id )
+{
+ size_t *i;
+ size_t j;
+
+ i = arg;
+ j = *i;
+ T_quiet_lt_sz( j, MAX_PARTITIONS );
+
+ *i = j + 1;
+
+ return rtems_partition_create(
+ rtems_build_name( 'S', 'I', 'Z', 'E' ),
+ buffers_to_seize[ j ],
+ sizeof( buffers_to_seize[ j ] ),
+ sizeof( buffers_to_seize[ j ][ 0 ] ),
+ RTEMS_DEFAULT_ATTRIBUTES,
+ id
+ );
+}
+
+static void RtemsPartReqCreate_Pre_Name_Prepare(
+ RtemsPartReqCreate_Context *ctx,
+ RtemsPartReqCreate_Pre_Name state
+)
+{
+ switch ( state ) {
+ case RtemsPartReqCreate_Pre_Name_Valid: {
+ /*
+ * While the ``name`` parameter is valid.
+ */
+ ctx->name = NAME;
+ break;
+ }
+
+ case RtemsPartReqCreate_Pre_Name_Invalid: {
+ /*
+ * While the ``name`` parameter is invalid.
+ */
+ ctx->name = 0;
+ break;
+ }
+
+ case RtemsPartReqCreate_Pre_Name_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqCreate_Pre_Id_Prepare(
+ RtemsPartReqCreate_Context *ctx,
+ RtemsPartReqCreate_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsPartReqCreate_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter references an object of type rtems_id.
+ */
+ ctx->id = &ctx->id_value;
+ break;
+ }
+
+ case RtemsPartReqCreate_Pre_Id_Null: {
+ /*
+ * While the ``id`` parameter is NULL.
+ */
+ ctx->id = NULL;
+ break;
+ }
+
+ case RtemsPartReqCreate_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqCreate_Pre_Start_Prepare(
+ RtemsPartReqCreate_Context *ctx,
+ RtemsPartReqCreate_Pre_Start state
+)
+{
+ switch ( state ) {
+ case RtemsPartReqCreate_Pre_Start_Valid: {
+ /*
+ * While the ``starting_address`` parameter is valid.
+ */
+ ctx->starting_address = buffers;
+ break;
+ }
+
+ case RtemsPartReqCreate_Pre_Start_Null: {
+ /*
+ * While the ``starting_address`` parameter is NULL.
+ */
+ ctx->starting_address = NULL;
+ break;
+ }
+
+ case RtemsPartReqCreate_Pre_Start_BadAlign: {
+ /*
+ * While the ``starting_address`` parameter is misaligned.
+ */
+ ctx->starting_address = &buffers[ 0 ][ 1 ];
+ break;
+ }
+
+ case RtemsPartReqCreate_Pre_Start_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqCreate_Pre_Length_Prepare(
+ RtemsPartReqCreate_Context *ctx,
+ RtemsPartReqCreate_Pre_Length state
+)
+{
+ switch ( state ) {
+ case RtemsPartReqCreate_Pre_Length_Valid: {
+ /*
+ * While the ``length`` parameter is valid.
+ */
+ ctx->length = sizeof( buffers );
+ break;
+ }
+
+ case RtemsPartReqCreate_Pre_Length_Zero: {
+ /*
+ * While the ``length`` parameter is zero.
+ */
+ ctx->length = 0;
+ break;
+ }
+
+ case RtemsPartReqCreate_Pre_Length_Invalid: {
+ /*
+ * While the ``length`` parameter is less than the buffer size.
+ */
+ ctx->length = sizeof( buffers[ 0 ] ) - 1;
+ break;
+ }
+
+ case RtemsPartReqCreate_Pre_Length_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqCreate_Pre_Size_Prepare(
+ RtemsPartReqCreate_Context *ctx,
+ RtemsPartReqCreate_Pre_Size state
+)
+{
+ switch ( state ) {
+ case RtemsPartReqCreate_Pre_Size_Valid: {
+ /*
+ * While the ``buffer_size`` parameter is valid.
+ */
+ ctx->buffer_size = sizeof( buffers[ 0 ] );
+ break;
+ }
+
+ case RtemsPartReqCreate_Pre_Size_Zero: {
+ /*
+ * While the ``buffer_size`` parameter is zero.
+ */
+ ctx->buffer_size = 0;
+ break;
+ }
+
+ case RtemsPartReqCreate_Pre_Size_Skew: {
+ /*
+ * The ``buffer_size`` parameter shall not an integral multiple of the
+ * pointer size.
+ */
+ ctx->buffer_size = 1;
+ break;
+ }
+
+ case RtemsPartReqCreate_Pre_Size_Small: {
+ /*
+ * The ``buffer_size`` parameter shall greater than zero and an integral
+ * multiple of the pointer size and less than the size of two pointers.
+ */
+ ctx->buffer_size = sizeof( uintptr_t );
+ break;
+ }
+
+ case RtemsPartReqCreate_Pre_Size_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqCreate_Pre_Free_Prepare(
+ RtemsPartReqCreate_Context *ctx,
+ RtemsPartReqCreate_Pre_Free state
+)
+{
+ size_t i;
+
+ switch ( state ) {
+ case RtemsPartReqCreate_Pre_Free_Yes: {
+ /*
+ * While the system has at least one inactive partition object available.
+ */
+ /* Nothing to do */
+ break;
+ }
+
+ case RtemsPartReqCreate_Pre_Free_No: {
+ /*
+ * While the system has no inactive partition object available.
+ */
+ i = 0;
+ ctx->seized_objects = T_seize_objects( Create, &i );
+ break;
+ }
+
+ case RtemsPartReqCreate_Pre_Free_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqCreate_Post_Status_Check(
+ RtemsPartReqCreate_Context *ctx,
+ RtemsPartReqCreate_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsPartReqCreate_Post_Status_Ok: {
+ /*
+ * The return status of rtems_partition_create() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsPartReqCreate_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_partition_create() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsPartReqCreate_Post_Status_InvName: {
+ /*
+ * The return status of rtems_partition_create() shall be
+ * RTEMS_INVALID_NAME.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsPartReqCreate_Post_Status_InvSize: {
+ /*
+ * The return status of rtems_partition_create() shall be
+ * RTEMS_INVALID_SIZE.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_SIZE );
+ break;
+ }
+
+ case RtemsPartReqCreate_Post_Status_TooMany: {
+ /*
+ * The return status of rtems_partition_create() shall be RTEMS_TOO_MANY.
+ */
+ T_rsc( ctx->status, RTEMS_TOO_MANY );
+ break;
+ }
+
+ case RtemsPartReqCreate_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqCreate_Post_Name_Check(
+ RtemsPartReqCreate_Context *ctx,
+ RtemsPartReqCreate_Post_Name state
+)
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ switch ( state ) {
+ case RtemsPartReqCreate_Post_Name_Valid: {
+ /*
+ * The unique object name shall identify the partition created by the
+ * rtems_partition_create() call.
+ */
+ id = 0;
+ sc = rtems_partition_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc_success( sc );
+ T_eq_u32( id, ctx->id_value );
+ break;
+ }
+
+ case RtemsPartReqCreate_Post_Name_Invalid: {
+ /*
+ * The unique object name shall not identify a partition.
+ */
+ sc = rtems_partition_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc( sc, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsPartReqCreate_Post_Name_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqCreate_Post_IdVar_Check(
+ RtemsPartReqCreate_Context *ctx,
+ RtemsPartReqCreate_Post_IdVar state
+)
+{
+ rtems_status_code sc;
+ size_t i;
+ void *buffers[ BUFFER_COUNT ];
+ void *no_buffer;
+
+ switch ( state ) {
+ case RtemsPartReqCreate_Post_IdVar_Set: {
+ /*
+ * The value of the object referenced by the ``id`` parameter shall be
+ * set to the object identifier of the created partition after the return
+ * of the rtems_partition_create() call.
+ */
+ T_eq_ptr( ctx->id, &ctx->id_value );
+ T_ne_u32( ctx->id_value, INVALID_ID );
+
+ for ( i = 0; i < BUFFER_COUNT; ++i) {
+ sc = rtems_partition_get_buffer( ctx->id_value, &buffers[ i ] );
+ T_rsc_success( sc );
+ T_not_null( buffers[ i ] );
+ }
+
+ no_buffer = (void *) (uintptr_t) 1;
+ sc = rtems_partition_get_buffer( ctx->id_value, &no_buffer );
+ T_rsc( sc, RTEMS_UNSATISFIED );
+ T_eq_ptr( no_buffer, (void *) (uintptr_t) 1 );
+
+ for ( i = 0; i < BUFFER_COUNT; ++i) {
+ sc = rtems_partition_return_buffer( ctx->id_value, buffers[ i ] );
+ T_rsc_success( sc );
+ }
+
+ sc = rtems_partition_delete( ctx->id_value );
+ T_rsc_success( sc );
+ break;
+ }
+
+ case RtemsPartReqCreate_Post_IdVar_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past calls to
+ * rtems_partition_create() shall not be accessed by the
+ * rtems_partition_create() call.
+ */
+ T_eq_u32( ctx->id_value, INVALID_ID );
+ break;
+ }
+
+ case RtemsPartReqCreate_Post_IdVar_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqCreate_Prepare( RtemsPartReqCreate_Context *ctx )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ ctx->id_value = INVALID_ID;
+ ctx->attribute_set = RTEMS_DEFAULT_ATTRIBUTES;
+
+ id = INVALID_ID;
+ sc = rtems_partition_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc( sc, RTEMS_INVALID_NAME );
+ T_eq_u32( id, INVALID_ID );
+}
+
+static void RtemsPartReqCreate_Action( RtemsPartReqCreate_Context *ctx )
+{
+ ctx->status = rtems_partition_create(
+ ctx->name,
+ ctx->starting_address,
+ ctx->length,
+ ctx->buffer_size,
+ ctx->attribute_set,
+ ctx->id
+ );
+}
+
+static void RtemsPartReqCreate_Cleanup( RtemsPartReqCreate_Context *ctx )
+{
+ T_surrender_objects( &ctx->seized_objects, rtems_partition_delete );
+}
+
+static const RtemsPartReqCreate_Entry
+RtemsPartReqCreate_Entries[] = {
+ { 0, 0, 0, 0, 0, 0, 0, RtemsPartReqCreate_Post_Status_InvName,
+ RtemsPartReqCreate_Post_Name_Invalid, RtemsPartReqCreate_Post_IdVar_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsPartReqCreate_Post_Status_InvAddr,
+ RtemsPartReqCreate_Post_Name_Invalid, RtemsPartReqCreate_Post_IdVar_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsPartReqCreate_Post_Status_InvSize,
+ RtemsPartReqCreate_Post_Name_Invalid, RtemsPartReqCreate_Post_IdVar_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsPartReqCreate_Post_Status_Ok,
+ RtemsPartReqCreate_Post_Name_Valid, RtemsPartReqCreate_Post_IdVar_Set },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsPartReqCreate_Post_Status_TooMany,
+ RtemsPartReqCreate_Post_Name_Invalid, RtemsPartReqCreate_Post_IdVar_Nop }
+};
+
+static const uint8_t
+RtemsPartReqCreate_Map[] = {
+ 3, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0
+};
+
+static size_t RtemsPartReqCreate_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsPartReqCreate_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsPartReqCreate_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsPartReqCreate_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsPartReqCreate_Scope,
+ .initial_context = &RtemsPartReqCreate_Instance
+};
+
+static inline RtemsPartReqCreate_Entry RtemsPartReqCreate_PopEntry(
+ RtemsPartReqCreate_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsPartReqCreate_Entries[
+ RtemsPartReqCreate_Map[ index ]
+ ];
+}
+
+static void RtemsPartReqCreate_TestVariant( RtemsPartReqCreate_Context *ctx )
+{
+ RtemsPartReqCreate_Pre_Name_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsPartReqCreate_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsPartReqCreate_Pre_Start_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsPartReqCreate_Pre_Length_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsPartReqCreate_Pre_Size_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsPartReqCreate_Pre_Free_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsPartReqCreate_Action( ctx );
+ RtemsPartReqCreate_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsPartReqCreate_Post_Name_Check( ctx, ctx->Map.entry.Post_Name );
+ RtemsPartReqCreate_Post_IdVar_Check( ctx, ctx->Map.entry.Post_IdVar );
+}
+
+/**
+ * @fn void T_case_body_RtemsPartReqCreate( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsPartReqCreate, &RtemsPartReqCreate_Fixture )
+{
+ RtemsPartReqCreate_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsPartReqCreate_Pre_Name_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsPartReqCreate_Pre_Name_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsPartReqCreate_Pre_Id_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsPartReqCreate_Pre_Id_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsPartReqCreate_Pre_Start_Valid;
+ ctx->Map.pcs[ 2 ] < RtemsPartReqCreate_Pre_Start_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsPartReqCreate_Pre_Length_Valid;
+ ctx->Map.pcs[ 3 ] < RtemsPartReqCreate_Pre_Length_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = RtemsPartReqCreate_Pre_Size_Valid;
+ ctx->Map.pcs[ 4 ] < RtemsPartReqCreate_Pre_Size_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 5 ] = RtemsPartReqCreate_Pre_Free_Yes;
+ ctx->Map.pcs[ 5 ] < RtemsPartReqCreate_Pre_Free_NA;
+ ++ctx->Map.pcs[ 5 ]
+ ) {
+ ctx->Map.entry = RtemsPartReqCreate_PopEntry( ctx );
+ RtemsPartReqCreate_Prepare( ctx );
+ RtemsPartReqCreate_TestVariant( ctx );
+ RtemsPartReqCreate_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-part-delete.c b/testsuites/validation/tc-part-delete.c
new file mode 100644
index 0000000000..227382961f
--- /dev/null
+++ b/testsuites/validation/tc-part-delete.c
@@ -0,0 +1,396 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsPartReqDelete
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsPartReqDelete spec:/rtems/part/req/delete
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsPartReqDelete_Pre_Id_NoObj,
+ RtemsPartReqDelete_Pre_Id_Part,
+ RtemsPartReqDelete_Pre_Id_NA
+} RtemsPartReqDelete_Pre_Id;
+
+typedef enum {
+ RtemsPartReqDelete_Pre_InUse_Yes,
+ RtemsPartReqDelete_Pre_InUse_No,
+ RtemsPartReqDelete_Pre_InUse_NA
+} RtemsPartReqDelete_Pre_InUse;
+
+typedef enum {
+ RtemsPartReqDelete_Post_Status_Ok,
+ RtemsPartReqDelete_Post_Status_InvId,
+ RtemsPartReqDelete_Post_Status_InUse,
+ RtemsPartReqDelete_Post_Status_NA
+} RtemsPartReqDelete_Post_Status;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Pre_InUse_NA : 1;
+ uint8_t Post_Status : 2;
+} RtemsPartReqDelete_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/part/req/delete test case.
+ */
+typedef struct {
+ rtems_status_code status;
+
+ rtems_id id;
+
+ rtems_id id_value;
+
+ void *buffer;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsPartReqDelete_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsPartReqDelete_Context;
+
+static RtemsPartReqDelete_Context
+ RtemsPartReqDelete_Instance;
+
+static const char * const RtemsPartReqDelete_PreDesc_Id[] = {
+ "NoObj",
+ "Part",
+ "NA"
+};
+
+static const char * const RtemsPartReqDelete_PreDesc_InUse[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsPartReqDelete_PreDesc[] = {
+ RtemsPartReqDelete_PreDesc_Id,
+ RtemsPartReqDelete_PreDesc_InUse,
+ NULL
+};
+
+#define PART_NAME rtems_build_name( 'N', 'A', 'M', 'E' )
+
+#define BUFFER_COUNT 1
+
+#define BUFFER_SIZE ( 2 * sizeof( void * ) )
+
+static RTEMS_ALIGNED( RTEMS_PARTITION_ALIGNMENT ) uint8_t
+ buffers[ BUFFER_COUNT ][ BUFFER_SIZE ];
+
+static void RtemsPartReqDelete_Pre_Id_Prepare(
+ RtemsPartReqDelete_Context *ctx,
+ RtemsPartReqDelete_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsPartReqDelete_Pre_Id_NoObj: {
+ /*
+ * While the ``id`` parameter is not associated with a partition.
+ */
+ ctx->id = 0xffffffff;
+ break;
+ }
+
+ case RtemsPartReqDelete_Pre_Id_Part: {
+ /*
+ * While the ``id`` parameter is associated with a partition.
+ */
+ ctx->id = ctx->id_value;
+ break;
+ }
+
+ case RtemsPartReqDelete_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqDelete_Pre_InUse_Prepare(
+ RtemsPartReqDelete_Context *ctx,
+ RtemsPartReqDelete_Pre_InUse state
+)
+{
+ rtems_status_code sc;
+
+ switch ( state ) {
+ case RtemsPartReqDelete_Pre_InUse_Yes: {
+ /*
+ * While the partition has at least one buffer in use.
+ */
+ ctx->buffer = NULL;
+ sc = rtems_partition_get_buffer( ctx->id_value, &ctx->buffer );
+ T_rsc_success( sc );
+ T_not_null( ctx->buffer );
+ break;
+ }
+
+ case RtemsPartReqDelete_Pre_InUse_No: {
+ /*
+ * While the partition does not have a buffer in use.
+ */
+ ctx->buffer = NULL;
+ break;
+ }
+
+ case RtemsPartReqDelete_Pre_InUse_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqDelete_Post_Status_Check(
+ RtemsPartReqDelete_Context *ctx,
+ RtemsPartReqDelete_Post_Status state
+)
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ switch ( state ) {
+ case RtemsPartReqDelete_Post_Status_Ok: {
+ /*
+ * The status shall be RTEMS_SUCCESSFUL. The deleted partition object
+ * shall be inactive.
+ */
+ T_rsc_success( ctx->status );
+ ctx->id_value = 0xffffffff;
+
+ id = 0xffffffff;
+ sc = rtems_partition_ident( PART_NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc( sc, RTEMS_INVALID_NAME );
+ T_eq_u32( id, 0xffffffff );
+ break;
+ }
+
+ case RtemsPartReqDelete_Post_Status_InvId: {
+ /*
+ * The status shall be RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+
+ id = 0xffffffff;
+ sc = rtems_partition_ident( PART_NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc_success( sc);
+ T_eq_u32( id, ctx->id_value );
+ break;
+ }
+
+ case RtemsPartReqDelete_Post_Status_InUse: {
+ /*
+ * The status shall be RTEMS_RESOURCE_IN_USE.
+ */
+ T_rsc( ctx->status, RTEMS_RESOURCE_IN_USE );
+
+ id = 0xffffffff;
+ sc = rtems_partition_ident( PART_NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc_success( sc);
+ T_eq_u32( id, ctx->id_value );
+ break;
+ }
+
+ case RtemsPartReqDelete_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqDelete_Prepare( RtemsPartReqDelete_Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_partition_create(
+ PART_NAME,
+ buffers,
+ sizeof( buffers ),
+ sizeof( buffers[ 0 ] ),
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &ctx->id_value
+ );
+ T_rsc_success( sc );
+}
+
+static void RtemsPartReqDelete_Action( RtemsPartReqDelete_Context *ctx )
+{
+ ctx->status = rtems_partition_delete( ctx->id );
+}
+
+static void RtemsPartReqDelete_Cleanup( RtemsPartReqDelete_Context *ctx )
+{
+ rtems_status_code sc;
+
+ if ( ctx->buffer != NULL ) {
+ sc = rtems_partition_return_buffer( ctx->id_value, ctx->buffer );
+ T_rsc_success( sc );
+ }
+
+ if ( ctx->id_value != 0xffffffff ) {
+ sc = rtems_partition_delete( ctx->id_value );
+ T_rsc_success( sc );
+ }
+}
+
+static const RtemsPartReqDelete_Entry
+RtemsPartReqDelete_Entries[] = {
+ { 0, 0, 0, RtemsPartReqDelete_Post_Status_InvId },
+ { 0, 0, 0, RtemsPartReqDelete_Post_Status_InUse },
+ { 0, 0, 0, RtemsPartReqDelete_Post_Status_Ok }
+};
+
+static const uint8_t
+RtemsPartReqDelete_Map[] = {
+ 0, 0, 1, 2
+};
+
+static size_t RtemsPartReqDelete_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsPartReqDelete_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsPartReqDelete_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsPartReqDelete_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsPartReqDelete_Scope,
+ .initial_context = &RtemsPartReqDelete_Instance
+};
+
+static inline RtemsPartReqDelete_Entry RtemsPartReqDelete_PopEntry(
+ RtemsPartReqDelete_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsPartReqDelete_Entries[
+ RtemsPartReqDelete_Map[ index ]
+ ];
+}
+
+static void RtemsPartReqDelete_TestVariant( RtemsPartReqDelete_Context *ctx )
+{
+ RtemsPartReqDelete_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsPartReqDelete_Pre_InUse_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsPartReqDelete_Action( ctx );
+ RtemsPartReqDelete_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+}
+
+/**
+ * @fn void T_case_body_RtemsPartReqDelete( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsPartReqDelete, &RtemsPartReqDelete_Fixture )
+{
+ RtemsPartReqDelete_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsPartReqDelete_Pre_Id_NoObj;
+ ctx->Map.pcs[ 0 ] < RtemsPartReqDelete_Pre_Id_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsPartReqDelete_Pre_InUse_Yes;
+ ctx->Map.pcs[ 1 ] < RtemsPartReqDelete_Pre_InUse_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ ctx->Map.entry = RtemsPartReqDelete_PopEntry( ctx );
+ RtemsPartReqDelete_Prepare( ctx );
+ RtemsPartReqDelete_TestVariant( ctx );
+ RtemsPartReqDelete_Cleanup( ctx );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-part-get.c b/testsuites/validation/tc-part-get.c
new file mode 100644
index 0000000000..3b8d2cc59b
--- /dev/null
+++ b/testsuites/validation/tc-part-get.c
@@ -0,0 +1,526 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsPartReqGetBuffer
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsPartReqGetBuffer spec:/rtems/part/req/get-buffer
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsPartReqGetBuffer_Pre_Id_NoObj,
+ RtemsPartReqGetBuffer_Pre_Id_Part,
+ RtemsPartReqGetBuffer_Pre_Id_NA
+} RtemsPartReqGetBuffer_Pre_Id;
+
+typedef enum {
+ RtemsPartReqGetBuffer_Pre_Buf_Valid,
+ RtemsPartReqGetBuffer_Pre_Buf_Null,
+ RtemsPartReqGetBuffer_Pre_Buf_NA
+} RtemsPartReqGetBuffer_Pre_Buf;
+
+typedef enum {
+ RtemsPartReqGetBuffer_Pre_Avail_Yes,
+ RtemsPartReqGetBuffer_Pre_Avail_No,
+ RtemsPartReqGetBuffer_Pre_Avail_NA
+} RtemsPartReqGetBuffer_Pre_Avail;
+
+typedef enum {
+ RtemsPartReqGetBuffer_Post_Status_Ok,
+ RtemsPartReqGetBuffer_Post_Status_InvId,
+ RtemsPartReqGetBuffer_Post_Status_InvAddr,
+ RtemsPartReqGetBuffer_Post_Status_Unsat,
+ RtemsPartReqGetBuffer_Post_Status_NA
+} RtemsPartReqGetBuffer_Post_Status;
+
+typedef enum {
+ RtemsPartReqGetBuffer_Post_BufVar_Set,
+ RtemsPartReqGetBuffer_Post_BufVar_Nop,
+ RtemsPartReqGetBuffer_Post_BufVar_NA
+} RtemsPartReqGetBuffer_Post_BufVar;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_Buf_NA : 1;
+ uint16_t Pre_Avail_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_BufVar : 2;
+} RtemsPartReqGetBuffer_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/part/req/get-buffer test case.
+ */
+typedef struct {
+ rtems_status_code status;
+
+ rtems_id id;
+
+ rtems_id id_value;
+
+ void **buffer;
+
+ void *buffer_pointer;
+
+ void *stolen_buffer;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsPartReqGetBuffer_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsPartReqGetBuffer_Context;
+
+static RtemsPartReqGetBuffer_Context
+ RtemsPartReqGetBuffer_Instance;
+
+static const char * const RtemsPartReqGetBuffer_PreDesc_Id[] = {
+ "NoObj",
+ "Part",
+ "NA"
+};
+
+static const char * const RtemsPartReqGetBuffer_PreDesc_Buf[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsPartReqGetBuffer_PreDesc_Avail[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsPartReqGetBuffer_PreDesc[] = {
+ RtemsPartReqGetBuffer_PreDesc_Id,
+ RtemsPartReqGetBuffer_PreDesc_Buf,
+ RtemsPartReqGetBuffer_PreDesc_Avail,
+ NULL
+};
+
+#define BUFFER_COUNT 1
+
+#define BUFFER_SIZE ( 2 * sizeof( void * ) )
+
+static RTEMS_ALIGNED( RTEMS_PARTITION_ALIGNMENT ) uint8_t
+ buffers[ BUFFER_COUNT ][ BUFFER_SIZE ];
+
+static void RtemsPartReqGetBuffer_Pre_Id_Prepare(
+ RtemsPartReqGetBuffer_Context *ctx,
+ RtemsPartReqGetBuffer_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsPartReqGetBuffer_Pre_Id_NoObj: {
+ /*
+ * While the ``id`` parameter is not associated with a partition.
+ */
+ ctx->id = 0xffffffff;
+ break;
+ }
+
+ case RtemsPartReqGetBuffer_Pre_Id_Part: {
+ /*
+ * While the ``id`` parameter is associated with a partition.
+ */
+ ctx->id = ctx->id_value;
+ break;
+ }
+
+ case RtemsPartReqGetBuffer_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqGetBuffer_Pre_Buf_Prepare(
+ RtemsPartReqGetBuffer_Context *ctx,
+ RtemsPartReqGetBuffer_Pre_Buf state
+)
+{
+ switch ( state ) {
+ case RtemsPartReqGetBuffer_Pre_Buf_Valid: {
+ /*
+ * While the ``buffer`` parameter references an object of type ``void
+ * *``.
+ */
+ ctx->buffer = &ctx->buffer_pointer;
+ break;
+ }
+
+ case RtemsPartReqGetBuffer_Pre_Buf_Null: {
+ /*
+ * While the ``buffer`` parameter is NULL.
+ */
+ ctx->buffer = NULL;
+ break;
+ }
+
+ case RtemsPartReqGetBuffer_Pre_Buf_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqGetBuffer_Pre_Avail_Prepare(
+ RtemsPartReqGetBuffer_Context *ctx,
+ RtemsPartReqGetBuffer_Pre_Avail state
+)
+{
+ rtems_status_code sc;
+
+ switch ( state ) {
+ case RtemsPartReqGetBuffer_Pre_Avail_Yes: {
+ /*
+ * While the partition has at least one free buffer available.
+ */
+ /* Nothing to do */
+ break;
+ }
+
+ case RtemsPartReqGetBuffer_Pre_Avail_No: {
+ /*
+ * While the partition does not have a buffer available.
+ */
+ sc = rtems_partition_get_buffer( ctx->id_value, &ctx->stolen_buffer );
+ T_rsc_success( sc );
+ break;
+ }
+
+ case RtemsPartReqGetBuffer_Pre_Avail_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqGetBuffer_Post_Status_Check(
+ RtemsPartReqGetBuffer_Context *ctx,
+ RtemsPartReqGetBuffer_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsPartReqGetBuffer_Post_Status_Ok: {
+ /*
+ * The return status of rtems_partition_get_buffer() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ T_eq_ptr( ctx->buffer_pointer, buffers );
+ break;
+ }
+
+ case RtemsPartReqGetBuffer_Post_Status_InvId: {
+ /*
+ * The return status of rtems_partition_get_buffer() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ T_eq_ptr( ctx->buffer_pointer, (void *) (uintptr_t) 1 );
+ break;
+ }
+
+ case RtemsPartReqGetBuffer_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_partition_get_buffer() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsPartReqGetBuffer_Post_Status_Unsat: {
+ /*
+ * The return status of rtems_partition_get_buffer() shall be
+ * RTEMS_UNSATISFIED.
+ */
+ T_rsc( ctx->status, RTEMS_UNSATISFIED );
+ T_eq_ptr( ctx->buffer_pointer, (void *) (uintptr_t) 1 );
+ break;
+ }
+
+ case RtemsPartReqGetBuffer_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqGetBuffer_Post_BufVar_Check(
+ RtemsPartReqGetBuffer_Context *ctx,
+ RtemsPartReqGetBuffer_Post_BufVar state
+)
+{
+ switch ( state ) {
+ case RtemsPartReqGetBuffer_Post_BufVar_Set: {
+ /*
+ * The value of the object referenced by the ``starting_address``
+ * parameter shall be set to the object identifier of the begin address
+ * of the returned buffer after the return of the
+ * rtems_partition_create() call.
+ */
+ T_eq_ptr( ctx->buffer, &ctx->buffer_pointer );
+ T_eq_ptr( ctx->buffer_pointer, buffers );
+ break;
+ }
+
+ case RtemsPartReqGetBuffer_Post_BufVar_Nop: {
+ /*
+ * Objects referenced by the ``buffer`` parameter in past calls to
+ * rtems_partition_get_buffer() shall not be accessed by the
+ * rtems_partition_get_buffer() call.
+ */
+ T_eq_ptr( ctx->buffer_pointer, (void *) (uintptr_t) 1 );
+ break;
+ }
+
+ case RtemsPartReqGetBuffer_Post_BufVar_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqGetBuffer_Setup( RtemsPartReqGetBuffer_Context *ctx )
+{
+ rtems_status_code sc;
+
+ ctx->id_value = 0;
+ sc = rtems_partition_create(
+ rtems_build_name( 'N', 'A', 'M', 'E' ),
+ buffers,
+ sizeof( buffers ),
+ sizeof( buffers[ 0 ] ),
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &ctx->id_value
+ );
+ T_assert_rsc_success( sc );
+}
+
+static void RtemsPartReqGetBuffer_Setup_Wrap( void *arg )
+{
+ RtemsPartReqGetBuffer_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsPartReqGetBuffer_Setup( ctx );
+}
+
+static void RtemsPartReqGetBuffer_Teardown(
+ RtemsPartReqGetBuffer_Context *ctx
+)
+{
+ if ( ctx->id_value != 0 ) {
+ rtems_status_code sc;
+
+ sc = rtems_partition_delete( ctx->id_value );
+ T_rsc_success( sc );
+ }
+}
+
+static void RtemsPartReqGetBuffer_Teardown_Wrap( void *arg )
+{
+ RtemsPartReqGetBuffer_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsPartReqGetBuffer_Teardown( ctx );
+}
+
+static void RtemsPartReqGetBuffer_Prepare( RtemsPartReqGetBuffer_Context *ctx )
+{
+ ctx->buffer_pointer = (void *) (uintptr_t) 1;
+ ctx->stolen_buffer = NULL;
+}
+
+static void RtemsPartReqGetBuffer_Action( RtemsPartReqGetBuffer_Context *ctx )
+{
+ ctx->status = rtems_partition_get_buffer( ctx->id, ctx->buffer );
+}
+
+static void RtemsPartReqGetBuffer_Cleanup( RtemsPartReqGetBuffer_Context *ctx )
+{
+ rtems_status_code sc;
+
+ if ( (uintptr_t) ctx->buffer_pointer != 1 ) {
+ sc = rtems_partition_return_buffer( ctx->id_value, ctx->buffer_pointer );
+ T_rsc_success( sc );
+ }
+
+ if ( ctx->stolen_buffer != NULL ) {
+ sc = rtems_partition_return_buffer( ctx->id_value, ctx->stolen_buffer );
+ T_rsc_success( sc );
+ }
+}
+
+static const RtemsPartReqGetBuffer_Entry
+RtemsPartReqGetBuffer_Entries[] = {
+ { 0, 0, 0, 0, RtemsPartReqGetBuffer_Post_Status_InvAddr,
+ RtemsPartReqGetBuffer_Post_BufVar_Nop },
+ { 0, 0, 0, 0, RtemsPartReqGetBuffer_Post_Status_InvId,
+ RtemsPartReqGetBuffer_Post_BufVar_Nop },
+ { 0, 0, 0, 0, RtemsPartReqGetBuffer_Post_Status_Ok,
+ RtemsPartReqGetBuffer_Post_BufVar_Set },
+ { 0, 0, 0, 0, RtemsPartReqGetBuffer_Post_Status_Unsat,
+ RtemsPartReqGetBuffer_Post_BufVar_Nop }
+};
+
+static const uint8_t
+RtemsPartReqGetBuffer_Map[] = {
+ 1, 1, 0, 0, 2, 3, 0, 0
+};
+
+static size_t RtemsPartReqGetBuffer_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsPartReqGetBuffer_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsPartReqGetBuffer_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsPartReqGetBuffer_Fixture = {
+ .setup = RtemsPartReqGetBuffer_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsPartReqGetBuffer_Teardown_Wrap,
+ .scope = RtemsPartReqGetBuffer_Scope,
+ .initial_context = &RtemsPartReqGetBuffer_Instance
+};
+
+static inline RtemsPartReqGetBuffer_Entry RtemsPartReqGetBuffer_PopEntry(
+ RtemsPartReqGetBuffer_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsPartReqGetBuffer_Entries[
+ RtemsPartReqGetBuffer_Map[ index ]
+ ];
+}
+
+static void RtemsPartReqGetBuffer_TestVariant(
+ RtemsPartReqGetBuffer_Context *ctx
+)
+{
+ RtemsPartReqGetBuffer_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsPartReqGetBuffer_Pre_Buf_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsPartReqGetBuffer_Pre_Avail_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsPartReqGetBuffer_Action( ctx );
+ RtemsPartReqGetBuffer_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsPartReqGetBuffer_Post_BufVar_Check( ctx, ctx->Map.entry.Post_BufVar );
+}
+
+/**
+ * @fn void T_case_body_RtemsPartReqGetBuffer( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsPartReqGetBuffer, &RtemsPartReqGetBuffer_Fixture )
+{
+ RtemsPartReqGetBuffer_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsPartReqGetBuffer_Pre_Id_NoObj;
+ ctx->Map.pcs[ 0 ] < RtemsPartReqGetBuffer_Pre_Id_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsPartReqGetBuffer_Pre_Buf_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsPartReqGetBuffer_Pre_Buf_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsPartReqGetBuffer_Pre_Avail_Yes;
+ ctx->Map.pcs[ 2 ] < RtemsPartReqGetBuffer_Pre_Avail_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ ctx->Map.entry = RtemsPartReqGetBuffer_PopEntry( ctx );
+ RtemsPartReqGetBuffer_Prepare( ctx );
+ RtemsPartReqGetBuffer_TestVariant( ctx );
+ RtemsPartReqGetBuffer_Cleanup( ctx );
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-part-ident.c b/testsuites/validation/tc-part-ident.c
new file mode 100644
index 0000000000..40f66d436e
--- /dev/null
+++ b/testsuites/validation/tc-part-ident.c
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsPartValIdent
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-object-ident.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsPartValIdent spec:/rtems/part/val/ident
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Test the rtems_partition_ident() directive.
+ *
+ * This test case performs the following actions:
+ *
+ * - Run the generic object identification tests for Classic API partition
+ * class objects defined by spec:/rtems/req/ident.
+ *
+ * @{
+ */
+
+#define NAME_LOCAL_OBJECT rtems_build_name( 'P', 'A', 'R', 'T' )
+
+static rtems_status_code ClassicPartIdentAction(
+ rtems_name name,
+ uint32_t node,
+ rtems_id *id
+)
+{
+ return rtems_partition_ident( name, node, id );
+}
+
+/**
+ * @brief Run the generic object identification tests for Classic API partition
+ * class objects defined by spec:/rtems/req/ident.
+ */
+static void RtemsPartValIdent_Action_0( void )
+{
+ static RTEMS_ALIGNED( RTEMS_PARTITION_ALIGNMENT ) long area[32];
+ rtems_status_code sc;
+ rtems_id id_local_object;
+
+ sc = rtems_partition_create(
+ NAME_LOCAL_OBJECT,
+ area,
+ sizeof( area ),
+ sizeof( area ),
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &id_local_object
+ );
+ T_assert_rsc_success( sc );
+
+ RtemsReqIdent_Run(
+ id_local_object,
+ NAME_LOCAL_OBJECT,
+ ClassicPartIdentAction
+ );
+
+ sc = rtems_partition_delete( id_local_object );
+ T_rsc_success( sc );
+}
+
+/**
+ * @fn void T_case_body_RtemsPartValIdent( void )
+ */
+T_TEST_CASE( RtemsPartValIdent )
+{
+ RtemsPartValIdent_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-part-performance.c b/testsuites/validation/tc-part-performance.c
index 5c3148edcc..858dbc0b4b 100644
--- a/testsuites/validation/tc-part-performance.c
+++ b/testsuites/validation/tc-part-performance.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsPartValPerformance
+ * @ingroup RtemsPartValPerf
*/
/*
- * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -53,24 +53,22 @@
#endif
#include <rtems.h>
-#include <rtems/chain.h>
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsPartValPerformance \
- * spec:/rtems/part/val/performance
+ * @defgroup RtemsPartValPerf spec:/rtems/part/val/perf
*
- * @ingroup RTEMSTestSuiteTestsuitesPerformance0
+ * @ingroup TestsuitesPerformanceNoClock0
*
- * @brief This test case provides a context to run Partition Manager
+ * @brief This test case provides a context to run @ref RTEMSAPIClassicPart
* performance tests.
*
* @{
*/
/**
- * @brief Test context for spec:/rtems/part/val/performance test case.
+ * @brief Test context for spec:/rtems/part/val/perf test case.
*/
typedef struct {
/**
@@ -79,8 +77,7 @@ typedef struct {
rtems_id part_one;
/**
- * @brief This member provides a partition with exactly
- * ${.:/params/buffer-count} free buffers.
+ * @brief This member provides a partition with exactly 100 free buffers.
*/
rtems_id part_many;
@@ -108,20 +105,29 @@ typedef struct {
* @brief This member provides the measure runtime request.
*/
T_measure_runtime_request request;
-} RtemsPartValPerformance_Context;
-static RtemsPartValPerformance_Context
- RtemsPartValPerformance_Instance;
+ /**
+ * @brief This member provides an optional measurement begin time point.
+ */
+ T_ticks begin;
-static void RtemsPartValPerformance_Setup_Context(
- RtemsPartValPerformance_Context *ctx
-)
+ /**
+ * @brief This member provides an optional measurement end time point.
+ */
+ T_ticks end;
+} RtemsPartValPerf_Context;
+
+static RtemsPartValPerf_Context
+ RtemsPartValPerf_Instance;
+
+static void RtemsPartValPerf_Setup_Context( RtemsPartValPerf_Context *ctx )
{
T_measure_runtime_config config;
memset( &config, 0, sizeof( config ) );
- config.sample_count = 1000;
+ config.sample_count = 100;
ctx->request.arg = ctx;
+ ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES;
ctx->context = T_measure_runtime_create( &config );
T_assert_not_null( ctx->context );
}
@@ -129,16 +135,14 @@ static void RtemsPartValPerformance_Setup_Context(
/**
* @brief Creates the test partition.
*/
-static void RtemsPartValPerformance_Setup(
- RtemsPartValPerformance_Context *ctx
-)
+static void RtemsPartValPerf_Setup( RtemsPartValPerf_Context *ctx )
{
rtems_status_code sc;
size_t size;
void *area;
uintptr_t length;
- size = sizeof( rtems_chain_node );
+ size = 2 * sizeof( uintptr_t );
area = T_malloc( size );
sc = rtems_partition_create(
@@ -164,21 +168,19 @@ static void RtemsPartValPerformance_Setup(
T_assert_rsc_success( sc );
}
-static void RtemsPartValPerformance_Setup_Wrap( void *arg )
+static void RtemsPartValPerf_Setup_Wrap( void *arg )
{
- RtemsPartValPerformance_Context *ctx;
+ RtemsPartValPerf_Context *ctx;
ctx = arg;
- RtemsPartValPerformance_Setup_Context( ctx );
- RtemsPartValPerformance_Setup( ctx );
+ RtemsPartValPerf_Setup_Context( ctx );
+ RtemsPartValPerf_Setup( ctx );
}
/**
* @brief Deletes the test partition.
*/
-static void RtemsPartValPerformance_Teardown(
- RtemsPartValPerformance_Context *ctx
-)
+static void RtemsPartValPerf_Teardown( RtemsPartValPerf_Context *ctx )
{
rtems_status_code sc;
@@ -193,35 +195,39 @@ static void RtemsPartValPerformance_Teardown(
}
}
-static void RtemsPartValPerformance_Teardown_Wrap( void *arg )
+static void RtemsPartValPerf_Teardown_Wrap( void *arg )
{
- RtemsPartValPerformance_Context *ctx;
+ RtemsPartValPerf_Context *ctx;
ctx = arg;
- RtemsPartValPerformance_Teardown( ctx );
+ RtemsPartValPerf_Teardown( ctx );
}
-static T_fixture RtemsPartValPerformance_Fixture = {
- .setup = RtemsPartValPerformance_Setup_Wrap,
+static T_fixture RtemsPartValPerf_Fixture = {
+ .setup = RtemsPartValPerf_Setup_Wrap,
.stop = NULL,
- .teardown = RtemsPartValPerformance_Teardown_Wrap,
+ .teardown = RtemsPartValPerf_Teardown_Wrap,
.scope = NULL,
- .initial_context = &RtemsPartValPerformance_Instance
+ .initial_context = &RtemsPartValPerf_Instance
};
/**
+ * @defgroup RtemsPartReqPerfGetBuffer spec:/rtems/part/req/perf-get-buffer
+ *
+ * @{
+ */
+
+/**
* @brief Get a buffer.
*/
-static void RtemsPartReqPerfGetBuffer_Body(
- RtemsPartValPerformance_Context *ctx
-)
+static void RtemsPartReqPerfGetBuffer_Body( RtemsPartValPerf_Context *ctx )
{
ctx->status = rtems_partition_get_buffer( ctx->part_many, &ctx->buffer );
}
static void RtemsPartReqPerfGetBuffer_Body_Wrap( void *arg )
{
- RtemsPartValPerformance_Context *ctx;
+ RtemsPartValPerf_Context *ctx;
ctx = arg;
RtemsPartReqPerfGetBuffer_Body( ctx );
@@ -231,11 +237,11 @@ static void RtemsPartReqPerfGetBuffer_Body_Wrap( void *arg )
* @brief Return the buffer.
*/
static bool RtemsPartReqPerfGetBuffer_Teardown(
- RtemsPartValPerformance_Context *ctx,
- T_ticks *delta,
- uint32_t tic,
- uint32_t toc,
- unsigned int retry
+ RtemsPartValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
)
{
rtems_status_code sc;
@@ -256,17 +262,26 @@ static bool RtemsPartReqPerfGetBuffer_Teardown_Wrap(
unsigned int retry
)
{
- RtemsPartValPerformance_Context *ctx;
+ RtemsPartValPerf_Context *ctx;
ctx = arg;
return RtemsPartReqPerfGetBuffer_Teardown( ctx, delta, tic, toc, retry );
}
+/** @} */
+
+/**
+ * @defgroup RtemsPartReqPerfGetNoBuffer \
+ * spec:/rtems/part/req/perf-get-no-buffer
+ *
+ * @{
+ */
+
/**
* @brief Get the buffer.
*/
static void RtemsPartReqPerfGetNoBuffer_Prepare(
- RtemsPartValPerformance_Context *ctx
+ RtemsPartValPerf_Context *ctx
)
{
rtems_status_code sc;
@@ -278,16 +293,14 @@ static void RtemsPartReqPerfGetNoBuffer_Prepare(
/**
* @brief Try to get a buffer.
*/
-static void RtemsPartReqPerfGetNoBuffer_Body(
- RtemsPartValPerformance_Context *ctx
-)
+static void RtemsPartReqPerfGetNoBuffer_Body( RtemsPartValPerf_Context *ctx )
{
ctx->status = rtems_partition_get_buffer( ctx->part_one, &ctx->buffer );
}
static void RtemsPartReqPerfGetNoBuffer_Body_Wrap( void *arg )
{
- RtemsPartValPerformance_Context *ctx;
+ RtemsPartValPerf_Context *ctx;
ctx = arg;
RtemsPartReqPerfGetNoBuffer_Body( ctx );
@@ -297,11 +310,11 @@ static void RtemsPartReqPerfGetNoBuffer_Body_Wrap( void *arg )
* @brief Check the status code.
*/
static bool RtemsPartReqPerfGetNoBuffer_Teardown(
- RtemsPartValPerformance_Context *ctx,
- T_ticks *delta,
- uint32_t tic,
- uint32_t toc,
- unsigned int retry
+ RtemsPartValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
)
{
T_quiet_rsc( ctx->status, RTEMS_UNSATISFIED );
@@ -317,7 +330,7 @@ static bool RtemsPartReqPerfGetNoBuffer_Teardown_Wrap(
unsigned int retry
)
{
- RtemsPartValPerformance_Context *ctx;
+ RtemsPartValPerf_Context *ctx;
ctx = arg;
return RtemsPartReqPerfGetNoBuffer_Teardown( ctx, delta, tic, toc, retry );
@@ -327,7 +340,7 @@ static bool RtemsPartReqPerfGetNoBuffer_Teardown_Wrap(
* @brief Return the buffer.
*/
static void RtemsPartReqPerfGetNoBuffer_Cleanup(
- RtemsPartValPerformance_Context *ctx
+ RtemsPartValPerf_Context *ctx
)
{
rtems_status_code sc;
@@ -336,12 +349,19 @@ static void RtemsPartReqPerfGetNoBuffer_Cleanup(
T_rsc_success( sc );
}
+/** @} */
+
+/**
+ * @defgroup RtemsPartReqPerfReturnBuffer \
+ * spec:/rtems/part/req/perf-return-buffer
+ *
+ * @{
+ */
+
/**
* @brief Get the buffer.
*/
-static void RtemsPartReqPerfReturnBuffer_Setup(
- RtemsPartValPerformance_Context *ctx
-)
+static void RtemsPartReqPerfReturnBuffer_Setup( RtemsPartValPerf_Context *ctx )
{
rtems_status_code sc;
@@ -351,7 +371,7 @@ static void RtemsPartReqPerfReturnBuffer_Setup(
static void RtemsPartReqPerfReturnBuffer_Setup_Wrap( void *arg )
{
- RtemsPartValPerformance_Context *ctx;
+ RtemsPartValPerf_Context *ctx;
ctx = arg;
RtemsPartReqPerfReturnBuffer_Setup( ctx );
@@ -360,16 +380,14 @@ static void RtemsPartReqPerfReturnBuffer_Setup_Wrap( void *arg )
/**
* @brief Return the buffer.
*/
-static void RtemsPartReqPerfReturnBuffer_Body(
- RtemsPartValPerformance_Context *ctx
-)
+static void RtemsPartReqPerfReturnBuffer_Body( RtemsPartValPerf_Context *ctx )
{
ctx->status = rtems_partition_return_buffer( ctx->part_many, ctx->buffer );
}
static void RtemsPartReqPerfReturnBuffer_Body_Wrap( void *arg )
{
- RtemsPartValPerformance_Context *ctx;
+ RtemsPartValPerf_Context *ctx;
ctx = arg;
RtemsPartReqPerfReturnBuffer_Body( ctx );
@@ -379,11 +397,11 @@ static void RtemsPartReqPerfReturnBuffer_Body_Wrap( void *arg )
* @brief Check the status code.
*/
static bool RtemsPartReqPerfReturnBuffer_Teardown(
- RtemsPartValPerformance_Context *ctx,
- T_ticks *delta,
- uint32_t tic,
- uint32_t toc,
- unsigned int retry
+ RtemsPartValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
)
{
T_quiet_rsc( ctx->status, RTEMS_SUCCESSFUL );
@@ -399,21 +417,20 @@ static bool RtemsPartReqPerfReturnBuffer_Teardown_Wrap(
unsigned int retry
)
{
- RtemsPartValPerformance_Context *ctx;
+ RtemsPartValPerf_Context *ctx;
ctx = arg;
return RtemsPartReqPerfReturnBuffer_Teardown( ctx, delta, tic, toc, retry );
}
+/** @} */
+
/**
- * @fn void T_case_body_RtemsPartValPerformance( void )
+ * @fn void T_case_body_RtemsPartValPerf( void )
*/
-T_TEST_CASE_FIXTURE(
- RtemsPartValPerformance,
- &RtemsPartValPerformance_Fixture
-)
+T_TEST_CASE_FIXTURE( RtemsPartValPerf, &RtemsPartValPerf_Fixture )
{
- RtemsPartValPerformance_Context *ctx;
+ RtemsPartValPerf_Context *ctx;
ctx = T_fixture_context();
diff --git a/testsuites/validation/tc-part-return.c b/testsuites/validation/tc-part-return.c
new file mode 100644
index 0000000000..864d916f61
--- /dev/null
+++ b/testsuites/validation/tc-part-return.c
@@ -0,0 +1,486 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsPartReqReturnBuffer
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsPartReqReturnBuffer spec:/rtems/part/req/return-buffer
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsPartReqReturnBuffer_Pre_Id_NoObj,
+ RtemsPartReqReturnBuffer_Pre_Id_Part,
+ RtemsPartReqReturnBuffer_Pre_Id_NA
+} RtemsPartReqReturnBuffer_Pre_Id;
+
+typedef enum {
+ RtemsPartReqReturnBuffer_Pre_Buf_Valid,
+ RtemsPartReqReturnBuffer_Pre_Buf_BadAlign,
+ RtemsPartReqReturnBuffer_Pre_Buf_BelowArea,
+ RtemsPartReqReturnBuffer_Pre_Buf_AboveArea,
+ RtemsPartReqReturnBuffer_Pre_Buf_NA
+} RtemsPartReqReturnBuffer_Pre_Buf;
+
+typedef enum {
+ RtemsPartReqReturnBuffer_Post_Status_Ok,
+ RtemsPartReqReturnBuffer_Post_Status_InvId,
+ RtemsPartReqReturnBuffer_Post_Status_InvAddr,
+ RtemsPartReqReturnBuffer_Post_Status_NA
+} RtemsPartReqReturnBuffer_Post_Status;
+
+typedef enum {
+ RtemsPartReqReturnBuffer_Post_Buf_Free,
+ RtemsPartReqReturnBuffer_Post_Buf_InUse,
+ RtemsPartReqReturnBuffer_Post_Buf_NA
+} RtemsPartReqReturnBuffer_Post_Buf;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Pre_Buf_NA : 1;
+ uint8_t Post_Status : 2;
+ uint8_t Post_Buf : 2;
+} RtemsPartReqReturnBuffer_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/part/req/return-buffer test case.
+ */
+typedef struct {
+ rtems_status_code status;
+
+ rtems_id id;
+
+ rtems_id id_value;
+
+ void *buffer;
+
+ void *buffer_in_use;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsPartReqReturnBuffer_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsPartReqReturnBuffer_Context;
+
+static RtemsPartReqReturnBuffer_Context
+ RtemsPartReqReturnBuffer_Instance;
+
+static const char * const RtemsPartReqReturnBuffer_PreDesc_Id[] = {
+ "NoObj",
+ "Part",
+ "NA"
+};
+
+static const char * const RtemsPartReqReturnBuffer_PreDesc_Buf[] = {
+ "Valid",
+ "BadAlign",
+ "BelowArea",
+ "AboveArea",
+ "NA"
+};
+
+static const char * const * const RtemsPartReqReturnBuffer_PreDesc[] = {
+ RtemsPartReqReturnBuffer_PreDesc_Id,
+ RtemsPartReqReturnBuffer_PreDesc_Buf,
+ NULL
+};
+
+#define BUFFER_COUNT 1
+
+#define BUFFER_SIZE ( 2 * sizeof( void * ) )
+
+static RTEMS_ALIGNED( RTEMS_PARTITION_ALIGNMENT ) uint8_t
+ buffers[ BUFFER_COUNT ][ BUFFER_SIZE ];
+
+static void RtemsPartReqReturnBuffer_Pre_Id_Prepare(
+ RtemsPartReqReturnBuffer_Context *ctx,
+ RtemsPartReqReturnBuffer_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsPartReqReturnBuffer_Pre_Id_NoObj: {
+ /*
+ * While the ``id`` parameter is invalid.
+ */
+ ctx->id = 0xffffffff;
+ break;
+ }
+
+ case RtemsPartReqReturnBuffer_Pre_Id_Part: {
+ /*
+ * While the ``id`` parameter is associated with a partition.
+ */
+ ctx->id = ctx->id_value;
+ break;
+ }
+
+ case RtemsPartReqReturnBuffer_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqReturnBuffer_Pre_Buf_Prepare(
+ RtemsPartReqReturnBuffer_Context *ctx,
+ RtemsPartReqReturnBuffer_Pre_Buf state
+)
+{
+ switch ( state ) {
+ case RtemsPartReqReturnBuffer_Pre_Buf_Valid: {
+ /*
+ * While the ``buffer`` parameter references a buffer previously returned
+ * by rtems_partition_get_buffer().
+ */
+ ctx->buffer = ctx->buffer_in_use;
+ break;
+ }
+
+ case RtemsPartReqReturnBuffer_Pre_Buf_BadAlign: {
+ /*
+ * While the ``buffer`` parameter is an address inside the buffer area of
+ * the partition, while the address is not on a valid buffer boundary.
+ */
+ ctx->buffer = (void *) ( (uintptr_t) ctx->buffer_in_use + 1 );
+ break;
+ }
+
+ case RtemsPartReqReturnBuffer_Pre_Buf_BelowArea: {
+ /*
+ * While the ``buffer`` parameter is an address below the buffer area of
+ * the partition.
+ */
+ ctx->buffer = (void *) ( (uintptr_t) buffers - 1 );
+ break;
+ }
+
+ case RtemsPartReqReturnBuffer_Pre_Buf_AboveArea: {
+ /*
+ * While the ``buffer`` parameter is an address above the buffer area of
+ * the partition.
+ */
+ ctx->buffer = (void *) ( (uintptr_t) buffers + sizeof( buffers ) );
+ break;
+ }
+
+ case RtemsPartReqReturnBuffer_Pre_Buf_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqReturnBuffer_Post_Status_Check(
+ RtemsPartReqReturnBuffer_Context *ctx,
+ RtemsPartReqReturnBuffer_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsPartReqReturnBuffer_Post_Status_Ok: {
+ /*
+ * The return status of rtems_partition_return_buffer() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsPartReqReturnBuffer_Post_Status_InvId: {
+ /*
+ * The return status of rtems_partition_return_buffer() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsPartReqReturnBuffer_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_partition_return_buffer() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsPartReqReturnBuffer_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqReturnBuffer_Post_Buf_Check(
+ RtemsPartReqReturnBuffer_Context *ctx,
+ RtemsPartReqReturnBuffer_Post_Buf state
+)
+{
+ rtems_status_code sc;
+ void *no_buffer;
+
+ switch ( state ) {
+ case RtemsPartReqReturnBuffer_Post_Buf_Free: {
+ /*
+ * The buffer obtained from the partition shall be made available for
+ * re-use by the rtems_partition_return_buffer() call.
+ */
+ sc = rtems_partition_get_buffer( ctx->id_value, &ctx->buffer_in_use );
+ T_rsc_success( sc );
+ T_eq_ptr( ctx->buffer_in_use, buffers );
+ break;
+ }
+
+ case RtemsPartReqReturnBuffer_Post_Buf_InUse: {
+ /*
+ * The buffer obtained from the partition shall be still in use after the
+ * rtems_partition_return_buffer() call.
+ */
+ sc = rtems_partition_get_buffer( ctx->id_value, &no_buffer );
+ T_rsc( sc, RTEMS_UNSATISFIED );
+ break;
+ }
+
+ case RtemsPartReqReturnBuffer_Post_Buf_NA:
+ break;
+ }
+}
+
+static void RtemsPartReqReturnBuffer_Setup(
+ RtemsPartReqReturnBuffer_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ ctx->buffer_in_use = NULL;
+ ctx->id_value = 0;
+
+ sc = rtems_partition_create(
+ rtems_build_name( 'N', 'A', 'M', 'E' ),
+ buffers,
+ sizeof( buffers ),
+ sizeof( buffers[ 0 ] ),
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &ctx->id_value
+ );
+ T_assert_rsc_success( sc );
+
+ sc = rtems_partition_get_buffer( ctx->id_value, &ctx->buffer_in_use );
+ T_assert_rsc_success( sc );
+ T_assert_eq_ptr( ctx->buffer_in_use, buffers );
+}
+
+static void RtemsPartReqReturnBuffer_Setup_Wrap( void *arg )
+{
+ RtemsPartReqReturnBuffer_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsPartReqReturnBuffer_Setup( ctx );
+}
+
+static void RtemsPartReqReturnBuffer_Teardown(
+ RtemsPartReqReturnBuffer_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ if ( ctx->buffer_in_use != NULL ) {
+ sc = rtems_partition_return_buffer( ctx->id_value, ctx->buffer_in_use );
+ T_rsc_success( sc );
+ }
+
+ if ( ctx->id_value != 0 ) {
+ sc = rtems_partition_delete( ctx->id_value );
+ T_rsc_success( sc );
+ }
+}
+
+static void RtemsPartReqReturnBuffer_Teardown_Wrap( void *arg )
+{
+ RtemsPartReqReturnBuffer_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsPartReqReturnBuffer_Teardown( ctx );
+}
+
+static void RtemsPartReqReturnBuffer_Action(
+ RtemsPartReqReturnBuffer_Context *ctx
+)
+{
+ ctx->status = rtems_partition_return_buffer( ctx->id, ctx->buffer );
+}
+
+static const RtemsPartReqReturnBuffer_Entry
+RtemsPartReqReturnBuffer_Entries[] = {
+ { 0, 0, 0, RtemsPartReqReturnBuffer_Post_Status_InvId,
+ RtemsPartReqReturnBuffer_Post_Buf_InUse },
+ { 0, 0, 0, RtemsPartReqReturnBuffer_Post_Status_InvAddr,
+ RtemsPartReqReturnBuffer_Post_Buf_InUse },
+ { 0, 0, 0, RtemsPartReqReturnBuffer_Post_Status_Ok,
+ RtemsPartReqReturnBuffer_Post_Buf_Free }
+};
+
+static const uint8_t
+RtemsPartReqReturnBuffer_Map[] = {
+ 0, 0, 0, 0, 2, 1, 1, 1
+};
+
+static size_t RtemsPartReqReturnBuffer_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsPartReqReturnBuffer_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsPartReqReturnBuffer_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsPartReqReturnBuffer_Fixture = {
+ .setup = RtemsPartReqReturnBuffer_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsPartReqReturnBuffer_Teardown_Wrap,
+ .scope = RtemsPartReqReturnBuffer_Scope,
+ .initial_context = &RtemsPartReqReturnBuffer_Instance
+};
+
+static inline RtemsPartReqReturnBuffer_Entry RtemsPartReqReturnBuffer_PopEntry(
+ RtemsPartReqReturnBuffer_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsPartReqReturnBuffer_Entries[
+ RtemsPartReqReturnBuffer_Map[ index ]
+ ];
+}
+
+static void RtemsPartReqReturnBuffer_TestVariant(
+ RtemsPartReqReturnBuffer_Context *ctx
+)
+{
+ RtemsPartReqReturnBuffer_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsPartReqReturnBuffer_Pre_Buf_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsPartReqReturnBuffer_Action( ctx );
+ RtemsPartReqReturnBuffer_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ RtemsPartReqReturnBuffer_Post_Buf_Check( ctx, ctx->Map.entry.Post_Buf );
+}
+
+/**
+ * @fn void T_case_body_RtemsPartReqReturnBuffer( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsPartReqReturnBuffer,
+ &RtemsPartReqReturnBuffer_Fixture
+)
+{
+ RtemsPartReqReturnBuffer_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsPartReqReturnBuffer_Pre_Id_NoObj;
+ ctx->Map.pcs[ 0 ] < RtemsPartReqReturnBuffer_Pre_Id_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsPartReqReturnBuffer_Pre_Buf_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsPartReqReturnBuffer_Pre_Buf_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ ctx->Map.entry = RtemsPartReqReturnBuffer_PopEntry( ctx );
+ RtemsPartReqReturnBuffer_TestVariant( ctx );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-part.c b/testsuites/validation/tc-part.c
new file mode 100644
index 0000000000..ad241e975c
--- /dev/null
+++ b/testsuites/validation/tc-part.c
@@ -0,0 +1,196 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsPartValPart
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsPartValPart spec:/rtems/part/val/part
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief This test case collection provides validation test cases for
+ * requirements of the @ref RTEMSAPIClassicPart.
+ *
+ * This test case performs the following actions:
+ *
+ * - Create a partition with a buffer area length which is greater than three
+ * times the buffer size and less than four times the buffer size.
+ *
+ * - Check that exactly three buffers can be obtained from the partition for
+ * use in parallel.
+ *
+ * - Return the three buffers in use to the partition and check that they can
+ * be obtained from the partition for use in parallel in FIFO order.
+ *
+ * - Assert that RTEMS_PARTITION_ALIGNMENT is a constant expression which
+ * evaluates to the expected value.
+ *
+ * @{
+ */
+
+/**
+ * @brief Create a partition with a buffer area length which is greater than
+ * three times the buffer size and less than four times the buffer size.
+ */
+static void RtemsPartValPart_Action_0( void )
+{
+ RTEMS_ALIGNED( RTEMS_PARTITION_ALIGNMENT ) uint8_t
+ buffers[ 4 ][ 2 * sizeof( void * ) ];
+ void *pointers[ RTEMS_ARRAY_SIZE( buffers ) ];
+ void *pointer;
+ rtems_status_code sc;
+ rtems_id id;
+
+ id = 0xffffffff;
+ sc = rtems_partition_create(
+ rtems_build_name( 'N', 'A', 'M', 'E' ),
+ buffers,
+ sizeof( buffers ) - 1,
+ sizeof( buffers[ 0 ] ),
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &id
+ );
+ T_step_rsc_success( 0, sc );
+
+ /*
+ * Check that exactly three buffers can be obtained from the partition for
+ * use in parallel.
+ */
+ pointers[ 0 ] = NULL;
+ sc = rtems_partition_get_buffer( id, &pointers[ 0 ] );
+ T_step_rsc_success( 1, sc );
+ T_step_not_null( 2, pointers[ 0 ] );
+
+ pointers[ 1 ] = NULL;
+ sc = rtems_partition_get_buffer( id, &pointers[ 1 ] );
+ T_step_rsc_success( 3, sc );
+ T_step_not_null( 4, pointers[ 1 ] );
+
+ pointers[ 2 ] = NULL;
+ sc = rtems_partition_get_buffer( id, &pointers[ 2 ] );
+ T_step_rsc_success( 5, sc );
+ T_step_not_null( 6, pointers[ 2 ] );
+
+ pointers[ 3 ] = NULL;
+ sc = rtems_partition_get_buffer( id, &pointers[ 3 ] );
+ T_step_rsc( 7, sc, RTEMS_UNSATISFIED );
+ T_step_null( 8, pointers[ 3 ] );
+
+ /*
+ * Return the three buffers in use to the partition and check that they can
+ * be obtained from the partition for use in parallel in FIFO order.
+ */
+ sc = rtems_partition_return_buffer( id, pointers[ 1 ] );
+ T_step_rsc_success( 9, sc );
+
+ sc = rtems_partition_return_buffer( id, pointers[ 2 ] );
+ T_step_rsc_success( 10, sc );
+
+ sc = rtems_partition_return_buffer( id, pointers[ 0 ] );
+ T_step_rsc_success( 11, sc );
+
+ pointer = NULL;
+ sc = rtems_partition_get_buffer( id, &pointer );
+ T_step_rsc_success( 12, sc );
+ T_step_eq_ptr( 13, pointer, pointers[ 1 ] );
+
+ pointer = NULL;
+ sc = rtems_partition_get_buffer( id, &pointer );
+ T_step_rsc_success( 14, sc );
+ T_step_eq_ptr( 15, pointer, pointers[ 2 ] );
+
+ pointer = NULL;
+ sc = rtems_partition_get_buffer( id, &pointer );
+ T_step_rsc_success( 16, sc );
+ T_step_eq_ptr( 17, pointer, pointers[ 0 ] );
+
+ sc = rtems_partition_return_buffer( id, pointers[ 0 ] );
+ T_step_rsc_success( 18, sc );
+
+ sc = rtems_partition_return_buffer( id, pointers[ 1 ] );
+ T_step_rsc_success( 19, sc );
+
+ sc = rtems_partition_return_buffer( id, pointers[ 2 ] );
+ T_step_rsc_success( 20, sc );
+
+ sc = rtems_partition_delete( id );
+ T_step_rsc_success( 21, sc );
+}
+
+/**
+ * @brief Assert that RTEMS_PARTITION_ALIGNMENT is a constant expression which
+ * evaluates to the expected value.
+ */
+static void RtemsPartValPart_Action_1( void )
+{
+ RTEMS_STATIC_ASSERT(
+ RTEMS_PARTITION_ALIGNMENT == CPU_SIZEOF_POINTER,
+ ALIGNMENT
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsPartValPart( void )
+ */
+T_TEST_CASE( RtemsPartValPart )
+{
+ T_plan( 22 );
+
+ RtemsPartValPart_Action_0();
+ RtemsPartValPart_Action_1();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-preinit-array.c b/testsuites/validation/tc-preinit-array.c
new file mode 100644
index 0000000000..244b30b40e
--- /dev/null
+++ b/testsuites/validation/tc-preinit-array.c
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreThreadValPreinitArray
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreThreadValPreinitArray spec:/score/thread/val/preinit-array
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests the ``.preinit_array`` constructor handling of the C runtime
+ * support.
+ *
+ * This test case performs the following actions:
+ *
+ * - Validate the ``.preinit_array`` constructor invocation. Mark that the
+ * test case executed.
+ *
+ * - Check that the ``.preinit_array`` constructor was called exactly once.
+ *
+ * - Check that the ``.preeinit_array`` construction was done by the Classic
+ * API user initialization task.
+ *
+ * - Check that the ``.preinit_array`` constructor was called before the
+ * global constructor invocations.
+ *
+ * @{
+ */
+
+static bool test_case_executed;
+
+static bool constructor_test_case_executed;
+
+static uint32_t counter;
+
+static uint32_t normal_constructor_counter;
+
+static uint32_t constructor_counter;
+
+static uint32_t constructor_calls;
+
+static rtems_id constructor_id;
+
+static __attribute__(( __constructor__ )) void NormalConstructor( void )
+{
+ ++counter;
+ normal_constructor_counter = counter;
+}
+
+static void Constructor( void )
+{
+ constructor_test_case_executed = test_case_executed;
+ ++counter;
+ constructor_counter = counter;
+ ++constructor_calls;
+ constructor_id = rtems_task_self();
+}
+
+static RTEMS_USED RTEMS_SECTION( ".preinit_array" ) void
+ ( * const constructor_registration )( void ) = Constructor;
+
+/**
+ * @brief Validate the ``.preinit_array`` constructor invocation. Mark that
+ * the test case executed.
+ */
+static void ScoreThreadValPreinitArray_Action_0( void )
+{
+ test_case_executed = true;
+
+ /*
+ * Check that the ``.preinit_array`` constructor was called exactly once.
+ */
+ T_eq_u32( constructor_calls, 1 );
+
+ /*
+ * Check that the ``.preeinit_array`` construction was done by the Classic
+ * API user initialization task.
+ */
+ T_eq_u32( constructor_id, rtems_task_self() );
+
+ /*
+ * Check that the ``.preinit_array`` constructor was called before the global
+ * constructor invocations.
+ */
+ T_eq_u32( constructor_counter, 1 );
+ T_eq_u32( normal_constructor_counter, 2 );
+}
+
+/**
+ * @fn void T_case_body_ScoreThreadValPreinitArray( void )
+ */
+T_TEST_CASE( ScoreThreadValPreinitArray )
+{
+ ScoreThreadValPreinitArray_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-ratemon-cancel.c b/testsuites/validation/tc-ratemon-cancel.c
new file mode 100644
index 0000000000..b3683ac338
--- /dev/null
+++ b/testsuites/validation/tc-ratemon-cancel.c
@@ -0,0 +1,882 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsRatemonReqCancel
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsRatemonReqCancel spec:/rtems/ratemon/req/cancel
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ * @ingroup TestsuitesValidationOneCpu0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsRatemonReqCancel_Pre_Id_Valid,
+ RtemsRatemonReqCancel_Pre_Id_Invalid,
+ RtemsRatemonReqCancel_Pre_Id_NA
+} RtemsRatemonReqCancel_Pre_Id;
+
+typedef enum {
+ RtemsRatemonReqCancel_Pre_Caller_OwnerTask,
+ RtemsRatemonReqCancel_Pre_Caller_OtherTask,
+ RtemsRatemonReqCancel_Pre_Caller_NA
+} RtemsRatemonReqCancel_Pre_Caller;
+
+typedef enum {
+ RtemsRatemonReqCancel_Pre_State_Inactive,
+ RtemsRatemonReqCancel_Pre_State_Active,
+ RtemsRatemonReqCancel_Pre_State_Expired,
+ RtemsRatemonReqCancel_Pre_State_NA
+} RtemsRatemonReqCancel_Pre_State;
+
+typedef enum {
+ RtemsRatemonReqCancel_Pre_Postponed_Zero,
+ RtemsRatemonReqCancel_Pre_Postponed_One,
+ RtemsRatemonReqCancel_Pre_Postponed_Several,
+ RtemsRatemonReqCancel_Pre_Postponed_NA
+} RtemsRatemonReqCancel_Pre_Postponed;
+
+typedef enum {
+ RtemsRatemonReqCancel_Post_Status_Ok,
+ RtemsRatemonReqCancel_Post_Status_InvId,
+ RtemsRatemonReqCancel_Post_Status_NotOwn,
+ RtemsRatemonReqCancel_Post_Status_NA
+} RtemsRatemonReqCancel_Post_Status;
+
+typedef enum {
+ RtemsRatemonReqCancel_Post_State_Inactive,
+ RtemsRatemonReqCancel_Post_State_Nop,
+ RtemsRatemonReqCancel_Post_State_NA
+} RtemsRatemonReqCancel_Post_State;
+
+typedef enum {
+ RtemsRatemonReqCancel_Post_Postponed_Zero,
+ RtemsRatemonReqCancel_Post_Postponed_Nop,
+ RtemsRatemonReqCancel_Post_Postponed_NA
+} RtemsRatemonReqCancel_Post_Postponed;
+
+typedef enum {
+ RtemsRatemonReqCancel_Post_Scheduler_Called,
+ RtemsRatemonReqCancel_Post_Scheduler_Nop,
+ RtemsRatemonReqCancel_Post_Scheduler_NA
+} RtemsRatemonReqCancel_Post_Scheduler;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_Caller_NA : 1;
+ uint16_t Pre_State_NA : 1;
+ uint16_t Pre_Postponed_NA : 1;
+ uint16_t Post_Status : 2;
+ uint16_t Post_State : 2;
+ uint16_t Post_Postponed : 2;
+ uint16_t Post_Scheduler : 2;
+} RtemsRatemonReqCancel_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/ratemon/req/cancel test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a valid identifier of a period.
+ */
+ rtems_id period_id;
+
+ /**
+ * @brief This member is used to receive the
+ * rtems_rate_monotonic_period_status after the action.
+ */
+ rtems_rate_monotonic_period_status period_status;
+
+ /**
+ * @brief This member specifies the ``id`` parameter for the action.
+ */
+ rtems_id id_param;
+
+ /**
+ * @brief This member contains the returned status code of the action.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member contains the pointer to the function which executes the
+ * action.
+ *
+ * The action is either executed by the owner task or by the worker task
+ * depending on the function pointer used here. ``argument`` is a pointer to
+ * this context structure.
+ */
+ void ( *do_action )( void *ctx );
+
+ /**
+ * @brief This member contains the task identifier of the owner task.
+ */
+ rtems_id task_id;
+
+ /**
+ * @brief This member contains the task identifier of the worker task (which
+ * is not the owner task).
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member contains a backup of the task priority before the
+ * execution of this test.
+ */
+ rtems_id original_priority;
+
+ /**
+ * @brief This member contains the number of postponed jobs before the
+ * action.
+ */
+ uint32_t postponed_jobs_count;
+
+ /**
+ * @brief This member contains the state before the action.
+ */
+ rtems_rate_monotonic_period_states previous_state;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 4 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 4 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsRatemonReqCancel_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsRatemonReqCancel_Context;
+
+static RtemsRatemonReqCancel_Context
+ RtemsRatemonReqCancel_Instance;
+
+static const char * const RtemsRatemonReqCancel_PreDesc_Id[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsRatemonReqCancel_PreDesc_Caller[] = {
+ "OwnerTask",
+ "OtherTask",
+ "NA"
+};
+
+static const char * const RtemsRatemonReqCancel_PreDesc_State[] = {
+ "Inactive",
+ "Active",
+ "Expired",
+ "NA"
+};
+
+static const char * const RtemsRatemonReqCancel_PreDesc_Postponed[] = {
+ "Zero",
+ "One",
+ "Several",
+ "NA"
+};
+
+static const char * const * const RtemsRatemonReqCancel_PreDesc[] = {
+ RtemsRatemonReqCancel_PreDesc_Id,
+ RtemsRatemonReqCancel_PreDesc_Caller,
+ RtemsRatemonReqCancel_PreDesc_State,
+ RtemsRatemonReqCancel_PreDesc_Postponed,
+ NULL
+};
+
+static const rtems_interval period_length = 5;
+static const rtems_task_priority background_task_priority = 100;
+static const rtems_task_priority foreground_task_priority = 10;
+static const rtems_event_set wake_main_task_event = RTEMS_EVENT_17;
+
+static void TickTheClock(
+ RtemsRatemonReqCancel_Context *ctx,
+ uint32_t ticks
+)
+{
+ uint32_t i;
+ for ( i = 0; i < ticks; ++i ) {
+ TimecounterTick();
+ }
+}
+
+static void Action( void *ctx_in )
+{
+ RtemsRatemonReqCancel_Context *ctx = ctx_in;
+ ctx->status = rtems_rate_monotonic_cancel( ctx->id_param );
+}
+
+static void WorkerTask( rtems_task_argument argument )
+{
+ RtemsRatemonReqCancel_Context *ctx =
+ (RtemsRatemonReqCancel_Context *) argument;
+
+ if ( ctx != NULL ) {
+ Action( ctx );
+ T_rsc_success( rtems_event_send( ctx->task_id, wake_main_task_event ) );
+ }
+
+ T_rsc_success( rtems_task_suspend( RTEMS_SELF ) );
+}
+
+static void WorkerTaskAction( void *ctx_in )
+{
+ rtems_status_code status;
+ rtems_event_set event_set;
+ RtemsRatemonReqCancel_Context *ctx = ctx_in;
+
+ status = rtems_task_restart( ctx->worker_id, (rtems_task_argument) ctx );
+ T_rsc_success( status );
+
+ /* Wait till the worker task finishes */
+ status = rtems_event_receive(
+ wake_main_task_event,
+ RTEMS_DEFAULT_OPTIONS,
+ RTEMS_NO_TIMEOUT,
+ &event_set
+ );
+ T_rsc_success( status );
+}
+
+static void CreatePostponedJobs(
+ RtemsRatemonReqCancel_Context *ctx,
+ uint32_t jobs_count
+)
+{
+ rtems_status_code status;
+ ctx->postponed_jobs_count = jobs_count;
+ if ( ctx->previous_state == RATE_MONOTONIC_ACTIVE ) {
+ TickTheClock( ctx, ( jobs_count + 1 ) * period_length );
+ status = rtems_rate_monotonic_period( ctx->period_id, period_length );
+ T_rsc( status, RTEMS_TIMEOUT );
+ } else {
+ /* ctx->previous_state == RATE_MONOTONIC_INACTIVE || _EXPIRED */
+ TickTheClock( ctx, jobs_count * period_length );
+ }
+}
+
+static void RtemsRatemonReqCancel_Pre_Id_Prepare(
+ RtemsRatemonReqCancel_Context *ctx,
+ RtemsRatemonReqCancel_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqCancel_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter is valid.
+ */
+ ctx->id_param = ctx->period_id;
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is invalid.
+ */
+ ctx->id_param = RTEMS_ID_NONE;
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqCancel_Pre_Caller_Prepare(
+ RtemsRatemonReqCancel_Context *ctx,
+ RtemsRatemonReqCancel_Pre_Caller state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqCancel_Pre_Caller_OwnerTask: {
+ /*
+ * While the task invoking rtems_rate_monotonic_cancel() is the task
+ * which created the period - the owner task.
+ */
+ ctx->do_action = Action;
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Pre_Caller_OtherTask: {
+ /*
+ * While the task invoking rtems_rate_monotonic_cancel() is not the owner
+ * task.
+ */
+ ctx->do_action = WorkerTaskAction;
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Pre_Caller_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqCancel_Pre_State_Prepare(
+ RtemsRatemonReqCancel_Context *ctx,
+ RtemsRatemonReqCancel_Pre_State state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqCancel_Pre_State_Inactive: {
+ /*
+ * While the ``id`` parameter references an period object in inactive
+ * state.
+ */
+ /* Nothing to do here as the period is newly created. */
+ ctx->previous_state = RATE_MONOTONIC_INACTIVE;
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Pre_State_Active: {
+ /*
+ * While the ``id`` parameter references an period object in active
+ * state.
+ */
+ rtems_status_code status;
+ status = rtems_rate_monotonic_period( ctx->period_id, period_length );
+ T_rsc_success( status );
+ ctx->previous_state = RATE_MONOTONIC_ACTIVE;
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Pre_State_Expired: {
+ /*
+ * While the ``id`` parameter references an period object in expired
+ * state.
+ */
+ rtems_status_code status;
+ status = rtems_rate_monotonic_period( ctx->period_id, period_length );
+ T_rsc_success( status );
+ ctx->previous_state = RATE_MONOTONIC_EXPIRED;
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Pre_State_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqCancel_Pre_Postponed_Prepare(
+ RtemsRatemonReqCancel_Context *ctx,
+ RtemsRatemonReqCancel_Pre_Postponed state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqCancel_Pre_Postponed_Zero: {
+ /*
+ * While the period is not in expired state.
+ */
+ ctx->postponed_jobs_count = 0;
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Pre_Postponed_One: {
+ /*
+ * While there is one postponed job.
+ */
+ CreatePostponedJobs( ctx, 1 );
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Pre_Postponed_Several: {
+ /*
+ * While there are two or more postponed jobs.
+ */
+ CreatePostponedJobs( ctx, 5 );
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Pre_Postponed_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqCancel_Post_Status_Check(
+ RtemsRatemonReqCancel_Context *ctx,
+ RtemsRatemonReqCancel_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqCancel_Post_Status_Ok: {
+ /*
+ * The return status of rtems_rate_monotonic_cancel() shall be
+ * RTEMS_SUCCESSFUL
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Post_Status_InvId: {
+ /*
+ * The return status of rtems_rate_monotonic_cancel() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Post_Status_NotOwn: {
+ /*
+ * The return status of rtems_rate_monotonic_cancel() shall be
+ * RTEMS_NOT_OWNER_OF_RESOURCE.
+ */
+ T_rsc( ctx->status, RTEMS_NOT_OWNER_OF_RESOURCE );
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqCancel_Post_State_Check(
+ RtemsRatemonReqCancel_Context *ctx,
+ RtemsRatemonReqCancel_Post_State state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqCancel_Post_State_Inactive: {
+ /*
+ * The state of the period shall be inactive after the return of the
+ * rtems_rate_monotonic_cancel() call.
+ */
+ T_eq_int( ctx->period_status.state, RATE_MONOTONIC_INACTIVE );
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Post_State_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past calls to
+ * rtems_rate_monotonic_cancel() shall not be accessed by the
+ * rtems_rate_monotonic_cancel() call (see also Nop).
+ */
+ T_eq_u32( ctx->period_status.state, ctx->previous_state );
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Post_State_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqCancel_Post_Postponed_Check(
+ RtemsRatemonReqCancel_Context *ctx,
+ RtemsRatemonReqCancel_Post_Postponed state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqCancel_Post_Postponed_Zero: {
+ /*
+ * There shall be no postponed jobs after the return of the
+ * rtems_rate_monotonic_cancel() call.
+ */
+ T_eq_u32( ctx->period_status.postponed_jobs_count, 0 );
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Post_Postponed_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past calls to
+ * rtems_rate_monotonic_cancel() shall not be accessed by the
+ * rtems_rate_monotonic_cancel() call (see also Nop).
+ */
+ T_eq_u32( ctx->period_status.postponed_jobs_count,
+ ctx->postponed_jobs_count );
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Post_Postponed_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqCancel_Post_Scheduler_Check(
+ RtemsRatemonReqCancel_Context *ctx,
+ RtemsRatemonReqCancel_Post_Scheduler state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqCancel_Post_Scheduler_Called: {
+ /*
+ * The last call of the rtems_rate_monotonic_cancel() function shall
+ * execute the ``cancel_job`` scheduler operation of the home scheduler.
+ */
+ /* Cannot be tested as the effect is unknown. */
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Post_Scheduler_Nop: {
+ /*
+ * The last call of the rtems_rate_monotonic_cancel() function shall not
+ * execute any scheduler operation.
+ */
+ /* Cannot be tested as the effect is unknown. */
+ break;
+ }
+
+ case RtemsRatemonReqCancel_Post_Scheduler_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqCancel_Setup( RtemsRatemonReqCancel_Context *ctx )
+{
+ rtems_status_code status;
+ rtems_task_priority priority;
+ rtems_event_set event_set;
+ ctx->worker_id = RTEMS_INVALID_ID;
+
+ status = rtems_task_ident(
+ RTEMS_SELF,
+ RTEMS_SEARCH_ALL_NODES,
+ &ctx->task_id
+ );
+ T_rsc_success( status );
+
+ status = rtems_task_set_priority(
+ RTEMS_SELF,
+ RTEMS_CURRENT_PRIORITY,
+ &ctx->original_priority
+ );
+ T_rsc_success( status );
+
+ status = rtems_task_set_priority(
+ RTEMS_SELF,
+ background_task_priority,
+ &priority
+ );
+ T_rsc_success( status );
+
+ status = rtems_task_create(
+ rtems_build_name( 'W', 'O', 'R', 'K' ),
+ foreground_task_priority,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &ctx->worker_id
+ );
+ T_rsc_success( status );
+
+ /* Defensive programming: clean away any pending events */
+ status = rtems_event_receive(
+ RTEMS_ALL_EVENTS,
+ RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
+ RTEMS_NO_TIMEOUT,
+ &event_set
+ );
+ T_true( status == RTEMS_SUCCESSFUL || status == RTEMS_UNSATISFIED );
+
+ status = rtems_task_start(
+ ctx->worker_id,
+ WorkerTask,
+ (rtems_task_argument) NULL
+ );
+ T_rsc_success( status );
+}
+
+static void RtemsRatemonReqCancel_Setup_Wrap( void *arg )
+{
+ RtemsRatemonReqCancel_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsRatemonReqCancel_Setup( ctx );
+}
+
+static void RtemsRatemonReqCancel_Teardown(
+ RtemsRatemonReqCancel_Context *ctx
+)
+{
+ rtems_status_code status;
+ rtems_task_priority priority;
+
+ T_rsc_success( rtems_task_delete( ctx->worker_id ) );
+
+ status = rtems_task_set_priority(
+ RTEMS_SELF,
+ ctx->original_priority,
+ &priority
+ );
+ T_rsc_success( status );
+}
+
+static void RtemsRatemonReqCancel_Teardown_Wrap( void *arg )
+{
+ RtemsRatemonReqCancel_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsRatemonReqCancel_Teardown( ctx );
+}
+
+static void RtemsRatemonReqCancel_Prepare( RtemsRatemonReqCancel_Context *ctx )
+{
+ rtems_status_code status;
+ status = rtems_rate_monotonic_create(
+ rtems_build_name( 'R', 'M', 'O', 'N' ),
+ &ctx->period_id
+ );
+ T_rsc_success( status );
+
+ ctx->postponed_jobs_count = 0;
+}
+
+static void RtemsRatemonReqCancel_Action( RtemsRatemonReqCancel_Context *ctx )
+{
+ rtems_status_code status;
+
+ ctx->do_action( ctx );
+
+ status = rtems_rate_monotonic_get_status(
+ ctx->period_id,
+ &ctx->period_status
+ );
+ T_rsc_success( status );
+}
+
+static void RtemsRatemonReqCancel_Cleanup( RtemsRatemonReqCancel_Context *ctx )
+{
+ T_rsc_success( rtems_rate_monotonic_delete( ctx->period_id ) );
+}
+
+static const RtemsRatemonReqCancel_Entry
+RtemsRatemonReqCancel_Entries[] = {
+ { 0, 0, 0, 0, 0, RtemsRatemonReqCancel_Post_Status_InvId,
+ RtemsRatemonReqCancel_Post_State_Nop,
+ RtemsRatemonReqCancel_Post_Postponed_Nop,
+ RtemsRatemonReqCancel_Post_Scheduler_Nop },
+ { 1, 0, 0, 0, 0, RtemsRatemonReqCancel_Post_Status_NA,
+ RtemsRatemonReqCancel_Post_State_NA,
+ RtemsRatemonReqCancel_Post_Postponed_NA,
+ RtemsRatemonReqCancel_Post_Scheduler_NA },
+ { 0, 0, 0, 0, 0, RtemsRatemonReqCancel_Post_Status_Ok,
+ RtemsRatemonReqCancel_Post_State_Inactive,
+ RtemsRatemonReqCancel_Post_Postponed_Zero,
+ RtemsRatemonReqCancel_Post_Scheduler_Called },
+ { 0, 0, 0, 0, 0, RtemsRatemonReqCancel_Post_Status_NotOwn,
+ RtemsRatemonReqCancel_Post_State_Nop,
+ RtemsRatemonReqCancel_Post_Postponed_Nop,
+ RtemsRatemonReqCancel_Post_Scheduler_Nop },
+ { 1, 0, 0, 0, 0, RtemsRatemonReqCancel_Post_Status_NA,
+ RtemsRatemonReqCancel_Post_State_NA,
+ RtemsRatemonReqCancel_Post_Postponed_NA,
+ RtemsRatemonReqCancel_Post_Scheduler_NA },
+ { 0, 0, 0, 0, 1, RtemsRatemonReqCancel_Post_Status_InvId,
+ RtemsRatemonReqCancel_Post_State_Nop,
+ RtemsRatemonReqCancel_Post_Postponed_Nop,
+ RtemsRatemonReqCancel_Post_Scheduler_Nop },
+ { 0, 0, 0, 0, 1, RtemsRatemonReqCancel_Post_Status_Ok,
+ RtemsRatemonReqCancel_Post_State_Inactive,
+ RtemsRatemonReqCancel_Post_Postponed_NA,
+ RtemsRatemonReqCancel_Post_Scheduler_Called },
+ { 0, 0, 0, 0, 1, RtemsRatemonReqCancel_Post_Status_NotOwn,
+ RtemsRatemonReqCancel_Post_State_Nop,
+ RtemsRatemonReqCancel_Post_Postponed_Nop,
+ RtemsRatemonReqCancel_Post_Scheduler_Nop }
+};
+
+static const uint8_t
+RtemsRatemonReqCancel_Map[] = {
+ 6, 1, 1, 2, 2, 2, 4, 2, 2, 7, 1, 1, 3, 3, 3, 4, 3, 3, 5, 1, 1, 0, 0, 0, 4, 0,
+ 0, 5, 1, 1, 0, 0, 0, 4, 0, 0
+};
+
+static size_t RtemsRatemonReqCancel_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsRatemonReqCancel_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsRatemonReqCancel_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsRatemonReqCancel_Fixture = {
+ .setup = RtemsRatemonReqCancel_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsRatemonReqCancel_Teardown_Wrap,
+ .scope = RtemsRatemonReqCancel_Scope,
+ .initial_context = &RtemsRatemonReqCancel_Instance
+};
+
+static inline RtemsRatemonReqCancel_Entry RtemsRatemonReqCancel_PopEntry(
+ RtemsRatemonReqCancel_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsRatemonReqCancel_Entries[
+ RtemsRatemonReqCancel_Map[ index ]
+ ];
+}
+
+static void RtemsRatemonReqCancel_SetPreConditionStates(
+ RtemsRatemonReqCancel_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+
+ if ( ctx->Map.entry.Pre_Postponed_NA ) {
+ ctx->Map.pcs[ 3 ] = RtemsRatemonReqCancel_Pre_Postponed_NA;
+ } else {
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ }
+}
+
+static void RtemsRatemonReqCancel_TestVariant(
+ RtemsRatemonReqCancel_Context *ctx
+)
+{
+ RtemsRatemonReqCancel_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsRatemonReqCancel_Pre_Caller_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsRatemonReqCancel_Pre_State_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsRatemonReqCancel_Pre_Postponed_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsRatemonReqCancel_Action( ctx );
+ RtemsRatemonReqCancel_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsRatemonReqCancel_Post_State_Check( ctx, ctx->Map.entry.Post_State );
+ RtemsRatemonReqCancel_Post_Postponed_Check(
+ ctx,
+ ctx->Map.entry.Post_Postponed
+ );
+ RtemsRatemonReqCancel_Post_Scheduler_Check(
+ ctx,
+ ctx->Map.entry.Post_Scheduler
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsRatemonReqCancel( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsRatemonReqCancel, &RtemsRatemonReqCancel_Fixture )
+{
+ RtemsRatemonReqCancel_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsRatemonReqCancel_Pre_Id_Valid;
+ ctx->Map.pci[ 0 ] < RtemsRatemonReqCancel_Pre_Id_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsRatemonReqCancel_Pre_Caller_OwnerTask;
+ ctx->Map.pci[ 1 ] < RtemsRatemonReqCancel_Pre_Caller_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsRatemonReqCancel_Pre_State_Inactive;
+ ctx->Map.pci[ 2 ] < RtemsRatemonReqCancel_Pre_State_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = RtemsRatemonReqCancel_Pre_Postponed_Zero;
+ ctx->Map.pci[ 3 ] < RtemsRatemonReqCancel_Pre_Postponed_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ ctx->Map.entry = RtemsRatemonReqCancel_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsRatemonReqCancel_SetPreConditionStates( ctx );
+ RtemsRatemonReqCancel_Prepare( ctx );
+ RtemsRatemonReqCancel_TestVariant( ctx );
+ RtemsRatemonReqCancel_Cleanup( ctx );
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-ratemon-create.c b/testsuites/validation/tc-ratemon-create.c
new file mode 100644
index 0000000000..ff7672beeb
--- /dev/null
+++ b/testsuites/validation/tc-ratemon-create.c
@@ -0,0 +1,529 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsRatemonReqCreate
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsRatemonReqCreate spec:/rtems/ratemon/req/create
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsRatemonReqCreate_Pre_Name_Valid,
+ RtemsRatemonReqCreate_Pre_Name_Invalid,
+ RtemsRatemonReqCreate_Pre_Name_NA
+} RtemsRatemonReqCreate_Pre_Name;
+
+typedef enum {
+ RtemsRatemonReqCreate_Pre_Id_Valid,
+ RtemsRatemonReqCreate_Pre_Id_Null,
+ RtemsRatemonReqCreate_Pre_Id_NA
+} RtemsRatemonReqCreate_Pre_Id;
+
+typedef enum {
+ RtemsRatemonReqCreate_Pre_Free_Yes,
+ RtemsRatemonReqCreate_Pre_Free_No,
+ RtemsRatemonReqCreate_Pre_Free_NA
+} RtemsRatemonReqCreate_Pre_Free;
+
+typedef enum {
+ RtemsRatemonReqCreate_Post_Status_Ok,
+ RtemsRatemonReqCreate_Post_Status_InvName,
+ RtemsRatemonReqCreate_Post_Status_InvAddr,
+ RtemsRatemonReqCreate_Post_Status_TooMany,
+ RtemsRatemonReqCreate_Post_Status_NA
+} RtemsRatemonReqCreate_Post_Status;
+
+typedef enum {
+ RtemsRatemonReqCreate_Post_Name_Valid,
+ RtemsRatemonReqCreate_Post_Name_Invalid,
+ RtemsRatemonReqCreate_Post_Name_NA
+} RtemsRatemonReqCreate_Post_Name;
+
+typedef enum {
+ RtemsRatemonReqCreate_Post_IdVar_Set,
+ RtemsRatemonReqCreate_Post_IdVar_Nop,
+ RtemsRatemonReqCreate_Post_IdVar_NA
+} RtemsRatemonReqCreate_Post_IdVar;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Name_NA : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_Free_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_Name : 2;
+ uint16_t Post_IdVar : 2;
+} RtemsRatemonReqCreate_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/ratemon/req/create test case.
+ */
+typedef struct {
+ void *seized_objects;
+
+ rtems_id id_value;
+
+ rtems_name name;
+
+ rtems_id *id;
+
+ rtems_status_code status;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsRatemonReqCreate_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsRatemonReqCreate_Context;
+
+static RtemsRatemonReqCreate_Context
+ RtemsRatemonReqCreate_Instance;
+
+static const char * const RtemsRatemonReqCreate_PreDesc_Name[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsRatemonReqCreate_PreDesc_Id[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsRatemonReqCreate_PreDesc_Free[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsRatemonReqCreate_PreDesc[] = {
+ RtemsRatemonReqCreate_PreDesc_Name,
+ RtemsRatemonReqCreate_PreDesc_Id,
+ RtemsRatemonReqCreate_PreDesc_Free,
+ NULL
+};
+
+#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+static rtems_status_code Create( void *arg, uint32_t *id )
+{
+ return rtems_rate_monotonic_create(
+ rtems_build_name( 'S', 'I', 'Z', 'E' ),
+ id
+ );
+}
+
+static void RtemsRatemonReqCreate_Pre_Name_Prepare(
+ RtemsRatemonReqCreate_Context *ctx,
+ RtemsRatemonReqCreate_Pre_Name state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqCreate_Pre_Name_Valid: {
+ /*
+ * While the ``name`` parameter is valid.
+ */
+ ctx->name = NAME;
+ break;
+ }
+
+ case RtemsRatemonReqCreate_Pre_Name_Invalid: {
+ /*
+ * While the ``name`` parameter is invalid.
+ */
+ ctx->name = 0;
+ break;
+ }
+
+ case RtemsRatemonReqCreate_Pre_Name_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqCreate_Pre_Id_Prepare(
+ RtemsRatemonReqCreate_Context *ctx,
+ RtemsRatemonReqCreate_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqCreate_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter references an object of type rtems_id.
+ */
+ ctx->id = &ctx->id_value;
+ break;
+ }
+
+ case RtemsRatemonReqCreate_Pre_Id_Null: {
+ /*
+ * While the ``id`` parameter is NULL.
+ */
+ ctx->id = NULL;
+ break;
+ }
+
+ case RtemsRatemonReqCreate_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqCreate_Pre_Free_Prepare(
+ RtemsRatemonReqCreate_Context *ctx,
+ RtemsRatemonReqCreate_Pre_Free state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqCreate_Pre_Free_Yes: {
+ /*
+ * While the system has at least one inactive period object available.
+ */
+ /* Nothing to do */
+ break;
+ }
+
+ case RtemsRatemonReqCreate_Pre_Free_No: {
+ /*
+ * While the system has no inactive period object available.
+ */
+ ctx->seized_objects = T_seize_objects( Create, NULL );
+ break;
+ }
+
+ case RtemsRatemonReqCreate_Pre_Free_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqCreate_Post_Status_Check(
+ RtemsRatemonReqCreate_Context *ctx,
+ RtemsRatemonReqCreate_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqCreate_Post_Status_Ok: {
+ /*
+ * The return status of rtems_rate_monotonic_create() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsRatemonReqCreate_Post_Status_InvName: {
+ /*
+ * The return status of rtems_rate_monotonic_create() shall be
+ * RTEMS_INVALID_NAME.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsRatemonReqCreate_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_rate_monotonic_create() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsRatemonReqCreate_Post_Status_TooMany: {
+ /*
+ * The return status of rtems_rate_monotonic_create() shall be
+ * RTEMS_TOO_MANY.
+ */
+ T_rsc( ctx->status, RTEMS_TOO_MANY );
+ break;
+ }
+
+ case RtemsRatemonReqCreate_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqCreate_Post_Name_Check(
+ RtemsRatemonReqCreate_Context *ctx,
+ RtemsRatemonReqCreate_Post_Name state
+)
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ switch ( state ) {
+ case RtemsRatemonReqCreate_Post_Name_Valid: {
+ /*
+ * The unique object name shall identify the period created by the
+ * rtems_rate_monotonic_create() call.
+ */
+ id = 0;
+ sc = rtems_rate_monotonic_ident( NAME, &id );
+ T_rsc_success( sc );
+ T_eq_u32( id, ctx->id_value );
+ break;
+ }
+
+ case RtemsRatemonReqCreate_Post_Name_Invalid: {
+ /*
+ * The unique object name shall not identify a period.
+ */
+ sc = rtems_rate_monotonic_ident( NAME, &id );
+ T_rsc( sc, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsRatemonReqCreate_Post_Name_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqCreate_Post_IdVar_Check(
+ RtemsRatemonReqCreate_Context *ctx,
+ RtemsRatemonReqCreate_Post_IdVar state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqCreate_Post_IdVar_Set: {
+ /*
+ * The value of the object referenced by the ``id`` parameter shall be
+ * set to the object identifier of the created period after the return of
+ * the rtems_rate_monotonic_create() call.
+ */
+ T_eq_ptr( ctx->id, &ctx->id_value );
+ T_ne_u32( ctx->id_value, INVALID_ID );
+ break;
+ }
+
+ case RtemsRatemonReqCreate_Post_IdVar_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past calls to
+ * rtems_rate_monotonic_create() shall not be accessed by the
+ * rtems_rate_monotonic_create() call.
+ */
+ T_eq_u32( ctx->id_value, INVALID_ID );
+ break;
+ }
+
+ case RtemsRatemonReqCreate_Post_IdVar_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqCreate_Setup( RtemsRatemonReqCreate_Context *ctx )
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->id_value = INVALID_ID;
+}
+
+static void RtemsRatemonReqCreate_Setup_Wrap( void *arg )
+{
+ RtemsRatemonReqCreate_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsRatemonReqCreate_Setup( ctx );
+}
+
+static void RtemsRatemonReqCreate_Action( RtemsRatemonReqCreate_Context *ctx )
+{
+ ctx->status = rtems_rate_monotonic_create( ctx->name, ctx->id );
+}
+
+static void RtemsRatemonReqCreate_Cleanup( RtemsRatemonReqCreate_Context *ctx )
+{
+ if ( ctx->id_value != INVALID_ID ) {
+ rtems_status_code sc;
+
+ sc = rtems_rate_monotonic_delete( ctx->id_value );
+ T_rsc_success( sc );
+
+ ctx->id_value = INVALID_ID;
+ }
+
+ T_surrender_objects( &ctx->seized_objects, rtems_rate_monotonic_delete );
+}
+
+static const RtemsRatemonReqCreate_Entry
+RtemsRatemonReqCreate_Entries[] = {
+ { 0, 0, 0, 0, RtemsRatemonReqCreate_Post_Status_InvName,
+ RtemsRatemonReqCreate_Post_Name_Invalid,
+ RtemsRatemonReqCreate_Post_IdVar_Nop },
+ { 0, 0, 0, 0, RtemsRatemonReqCreate_Post_Status_InvAddr,
+ RtemsRatemonReqCreate_Post_Name_Invalid,
+ RtemsRatemonReqCreate_Post_IdVar_Nop },
+ { 0, 0, 0, 0, RtemsRatemonReqCreate_Post_Status_Ok,
+ RtemsRatemonReqCreate_Post_Name_Valid, RtemsRatemonReqCreate_Post_IdVar_Set },
+ { 0, 0, 0, 0, RtemsRatemonReqCreate_Post_Status_TooMany,
+ RtemsRatemonReqCreate_Post_Name_Invalid,
+ RtemsRatemonReqCreate_Post_IdVar_Nop }
+};
+
+static const uint8_t
+RtemsRatemonReqCreate_Map[] = {
+ 2, 3, 1, 1, 0, 0, 0, 0
+};
+
+static size_t RtemsRatemonReqCreate_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsRatemonReqCreate_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsRatemonReqCreate_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsRatemonReqCreate_Fixture = {
+ .setup = RtemsRatemonReqCreate_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsRatemonReqCreate_Scope,
+ .initial_context = &RtemsRatemonReqCreate_Instance
+};
+
+static inline RtemsRatemonReqCreate_Entry RtemsRatemonReqCreate_PopEntry(
+ RtemsRatemonReqCreate_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsRatemonReqCreate_Entries[
+ RtemsRatemonReqCreate_Map[ index ]
+ ];
+}
+
+static void RtemsRatemonReqCreate_TestVariant(
+ RtemsRatemonReqCreate_Context *ctx
+)
+{
+ RtemsRatemonReqCreate_Pre_Name_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsRatemonReqCreate_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsRatemonReqCreate_Pre_Free_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsRatemonReqCreate_Action( ctx );
+ RtemsRatemonReqCreate_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsRatemonReqCreate_Post_Name_Check( ctx, ctx->Map.entry.Post_Name );
+ RtemsRatemonReqCreate_Post_IdVar_Check( ctx, ctx->Map.entry.Post_IdVar );
+}
+
+/**
+ * @fn void T_case_body_RtemsRatemonReqCreate( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsRatemonReqCreate, &RtemsRatemonReqCreate_Fixture )
+{
+ RtemsRatemonReqCreate_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsRatemonReqCreate_Pre_Name_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsRatemonReqCreate_Pre_Name_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsRatemonReqCreate_Pre_Id_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsRatemonReqCreate_Pre_Id_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsRatemonReqCreate_Pre_Free_Yes;
+ ctx->Map.pcs[ 2 ] < RtemsRatemonReqCreate_Pre_Free_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ ctx->Map.entry = RtemsRatemonReqCreate_PopEntry( ctx );
+ RtemsRatemonReqCreate_TestVariant( ctx );
+ RtemsRatemonReqCreate_Cleanup( ctx );
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-ratemon-delete.c b/testsuites/validation/tc-ratemon-delete.c
new file mode 100644
index 0000000000..93e863f023
--- /dev/null
+++ b/testsuites/validation/tc-ratemon-delete.c
@@ -0,0 +1,368 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsRatemonReqDelete
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsRatemonReqDelete spec:/rtems/ratemon/req/delete
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsRatemonReqDelete_Pre_Id_NoObj,
+ RtemsRatemonReqDelete_Pre_Id_Period,
+ RtemsRatemonReqDelete_Pre_Id_NA
+} RtemsRatemonReqDelete_Pre_Id;
+
+typedef enum {
+ RtemsRatemonReqDelete_Post_Status_Ok,
+ RtemsRatemonReqDelete_Post_Status_InvId,
+ RtemsRatemonReqDelete_Post_Status_NA
+} RtemsRatemonReqDelete_Post_Status;
+
+typedef enum {
+ RtemsRatemonReqDelete_Post_Name_Valid,
+ RtemsRatemonReqDelete_Post_Name_Invalid,
+ RtemsRatemonReqDelete_Post_Name_NA
+} RtemsRatemonReqDelete_Post_Name;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Post_Status : 2;
+ uint8_t Post_Name : 2;
+} RtemsRatemonReqDelete_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/ratemon/req/delete test case.
+ */
+typedef struct {
+ rtems_id period_id;
+
+ rtems_id id;
+
+ rtems_status_code status;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsRatemonReqDelete_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsRatemonReqDelete_Context;
+
+static RtemsRatemonReqDelete_Context
+ RtemsRatemonReqDelete_Instance;
+
+static const char * const RtemsRatemonReqDelete_PreDesc_Id[] = {
+ "NoObj",
+ "Period",
+ "NA"
+};
+
+static const char * const * const RtemsRatemonReqDelete_PreDesc[] = {
+ RtemsRatemonReqDelete_PreDesc_Id,
+ NULL
+};
+
+#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+static void RtemsRatemonReqDelete_Pre_Id_Prepare(
+ RtemsRatemonReqDelete_Context *ctx,
+ RtemsRatemonReqDelete_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqDelete_Pre_Id_NoObj: {
+ /*
+ * While the ``id`` parameter is not associated with a period.
+ */
+ ctx->id = 0;
+ break;
+ }
+
+ case RtemsRatemonReqDelete_Pre_Id_Period: {
+ /*
+ * While the ``id`` parameter is associated with a period.
+ */
+ ctx->id = ctx->period_id;
+ break;
+ }
+
+ case RtemsRatemonReqDelete_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqDelete_Post_Status_Check(
+ RtemsRatemonReqDelete_Context *ctx,
+ RtemsRatemonReqDelete_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqDelete_Post_Status_Ok: {
+ /*
+ * The return status of rtems_rate_monotonic_delete() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ ctx->period_id = 0;
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsRatemonReqDelete_Post_Status_InvId: {
+ /*
+ * The return status of rtems_rate_monotonic_delete() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsRatemonReqDelete_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqDelete_Post_Name_Check(
+ RtemsRatemonReqDelete_Context *ctx,
+ RtemsRatemonReqDelete_Post_Name state
+)
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ switch ( state ) {
+ case RtemsRatemonReqDelete_Post_Name_Valid: {
+ /*
+ * The unique object name shall identify a period.
+ */
+ id = 0;
+ sc = rtems_rate_monotonic_ident( NAME, &id );
+ T_rsc_success( sc );
+ T_eq_u32( id, ctx->period_id );
+ break;
+ }
+
+ case RtemsRatemonReqDelete_Post_Name_Invalid: {
+ /*
+ * The unique object name shall not identify a period.
+ */
+ sc = rtems_rate_monotonic_ident( NAME, &id );
+ T_rsc( sc, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsRatemonReqDelete_Post_Name_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqDelete_Setup( RtemsRatemonReqDelete_Context *ctx )
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+}
+
+static void RtemsRatemonReqDelete_Setup_Wrap( void *arg )
+{
+ RtemsRatemonReqDelete_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsRatemonReqDelete_Setup( ctx );
+}
+
+static void RtemsRatemonReqDelete_Teardown(
+ RtemsRatemonReqDelete_Context *ctx
+)
+{
+ if ( ctx->period_id != 0 ) {
+ rtems_status_code sc;
+
+ sc = rtems_rate_monotonic_delete( ctx->period_id );
+ T_rsc_success( sc );
+ }
+}
+
+static void RtemsRatemonReqDelete_Teardown_Wrap( void *arg )
+{
+ RtemsRatemonReqDelete_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsRatemonReqDelete_Teardown( ctx );
+}
+
+static void RtemsRatemonReqDelete_Prepare( RtemsRatemonReqDelete_Context *ctx )
+{
+ if ( ctx->period_id == 0 ) {
+ rtems_status_code sc;
+
+ sc = rtems_rate_monotonic_create( NAME, &ctx->period_id );
+ T_rsc_success( sc );
+ }
+}
+
+static void RtemsRatemonReqDelete_Action( RtemsRatemonReqDelete_Context *ctx )
+{
+ ctx->status = rtems_rate_monotonic_delete( ctx->id );
+}
+
+static const RtemsRatemonReqDelete_Entry
+RtemsRatemonReqDelete_Entries[] = {
+ { 0, 0, RtemsRatemonReqDelete_Post_Status_InvId,
+ RtemsRatemonReqDelete_Post_Name_Valid },
+ { 0, 0, RtemsRatemonReqDelete_Post_Status_Ok,
+ RtemsRatemonReqDelete_Post_Name_Invalid }
+};
+
+static const uint8_t
+RtemsRatemonReqDelete_Map[] = {
+ 0, 1
+};
+
+static size_t RtemsRatemonReqDelete_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsRatemonReqDelete_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsRatemonReqDelete_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsRatemonReqDelete_Fixture = {
+ .setup = RtemsRatemonReqDelete_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsRatemonReqDelete_Teardown_Wrap,
+ .scope = RtemsRatemonReqDelete_Scope,
+ .initial_context = &RtemsRatemonReqDelete_Instance
+};
+
+static inline RtemsRatemonReqDelete_Entry RtemsRatemonReqDelete_PopEntry(
+ RtemsRatemonReqDelete_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsRatemonReqDelete_Entries[
+ RtemsRatemonReqDelete_Map[ index ]
+ ];
+}
+
+static void RtemsRatemonReqDelete_TestVariant(
+ RtemsRatemonReqDelete_Context *ctx
+)
+{
+ RtemsRatemonReqDelete_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsRatemonReqDelete_Action( ctx );
+ RtemsRatemonReqDelete_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsRatemonReqDelete_Post_Name_Check( ctx, ctx->Map.entry.Post_Name );
+}
+
+/**
+ * @fn void T_case_body_RtemsRatemonReqDelete( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsRatemonReqDelete, &RtemsRatemonReqDelete_Fixture )
+{
+ RtemsRatemonReqDelete_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsRatemonReqDelete_Pre_Id_NoObj;
+ ctx->Map.pcs[ 0 ] < RtemsRatemonReqDelete_Pre_Id_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = RtemsRatemonReqDelete_PopEntry( ctx );
+ RtemsRatemonReqDelete_Prepare( ctx );
+ RtemsRatemonReqDelete_TestVariant( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-ratemon-get-status.c b/testsuites/validation/tc-ratemon-get-status.c
new file mode 100644
index 0000000000..750654e2c9
--- /dev/null
+++ b/testsuites/validation/tc-ratemon-get-status.c
@@ -0,0 +1,1170 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsRatemonReqGetStatus
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/cpuuse.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsRatemonReqGetStatus spec:/rtems/ratemon/req/get-status
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ * @ingroup TestsuitesValidationOneCpu0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsRatemonReqGetStatus_Pre_StatusAddr_Valid,
+ RtemsRatemonReqGetStatus_Pre_StatusAddr_Null,
+ RtemsRatemonReqGetStatus_Pre_StatusAddr_NA
+} RtemsRatemonReqGetStatus_Pre_StatusAddr;
+
+typedef enum {
+ RtemsRatemonReqGetStatus_Pre_Id_Valid,
+ RtemsRatemonReqGetStatus_Pre_Id_Invalid,
+ RtemsRatemonReqGetStatus_Pre_Id_NA
+} RtemsRatemonReqGetStatus_Pre_Id;
+
+typedef enum {
+ RtemsRatemonReqGetStatus_Pre_State_Inactive,
+ RtemsRatemonReqGetStatus_Pre_State_Active,
+ RtemsRatemonReqGetStatus_Pre_State_Expired,
+ RtemsRatemonReqGetStatus_Pre_State_NA
+} RtemsRatemonReqGetStatus_Pre_State;
+
+typedef enum {
+ RtemsRatemonReqGetStatus_Pre_Elapsed_Time,
+ RtemsRatemonReqGetStatus_Pre_Elapsed_NA
+} RtemsRatemonReqGetStatus_Pre_Elapsed;
+
+typedef enum {
+ RtemsRatemonReqGetStatus_Pre_Consumed_CpuTime,
+ RtemsRatemonReqGetStatus_Pre_Consumed_NA
+} RtemsRatemonReqGetStatus_Pre_Consumed;
+
+typedef enum {
+ RtemsRatemonReqGetStatus_Pre_Postponed_Zero,
+ RtemsRatemonReqGetStatus_Pre_Postponed_One,
+ RtemsRatemonReqGetStatus_Pre_Postponed_Several,
+ RtemsRatemonReqGetStatus_Pre_Postponed_NA
+} RtemsRatemonReqGetStatus_Pre_Postponed;
+
+typedef enum {
+ RtemsRatemonReqGetStatus_Post_Status_Ok,
+ RtemsRatemonReqGetStatus_Post_Status_InvAddr,
+ RtemsRatemonReqGetStatus_Post_Status_InvId,
+ RtemsRatemonReqGetStatus_Post_Status_NA
+} RtemsRatemonReqGetStatus_Post_Status;
+
+typedef enum {
+ RtemsRatemonReqGetStatus_Post_Owner_OwnerTask,
+ RtemsRatemonReqGetStatus_Post_Owner_Nop,
+ RtemsRatemonReqGetStatus_Post_Owner_NA
+} RtemsRatemonReqGetStatus_Post_Owner;
+
+typedef enum {
+ RtemsRatemonReqGetStatus_Post_State_Inactive,
+ RtemsRatemonReqGetStatus_Post_State_Active,
+ RtemsRatemonReqGetStatus_Post_State_Expired,
+ RtemsRatemonReqGetStatus_Post_State_Nop,
+ RtemsRatemonReqGetStatus_Post_State_NA
+} RtemsRatemonReqGetStatus_Post_State;
+
+typedef enum {
+ RtemsRatemonReqGetStatus_Post_Elapsed_Time,
+ RtemsRatemonReqGetStatus_Post_Elapsed_Zero,
+ RtemsRatemonReqGetStatus_Post_Elapsed_Nop,
+ RtemsRatemonReqGetStatus_Post_Elapsed_NA
+} RtemsRatemonReqGetStatus_Post_Elapsed;
+
+typedef enum {
+ RtemsRatemonReqGetStatus_Post_Consumed_CpuTime,
+ RtemsRatemonReqGetStatus_Post_Consumed_Zero,
+ RtemsRatemonReqGetStatus_Post_Consumed_Nop,
+ RtemsRatemonReqGetStatus_Post_Consumed_NA
+} RtemsRatemonReqGetStatus_Post_Consumed;
+
+typedef enum {
+ RtemsRatemonReqGetStatus_Post_Postponed_Zero,
+ RtemsRatemonReqGetStatus_Post_Postponed_One,
+ RtemsRatemonReqGetStatus_Post_Postponed_Several,
+ RtemsRatemonReqGetStatus_Post_Postponed_Nop,
+ RtemsRatemonReqGetStatus_Post_Postponed_NA
+} RtemsRatemonReqGetStatus_Post_Postponed;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_StatusAddr_NA : 1;
+ uint32_t Pre_Id_NA : 1;
+ uint32_t Pre_State_NA : 1;
+ uint32_t Pre_Elapsed_NA : 1;
+ uint32_t Pre_Consumed_NA : 1;
+ uint32_t Pre_Postponed_NA : 1;
+ uint32_t Post_Status : 2;
+ uint32_t Post_Owner : 2;
+ uint32_t Post_State : 3;
+ uint32_t Post_Elapsed : 2;
+ uint32_t Post_Consumed : 2;
+ uint32_t Post_Postponed : 3;
+} RtemsRatemonReqGetStatus_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/ratemon/req/get-status test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a valid identifier of a period.
+ */
+ rtems_id period_id;
+
+ /**
+ * @brief This member contains the previous timecounter handler to restore.
+ */
+ GetTimecountHandler previous_timecounter_handler;
+
+ /**
+ * @brief This member is used to receive the
+ * rtems_rate_monotonic_period_status from the action.
+ */
+ rtems_rate_monotonic_period_status period_status;
+
+ /**
+ * @brief This member specifies the ``id`` parameter for the action.
+ */
+ rtems_id id_param;
+
+ /**
+ * @brief This member specifies the ``status`` parameter for the action.
+ */
+ rtems_rate_monotonic_period_status *status_param;
+
+ /**
+ * @brief This member contains the returned status code of the action.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member contains the task identifier of the owner task.
+ */
+ rtems_id task_id;
+
+ /**
+ * @brief This member contains the state before the action.
+ */
+ rtems_rate_monotonic_period_states previous_state;
+
+ /**
+ * @brief If the rtems_cpu_usage_reset() directive should be called before
+ * rtems_rate_monotonic_get_status(), this member contains a pointer to it.
+ */
+ void (*do_reset)( void );
+
+ /**
+ * @brief This member contains the CLOCK_MONOTONIC time elapsed.
+ */
+ struct timespec elapsed;
+
+ /**
+ * @brief This member contains the CPU time consumed by the owner task.
+ */
+ struct timespec consumed;
+
+ /**
+ * @brief This member contains the number of postponed jobs.
+ */
+ uint32_t postponed_jobs_count;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 6 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 6 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsRatemonReqGetStatus_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsRatemonReqGetStatus_Context;
+
+static RtemsRatemonReqGetStatus_Context
+ RtemsRatemonReqGetStatus_Instance;
+
+static const char * const RtemsRatemonReqGetStatus_PreDesc_StatusAddr[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsRatemonReqGetStatus_PreDesc_Id[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsRatemonReqGetStatus_PreDesc_State[] = {
+ "Inactive",
+ "Active",
+ "Expired",
+ "NA"
+};
+
+static const char * const RtemsRatemonReqGetStatus_PreDesc_Elapsed[] = {
+ "Time",
+ "NA"
+};
+
+static const char * const RtemsRatemonReqGetStatus_PreDesc_Consumed[] = {
+ "CpuTime",
+ "NA"
+};
+
+static const char * const RtemsRatemonReqGetStatus_PreDesc_Postponed[] = {
+ "Zero",
+ "One",
+ "Several",
+ "NA"
+};
+
+static const char * const * const RtemsRatemonReqGetStatus_PreDesc[] = {
+ RtemsRatemonReqGetStatus_PreDesc_StatusAddr,
+ RtemsRatemonReqGetStatus_PreDesc_Id,
+ RtemsRatemonReqGetStatus_PreDesc_State,
+ RtemsRatemonReqGetStatus_PreDesc_Elapsed,
+ RtemsRatemonReqGetStatus_PreDesc_Consumed,
+ RtemsRatemonReqGetStatus_PreDesc_Postponed,
+ NULL
+};
+
+static const rtems_id initial_owner = 0xFFFFFFFF;
+static const rtems_rate_monotonic_period_states initial_state =
+ (rtems_rate_monotonic_period_states) 0xFFFFFFFF;
+static const struct timespec initial_period = { 0xFFFFFFFF, 0xFFFFFFFF };
+static const uint32_t initial_postponed_jobs_count = 0xFFFFFFFF;
+static const rtems_interval period_length = 5;
+static const uint32_t elapsed_cpu_ticks = 3;
+
+static uint32_t FreezeTime( void )
+{
+ return GetTimecountCounter() - 1;
+}
+
+static void TickTheClock(
+ RtemsRatemonReqGetStatus_Context *ctx,
+ uint32_t ticks
+)
+{
+ uint32_t i;
+ for ( i = 0; i < ticks; ++i ) {
+ TimecounterTick();
+ }
+ ctx->elapsed.tv_nsec +=
+ rtems_configuration_get_nanoseconds_per_tick() * ticks;
+}
+
+static void CreatePostponedJobs(
+ RtemsRatemonReqGetStatus_Context *ctx,
+ uint32_t jobs_count
+)
+{
+ rtems_status_code status;
+ ctx->postponed_jobs_count = jobs_count;
+ if ( ctx->previous_state == RATE_MONOTONIC_ACTIVE ) {
+ jobs_count++;
+ TickTheClock( ctx, jobs_count * period_length );
+ status = rtems_rate_monotonic_period( ctx->period_id, period_length );
+ T_rsc( status, RTEMS_TIMEOUT );
+ } else {
+ /* ctx->previous_state == RATE_MONOTONIC_INACTIVE || _EXPIRED */
+ TickTheClock( ctx, jobs_count * period_length );
+ }
+ ctx->consumed.tv_nsec +=
+ rtems_configuration_get_nanoseconds_per_tick() *
+ jobs_count * period_length;
+}
+
+static void RtemsRatemonReqGetStatus_Pre_StatusAddr_Prepare(
+ RtemsRatemonReqGetStatus_Context *ctx,
+ RtemsRatemonReqGetStatus_Pre_StatusAddr state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqGetStatus_Pre_StatusAddr_Valid: {
+ /*
+ * While the ``status`` parameter references an object of type
+ * rtems_rate_monotonic_period_status.
+ */
+ ctx->status_param = &ctx->period_status;
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Pre_StatusAddr_Null: {
+ /*
+ * While the ``status`` parameter is NULL.
+ */
+ ctx->status_param = NULL;
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Pre_StatusAddr_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqGetStatus_Pre_Id_Prepare(
+ RtemsRatemonReqGetStatus_Context *ctx,
+ RtemsRatemonReqGetStatus_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqGetStatus_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter is valid.
+ */
+ ctx->id_param = ctx->period_id;
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is invalid.
+ */
+ ctx->id_param = RTEMS_ID_NONE;
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqGetStatus_Pre_State_Prepare(
+ RtemsRatemonReqGetStatus_Context *ctx,
+ RtemsRatemonReqGetStatus_Pre_State state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqGetStatus_Pre_State_Inactive: {
+ /*
+ * While the ``id`` parameter references an period object in inactive
+ * state.
+ */
+ /* Nothing to do here as the period is newly created. */
+ ctx->previous_state = RATE_MONOTONIC_INACTIVE;
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Pre_State_Active: {
+ /*
+ * While the ``id`` parameter references an period object in active
+ * state.
+ */
+ rtems_status_code status;
+ status = rtems_rate_monotonic_period( ctx->period_id, period_length );
+ T_rsc_success( status );
+ ctx->previous_state = RATE_MONOTONIC_ACTIVE;
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Pre_State_Expired: {
+ /*
+ * While the ``id`` parameter references an period object in expired
+ * state.
+ */
+ rtems_status_code status;
+ status = rtems_rate_monotonic_period( ctx->period_id, period_length );
+ T_rsc_success( status );
+ ctx->previous_state = RATE_MONOTONIC_EXPIRED;
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Pre_State_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqGetStatus_Pre_Elapsed_Prepare(
+ RtemsRatemonReqGetStatus_Context *ctx,
+ RtemsRatemonReqGetStatus_Pre_Elapsed state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqGetStatus_Pre_Elapsed_Time: {
+ /*
+ * While a certain time of the CLOCK_MONOTONIC has elapsed.
+ */
+ /* Time elapsed while having a CPU is added below in "CpuTime". */
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Pre_Elapsed_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqGetStatus_Pre_Consumed_Prepare(
+ RtemsRatemonReqGetStatus_Context *ctx,
+ RtemsRatemonReqGetStatus_Pre_Consumed state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqGetStatus_Pre_Consumed_CpuTime: {
+ /*
+ * While the owner task has consumed a certain amount of CPU time.
+ */
+ TickTheClock( ctx, elapsed_cpu_ticks );
+ ctx->consumed.tv_nsec +=
+ rtems_configuration_get_nanoseconds_per_tick() * elapsed_cpu_ticks;
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Pre_Consumed_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqGetStatus_Pre_Postponed_Prepare(
+ RtemsRatemonReqGetStatus_Context *ctx,
+ RtemsRatemonReqGetStatus_Pre_Postponed state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqGetStatus_Pre_Postponed_Zero: {
+ /*
+ * While the period is not in expired state.
+ */
+ ctx->postponed_jobs_count = 0;
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Pre_Postponed_One: {
+ /*
+ * While there is one postponed job.
+ */
+ CreatePostponedJobs( ctx, 1 );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Pre_Postponed_Several: {
+ /*
+ * While there are two or more postponed job.
+ */
+ CreatePostponedJobs( ctx, 5 );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Pre_Postponed_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqGetStatus_Post_Status_Check(
+ RtemsRatemonReqGetStatus_Context *ctx,
+ RtemsRatemonReqGetStatus_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqGetStatus_Post_Status_Ok: {
+ /*
+ * The return status of rtems_rate_monotonic_get_status() shall be
+ * RTEMS_SUCCESSFUL
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_rate_monotonic_get_status() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_Status_InvId: {
+ /*
+ * The return status of rtems_rate_monotonic_get_status() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqGetStatus_Post_Owner_Check(
+ RtemsRatemonReqGetStatus_Context *ctx,
+ RtemsRatemonReqGetStatus_Post_Owner state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqGetStatus_Post_Owner_OwnerTask: {
+ /*
+ * The value of the member owner of the object referenced by the
+ * ``status`` parameter shall be set to the object identifier of the
+ * owner task of the period after the return of the
+ * rtems_rate_monotonic_get_status() call.
+ */
+ T_eq_u32( ctx->period_status.owner, ctx->task_id );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_Owner_Nop: {
+ /*
+ * Objects referenced by the ``status`` parameter in past call to
+ * rtems_rate_monotonic_get_status() shall not be accessed by the
+ * rtems_rate_monotonic_get_status() call (see also Nop).
+ */
+ T_eq_u32( ctx->period_status.owner, initial_owner );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_Owner_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqGetStatus_Post_State_Check(
+ RtemsRatemonReqGetStatus_Context *ctx,
+ RtemsRatemonReqGetStatus_Post_State state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqGetStatus_Post_State_Inactive: {
+ /*
+ * The value of the member state of the object referenced by the
+ * ``status`` parameter shall be set to RATE_MONOTONIC_INACTIVE after the
+ * return of the rtems_rate_monotonic_get_status() call. (See also
+ * inactive)
+ */
+ T_eq_int( ctx->period_status.state, RATE_MONOTONIC_INACTIVE );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_State_Active: {
+ /*
+ * The value of the member state of the object referenced by the
+ * ``status`` parameter shall be set to RATE_MONOTONIC_ACTIVE after the
+ * return of the rtems_rate_monotonic_get_status() call. (See also
+ * active)
+ */
+ T_eq_int( ctx->period_status.state, RATE_MONOTONIC_ACTIVE );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_State_Expired: {
+ /*
+ * The value of the member state of the object referenced by the
+ * ``status`` parameter shall be set to RATE_MONOTONIC_EXPIRED after the
+ * return of the rtems_rate_monotonic_get_status() call. (See also
+ * expired)
+ */
+ T_eq_int( ctx->period_status.state, RATE_MONOTONIC_EXPIRED );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_State_Nop: {
+ /*
+ * Objects referenced by the ``status`` parameter in past calls to
+ * rtems_rate_monotonic_get_status() shall not be accessed by the
+ * rtems_rate_monotonic_get_status() call (see also Nop).
+ */
+ T_eq_u32( ctx->period_status.state, initial_state );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_State_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqGetStatus_Post_Elapsed_Check(
+ RtemsRatemonReqGetStatus_Context *ctx,
+ RtemsRatemonReqGetStatus_Post_Elapsed state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqGetStatus_Post_Elapsed_Time: {
+ /*
+ * The value of the member since_last_period of the object referenced by
+ * the ``status`` parameter shall be set to the time elapsed.
+ */
+ T_log( T_VERBOSE, "Elapsed: %lld.%ld (expected: %lld.%ld)",
+ ctx->period_status.since_last_period.tv_sec,
+ ctx->period_status.since_last_period.tv_nsec,
+ ctx->elapsed.tv_sec,
+ ctx->elapsed.tv_nsec
+ );
+ T_eq_u64(
+ ctx->period_status.since_last_period.tv_sec,
+ ctx->elapsed.tv_sec
+ );
+ /* period_status integer arithmetic is plagued by a rounding error. */
+ T_le_long(
+ ctx->period_status.since_last_period.tv_nsec,
+ ctx->elapsed.tv_nsec + 1
+ );
+ T_ge_long(
+ ctx->period_status.since_last_period.tv_nsec,
+ ctx->elapsed.tv_nsec - 1
+ );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_Elapsed_Zero: {
+ /*
+ * The value of the member since_last_period of the object referenced by
+ * the ``status`` parameter shall be set to 0.
+ */
+ T_eq_u64( ctx->period_status.since_last_period.tv_sec, 0 );
+ T_eq_long( ctx->period_status.since_last_period.tv_nsec, 0 );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_Elapsed_Nop: {
+ /*
+ * Objects referenced by the ``status`` parameter in past calls to
+ * rtems_rate_monotonic_get_status() shall not be accessed by the
+ * rtems_rate_monotonic_get_status() call (see also Nop).
+ */
+ T_eq_u64(
+ ctx->period_status.since_last_period.tv_sec,
+ initial_period.tv_sec
+ );
+ T_eq_long(
+ ctx->period_status.since_last_period.tv_nsec,
+ initial_period.tv_nsec
+ );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_Elapsed_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqGetStatus_Post_Consumed_Check(
+ RtemsRatemonReqGetStatus_Context *ctx,
+ RtemsRatemonReqGetStatus_Post_Consumed state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqGetStatus_Post_Consumed_CpuTime: {
+ /*
+ * The value of the member executed_since_last_period of the object
+ * referenced by the ``status`` parameter shall be set to the CPU time
+ * consumed by the owner task.
+ */
+ T_log( T_VERBOSE, "CPU elapsed: %lld.%ld (expected: %lld.%ld)",
+ ctx->period_status.executed_since_last_period.tv_sec,
+ ctx->period_status.executed_since_last_period.tv_nsec,
+ ctx->consumed.tv_sec,
+ ctx->consumed.tv_nsec
+ );
+ T_eq_u64(
+ ctx->period_status.executed_since_last_period.tv_sec,
+ ctx->consumed.tv_sec
+ );
+ /* period_status integer arithmetic is plagued by a rounding error. */
+ T_le_long(
+ ctx->period_status.executed_since_last_period.tv_nsec,
+ ctx->consumed.tv_nsec + 1
+ );
+ T_ge_long(
+ ctx->period_status.executed_since_last_period.tv_nsec,
+ ctx->consumed.tv_nsec - 1
+ );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_Consumed_Zero: {
+ /*
+ * The value of the member since_last_period of the object referenced by
+ * the ``status`` parameter shall be set to 0.
+ */
+ T_eq_u64( ctx->period_status.executed_since_last_period.tv_sec, 0 );
+ T_eq_long( ctx->period_status.executed_since_last_period.tv_nsec, 0 );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_Consumed_Nop: {
+ /*
+ * Objects referenced by the ``status`` parameter in past calls to
+ * rtems_rate_monotonic_get_status() shall not be accessed by the
+ * rtems_rate_monotonic_get_status() call (see also Nop).
+ */
+ T_eq_u64(
+ ctx->period_status.executed_since_last_period.tv_sec,
+ initial_period.tv_sec
+ );
+ T_eq_long(
+ ctx->period_status.executed_since_last_period.tv_nsec,
+ initial_period.tv_nsec
+ );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_Consumed_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqGetStatus_Post_Postponed_Check(
+ RtemsRatemonReqGetStatus_Context *ctx,
+ RtemsRatemonReqGetStatus_Post_Postponed state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqGetStatus_Post_Postponed_Zero: {
+ /*
+ * The value of the member postponed_jobs_count of the object referenced
+ * by the ``status`` parameter shall be set to 0 after the return of the
+ * rtems_rate_monotonic_get_status() call.
+ */
+ T_eq_u32( ctx->period_status.postponed_jobs_count, 0 );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_Postponed_One: {
+ /*
+ * The value of the member postponed_jobs_count of the object referenced
+ * by the ``status`` parameter shall be set to the number of postponed
+ * jobs (here 1) after the return of the
+ * rtems_rate_monotonic_get_status() call.
+ */
+ T_eq_u32( ctx->period_status.postponed_jobs_count, 1 );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_Postponed_Several: {
+ /*
+ * The value of the member postponed_jobs_count of the object referenced
+ * by the ``status`` parameter shall be set to the number of postponed
+ * jobs after the return of the rtems_rate_monotonic_get_status() call.
+ */
+ T_eq_u32(
+ ctx->period_status.postponed_jobs_count,
+ ctx->postponed_jobs_count
+ );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_Postponed_Nop: {
+ /*
+ * Objects referenced by the ``status`` parameter in past calls to
+ * rtems_rate_monotonic_get_status() shall not be accessed by the
+ * rtems_rate_monotonic_get_status() call (see also Nop).
+ */
+ T_eq_u32( ctx->period_status.postponed_jobs_count,
+ initial_postponed_jobs_count );
+ break;
+ }
+
+ case RtemsRatemonReqGetStatus_Post_Postponed_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqGetStatus_Setup(
+ RtemsRatemonReqGetStatus_Context *ctx
+)
+{
+ ctx->previous_timecounter_handler = SetGetTimecountHandler( FreezeTime );
+ ctx->task_id = rtems_task_self();
+}
+
+static void RtemsRatemonReqGetStatus_Setup_Wrap( void *arg )
+{
+ RtemsRatemonReqGetStatus_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsRatemonReqGetStatus_Setup( ctx );
+}
+
+static void RtemsRatemonReqGetStatus_Teardown(
+ RtemsRatemonReqGetStatus_Context *ctx
+)
+{
+ SetGetTimecountHandler( ctx->previous_timecounter_handler );
+}
+
+static void RtemsRatemonReqGetStatus_Teardown_Wrap( void *arg )
+{
+ RtemsRatemonReqGetStatus_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsRatemonReqGetStatus_Teardown( ctx );
+}
+
+static void RtemsRatemonReqGetStatus_Prepare(
+ RtemsRatemonReqGetStatus_Context *ctx
+)
+{
+ rtems_status_code status;
+ status = rtems_rate_monotonic_create(
+ rtems_build_name( 'R', 'M', 'O', 'N' ),
+ &ctx->period_id
+ );
+ T_rsc_success( status );
+
+ ctx->period_status = (rtems_rate_monotonic_period_status) {
+ .owner = initial_owner,
+ .state = initial_state,
+ .since_last_period = initial_period,
+ .executed_since_last_period = initial_period,
+ .postponed_jobs_count = initial_postponed_jobs_count
+ };
+
+ ctx->elapsed.tv_sec = 0;
+ ctx->elapsed.tv_nsec = 0;
+ ctx->consumed.tv_sec = 0;
+ ctx->consumed.tv_nsec = 0;
+ ctx->postponed_jobs_count = 0;
+ TimecounterTick();
+}
+
+static void RtemsRatemonReqGetStatus_Action(
+ RtemsRatemonReqGetStatus_Context *ctx
+)
+{
+ if ( ctx->do_reset != NULL ) {
+ ctx->do_reset();
+ }
+ ctx->status = rtems_rate_monotonic_get_status(
+ ctx->id_param,
+ ctx->status_param
+ );
+}
+
+static void RtemsRatemonReqGetStatus_Cleanup(
+ RtemsRatemonReqGetStatus_Context *ctx
+)
+{
+ T_rsc_success( rtems_rate_monotonic_delete( ctx->period_id ) );
+}
+
+static const RtemsRatemonReqGetStatus_Entry
+RtemsRatemonReqGetStatus_Entries[] = {
+ { 0, 0, 0, 0, 0, 0, 0, RtemsRatemonReqGetStatus_Post_Status_InvAddr,
+ RtemsRatemonReqGetStatus_Post_Owner_Nop,
+ RtemsRatemonReqGetStatus_Post_State_Nop,
+ RtemsRatemonReqGetStatus_Post_Elapsed_Nop,
+ RtemsRatemonReqGetStatus_Post_Consumed_Nop,
+ RtemsRatemonReqGetStatus_Post_Postponed_Nop },
+ { 1, 0, 0, 0, 0, 0, 0, RtemsRatemonReqGetStatus_Post_Status_NA,
+ RtemsRatemonReqGetStatus_Post_Owner_NA,
+ RtemsRatemonReqGetStatus_Post_State_NA,
+ RtemsRatemonReqGetStatus_Post_Elapsed_NA,
+ RtemsRatemonReqGetStatus_Post_Consumed_NA,
+ RtemsRatemonReqGetStatus_Post_Postponed_NA },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsRatemonReqGetStatus_Post_Status_InvId,
+ RtemsRatemonReqGetStatus_Post_Owner_Nop,
+ RtemsRatemonReqGetStatus_Post_State_Nop,
+ RtemsRatemonReqGetStatus_Post_Elapsed_Nop,
+ RtemsRatemonReqGetStatus_Post_Consumed_Nop,
+ RtemsRatemonReqGetStatus_Post_Postponed_Nop },
+ { 1, 0, 0, 0, 0, 0, 0, RtemsRatemonReqGetStatus_Post_Status_NA,
+ RtemsRatemonReqGetStatus_Post_Owner_NA,
+ RtemsRatemonReqGetStatus_Post_State_NA,
+ RtemsRatemonReqGetStatus_Post_Elapsed_NA,
+ RtemsRatemonReqGetStatus_Post_Consumed_NA,
+ RtemsRatemonReqGetStatus_Post_Postponed_NA },
+ { 0, 0, 0, 0, 0, 0, 1, RtemsRatemonReqGetStatus_Post_Status_InvAddr,
+ RtemsRatemonReqGetStatus_Post_Owner_Nop,
+ RtemsRatemonReqGetStatus_Post_State_Nop,
+ RtemsRatemonReqGetStatus_Post_Elapsed_Nop,
+ RtemsRatemonReqGetStatus_Post_Consumed_Nop,
+ RtemsRatemonReqGetStatus_Post_Postponed_Nop },
+ { 0, 0, 0, 0, 1, 1, 1, RtemsRatemonReqGetStatus_Post_Status_Ok,
+ RtemsRatemonReqGetStatus_Post_Owner_OwnerTask,
+ RtemsRatemonReqGetStatus_Post_State_Inactive,
+ RtemsRatemonReqGetStatus_Post_Elapsed_Zero,
+ RtemsRatemonReqGetStatus_Post_Consumed_Zero,
+ RtemsRatemonReqGetStatus_Post_Postponed_NA },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsRatemonReqGetStatus_Post_Status_Ok,
+ RtemsRatemonReqGetStatus_Post_Owner_OwnerTask,
+ RtemsRatemonReqGetStatus_Post_State_Active,
+ RtemsRatemonReqGetStatus_Post_Elapsed_Time,
+ RtemsRatemonReqGetStatus_Post_Consumed_CpuTime,
+ RtemsRatemonReqGetStatus_Post_Postponed_Zero },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsRatemonReqGetStatus_Post_Status_Ok,
+ RtemsRatemonReqGetStatus_Post_Owner_OwnerTask,
+ RtemsRatemonReqGetStatus_Post_State_Active,
+ RtemsRatemonReqGetStatus_Post_Elapsed_Time,
+ RtemsRatemonReqGetStatus_Post_Consumed_CpuTime,
+ RtemsRatemonReqGetStatus_Post_Postponed_One },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsRatemonReqGetStatus_Post_Status_Ok,
+ RtemsRatemonReqGetStatus_Post_Owner_OwnerTask,
+ RtemsRatemonReqGetStatus_Post_State_Active,
+ RtemsRatemonReqGetStatus_Post_Elapsed_Time,
+ RtemsRatemonReqGetStatus_Post_Consumed_CpuTime,
+ RtemsRatemonReqGetStatus_Post_Postponed_Several },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsRatemonReqGetStatus_Post_Status_Ok,
+ RtemsRatemonReqGetStatus_Post_Owner_OwnerTask,
+ RtemsRatemonReqGetStatus_Post_State_Expired,
+ RtemsRatemonReqGetStatus_Post_Elapsed_Time,
+ RtemsRatemonReqGetStatus_Post_Consumed_CpuTime,
+ RtemsRatemonReqGetStatus_Post_Postponed_One },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsRatemonReqGetStatus_Post_Status_Ok,
+ RtemsRatemonReqGetStatus_Post_Owner_OwnerTask,
+ RtemsRatemonReqGetStatus_Post_State_Expired,
+ RtemsRatemonReqGetStatus_Post_Elapsed_Time,
+ RtemsRatemonReqGetStatus_Post_Consumed_CpuTime,
+ RtemsRatemonReqGetStatus_Post_Postponed_Several },
+ { 0, 0, 0, 0, 0, 0, 1, RtemsRatemonReqGetStatus_Post_Status_InvId,
+ RtemsRatemonReqGetStatus_Post_Owner_Nop,
+ RtemsRatemonReqGetStatus_Post_State_Nop,
+ RtemsRatemonReqGetStatus_Post_Elapsed_Nop,
+ RtemsRatemonReqGetStatus_Post_Consumed_Nop,
+ RtemsRatemonReqGetStatus_Post_Postponed_Nop }
+};
+
+static const uint8_t
+RtemsRatemonReqGetStatus_Map[] = {
+ 5, 1, 1, 6, 7, 8, 3, 9, 10, 11, 1, 1, 2, 2, 2, 3, 2, 2, 4, 1, 1, 0, 0, 0, 3,
+ 0, 0, 4, 1, 1, 0, 0, 0, 3, 0, 0
+};
+
+static size_t RtemsRatemonReqGetStatus_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsRatemonReqGetStatus_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsRatemonReqGetStatus_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsRatemonReqGetStatus_Fixture = {
+ .setup = RtemsRatemonReqGetStatus_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsRatemonReqGetStatus_Teardown_Wrap,
+ .scope = RtemsRatemonReqGetStatus_Scope,
+ .initial_context = &RtemsRatemonReqGetStatus_Instance
+};
+
+static inline RtemsRatemonReqGetStatus_Entry RtemsRatemonReqGetStatus_PopEntry(
+ RtemsRatemonReqGetStatus_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsRatemonReqGetStatus_Entries[
+ RtemsRatemonReqGetStatus_Map[ index ]
+ ];
+}
+
+static void RtemsRatemonReqGetStatus_SetPreConditionStates(
+ RtemsRatemonReqGetStatus_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+
+ if ( ctx->Map.entry.Pre_Elapsed_NA ) {
+ ctx->Map.pcs[ 3 ] = RtemsRatemonReqGetStatus_Pre_Elapsed_NA;
+ } else {
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Consumed_NA ) {
+ ctx->Map.pcs[ 4 ] = RtemsRatemonReqGetStatus_Pre_Consumed_NA;
+ } else {
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Postponed_NA ) {
+ ctx->Map.pcs[ 5 ] = RtemsRatemonReqGetStatus_Pre_Postponed_NA;
+ } else {
+ ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
+ }
+}
+
+static void RtemsRatemonReqGetStatus_TestVariant(
+ RtemsRatemonReqGetStatus_Context *ctx
+)
+{
+ RtemsRatemonReqGetStatus_Pre_StatusAddr_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsRatemonReqGetStatus_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsRatemonReqGetStatus_Pre_State_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsRatemonReqGetStatus_Pre_Elapsed_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsRatemonReqGetStatus_Pre_Consumed_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsRatemonReqGetStatus_Pre_Postponed_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsRatemonReqGetStatus_Action( ctx );
+ RtemsRatemonReqGetStatus_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ RtemsRatemonReqGetStatus_Post_Owner_Check( ctx, ctx->Map.entry.Post_Owner );
+ RtemsRatemonReqGetStatus_Post_State_Check( ctx, ctx->Map.entry.Post_State );
+ RtemsRatemonReqGetStatus_Post_Elapsed_Check(
+ ctx,
+ ctx->Map.entry.Post_Elapsed
+ );
+ RtemsRatemonReqGetStatus_Post_Consumed_Check(
+ ctx,
+ ctx->Map.entry.Post_Consumed
+ );
+ RtemsRatemonReqGetStatus_Post_Postponed_Check(
+ ctx,
+ ctx->Map.entry.Post_Postponed
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsRatemonReqGetStatus( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsRatemonReqGetStatus,
+ &RtemsRatemonReqGetStatus_Fixture
+)
+{
+ RtemsRatemonReqGetStatus_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsRatemonReqGetStatus_Pre_StatusAddr_Valid;
+ ctx->Map.pci[ 0 ] < RtemsRatemonReqGetStatus_Pre_StatusAddr_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsRatemonReqGetStatus_Pre_Id_Valid;
+ ctx->Map.pci[ 1 ] < RtemsRatemonReqGetStatus_Pre_Id_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsRatemonReqGetStatus_Pre_State_Inactive;
+ ctx->Map.pci[ 2 ] < RtemsRatemonReqGetStatus_Pre_State_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = RtemsRatemonReqGetStatus_Pre_Elapsed_Time;
+ ctx->Map.pci[ 3 ] < RtemsRatemonReqGetStatus_Pre_Elapsed_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ for (
+ ctx->Map.pci[ 4 ] = RtemsRatemonReqGetStatus_Pre_Consumed_CpuTime;
+ ctx->Map.pci[ 4 ] < RtemsRatemonReqGetStatus_Pre_Consumed_NA;
+ ++ctx->Map.pci[ 4 ]
+ ) {
+ for (
+ ctx->Map.pci[ 5 ] = RtemsRatemonReqGetStatus_Pre_Postponed_Zero;
+ ctx->Map.pci[ 5 ] < RtemsRatemonReqGetStatus_Pre_Postponed_NA;
+ ++ctx->Map.pci[ 5 ]
+ ) {
+ ctx->Map.entry = RtemsRatemonReqGetStatus_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsRatemonReqGetStatus_SetPreConditionStates( ctx );
+ RtemsRatemonReqGetStatus_Prepare( ctx );
+ RtemsRatemonReqGetStatus_TestVariant( ctx );
+ RtemsRatemonReqGetStatus_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-ratemon-ident.c b/testsuites/validation/tc-ratemon-ident.c
new file mode 100644
index 0000000000..27a414a980
--- /dev/null
+++ b/testsuites/validation/tc-ratemon-ident.c
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsRatemonValIdent
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-object-ident-local.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsRatemonValIdent spec:/rtems/ratemon/val/ident
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Test the rtems_rate_monotonic_ident() directive.
+ *
+ * This test case performs the following actions:
+ *
+ * - Run the generic object identification tests for Classic API rate monotonic
+ * class objects defined by spec:/rtems/req/ident-local.
+ *
+ * @{
+ */
+
+#define NAME_LOCAL_OBJECT rtems_build_name( 'R', 'A', 'T', 'E' )
+
+static rtems_status_code ClassicRatemonIdentAction(
+ rtems_name name,
+ rtems_id *id
+)
+{
+ return rtems_rate_monotonic_ident( name, id );
+}
+
+/**
+ * @brief Run the generic object identification tests for Classic API rate
+ * monotonic class objects defined by spec:/rtems/req/ident-local.
+ */
+static void RtemsRatemonValIdent_Action_0( void )
+{
+ rtems_status_code sc;
+ rtems_id id_local_object;
+
+ sc = rtems_rate_monotonic_create(
+ NAME_LOCAL_OBJECT,
+ &id_local_object
+ );
+ T_assert_rsc_success( sc );
+
+ RtemsReqIdentLocal_Run(
+ id_local_object,
+ NAME_LOCAL_OBJECT,
+ ClassicRatemonIdentAction
+ );
+
+ sc = rtems_rate_monotonic_delete( id_local_object );
+ T_rsc_success( sc );
+}
+
+/**
+ * @fn void T_case_body_RtemsRatemonValIdent( void )
+ */
+T_TEST_CASE( RtemsRatemonValIdent )
+{
+ RtemsRatemonValIdent_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-ratemon-period.c b/testsuites/validation/tc-ratemon-period.c
new file mode 100644
index 0000000000..c8a73905c1
--- /dev/null
+++ b/testsuites/validation/tc-ratemon-period.c
@@ -0,0 +1,1273 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsRatemonReqPeriod
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsRatemonReqPeriod spec:/rtems/ratemon/req/period
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ * @ingroup TestsuitesValidationOneCpu0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsRatemonReqPeriod_Pre_Id_Valid,
+ RtemsRatemonReqPeriod_Pre_Id_Invalid,
+ RtemsRatemonReqPeriod_Pre_Id_NA
+} RtemsRatemonReqPeriod_Pre_Id;
+
+typedef enum {
+ RtemsRatemonReqPeriod_Pre_Caller_OwnerTask,
+ RtemsRatemonReqPeriod_Pre_Caller_OtherTask,
+ RtemsRatemonReqPeriod_Pre_Caller_NA
+} RtemsRatemonReqPeriod_Pre_Caller;
+
+typedef enum {
+ RtemsRatemonReqPeriod_Pre_Length_Ticks,
+ RtemsRatemonReqPeriod_Pre_Length_Status,
+ RtemsRatemonReqPeriod_Pre_Length_NA
+} RtemsRatemonReqPeriod_Pre_Length;
+
+typedef enum {
+ RtemsRatemonReqPeriod_Pre_State_Inactive,
+ RtemsRatemonReqPeriod_Pre_State_Active,
+ RtemsRatemonReqPeriod_Pre_State_Expired,
+ RtemsRatemonReqPeriod_Pre_State_NA
+} RtemsRatemonReqPeriod_Pre_State;
+
+typedef enum {
+ RtemsRatemonReqPeriod_Pre_Postponed_Zero,
+ RtemsRatemonReqPeriod_Pre_Postponed_One,
+ RtemsRatemonReqPeriod_Pre_Postponed_Several,
+ RtemsRatemonReqPeriod_Pre_Postponed_NA
+} RtemsRatemonReqPeriod_Pre_Postponed;
+
+typedef enum {
+ RtemsRatemonReqPeriod_Pre_InactiveCause_New,
+ RtemsRatemonReqPeriod_Pre_InactiveCause_Canceled,
+ RtemsRatemonReqPeriod_Pre_InactiveCause_NA
+} RtemsRatemonReqPeriod_Pre_InactiveCause;
+
+typedef enum {
+ RtemsRatemonReqPeriod_Post_Status_Ok,
+ RtemsRatemonReqPeriod_Post_Status_InvId,
+ RtemsRatemonReqPeriod_Post_Status_NotOwn,
+ RtemsRatemonReqPeriod_Post_Status_NotDef,
+ RtemsRatemonReqPeriod_Post_Status_TimeOut,
+ RtemsRatemonReqPeriod_Post_Status_NA
+} RtemsRatemonReqPeriod_Post_Status;
+
+typedef enum {
+ RtemsRatemonReqPeriod_Post_State_Inactive,
+ RtemsRatemonReqPeriod_Post_State_Active,
+ RtemsRatemonReqPeriod_Post_State_Expired,
+ RtemsRatemonReqPeriod_Post_State_Nop,
+ RtemsRatemonReqPeriod_Post_State_NA
+} RtemsRatemonReqPeriod_Post_State;
+
+typedef enum {
+ RtemsRatemonReqPeriod_Post_Postponed_Zero,
+ RtemsRatemonReqPeriod_Post_Postponed_OneOrMore,
+ RtemsRatemonReqPeriod_Post_Postponed_Nop,
+ RtemsRatemonReqPeriod_Post_Postponed_NA
+} RtemsRatemonReqPeriod_Post_Postponed;
+
+typedef enum {
+ RtemsRatemonReqPeriod_Post_Delay_None,
+ RtemsRatemonReqPeriod_Post_Delay_TillDeadline,
+ RtemsRatemonReqPeriod_Post_Delay_NA
+} RtemsRatemonReqPeriod_Post_Delay;
+
+typedef enum {
+ RtemsRatemonReqPeriod_Post_Scheduler_Called,
+ RtemsRatemonReqPeriod_Post_Scheduler_Nop,
+ RtemsRatemonReqPeriod_Post_Scheduler_NA
+} RtemsRatemonReqPeriod_Post_Scheduler;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_Id_NA : 1;
+ uint32_t Pre_Caller_NA : 1;
+ uint32_t Pre_Length_NA : 1;
+ uint32_t Pre_State_NA : 1;
+ uint32_t Pre_Postponed_NA : 1;
+ uint32_t Pre_InactiveCause_NA : 1;
+ uint32_t Post_Status : 3;
+ uint32_t Post_State : 3;
+ uint32_t Post_Postponed : 2;
+ uint32_t Post_Delay : 2;
+ uint32_t Post_Scheduler : 2;
+} RtemsRatemonReqPeriod_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/ratemon/req/period test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a valid identifier of a period.
+ */
+ rtems_id period_id;
+
+ /**
+ * @brief This member is used to receive the
+ * rtems_rate_monotonic_period_status after the action.
+ */
+ rtems_rate_monotonic_period_status period_status;
+
+ /**
+ * @brief This member specifies the ``id`` parameter for the action.
+ */
+ rtems_id id_param;
+
+ /**
+ * @brief This member specifies the ``length`` parameter for the action.
+ */
+ rtems_interval length_param;
+
+ /**
+ * @brief This member contains the returned status code of the action.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member contains the pointer to the function which executes the
+ * action.
+ *
+ * The action is either executed by the owner task or by the worker task
+ * depending on the function pointer used here. ``ctx_arg`` must be a
+ * pointer to this context structure.
+ */
+ uint32_t ( *do_action )( void *ctx, void (*todo)( void *ctx_arg ) );
+
+ /**
+ * @brief This member serves to pass the pointer to the function which the
+ * work owner task shall execute from function ``OwnerDoWork`` to function
+ * ``WorkerTask``.
+ */
+ void (*worker_todo)( void *ctx );
+
+ /**
+ * @brief This member contains the owner task identifier of the owner task.
+ */
+ rtems_id task_id;
+
+ /**
+ * @brief This member contains the owner task identifier of the worker task
+ * (which is not the owner task).
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member contains a backup of the task priority before the
+ * execution of this test.
+ */
+ rtems_id original_priority;
+
+ /**
+ * @brief This member contains the number of postponed jobs before the
+ * action.
+ */
+ uint32_t postponed_jobs_count;
+
+ /**
+ * @brief This member contains the state before the action.
+ */
+ rtems_rate_monotonic_period_states previous_state;
+
+ /**
+ * @brief This member contains the number of clock ticks passed since the
+ * test started.
+ */
+ uint32_t test_duration;
+
+ /**
+ * @brief This member contains the number of clock ticks passed since the
+ * test started till (before) the rtems_rate_monotonic_period() action is
+ * invoked.
+ */
+ uint32_t test_duration_till_action;
+
+ /**
+ * @brief This member contains the number of times the
+ * rtems_rate_monotonic_period() function returned since the test started.
+ */
+ uint32_t period_calls;
+
+ /**
+ * @brief This member contains the number of clock ticks which passed in the
+ * action till the rtems_rate_monotonic_period() function returned.
+ */
+ uint32_t action_duration;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 6 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 6 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsRatemonReqPeriod_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsRatemonReqPeriod_Context;
+
+static RtemsRatemonReqPeriod_Context
+ RtemsRatemonReqPeriod_Instance;
+
+static const char * const RtemsRatemonReqPeriod_PreDesc_Id[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsRatemonReqPeriod_PreDesc_Caller[] = {
+ "OwnerTask",
+ "OtherTask",
+ "NA"
+};
+
+static const char * const RtemsRatemonReqPeriod_PreDesc_Length[] = {
+ "Ticks",
+ "Status",
+ "NA"
+};
+
+static const char * const RtemsRatemonReqPeriod_PreDesc_State[] = {
+ "Inactive",
+ "Active",
+ "Expired",
+ "NA"
+};
+
+static const char * const RtemsRatemonReqPeriod_PreDesc_Postponed[] = {
+ "Zero",
+ "One",
+ "Several",
+ "NA"
+};
+
+static const char * const RtemsRatemonReqPeriod_PreDesc_InactiveCause[] = {
+ "New",
+ "Canceled",
+ "NA"
+};
+
+static const char * const * const RtemsRatemonReqPeriod_PreDesc[] = {
+ RtemsRatemonReqPeriod_PreDesc_Id,
+ RtemsRatemonReqPeriod_PreDesc_Caller,
+ RtemsRatemonReqPeriod_PreDesc_Length,
+ RtemsRatemonReqPeriod_PreDesc_State,
+ RtemsRatemonReqPeriod_PreDesc_Postponed,
+ RtemsRatemonReqPeriod_PreDesc_InactiveCause,
+ NULL
+};
+
+static const rtems_interval period_length = 5;
+static const rtems_task_priority background_task_priority = 100;
+static const rtems_task_priority foreground_task_priority = 10;
+static const rtems_event_set wake_main_task_event = RTEMS_EVENT_17;
+
+static void TickTheClock(
+ RtemsRatemonReqPeriod_Context *ctx,
+ uint32_t ticks
+)
+{
+ uint32_t i;
+ for ( i = 0; i < ticks; ++i ) {
+ TimecounterTick();
+ ctx->test_duration++;
+ }
+}
+
+static rtems_status_code CallPeriodFunction(
+ RtemsRatemonReqPeriod_Context *ctx,
+ rtems_id id,
+ rtems_interval length
+)
+{
+ rtems_status_code status;
+ status = rtems_rate_monotonic_period( id, length );
+ ctx->period_calls++;
+ return status;
+}
+
+static void CreatePeriod( void *ctx_in )
+{
+ RtemsRatemonReqPeriod_Context *ctx = ctx_in;
+ rtems_status_code status;
+ status = rtems_rate_monotonic_create(
+ rtems_build_name( 'R', 'M', 'O', 'N' ),
+ &ctx->period_id
+ );
+ T_rsc_success( status );
+}
+
+static void DeletePeriod( void *ctx_in )
+{
+ RtemsRatemonReqPeriod_Context *ctx = ctx_in;
+ T_rsc_success( rtems_rate_monotonic_delete( ctx->period_id ) );
+}
+
+static void CancelPeriod( void *ctx_in )
+{
+ RtemsRatemonReqPeriod_Context *ctx = ctx_in;
+ T_rsc_success( rtems_rate_monotonic_cancel( ctx->period_id ) );
+}
+
+static void CallPeriod( void *ctx_in )
+{
+ RtemsRatemonReqPeriod_Context *ctx = ctx_in;
+ T_rsc_success( CallPeriodFunction( ctx, ctx->period_id, period_length ) );
+}
+
+static void CallPeriodTimeout( void *ctx_in )
+{
+ RtemsRatemonReqPeriod_Context *ctx = ctx_in;
+ rtems_status_code status;
+ status = CallPeriodFunction( ctx, ctx->period_id, period_length );
+ T_rsc( status, RTEMS_TIMEOUT );
+}
+
+static void DoAction( void *ctx_in )
+{
+ RtemsRatemonReqPeriod_Context *ctx = ctx_in;
+ ctx->status = CallPeriodFunction( ctx, ctx->id_param, ctx->length_param );
+}
+
+static void WorkerTask( rtems_task_argument argument )
+{
+ RtemsRatemonReqPeriod_Context *ctx =
+ (RtemsRatemonReqPeriod_Context *) argument;
+ if ( ctx != NULL ) {
+ ctx->worker_todo( ctx );
+ T_rsc_success( rtems_event_send( ctx->task_id, wake_main_task_event ) );
+ }
+ T_rsc_success( rtems_task_suspend( RTEMS_SELF ) );
+}
+
+static uint32_t OwnerDoWork( void *ctx_in, void (*todo)( void *ctx_arg ) )
+{
+ RtemsRatemonReqPeriod_Context *ctx = ctx_in;
+ uint32_t ticks_to_wait = period_length + 1;
+ rtems_status_code status;
+ rtems_event_set event_set;
+
+ ctx->worker_todo = todo;
+ status = rtems_task_restart( ctx->worker_id, (rtems_task_argument) ctx );
+ T_rsc_success( status );
+
+ for ( ; ticks_to_wait > 0; --ticks_to_wait ) {
+ /* Check whether the worker finished executing the action */
+ status = rtems_event_receive(
+ RTEMS_PENDING_EVENTS,
+ RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
+ RTEMS_NO_TIMEOUT,
+ &event_set
+ );
+ T_rsc_success( status );
+
+ if ( ( event_set & wake_main_task_event ) == wake_main_task_event ) {
+ break;
+ }
+ TickTheClock( ctx, 1 );
+ }
+
+ /* Wait till the worker task finishes */
+ status = rtems_event_receive(
+ wake_main_task_event,
+ RTEMS_DEFAULT_OPTIONS,
+ RTEMS_NO_TIMEOUT,
+ &event_set
+ );
+ T_rsc_success( status );
+
+ return period_length + 1 - ticks_to_wait;
+}
+
+static uint32_t OtherDoWork( void *ctx_in, void (*todo)( void *ctx_arg ) )
+{
+ RtemsRatemonReqPeriod_Context *ctx = ctx_in;
+ todo( ctx );
+ /* Duration = 0 ticks as DoAction() does not call TickTheClock() */
+ return 0;
+}
+
+static void CreatePostponedJobs(
+ RtemsRatemonReqPeriod_Context *ctx,
+ uint32_t jobs_count
+)
+{
+ ctx->postponed_jobs_count = jobs_count;
+ if ( ctx->previous_state == RATE_MONOTONIC_ACTIVE ) {
+ TickTheClock( ctx, ( jobs_count + 1 ) * period_length );
+ OwnerDoWork( ctx, CallPeriodTimeout );
+ } else {
+ /* ctx->previous_state == RATE_MONOTONIC_INACTIVE || _EXPIRED */
+ TickTheClock( ctx, jobs_count * period_length );
+ }
+}
+
+static void RtemsRatemonReqPeriod_Pre_Id_Prepare(
+ RtemsRatemonReqPeriod_Context *ctx,
+ RtemsRatemonReqPeriod_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqPeriod_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter is valid.
+ */
+ ctx->id_param = ctx->period_id;
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is invalid.
+ */
+ ctx->id_param = RTEMS_ID_NONE;
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqPeriod_Pre_Caller_Prepare(
+ RtemsRatemonReqPeriod_Context *ctx,
+ RtemsRatemonReqPeriod_Pre_Caller state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqPeriod_Pre_Caller_OwnerTask: {
+ /*
+ * While the task invoking rtems_rate_monotonic_period() is the task
+ * which created the period - the owner task.
+ */
+ ctx->do_action = OwnerDoWork;
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Pre_Caller_OtherTask: {
+ /*
+ * While the task invoking rtems_rate_monotonic_period() is not the owner
+ * task.
+ */
+ ctx->do_action = OtherDoWork;
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Pre_Caller_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqPeriod_Pre_Length_Prepare(
+ RtemsRatemonReqPeriod_Context *ctx,
+ RtemsRatemonReqPeriod_Pre_Length state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqPeriod_Pre_Length_Ticks: {
+ /*
+ * While the ``length`` parameter is a number larger than 0.
+ *
+ * Note:
+ *
+ * * RTEMS_PERIOD_STATUS == 0
+ *
+ * * The ``length`` parameter of all calls to
+ * rtems_rate_monotonic_period() must have the same value (see
+ * interval).
+ */
+ ctx->length_param = period_length;
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Pre_Length_Status: {
+ /*
+ * While the ``length`` parameter is RTEMS_PERIOD_STATUS.
+ */
+ ctx->length_param = RTEMS_PERIOD_STATUS;
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Pre_Length_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqPeriod_Pre_State_Prepare(
+ RtemsRatemonReqPeriod_Context *ctx,
+ RtemsRatemonReqPeriod_Pre_State state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqPeriod_Pre_State_Inactive: {
+ /*
+ * While the ``id`` parameter references an period object in inactive
+ * state.
+ */
+ /* Nothing to do here as the period is newly created. */
+ ctx->previous_state = RATE_MONOTONIC_INACTIVE;
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Pre_State_Active: {
+ /*
+ * While the ``id`` parameter references an period object in active
+ * state.
+ */
+ OwnerDoWork( ctx, CallPeriod );
+ ctx->previous_state = RATE_MONOTONIC_ACTIVE;
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Pre_State_Expired: {
+ /*
+ * While the ``id`` parameter references an period object in expired
+ * state.
+ */
+ OwnerDoWork( ctx, CallPeriod );
+ ctx->previous_state = RATE_MONOTONIC_EXPIRED;
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Pre_State_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqPeriod_Pre_Postponed_Prepare(
+ RtemsRatemonReqPeriod_Context *ctx,
+ RtemsRatemonReqPeriod_Pre_Postponed state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqPeriod_Pre_Postponed_Zero: {
+ /*
+ * While there is no postponed job.
+ */
+ ctx->postponed_jobs_count = 0;
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Pre_Postponed_One: {
+ /*
+ * While there is one postponed job.
+ */
+ CreatePostponedJobs( ctx, 1 );
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Pre_Postponed_Several: {
+ /*
+ * While there are two or more postponed jobs.
+ */
+ CreatePostponedJobs( ctx, 5 );
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Pre_Postponed_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqPeriod_Pre_InactiveCause_Prepare(
+ RtemsRatemonReqPeriod_Context *ctx,
+ RtemsRatemonReqPeriod_Pre_InactiveCause state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqPeriod_Pre_InactiveCause_New: {
+ /*
+ * While rtems_rate_monotonic_period() has never been invoked with result
+ * RTEMS_SUCCESSFUL on the period object referenced by the ``id``
+ * parameter since that period object has been created.
+ */
+ /* Nothing to do here as the period is newly created. */
+ ctx->postponed_jobs_count = 0;
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Pre_InactiveCause_Canceled: {
+ /*
+ * While rtems_rate_monotonic_period() has never been invoked with result
+ * RTEMS_SUCCESSFUL on the period object referenced by the ``id``
+ * parameter since that period object has been canceled using
+ * rtems_rate_monotonic_cancel().
+ */
+ if ( ctx->period_calls == 0 ) {
+ OwnerDoWork( ctx, CallPeriod );
+ TickTheClock( ctx, ctx->postponed_jobs_count * period_length );
+ }
+ OwnerDoWork( ctx, CancelPeriod );
+ ctx->postponed_jobs_count = 0;
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Pre_InactiveCause_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqPeriod_Post_Status_Check(
+ RtemsRatemonReqPeriod_Context *ctx,
+ RtemsRatemonReqPeriod_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqPeriod_Post_Status_Ok: {
+ /*
+ * The return status of rtems_rate_monotonic_period() shall be
+ * RTEMS_SUCCESSFUL
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Post_Status_InvId: {
+ /*
+ * The return status of rtems_rate_monotonic_period() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Post_Status_NotOwn: {
+ /*
+ * The return status of rtems_rate_monotonic_period() shall be
+ * RTEMS_NOT_OWNER_OF_RESOURCE.
+ */
+ T_rsc( ctx->status, RTEMS_NOT_OWNER_OF_RESOURCE );
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Post_Status_NotDef: {
+ /*
+ * The return status of rtems_rate_monotonic_period() shall be
+ * RTEMS_NOT_DEFINED.
+ */
+ T_rsc( ctx->status, RTEMS_NOT_DEFINED );
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Post_Status_TimeOut: {
+ /*
+ * The return status of rtems_rate_monotonic_period() shall be
+ * RTEMS_TIMEOUT.
+ */
+ T_rsc( ctx->status, RTEMS_TIMEOUT );
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqPeriod_Post_State_Check(
+ RtemsRatemonReqPeriod_Context *ctx,
+ RtemsRatemonReqPeriod_Post_State state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqPeriod_Post_State_Inactive: {
+ /*
+ * The state of the period shall be inactive after the return of the
+ * rtems_rate_monotonic_period() call.
+ */
+ T_eq_int( ctx->period_status.state, RATE_MONOTONIC_INACTIVE );
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Post_State_Active: {
+ /*
+ * The state of the period shall be RATE_MONOTONIC_ACTIVE after the
+ * return of the rtems_rate_monotonic_period() call.
+ */
+ T_eq_int( ctx->period_status.state, RATE_MONOTONIC_ACTIVE );
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Post_State_Expired: {
+ /*
+ * The state of the period shall be RATE_MONOTONIC_EXPIRED after the
+ * return of the rtems_rate_monotonic_period() call.
+ */
+ T_eq_int( ctx->period_status.state, RATE_MONOTONIC_EXPIRED );
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Post_State_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past calls to
+ * rtems_rate_monotonic_period() shall not be accessed by the
+ * rtems_rate_monotonic_period() call (see also Nop).
+ */
+ T_eq_u32( ctx->period_status.state, ctx->previous_state );
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Post_State_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqPeriod_Post_Postponed_Check(
+ RtemsRatemonReqPeriod_Context *ctx,
+ RtemsRatemonReqPeriod_Post_Postponed state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqPeriod_Post_Postponed_Zero: {
+ /*
+ * There shall be no postponed jobs after the return of the
+ * rtems_rate_monotonic_period() call.
+ */
+ T_eq_u32( ctx->period_status.postponed_jobs_count, 0 );
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Post_Postponed_OneOrMore: {
+ /*
+ * The number of postponed jobs shall be the number of deadlines passed
+ * minus the number of returned calls to rtems_rate_monotonic_period().
+ *
+ * The last call to rtems_rate_monotonic_period() where the state changes
+ * from inactive to RATE_MONOTONIC_ACTIVE is counted as the first
+ * returned call. The first deadline occurred at a point in time during
+ * that call to rtems_rate_monotonic_period().
+ */
+ T_eq_u32(
+ ctx->period_status.postponed_jobs_count,
+ ( ctx->test_duration / period_length + 1 ) - ctx->period_calls
+ );
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Post_Postponed_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past calls to
+ * rtems_rate_monotonic_period() shall not be accessed by the
+ * rtems_rate_monotonic_period() call (see also Nop).
+ */
+ T_eq_u32(
+ ctx->period_status.postponed_jobs_count,
+ ctx->postponed_jobs_count
+ );
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Post_Postponed_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqPeriod_Post_Delay_Check(
+ RtemsRatemonReqPeriod_Context *ctx,
+ RtemsRatemonReqPeriod_Post_Delay state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqPeriod_Post_Delay_None: {
+ /*
+ * The last call to rtems_rate_monotonic_period() shall return without
+ * delay.
+ */
+ T_eq_u32( ctx->action_duration, 0 );
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Post_Delay_TillDeadline: {
+ /*
+ * The last call to rtems_rate_monotonic_period() shall block the owner
+ * task till the next deadline and return afterwards.
+ */
+ T_eq_u32(
+ ctx->action_duration,
+ ( ctx->test_duration_till_action % period_length + 1 ) * period_length -
+ ctx->test_duration_till_action
+ );
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Post_Delay_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqPeriod_Post_Scheduler_Check(
+ RtemsRatemonReqPeriod_Context *ctx,
+ RtemsRatemonReqPeriod_Post_Scheduler state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqPeriod_Post_Scheduler_Called: {
+ /*
+ * The last call of the rtems_rate_monotonic_period() function shall
+ * execute the ``release_job`` scheduler operation of the home scheduler.
+ */
+ /* Cannot be tested as the effect is unknown. */
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Post_Scheduler_Nop: {
+ /*
+ * The last call of the rtems_rate_monotonic_period() function shall not
+ * execute any scheduler operation.
+ */
+ /* Cannot be tested as the effect is unknown. */
+ break;
+ }
+
+ case RtemsRatemonReqPeriod_Post_Scheduler_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqPeriod_Setup( RtemsRatemonReqPeriod_Context *ctx )
+{
+ rtems_status_code status;
+ rtems_task_priority priority;
+ rtems_event_set event_set;
+ ctx->worker_id = RTEMS_INVALID_ID;
+
+ status = rtems_task_ident(
+ RTEMS_SELF,
+ RTEMS_SEARCH_ALL_NODES,
+ &ctx->task_id
+ );
+ T_rsc_success( status );
+
+ status = rtems_task_set_priority(
+ RTEMS_SELF,
+ RTEMS_CURRENT_PRIORITY,
+ &ctx->original_priority
+ );
+ T_rsc_success( status );
+
+ status = rtems_task_set_priority(
+ RTEMS_SELF,
+ background_task_priority,
+ &priority
+ );
+ T_rsc_success( status );
+
+ status = rtems_task_create(
+ rtems_build_name( 'W', 'O', 'R', 'K' ),
+ foreground_task_priority,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &ctx->worker_id
+ );
+ T_rsc_success( status );
+
+ /* Defensive programming: clean away any pending events */
+ status = rtems_event_receive(
+ RTEMS_ALL_EVENTS,
+ RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
+ RTEMS_NO_TIMEOUT,
+ &event_set
+ );
+ T_true( status == RTEMS_SUCCESSFUL || status == RTEMS_UNSATISFIED );
+
+ status = rtems_task_start(
+ ctx->worker_id,
+ WorkerTask,
+ (rtems_task_argument) NULL
+ );
+ T_rsc_success( status );
+}
+
+static void RtemsRatemonReqPeriod_Setup_Wrap( void *arg )
+{
+ RtemsRatemonReqPeriod_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsRatemonReqPeriod_Setup( ctx );
+}
+
+static void RtemsRatemonReqPeriod_Teardown(
+ RtemsRatemonReqPeriod_Context *ctx
+)
+{
+ rtems_status_code status;
+ rtems_task_priority priority;
+
+ T_rsc_success( rtems_task_delete( ctx->worker_id ) );
+
+ status = rtems_task_set_priority(
+ RTEMS_SELF,
+ ctx->original_priority,
+ &priority
+ );
+ T_rsc_success( status );
+}
+
+static void RtemsRatemonReqPeriod_Teardown_Wrap( void *arg )
+{
+ RtemsRatemonReqPeriod_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsRatemonReqPeriod_Teardown( ctx );
+}
+
+static void RtemsRatemonReqPeriod_Prepare( RtemsRatemonReqPeriod_Context *ctx )
+{
+ rtems_status_code status;
+ rtems_rate_monotonic_period_status period_status;
+ ctx->test_duration = 0;
+ ctx->period_calls = 0;
+ OwnerDoWork( ctx, CreatePeriod );
+
+ /*
+ * In case of a new period the postponed jobs count is arbitrary
+ * (what ever value happens to be stored in that field of the internal data
+ * structure) until period() is called.
+ */
+ status = rtems_rate_monotonic_get_status(
+ ctx->period_id,
+ &period_status
+ );
+ T_rsc_success( status );
+}
+
+static void RtemsRatemonReqPeriod_Action( RtemsRatemonReqPeriod_Context *ctx )
+{
+ rtems_status_code status;
+
+ ctx->test_duration_till_action = ctx->test_duration;
+ ctx->action_duration = ctx->do_action( ctx, DoAction );
+
+ status = rtems_rate_monotonic_get_status(
+ ctx->period_id,
+ &ctx->period_status
+ );
+ T_rsc_success( status );
+}
+
+static void RtemsRatemonReqPeriod_Cleanup( RtemsRatemonReqPeriod_Context *ctx )
+{
+ OwnerDoWork( ctx, DeletePeriod );
+}
+
+static const RtemsRatemonReqPeriod_Entry
+RtemsRatemonReqPeriod_Entries[] = {
+ { 0, 0, 0, 0, 0, 0, 1, RtemsRatemonReqPeriod_Post_Status_InvId,
+ RtemsRatemonReqPeriod_Post_State_Nop,
+ RtemsRatemonReqPeriod_Post_Postponed_Nop,
+ RtemsRatemonReqPeriod_Post_Delay_None,
+ RtemsRatemonReqPeriod_Post_Scheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 1, RtemsRatemonReqPeriod_Post_Status_NotOwn,
+ RtemsRatemonReqPeriod_Post_State_Nop,
+ RtemsRatemonReqPeriod_Post_Postponed_Nop,
+ RtemsRatemonReqPeriod_Post_Delay_None,
+ RtemsRatemonReqPeriod_Post_Scheduler_Nop },
+ { 1, 0, 0, 0, 0, 0, 1, RtemsRatemonReqPeriod_Post_Status_NA,
+ RtemsRatemonReqPeriod_Post_State_NA,
+ RtemsRatemonReqPeriod_Post_Postponed_NA,
+ RtemsRatemonReqPeriod_Post_Delay_NA,
+ RtemsRatemonReqPeriod_Post_Scheduler_NA },
+ { 0, 0, 0, 0, 0, 1, 0, RtemsRatemonReqPeriod_Post_Status_InvId,
+ RtemsRatemonReqPeriod_Post_State_Nop,
+ RtemsRatemonReqPeriod_Post_Postponed_Nop,
+ RtemsRatemonReqPeriod_Post_Delay_None,
+ RtemsRatemonReqPeriod_Post_Scheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsRatemonReqPeriod_Post_Status_InvId,
+ RtemsRatemonReqPeriod_Post_State_Nop,
+ RtemsRatemonReqPeriod_Post_Postponed_Nop,
+ RtemsRatemonReqPeriod_Post_Delay_None,
+ RtemsRatemonReqPeriod_Post_Scheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 1, RtemsRatemonReqPeriod_Post_Status_Ok,
+ RtemsRatemonReqPeriod_Post_State_Nop,
+ RtemsRatemonReqPeriod_Post_Postponed_Nop,
+ RtemsRatemonReqPeriod_Post_Delay_None,
+ RtemsRatemonReqPeriod_Post_Scheduler_Nop },
+ { 0, 0, 0, 0, 0, 1, 0, RtemsRatemonReqPeriod_Post_Status_NotOwn,
+ RtemsRatemonReqPeriod_Post_State_Nop,
+ RtemsRatemonReqPeriod_Post_Postponed_Nop,
+ RtemsRatemonReqPeriod_Post_Delay_None,
+ RtemsRatemonReqPeriod_Post_Scheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsRatemonReqPeriod_Post_Status_NotOwn,
+ RtemsRatemonReqPeriod_Post_State_Nop,
+ RtemsRatemonReqPeriod_Post_Postponed_Nop,
+ RtemsRatemonReqPeriod_Post_Delay_None,
+ RtemsRatemonReqPeriod_Post_Scheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 1, RtemsRatemonReqPeriod_Post_Status_TimeOut,
+ RtemsRatemonReqPeriod_Post_State_Active,
+ RtemsRatemonReqPeriod_Post_Postponed_Zero,
+ RtemsRatemonReqPeriod_Post_Delay_None,
+ RtemsRatemonReqPeriod_Post_Scheduler_Called },
+ { 0, 0, 0, 0, 0, 0, 1, RtemsRatemonReqPeriod_Post_Status_TimeOut,
+ RtemsRatemonReqPeriod_Post_State_Active,
+ RtemsRatemonReqPeriod_Post_Postponed_OneOrMore,
+ RtemsRatemonReqPeriod_Post_Delay_None,
+ RtemsRatemonReqPeriod_Post_Scheduler_Called },
+ { 0, 0, 0, 0, 0, 0, 1, RtemsRatemonReqPeriod_Post_Status_TimeOut,
+ RtemsRatemonReqPeriod_Post_State_Nop,
+ RtemsRatemonReqPeriod_Post_Postponed_Nop,
+ RtemsRatemonReqPeriod_Post_Delay_None,
+ RtemsRatemonReqPeriod_Post_Scheduler_Nop },
+ { 0, 0, 0, 0, 0, 1, 0, RtemsRatemonReqPeriod_Post_Status_Ok,
+ RtemsRatemonReqPeriod_Post_State_Active,
+ RtemsRatemonReqPeriod_Post_Postponed_Zero,
+ RtemsRatemonReqPeriod_Post_Delay_None,
+ RtemsRatemonReqPeriod_Post_Scheduler_Called },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsRatemonReqPeriod_Post_Status_Ok,
+ RtemsRatemonReqPeriod_Post_State_Active,
+ RtemsRatemonReqPeriod_Post_Postponed_Zero,
+ RtemsRatemonReqPeriod_Post_Delay_None,
+ RtemsRatemonReqPeriod_Post_Scheduler_Called },
+ { 0, 0, 0, 0, 0, 1, 0, RtemsRatemonReqPeriod_Post_Status_NotDef,
+ RtemsRatemonReqPeriod_Post_State_Nop,
+ RtemsRatemonReqPeriod_Post_Postponed_Nop,
+ RtemsRatemonReqPeriod_Post_Delay_None,
+ RtemsRatemonReqPeriod_Post_Scheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsRatemonReqPeriod_Post_Status_NotDef,
+ RtemsRatemonReqPeriod_Post_State_Nop,
+ RtemsRatemonReqPeriod_Post_Postponed_Nop,
+ RtemsRatemonReqPeriod_Post_Delay_None,
+ RtemsRatemonReqPeriod_Post_Scheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 1, RtemsRatemonReqPeriod_Post_Status_Ok,
+ RtemsRatemonReqPeriod_Post_State_Active,
+ RtemsRatemonReqPeriod_Post_Postponed_Zero,
+ RtemsRatemonReqPeriod_Post_Delay_TillDeadline,
+ RtemsRatemonReqPeriod_Post_Scheduler_Called }
+};
+
+static const uint8_t
+RtemsRatemonReqPeriod_Map[] = {
+ 11, 12, 11, 12, 11, 12, 15, 15, 8, 8, 9, 9, 2, 2, 8, 8, 9, 9, 13, 14, 13, 14,
+ 13, 14, 5, 5, 5, 5, 5, 5, 2, 2, 10, 10, 10, 10, 6, 7, 6, 7, 6, 7, 1, 1, 1, 1,
+ 1, 1, 2, 2, 1, 1, 1, 1, 6, 7, 6, 7, 6, 7, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1,
+ 3, 4, 3, 4, 3, 4, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 3, 4, 3, 4, 3, 4, 0, 0,
+ 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 3, 4, 3, 4, 3, 4, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0,
+ 0, 0, 3, 4, 3, 4, 3, 4, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0
+};
+
+static size_t RtemsRatemonReqPeriod_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsRatemonReqPeriod_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsRatemonReqPeriod_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsRatemonReqPeriod_Fixture = {
+ .setup = RtemsRatemonReqPeriod_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsRatemonReqPeriod_Teardown_Wrap,
+ .scope = RtemsRatemonReqPeriod_Scope,
+ .initial_context = &RtemsRatemonReqPeriod_Instance
+};
+
+static inline RtemsRatemonReqPeriod_Entry RtemsRatemonReqPeriod_PopEntry(
+ RtemsRatemonReqPeriod_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsRatemonReqPeriod_Entries[
+ RtemsRatemonReqPeriod_Map[ index ]
+ ];
+}
+
+static void RtemsRatemonReqPeriod_SetPreConditionStates(
+ RtemsRatemonReqPeriod_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+
+ if ( ctx->Map.entry.Pre_Postponed_NA ) {
+ ctx->Map.pcs[ 4 ] = RtemsRatemonReqPeriod_Pre_Postponed_NA;
+ } else {
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+ }
+
+ if ( ctx->Map.entry.Pre_InactiveCause_NA ) {
+ ctx->Map.pcs[ 5 ] = RtemsRatemonReqPeriod_Pre_InactiveCause_NA;
+ } else {
+ ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
+ }
+}
+
+static void RtemsRatemonReqPeriod_TestVariant(
+ RtemsRatemonReqPeriod_Context *ctx
+)
+{
+ RtemsRatemonReqPeriod_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsRatemonReqPeriod_Pre_Caller_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsRatemonReqPeriod_Pre_Length_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsRatemonReqPeriod_Pre_State_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsRatemonReqPeriod_Pre_Postponed_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsRatemonReqPeriod_Pre_InactiveCause_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsRatemonReqPeriod_Action( ctx );
+ RtemsRatemonReqPeriod_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsRatemonReqPeriod_Post_State_Check( ctx, ctx->Map.entry.Post_State );
+ RtemsRatemonReqPeriod_Post_Postponed_Check(
+ ctx,
+ ctx->Map.entry.Post_Postponed
+ );
+ RtemsRatemonReqPeriod_Post_Delay_Check( ctx, ctx->Map.entry.Post_Delay );
+ RtemsRatemonReqPeriod_Post_Scheduler_Check(
+ ctx,
+ ctx->Map.entry.Post_Scheduler
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsRatemonReqPeriod( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsRatemonReqPeriod, &RtemsRatemonReqPeriod_Fixture )
+{
+ RtemsRatemonReqPeriod_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsRatemonReqPeriod_Pre_Id_Valid;
+ ctx->Map.pci[ 0 ] < RtemsRatemonReqPeriod_Pre_Id_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsRatemonReqPeriod_Pre_Caller_OwnerTask;
+ ctx->Map.pci[ 1 ] < RtemsRatemonReqPeriod_Pre_Caller_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsRatemonReqPeriod_Pre_Length_Ticks;
+ ctx->Map.pci[ 2 ] < RtemsRatemonReqPeriod_Pre_Length_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = RtemsRatemonReqPeriod_Pre_State_Inactive;
+ ctx->Map.pci[ 3 ] < RtemsRatemonReqPeriod_Pre_State_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ for (
+ ctx->Map.pci[ 4 ] = RtemsRatemonReqPeriod_Pre_Postponed_Zero;
+ ctx->Map.pci[ 4 ] < RtemsRatemonReqPeriod_Pre_Postponed_NA;
+ ++ctx->Map.pci[ 4 ]
+ ) {
+ for (
+ ctx->Map.pci[ 5 ] = RtemsRatemonReqPeriod_Pre_InactiveCause_New;
+ ctx->Map.pci[ 5 ] < RtemsRatemonReqPeriod_Pre_InactiveCause_NA;
+ ++ctx->Map.pci[ 5 ]
+ ) {
+ ctx->Map.entry = RtemsRatemonReqPeriod_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsRatemonReqPeriod_SetPreConditionStates( ctx );
+ RtemsRatemonReqPeriod_Prepare( ctx );
+ RtemsRatemonReqPeriod_TestVariant( ctx );
+ RtemsRatemonReqPeriod_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-ratemon-timeout.c b/testsuites/validation/tc-ratemon-timeout.c
new file mode 100644
index 0000000000..dc2c745e61
--- /dev/null
+++ b/testsuites/validation/tc-ratemon-timeout.c
@@ -0,0 +1,961 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsRatemonReqTimeout
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test-scheduler.h>
+#include <rtems/rtems/ratemonimpl.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsRatemonReqTimeout spec:/rtems/ratemon/req/timeout
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ * @ingroup TestsuitesValidationOneCpu0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsRatemonReqTimeout_Pre_WaitFor_PeriodSelf,
+ RtemsRatemonReqTimeout_Pre_WaitFor_PeriodOther,
+ RtemsRatemonReqTimeout_Pre_WaitFor_Other,
+ RtemsRatemonReqTimeout_Pre_WaitFor_NA
+} RtemsRatemonReqTimeout_Pre_WaitFor;
+
+typedef enum {
+ RtemsRatemonReqTimeout_Pre_WaitState_Blocked,
+ RtemsRatemonReqTimeout_Pre_WaitState_IntendToBlock,
+ RtemsRatemonReqTimeout_Pre_WaitState_NA
+} RtemsRatemonReqTimeout_Pre_WaitState;
+
+typedef enum {
+ RtemsRatemonReqTimeout_Pre_PostponedJobs_Zero,
+ RtemsRatemonReqTimeout_Pre_PostponedJobs_NotZeroOrMax,
+ RtemsRatemonReqTimeout_Pre_PostponedJobs_Max,
+ RtemsRatemonReqTimeout_Pre_PostponedJobs_NA
+} RtemsRatemonReqTimeout_Pre_PostponedJobs;
+
+typedef enum {
+ RtemsRatemonReqTimeout_Post_PostponedJobs_Nop,
+ RtemsRatemonReqTimeout_Post_PostponedJobs_PlusOne,
+ RtemsRatemonReqTimeout_Post_PostponedJobs_NA
+} RtemsRatemonReqTimeout_Post_PostponedJobs;
+
+typedef enum {
+ RtemsRatemonReqTimeout_Post_ReleaseJob_Yes,
+ RtemsRatemonReqTimeout_Post_ReleaseJob_No,
+ RtemsRatemonReqTimeout_Post_ReleaseJob_NA
+} RtemsRatemonReqTimeout_Post_ReleaseJob;
+
+typedef enum {
+ RtemsRatemonReqTimeout_Post_Unblock_Yes,
+ RtemsRatemonReqTimeout_Post_Unblock_No,
+ RtemsRatemonReqTimeout_Post_Unblock_NA
+} RtemsRatemonReqTimeout_Post_Unblock;
+
+typedef enum {
+ RtemsRatemonReqTimeout_Post_PeriodState_Active,
+ RtemsRatemonReqTimeout_Post_PeriodState_Expired,
+ RtemsRatemonReqTimeout_Post_PeriodState_NA
+} RtemsRatemonReqTimeout_Post_PeriodState;
+
+typedef enum {
+ RtemsRatemonReqTimeout_Post_Timer_Active,
+ RtemsRatemonReqTimeout_Post_Timer_NA
+} RtemsRatemonReqTimeout_Post_Timer;
+
+typedef enum {
+ RtemsRatemonReqTimeout_Post_Uptime_Nop,
+ RtemsRatemonReqTimeout_Post_Uptime_Set,
+ RtemsRatemonReqTimeout_Post_Uptime_NA
+} RtemsRatemonReqTimeout_Post_Uptime;
+
+typedef enum {
+ RtemsRatemonReqTimeout_Post_CPUUsage_Nop,
+ RtemsRatemonReqTimeout_Post_CPUUsage_Set,
+ RtemsRatemonReqTimeout_Post_CPUUsage_NA
+} RtemsRatemonReqTimeout_Post_CPUUsage;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_WaitFor_NA : 1;
+ uint32_t Pre_WaitState_NA : 1;
+ uint32_t Pre_PostponedJobs_NA : 1;
+ uint32_t Post_PostponedJobs : 2;
+ uint32_t Post_ReleaseJob : 2;
+ uint32_t Post_Unblock : 2;
+ uint32_t Post_PeriodState : 2;
+ uint32_t Post_Timer : 1;
+ uint32_t Post_Uptime : 2;
+ uint32_t Post_CPUUsage : 2;
+} RtemsRatemonReqTimeout_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/ratemon/req/timeout test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the period identifier.
+ */
+ rtems_id period_id;
+
+ /**
+ * @brief This member references the period control block.
+ */
+ Rate_monotonic_Control *period;
+
+ /**
+ * @brief This member contains another period identifier.
+ */
+ rtems_id other_period_id;
+
+ /**
+ * @brief This member contains the worker task identifier.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member contains the call within ISR request.
+ */
+ CallWithinISRRequest request;
+
+ /**
+ * @brief If this member is true, then the worker shall wait for a period.
+ */
+ bool wait_for_period;
+
+ /**
+ * @brief If this member is true, then the worker shall wait for another
+ * period.
+ */
+ bool period_is_other;
+
+ /**
+ * @brief If this member is true, then the worker shall intend to block for a
+ * period.
+ */
+ bool intend_to_block;
+
+ /**
+ * @brief This member contains the postponed jobs count before the timeout.
+ */
+ uint32_t postponed_jobs;
+
+ /**
+ * @brief This member contains the uptime of the period before the timeout.
+ */
+ Timestamp_Control uptime_before;
+
+ /**
+ * @brief This member contains the CPU usage of the period before the
+ * timeout.
+ */
+ Timestamp_Control cpu_usage_before;
+
+ /**
+ * @brief This member contains the release job counter.
+ */
+ uint32_t release_job_counter;
+
+ /**
+ * @brief This member contains the unblock counter.
+ */
+ uint32_t unblock_counter;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 3 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsRatemonReqTimeout_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsRatemonReqTimeout_Context;
+
+static RtemsRatemonReqTimeout_Context
+ RtemsRatemonReqTimeout_Instance;
+
+static const char * const RtemsRatemonReqTimeout_PreDesc_WaitFor[] = {
+ "PeriodSelf",
+ "PeriodOther",
+ "Other",
+ "NA"
+};
+
+static const char * const RtemsRatemonReqTimeout_PreDesc_WaitState[] = {
+ "Blocked",
+ "IntendToBlock",
+ "NA"
+};
+
+static const char * const RtemsRatemonReqTimeout_PreDesc_PostponedJobs[] = {
+ "Zero",
+ "NotZeroOrMax",
+ "Max",
+ "NA"
+};
+
+static const char * const * const RtemsRatemonReqTimeout_PreDesc[] = {
+ RtemsRatemonReqTimeout_PreDesc_WaitFor,
+ RtemsRatemonReqTimeout_PreDesc_WaitState,
+ RtemsRatemonReqTimeout_PreDesc_PostponedJobs,
+ NULL
+};
+
+#define EVENT_RESET RTEMS_EVENT_0
+
+#define EVENT_PERIOD_WAIT RTEMS_EVENT_1
+
+#define EVENT_PERIOD_OTHER RTEMS_EVENT_2
+
+typedef RtemsRatemonReqTimeout_Context Context;
+
+static void Tick( void *arg )
+{
+ Context *ctx;
+ T_scheduler_log_10 scheduler_log_10;
+ const T_scheduler_log *scheduler_log;
+ size_t index;
+
+ ctx = arg;
+ ctx->release_job_counter = 0;
+ ctx->unblock_counter = 0;
+ ctx->uptime_before = ctx->period->time_period_initiated;
+ ctx->cpu_usage_before = ctx->period->cpu_usage_period_initiated;
+ scheduler_log = T_scheduler_record_10( &scheduler_log_10 );
+ T_null( scheduler_log );
+ ClockTick();
+ scheduler_log = T_scheduler_record( NULL );
+ T_eq_ptr( &scheduler_log->header, &scheduler_log_10.header );
+
+ index = 0;
+
+ while ( true ) {
+ const T_scheduler_event *event;
+
+ event = T_scheduler_next_any( &scheduler_log_10.header, &index );
+
+ if ( event == &T_scheduler_event_null ) {
+ break;
+ }
+
+ T_eq_u32( event->thread->Object.id, ctx->worker_id );
+
+ switch ( event->operation ) {
+ case T_SCHEDULER_RELEASE_JOB:
+ ++ctx->release_job_counter;
+ T_eq_u64(
+ event->release_job.deadline,
+ rtems_clock_get_ticks_since_boot() + 1
+ );
+ break;
+ case T_SCHEDULER_UNBLOCK:
+ ++ctx->unblock_counter;
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static void SchedulerBlock(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ if (
+ when == T_SCHEDULER_BEFORE &&
+ event->operation == T_SCHEDULER_BLOCK
+ ) {
+ T_scheduler_set_event_handler( NULL, NULL );
+ ctx->request.handler = Tick;
+ CallWithinISRSubmit( &ctx->request );
+ }
+}
+
+static Rate_monotonic_Control *GetControl( rtems_id id )
+{
+ Rate_monotonic_Control *period;
+ ISR_lock_Context lock_context;
+
+ period = _Rate_monotonic_Get( id, &lock_context );
+ T_assert_not_null( period );
+ _ISR_lock_ISR_enable( &lock_context );
+
+ return period;
+}
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+ rtems_status_code sc;
+
+ ctx = (Context *) arg;
+
+ sc = rtems_rate_monotonic_create( OBJECT_NAME, &ctx->period_id );
+ T_rsc_success( sc );
+
+ sc = rtems_rate_monotonic_create( OBJECT_NAME, &ctx->other_period_id );
+ T_rsc_success( sc );
+
+ while ( true ) {
+ rtems_event_set events;
+
+ events = ReceiveAnyEvents();
+
+ if ( ( events & EVENT_RESET ) != 0 ) {
+ sc = rtems_rate_monotonic_cancel( ctx->period_id );
+ T_rsc_success( sc );
+
+ sc = rtems_rate_monotonic_cancel( ctx->other_period_id );
+ T_rsc_success( sc );
+
+ sc = rtems_rate_monotonic_period( ctx->period_id, 1 );
+ T_rsc_success( sc );
+
+ ctx->period->postponed_jobs = ctx->postponed_jobs;
+ }
+
+ if ( ( events & EVENT_PERIOD_WAIT ) != 0 ) {
+ if ( ctx->intend_to_block ) {
+ T_scheduler_set_event_handler( SchedulerBlock, ctx );
+ }
+
+ sc = rtems_rate_monotonic_period( ctx->period_id, 1 );
+ T_rsc_success( sc );
+ }
+
+ if ( ( events & EVENT_PERIOD_OTHER ) != 0 ) {
+ sc = rtems_rate_monotonic_period( ctx->other_period_id, 2 );
+ T_rsc_success( sc );
+
+ sc = rtems_rate_monotonic_period( ctx->other_period_id, 2 );
+ T_rsc_success( sc );
+ }
+ }
+}
+
+static void RtemsRatemonReqTimeout_Pre_WaitFor_Prepare(
+ RtemsRatemonReqTimeout_Context *ctx,
+ RtemsRatemonReqTimeout_Pre_WaitFor state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqTimeout_Pre_WaitFor_PeriodSelf: {
+ /*
+ * While the owner task of the period waits for the period.
+ */
+ ctx->wait_for_period = true;
+ ctx->period_is_other = false;
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Pre_WaitFor_PeriodOther: {
+ /*
+ * While the owner task of the period waits for another period.
+ */
+ ctx->wait_for_period = true;
+ ctx->period_is_other = true;
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Pre_WaitFor_Other: {
+ /*
+ * While the owner task of the period does not wait for a period.
+ */
+ ctx->wait_for_period = false;
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Pre_WaitFor_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqTimeout_Pre_WaitState_Prepare(
+ RtemsRatemonReqTimeout_Context *ctx,
+ RtemsRatemonReqTimeout_Pre_WaitState state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqTimeout_Pre_WaitState_Blocked: {
+ /*
+ * While the owner task is in the blocked wait state.
+ */
+ ctx->intend_to_block = false;
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Pre_WaitState_IntendToBlock: {
+ /*
+ * While the owner task is in the intend to block wait state.
+ */
+ ctx->intend_to_block = true;
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Pre_WaitState_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqTimeout_Pre_PostponedJobs_Prepare(
+ RtemsRatemonReqTimeout_Context *ctx,
+ RtemsRatemonReqTimeout_Pre_PostponedJobs state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqTimeout_Pre_PostponedJobs_Zero: {
+ /*
+ * While the count of postponed jobs is equal to zero.
+ */
+ ctx->postponed_jobs = 0;
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Pre_PostponedJobs_NotZeroOrMax: {
+ /*
+ * While the count of postponed jobs is not equal to zero or UINT32_MAX.
+ */
+ ctx->postponed_jobs = 123;
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Pre_PostponedJobs_Max: {
+ /*
+ * While the count of postponed jobs is equal to UINT32_MAX.
+ */
+ ctx->postponed_jobs = UINT32_MAX;
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Pre_PostponedJobs_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqTimeout_Post_PostponedJobs_Check(
+ RtemsRatemonReqTimeout_Context *ctx,
+ RtemsRatemonReqTimeout_Post_PostponedJobs state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqTimeout_Post_PostponedJobs_Nop: {
+ /*
+ * The count of postponed jobs of the period shall not be modified.
+ */
+ T_eq_u32( ctx->period->postponed_jobs, ctx->postponed_jobs );
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Post_PostponedJobs_PlusOne: {
+ /*
+ * The count of postponed jobs of the period shall be incremented by one.
+ */
+ T_eq_u32( ctx->period->postponed_jobs, ctx->postponed_jobs + 1 );
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Post_PostponedJobs_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqTimeout_Post_ReleaseJob_Check(
+ RtemsRatemonReqTimeout_Context *ctx,
+ RtemsRatemonReqTimeout_Post_ReleaseJob state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqTimeout_Post_ReleaseJob_Yes: {
+ /*
+ * The owner task of the period shall release a job with a deadline equal
+ * to the clock tick plus the next period length by the timeout
+ * operation.
+ */
+ T_eq_u32( ctx->release_job_counter, 1 );
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Post_ReleaseJob_No: {
+ /*
+ * The owner task of the period shall not release a job by the timeout
+ * operation.
+ */
+ T_eq_u32( ctx->release_job_counter, 0 );
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Post_ReleaseJob_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqTimeout_Post_Unblock_Check(
+ RtemsRatemonReqTimeout_Context *ctx,
+ RtemsRatemonReqTimeout_Post_Unblock state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqTimeout_Post_Unblock_Yes: {
+ /*
+ * The owner task of the period shall be unblocked by the timeout
+ * operation.
+ */
+ T_eq_u32( ctx->unblock_counter, 1 );
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Post_Unblock_No: {
+ /*
+ * The owner task of the period shall not be unblocked by the timeout
+ * operation.
+ */
+ T_eq_u32( ctx->unblock_counter, 0 );
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Post_Unblock_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqTimeout_Post_PeriodState_Check(
+ RtemsRatemonReqTimeout_Context *ctx,
+ RtemsRatemonReqTimeout_Post_PeriodState state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqTimeout_Post_PeriodState_Active: {
+ /*
+ * The period state shall be active.
+ */
+ T_eq_int( ctx->period->state, RATE_MONOTONIC_ACTIVE );
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Post_PeriodState_Expired: {
+ /*
+ * The period state shall be expired.
+ */
+ T_eq_int( ctx->period->state, RATE_MONOTONIC_EXPIRED );
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Post_PeriodState_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqTimeout_Post_Timer_Check(
+ RtemsRatemonReqTimeout_Context *ctx,
+ RtemsRatemonReqTimeout_Post_Timer state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqTimeout_Post_Timer_Active: {
+ /*
+ * The timeout timer of the period shall expired at the current clock
+ * tick plus the next period length.
+ */
+ T_true( _Watchdog_Is_scheduled( &ctx->period->Timer ) );
+ T_eq_u64(
+ ctx->period->Timer.expire,
+ rtems_clock_get_ticks_since_boot() + 1
+ );
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Post_Timer_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqTimeout_Post_Uptime_Check(
+ RtemsRatemonReqTimeout_Context *ctx,
+ RtemsRatemonReqTimeout_Post_Uptime state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqTimeout_Post_Uptime_Nop: {
+ /*
+ * The period initiated CLOCK_MONOTONIC value shall not be modified.
+ */
+ T_eq_i64( ctx->uptime_before, ctx->period->time_period_initiated );
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Post_Uptime_Set: {
+ /*
+ * The period initiated CLOCK_MONOTONIC value shall be set to the
+ * CLOCK_MONOTONIC at some time point during the timeout operation.
+ */
+ T_ne_i64( ctx->uptime_before, ctx->period->time_period_initiated );
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Post_Uptime_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqTimeout_Post_CPUUsage_Check(
+ RtemsRatemonReqTimeout_Context *ctx,
+ RtemsRatemonReqTimeout_Post_CPUUsage state
+)
+{
+ switch ( state ) {
+ case RtemsRatemonReqTimeout_Post_CPUUsage_Nop: {
+ /*
+ * The period initiated CPU usage of the owner task value shall not be
+ * modified.
+ */
+ T_eq_i64(
+ ctx->cpu_usage_before,
+ ctx->period->cpu_usage_period_initiated
+ );
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Post_CPUUsage_Set: {
+ /*
+ * The period initiated CPU usage of the owner task value shall be set to
+ * the CPU usage of the owner task at some time point during the timeout
+ * operation.
+ */
+ T_ne_i64(
+ ctx->cpu_usage_before,
+ ctx->period->cpu_usage_period_initiated
+ );
+ break;
+ }
+
+ case RtemsRatemonReqTimeout_Post_CPUUsage_NA:
+ break;
+ }
+}
+
+static void RtemsRatemonReqTimeout_Setup( RtemsRatemonReqTimeout_Context *ctx )
+{
+ ctx->request.arg = ctx;
+ ctx->worker_id = CreateTask( "WORK", GetSelfPriority() );
+ StartTask( ctx->worker_id, Worker, ctx );
+ Yield();
+ ctx->period = GetControl( ctx->period_id );
+}
+
+static void RtemsRatemonReqTimeout_Setup_Wrap( void *arg )
+{
+ RtemsRatemonReqTimeout_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsRatemonReqTimeout_Setup( ctx );
+}
+
+static void RtemsRatemonReqTimeout_Teardown(
+ RtemsRatemonReqTimeout_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ DeleteTask( ctx->worker_id );
+
+ sc = rtems_rate_monotonic_delete( ctx->period_id );
+ T_rsc_success( sc );
+
+ sc = rtems_rate_monotonic_delete( ctx->other_period_id );
+ T_rsc_success( sc );
+}
+
+static void RtemsRatemonReqTimeout_Teardown_Wrap( void *arg )
+{
+ RtemsRatemonReqTimeout_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsRatemonReqTimeout_Teardown( ctx );
+}
+
+static void RtemsRatemonReqTimeout_Action(
+ RtemsRatemonReqTimeout_Context *ctx
+)
+{
+ SendEvents( ctx->worker_id, EVENT_RESET );
+ Yield();
+
+ if ( ctx->wait_for_period ) {
+ if ( ctx->period_is_other ) {
+ SendEvents( ctx->worker_id, EVENT_PERIOD_OTHER );
+ Yield();
+ Tick( ctx );
+ } else {
+ SendEvents( ctx->worker_id, EVENT_PERIOD_WAIT );
+ Yield();
+
+ if ( !ctx->intend_to_block ) {
+ Tick( ctx );
+ }
+ }
+ } else {
+ Tick( ctx );
+ }
+}
+
+static void RtemsRatemonReqTimeout_Cleanup(
+ RtemsRatemonReqTimeout_Context *ctx
+)
+{
+ ClockTick();
+ Yield();
+}
+
+static const RtemsRatemonReqTimeout_Entry
+RtemsRatemonReqTimeout_Entries[] = {
+ { 0, 0, 1, 0, RtemsRatemonReqTimeout_Post_PostponedJobs_PlusOne,
+ RtemsRatemonReqTimeout_Post_ReleaseJob_No,
+ RtemsRatemonReqTimeout_Post_Unblock_No,
+ RtemsRatemonReqTimeout_Post_PeriodState_Expired,
+ RtemsRatemonReqTimeout_Post_Timer_Active,
+ RtemsRatemonReqTimeout_Post_Uptime_Nop,
+ RtemsRatemonReqTimeout_Post_CPUUsage_Nop },
+ { 1, 0, 0, 0, RtemsRatemonReqTimeout_Post_PostponedJobs_NA,
+ RtemsRatemonReqTimeout_Post_ReleaseJob_NA,
+ RtemsRatemonReqTimeout_Post_Unblock_NA,
+ RtemsRatemonReqTimeout_Post_PeriodState_NA,
+ RtemsRatemonReqTimeout_Post_Timer_NA,
+ RtemsRatemonReqTimeout_Post_Uptime_NA,
+ RtemsRatemonReqTimeout_Post_CPUUsage_NA },
+ { 0, 0, 1, 0, RtemsRatemonReqTimeout_Post_PostponedJobs_Nop,
+ RtemsRatemonReqTimeout_Post_ReleaseJob_No,
+ RtemsRatemonReqTimeout_Post_Unblock_No,
+ RtemsRatemonReqTimeout_Post_PeriodState_Expired,
+ RtemsRatemonReqTimeout_Post_Timer_Active,
+ RtemsRatemonReqTimeout_Post_Uptime_Nop,
+ RtemsRatemonReqTimeout_Post_CPUUsage_Nop },
+ { 0, 0, 0, 0, RtemsRatemonReqTimeout_Post_PostponedJobs_Nop,
+ RtemsRatemonReqTimeout_Post_ReleaseJob_Yes,
+ RtemsRatemonReqTimeout_Post_Unblock_Yes,
+ RtemsRatemonReqTimeout_Post_PeriodState_Active,
+ RtemsRatemonReqTimeout_Post_Timer_Active,
+ RtemsRatemonReqTimeout_Post_Uptime_Set,
+ RtemsRatemonReqTimeout_Post_CPUUsage_Set },
+ { 0, 0, 0, 0, RtemsRatemonReqTimeout_Post_PostponedJobs_Nop,
+ RtemsRatemonReqTimeout_Post_ReleaseJob_Yes,
+ RtemsRatemonReqTimeout_Post_Unblock_No,
+ RtemsRatemonReqTimeout_Post_PeriodState_Active,
+ RtemsRatemonReqTimeout_Post_Timer_Active,
+ RtemsRatemonReqTimeout_Post_Uptime_Set,
+ RtemsRatemonReqTimeout_Post_CPUUsage_Set }
+};
+
+static const uint8_t
+RtemsRatemonReqTimeout_Map[] = {
+ 3, 1, 1, 4, 1, 1, 0, 0, 2, 0, 0, 2, 0, 0, 2, 0, 0, 2
+};
+
+static size_t RtemsRatemonReqTimeout_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsRatemonReqTimeout_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsRatemonReqTimeout_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsRatemonReqTimeout_Fixture = {
+ .setup = RtemsRatemonReqTimeout_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsRatemonReqTimeout_Teardown_Wrap,
+ .scope = RtemsRatemonReqTimeout_Scope,
+ .initial_context = &RtemsRatemonReqTimeout_Instance
+};
+
+static inline RtemsRatemonReqTimeout_Entry RtemsRatemonReqTimeout_PopEntry(
+ RtemsRatemonReqTimeout_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsRatemonReqTimeout_Entries[
+ RtemsRatemonReqTimeout_Map[ index ]
+ ];
+}
+
+static void RtemsRatemonReqTimeout_SetPreConditionStates(
+ RtemsRatemonReqTimeout_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+
+ if ( ctx->Map.entry.Pre_WaitState_NA ) {
+ ctx->Map.pcs[ 1 ] = RtemsRatemonReqTimeout_Pre_WaitState_NA;
+ } else {
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ }
+
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+}
+
+static void RtemsRatemonReqTimeout_TestVariant(
+ RtemsRatemonReqTimeout_Context *ctx
+)
+{
+ RtemsRatemonReqTimeout_Pre_WaitFor_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsRatemonReqTimeout_Pre_WaitState_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsRatemonReqTimeout_Pre_PostponedJobs_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsRatemonReqTimeout_Action( ctx );
+ RtemsRatemonReqTimeout_Post_PostponedJobs_Check(
+ ctx,
+ ctx->Map.entry.Post_PostponedJobs
+ );
+ RtemsRatemonReqTimeout_Post_ReleaseJob_Check(
+ ctx,
+ ctx->Map.entry.Post_ReleaseJob
+ );
+ RtemsRatemonReqTimeout_Post_Unblock_Check(
+ ctx,
+ ctx->Map.entry.Post_Unblock
+ );
+ RtemsRatemonReqTimeout_Post_PeriodState_Check(
+ ctx,
+ ctx->Map.entry.Post_PeriodState
+ );
+ RtemsRatemonReqTimeout_Post_Timer_Check( ctx, ctx->Map.entry.Post_Timer );
+ RtemsRatemonReqTimeout_Post_Uptime_Check( ctx, ctx->Map.entry.Post_Uptime );
+ RtemsRatemonReqTimeout_Post_CPUUsage_Check(
+ ctx,
+ ctx->Map.entry.Post_CPUUsage
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsRatemonReqTimeout( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsRatemonReqTimeout, &RtemsRatemonReqTimeout_Fixture )
+{
+ RtemsRatemonReqTimeout_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsRatemonReqTimeout_Pre_WaitFor_PeriodSelf;
+ ctx->Map.pci[ 0 ] < RtemsRatemonReqTimeout_Pre_WaitFor_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsRatemonReqTimeout_Pre_WaitState_Blocked;
+ ctx->Map.pci[ 1 ] < RtemsRatemonReqTimeout_Pre_WaitState_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsRatemonReqTimeout_Pre_PostponedJobs_Zero;
+ ctx->Map.pci[ 2 ] < RtemsRatemonReqTimeout_Pre_PostponedJobs_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ ctx->Map.entry = RtemsRatemonReqTimeout_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsRatemonReqTimeout_SetPreConditionStates( ctx );
+ RtemsRatemonReqTimeout_TestVariant( ctx );
+ RtemsRatemonReqTimeout_Cleanup( ctx );
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-sched-smp-edf-set-affinity.c b/testsuites/validation/tc-sched-smp-edf-set-affinity.c
new file mode 100644
index 0000000000..9e13c19ff7
--- /dev/null
+++ b/testsuites/validation/tc-sched-smp-edf-set-affinity.c
@@ -0,0 +1,1628 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSchedSmpEdfReqSetAffinity
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/threaddispatch.h>
+#include <rtems/score/threadimpl.h>
+
+#include "tx-support.h"
+#include "tx-thread-queue.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreSchedSmpEdfReqSetAffinity \
+ * spec:/score/sched/smp/edf/req/set-affinity
+ *
+ * @ingroup TestsuitesValidationSmpOnly0
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Before_All,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Before_X,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Before_NA
+} ScoreSchedSmpEdfReqSetAffinity_Pre_Before;
+
+typedef enum {
+ ScoreSchedSmpEdfReqSetAffinity_Pre_After_All,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_After_X,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_After_Y,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_After_NA
+} ScoreSchedSmpEdfReqSetAffinity_Pre_After;
+
+typedef enum {
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Priority_High,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Priority_Low,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Priority_NA
+} ScoreSchedSmpEdfReqSetAffinity_Pre_Priority;
+
+typedef enum {
+ ScoreSchedSmpEdfReqSetAffinity_Pre_State_Ready,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_State_Blocked,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_State_NA
+} ScoreSchedSmpEdfReqSetAffinity_Pre_State;
+
+typedef enum {
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Sticky_Yes,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Sticky_No,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Sticky_NA
+} ScoreSchedSmpEdfReqSetAffinity_Pre_Sticky;
+
+typedef enum {
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Pinned_Yes,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Pinned_No,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Pinned_NA
+} ScoreSchedSmpEdfReqSetAffinity_Pre_Pinned;
+
+typedef enum {
+ ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaPriority_High,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaPriority_Low,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaPriority_NA
+} ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaPriority;
+
+typedef enum {
+ ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaAffinity_All,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaAffinity_X,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaAffinity_NA
+} ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaAffinity;
+
+typedef enum {
+ ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaIdle_Yes,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaIdle_No,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaIdle_NA
+} ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaIdle;
+
+typedef enum {
+ ScoreSchedSmpEdfReqSetAffinity_Pre_BetaPriority_High,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_BetaPriority_Low,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_BetaPriority_NA
+} ScoreSchedSmpEdfReqSetAffinity_Pre_BetaPriority;
+
+typedef enum {
+ ScoreSchedSmpEdfReqSetAffinity_Pre_BetaAffinity_All,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_BetaAffinity_Y,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_BetaAffinity_NA
+} ScoreSchedSmpEdfReqSetAffinity_Pre_BetaAffinity;
+
+typedef enum {
+ ScoreSchedSmpEdfReqSetAffinity_Pre_BetaIdle_Yes,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_BetaIdle_No,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_BetaIdle_NA
+} ScoreSchedSmpEdfReqSetAffinity_Pre_BetaIdle;
+
+typedef enum {
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_Task,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_TaskIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_Alpha,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_AlphaIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_Beta,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_BetaIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_NA
+} ScoreSchedSmpEdfReqSetAffinity_Post_X;
+
+typedef enum {
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_Task,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_TaskIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_Alpha,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_AlphaIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_Beta,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_BetaIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_NA
+} ScoreSchedSmpEdfReqSetAffinity_Post_Y;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_Before_NA : 1;
+ uint32_t Pre_After_NA : 1;
+ uint32_t Pre_Priority_NA : 1;
+ uint32_t Pre_State_NA : 1;
+ uint32_t Pre_Sticky_NA : 1;
+ uint32_t Pre_Pinned_NA : 1;
+ uint32_t Pre_AlphaPriority_NA : 1;
+ uint32_t Pre_AlphaAffinity_NA : 1;
+ uint32_t Pre_AlphaIdle_NA : 1;
+ uint32_t Pre_BetaPriority_NA : 1;
+ uint32_t Pre_BetaAffinity_NA : 1;
+ uint32_t Pre_BetaIdle_NA : 1;
+ uint32_t Post_X : 3;
+ uint32_t Post_Y : 3;
+} ScoreSchedSmpEdfReqSetAffinity_Entry;
+
+/**
+ * @brief Test context for spec:/score/sched/smp/edf/req/set-affinity test
+ * case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the thread queue test context.
+ */
+ TQContext tq_ctx;
+
+ /**
+ * @brief This member specifies the task affinity before changing the
+ * affinity.
+ */
+ cpu_set_t task_affinity_before;
+
+ /**
+ * @brief This member specifies the task affinity after changing the
+ * affinity.
+ */
+ cpu_set_t task_affinity_after;
+
+ /**
+ * @brief This member specifies the priority of the task.
+ */
+ rtems_task_priority task_priority;
+
+ /**
+ * @brief If this member is true, then the task state shall be ready.
+ */
+ bool task_ready;
+
+ /**
+ * @brief If this member is true, then the task shall have obtained a sticky
+ * mutex.
+ */
+ bool task_sticky;
+
+ /**
+ * @brief If this member is true, then the task shall be pinned.
+ */
+ bool task_pinned;
+
+ /**
+ * @brief This member specifies the priority of the alpha task.
+ */
+ rtems_task_priority alpha_priority;
+
+ /**
+ * @brief This member specifies the affinity of the alpha task.
+ */
+ cpu_set_t alpha_affinity;
+
+ /**
+ * @brief If this member is true, then an idle task shall execute on behalf
+ * of the alpha task.
+ */
+ bool alpha_idle;
+
+ /**
+ * @brief This member specifies the priority of the beta task.
+ */
+ rtems_task_priority beta_priority;
+
+ /**
+ * @brief This member specifies the affinity of the beta task.
+ */
+ cpu_set_t beta_affinity;
+
+ /**
+ * @brief If this member is true, then an idle task shall execute on behalf
+ * of the beta task.
+ */
+ bool beta_idle;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 12 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreSchedSmpEdfReqSetAffinity_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreSchedSmpEdfReqSetAffinity_Context;
+
+static ScoreSchedSmpEdfReqSetAffinity_Context
+ ScoreSchedSmpEdfReqSetAffinity_Instance;
+
+static const char * const ScoreSchedSmpEdfReqSetAffinity_PreDesc_Before[] = {
+ "All",
+ "X",
+ "NA"
+};
+
+static const char * const ScoreSchedSmpEdfReqSetAffinity_PreDesc_After[] = {
+ "All",
+ "X",
+ "Y",
+ "NA"
+};
+
+static const char * const ScoreSchedSmpEdfReqSetAffinity_PreDesc_Priority[] = {
+ "High",
+ "Low",
+ "NA"
+};
+
+static const char * const ScoreSchedSmpEdfReqSetAffinity_PreDesc_State[] = {
+ "Ready",
+ "Blocked",
+ "NA"
+};
+
+static const char * const ScoreSchedSmpEdfReqSetAffinity_PreDesc_Sticky[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const ScoreSchedSmpEdfReqSetAffinity_PreDesc_Pinned[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const ScoreSchedSmpEdfReqSetAffinity_PreDesc_AlphaPriority[] = {
+ "High",
+ "Low",
+ "NA"
+};
+
+static const char * const ScoreSchedSmpEdfReqSetAffinity_PreDesc_AlphaAffinity[] = {
+ "All",
+ "X",
+ "NA"
+};
+
+static const char * const ScoreSchedSmpEdfReqSetAffinity_PreDesc_AlphaIdle[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const ScoreSchedSmpEdfReqSetAffinity_PreDesc_BetaPriority[] = {
+ "High",
+ "Low",
+ "NA"
+};
+
+static const char * const ScoreSchedSmpEdfReqSetAffinity_PreDesc_BetaAffinity[] = {
+ "All",
+ "Y",
+ "NA"
+};
+
+static const char * const ScoreSchedSmpEdfReqSetAffinity_PreDesc_BetaIdle[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const ScoreSchedSmpEdfReqSetAffinity_PreDesc[] = {
+ ScoreSchedSmpEdfReqSetAffinity_PreDesc_Before,
+ ScoreSchedSmpEdfReqSetAffinity_PreDesc_After,
+ ScoreSchedSmpEdfReqSetAffinity_PreDesc_Priority,
+ ScoreSchedSmpEdfReqSetAffinity_PreDesc_State,
+ ScoreSchedSmpEdfReqSetAffinity_PreDesc_Sticky,
+ ScoreSchedSmpEdfReqSetAffinity_PreDesc_Pinned,
+ ScoreSchedSmpEdfReqSetAffinity_PreDesc_AlphaPriority,
+ ScoreSchedSmpEdfReqSetAffinity_PreDesc_AlphaAffinity,
+ ScoreSchedSmpEdfReqSetAffinity_PreDesc_AlphaIdle,
+ ScoreSchedSmpEdfReqSetAffinity_PreDesc_BetaPriority,
+ ScoreSchedSmpEdfReqSetAffinity_PreDesc_BetaAffinity,
+ ScoreSchedSmpEdfReqSetAffinity_PreDesc_BetaIdle,
+ NULL
+};
+
+#define TASK TQ_BLOCKER_C
+
+#define ALPHA TQ_BLOCKER_A
+
+#define BETA TQ_BLOCKER_B
+
+static void ScoreSchedSmpEdfReqSetAffinity_Pre_Before_Prepare(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Before state
+)
+{
+ switch ( state ) {
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_Before_All: {
+ /*
+ * While task ``T`` is affine to all processors of its home scheduler
+ * before the new thread to processor affinity is set.
+ */
+ CPU_FILL( &ctx->task_affinity_before );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_Before_X: {
+ /*
+ * While task ``T`` is affine to processor ``X`` before the new thread to
+ * processor affinity is set.
+ */
+ CPU_ZERO( &ctx->task_affinity_before );
+ CPU_SET( 0, &ctx->task_affinity_before );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_Before_NA:
+ break;
+ }
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Pre_After_Prepare(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_After state
+)
+{
+ switch ( state ) {
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_After_All: {
+ /*
+ * While task ``T`` is set to be affine to all processors of its home
+ * scheduler.
+ */
+ CPU_FILL( &ctx->task_affinity_after );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_After_X: {
+ /*
+ * While task ``T`` is set to be affine to processor ``X``.
+ */
+ CPU_ZERO( &ctx->task_affinity_after );
+ CPU_SET( 0, &ctx->task_affinity_after );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_After_Y: {
+ /*
+ * While task ``T`` is set to be affine to processor ``Y``.
+ */
+ CPU_ZERO( &ctx->task_affinity_after );
+ CPU_SET( 1, &ctx->task_affinity_after );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_After_NA:
+ break;
+ }
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Pre_Priority_Prepare(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Priority state
+)
+{
+ switch ( state ) {
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_Priority_High: {
+ /*
+ * While task ``T`` has a high priority.
+ */
+ ctx->task_priority = PRIO_HIGH;
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_Priority_Low: {
+ /*
+ * While task ``T`` has a low priority.
+ */
+ ctx->task_priority = PRIO_NORMAL;
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_Priority_NA:
+ break;
+ }
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Pre_State_Prepare(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_State state
+)
+{
+ switch ( state ) {
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_State_Ready: {
+ /*
+ * While task ``T`` is ready.
+ */
+ ctx->task_ready = true;
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_State_Blocked: {
+ /*
+ * While task ``T`` is blocked.
+ */
+ ctx->task_ready = false;
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_State_NA:
+ break;
+ }
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Pre_Sticky_Prepare(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Sticky state
+)
+{
+ switch ( state ) {
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_Sticky_Yes: {
+ /*
+ * While task ``T`` is sticky.
+ */
+ ctx->task_sticky = true;
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_Sticky_No: {
+ /*
+ * While task ``T`` is not sticky.
+ */
+ ctx->task_sticky = false;
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_Sticky_NA:
+ break;
+ }
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Pre_Pinned_Prepare(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Pinned state
+)
+{
+ switch ( state ) {
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_Pinned_Yes: {
+ /*
+ * While task ``T`` is pinned to a processor.
+ */
+ ctx->task_pinned = true;
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_Pinned_No: {
+ /*
+ * While task ``T`` is not pinned to a processor.
+ */
+ ctx->task_pinned = false;
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_Pinned_NA:
+ break;
+ }
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaPriority_Prepare(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaPriority state
+)
+{
+ switch ( state ) {
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaPriority_High: {
+ /*
+ * While task ``A`` has a high priority.
+ */
+ ctx->alpha_priority = PRIO_HIGH;
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaPriority_Low: {
+ /*
+ * While task ``A`` has a low priority.
+ */
+ ctx->alpha_priority = PRIO_NORMAL;
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaPriority_NA:
+ break;
+ }
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaAffinity_Prepare(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaAffinity state
+)
+{
+ switch ( state ) {
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaAffinity_All: {
+ /*
+ * While task ``A`` is affine to all processors of its home scheduler.
+ */
+ CPU_FILL( &ctx->alpha_affinity );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaAffinity_X: {
+ /*
+ * While task ``A`` is affine to processor ``X``.
+ */
+ CPU_ZERO( &ctx->alpha_affinity );
+ CPU_SET( 0, &ctx->alpha_affinity );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaAffinity_NA:
+ break;
+ }
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaIdle_Prepare(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaIdle state
+)
+{
+ switch ( state ) {
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaIdle_Yes: {
+ /*
+ * While task ``A`` is sticky, while task ``A`` is blocked.
+ */
+ ctx->alpha_idle = true;
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaIdle_No: {
+ /*
+ * While task ``A`` is not sticky.
+ */
+ ctx->alpha_idle = false;
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaIdle_NA:
+ break;
+ }
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Pre_BetaPriority_Prepare(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_BetaPriority state
+)
+{
+ switch ( state ) {
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_BetaPriority_High: {
+ /*
+ * While task ``B`` has a high priority.
+ */
+ ctx->beta_priority = PRIO_HIGH;
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_BetaPriority_Low: {
+ /*
+ * While task ``B`` has a low priority.
+ */
+ ctx->beta_priority = PRIO_NORMAL;
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_BetaPriority_NA:
+ break;
+ }
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Pre_BetaAffinity_Prepare(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_BetaAffinity state
+)
+{
+ switch ( state ) {
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_BetaAffinity_All: {
+ /*
+ * While task ``B`` is affine to all processors of its home scheduler.
+ */
+ CPU_FILL( &ctx->beta_affinity );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_BetaAffinity_Y: {
+ /*
+ * While task ``B`` is affine to processor ``Y``.
+ */
+ CPU_ZERO( &ctx->beta_affinity );
+ CPU_SET( 1, &ctx->beta_affinity );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_BetaAffinity_NA:
+ break;
+ }
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Pre_BetaIdle_Prepare(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx,
+ ScoreSchedSmpEdfReqSetAffinity_Pre_BetaIdle state
+)
+{
+ switch ( state ) {
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_BetaIdle_Yes: {
+ /*
+ * While task ``B`` is sticky, while task ``B`` is blocked.
+ */
+ ctx->beta_idle = true;
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_BetaIdle_No: {
+ /*
+ * While task ``B`` is not sticky,
+ */
+ ctx->beta_idle = false;
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Pre_BetaIdle_NA:
+ break;
+ }
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Post_X_Check(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X state
+)
+{
+ const Per_CPU_Control *cpu;
+ const Thread_Control *scheduled;
+ const Scheduler_Node *scheduler_node;
+
+ cpu = _Per_CPU_Get_by_index( 0 );
+ scheduled = cpu->heir;
+
+ switch ( state ) {
+ case ScoreSchedSmpEdfReqSetAffinity_Post_X_Task: {
+ /*
+ * The task ``T`` shall be scheduled on processor ``X``.
+ */
+ T_eq_ptr( scheduled, ctx->tq_ctx.worker_tcb[ TASK ] );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Post_X_TaskIdle: {
+ /*
+ * An idle task on behalf of task ``T`` shall be scheduled on processor
+ * ``X``.
+ */
+ T_true( scheduled->is_idle );
+ scheduler_node = _Thread_Scheduler_get_home_node(
+ ctx->tq_ctx.worker_tcb[ TASK ]
+ );
+ T_eq_ptr( scheduler_node->user, scheduled );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Post_X_Alpha: {
+ /*
+ * The task ``A`` shall be scheduled on processor ``X``.
+ */
+ T_eq_ptr( scheduled, ctx->tq_ctx.worker_tcb[ ALPHA ] );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Post_X_AlphaIdle: {
+ /*
+ * An idle task on behalf of task ``A`` shall be scheduled on processor
+ * ``X``.
+ */
+ T_true( scheduled->is_idle );
+ scheduler_node = _Thread_Scheduler_get_home_node(
+ ctx->tq_ctx.worker_tcb[ ALPHA ]
+ );
+ T_eq_ptr( scheduler_node->user, scheduled );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Post_X_Beta: {
+ /*
+ * The task ``B`` shall be scheduled on processor ``X``.
+ */
+ T_eq_ptr( scheduled, ctx->tq_ctx.worker_tcb[ BETA ] );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Post_X_BetaIdle: {
+ /*
+ * An idle task on behalf of task ``B`` shall be scheduled on processor
+ * ``X``.
+ */
+ T_true( scheduled->is_idle );
+ scheduler_node = _Thread_Scheduler_get_home_node(
+ ctx->tq_ctx.worker_tcb[ BETA ]
+ );
+ T_eq_ptr( scheduler_node->user, scheduled );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Post_X_NA:
+ break;
+ }
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Post_Y_Check(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y state
+)
+{
+ const Per_CPU_Control *cpu;
+ const Thread_Control *scheduled;
+ const Scheduler_Node *scheduler_node;
+
+ cpu = _Per_CPU_Get_by_index( 1 );
+ scheduled = cpu->heir;
+
+ switch ( state ) {
+ case ScoreSchedSmpEdfReqSetAffinity_Post_Y_Task: {
+ /*
+ * The task ``T`` shall be scheduled on processor ``Y``.
+ */
+ T_eq_ptr( scheduled, ctx->tq_ctx.worker_tcb[ TASK ] );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Post_Y_TaskIdle: {
+ /*
+ * An idle task on behalf of task ``T`` shall be scheduled on processor
+ * ``Y``.
+ */
+ T_true( scheduled->is_idle );
+ scheduler_node = _Thread_Scheduler_get_home_node(
+ ctx->tq_ctx.worker_tcb[ TASK ]
+ );
+ T_eq_ptr( scheduler_node->user, scheduled );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Post_Y_Alpha: {
+ /*
+ * The task ``A`` shall be scheduled on processor ``Y``.
+ */
+ T_eq_ptr( scheduled, ctx->tq_ctx.worker_tcb[ ALPHA ] );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Post_Y_AlphaIdle: {
+ /*
+ * An idle task on behalf of task ``A`` shall be scheduled on processor
+ * ``Y``.
+ */
+ T_true( scheduled->is_idle );
+ scheduler_node = _Thread_Scheduler_get_home_node(
+ ctx->tq_ctx.worker_tcb[ ALPHA ]
+ );
+ T_eq_ptr( scheduler_node->user, scheduled );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Post_Y_Beta: {
+ /*
+ * The task ``B`` shall be scheduled on processor ``Y``.
+ */
+ T_eq_ptr( scheduled, ctx->tq_ctx.worker_tcb[ BETA ] );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Post_Y_BetaIdle: {
+ /*
+ * An idle task on behalf of task ``B`` shall be scheduled on processor
+ * ``Y``.
+ */
+ T_true( scheduled->is_idle );
+ scheduler_node = _Thread_Scheduler_get_home_node(
+ ctx->tq_ctx.worker_tcb[ BETA ]
+ );
+ T_eq_ptr( scheduler_node->user, scheduled );
+ break;
+ }
+
+ case ScoreSchedSmpEdfReqSetAffinity_Post_Y_NA:
+ break;
+ }
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Setup(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx
+)
+{
+ rtems_status_code sc;
+ rtems_id mutex_a;
+ rtems_id mutex_b;
+ rtems_id mutex_c;
+
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->tq_ctx.deadlock = TQ_DEADLOCK_STATUS;
+ ctx->tq_ctx.enqueue_prepare = TQEnqueuePrepareDefault;
+ ctx->tq_ctx.enqueue_done = TQEnqueueDoneDefault;
+ ctx->tq_ctx.enqueue = TQEnqueueClassicSem;
+ ctx->tq_ctx.surrender = TQSurrenderClassicSem;
+ ctx->tq_ctx.get_owner = TQGetOwnerClassicSem;
+ ctx->tq_ctx.convert_status = TQConvertStatusClassic;
+ TQInitialize( &ctx->tq_ctx );
+
+ DeleteMutex( ctx->tq_ctx.mutex_id[ TQ_MUTEX_A ] );
+ DeleteMutex( ctx->tq_ctx.mutex_id[ TQ_MUTEX_B ] );
+ DeleteMutex( ctx->tq_ctx.mutex_id[ TQ_MUTEX_C ] );
+
+ mutex_a = 0;
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'M', 'T', 'X', 'A' ),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
+ PRIO_LOW,
+ &mutex_a
+ );
+ T_rsc_success( sc );
+
+ mutex_b = 0;
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'M', 'T', 'X', 'B' ),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
+ PRIO_VERY_LOW,
+ &mutex_b
+ );
+ T_rsc_success( sc );
+
+ mutex_c = 0;
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'M', 'T', 'X', 'C' ),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
+ PRIO_NORMAL,
+ &mutex_c
+ );
+ T_rsc_success( sc );
+
+ ctx->tq_ctx.mutex_id[ TQ_MUTEX_A ] = mutex_a;
+ ctx->tq_ctx.mutex_id[ TQ_MUTEX_B ] = mutex_b;
+ ctx->tq_ctx.mutex_id[ TQ_MUTEX_C ] = mutex_c;
+
+ RemoveProcessor( SCHEDULER_B_ID, 1 );
+ AddProcessor( SCHEDULER_A_ID, 1 );
+
+ TQSetPriority( &ctx->tq_ctx, TASK, PRIO_NORMAL );
+ TQSetPriority( &ctx->tq_ctx, ALPHA, PRIO_LOW );
+ TQSetPriority( &ctx->tq_ctx, BETA, PRIO_VERY_LOW );
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Setup_Wrap( void *arg )
+{
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreSchedSmpEdfReqSetAffinity_Setup( ctx );
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Teardown(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx
+)
+{
+ SetSelfAffinityAll();
+ TQDestroy( &ctx->tq_ctx );
+ RemoveProcessor( SCHEDULER_A_ID, 1 );
+ AddProcessor( SCHEDULER_B_ID, 1 );
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Teardown_Wrap( void *arg )
+{
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreSchedSmpEdfReqSetAffinity_Teardown( ctx );
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Action(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx
+)
+{
+ rtems_event_set events;
+
+ SetSelfPriority( PRIO_ULTRA_HIGH );
+ SetSelfAffinityAll();
+
+ if ( ctx->beta_idle ) {
+ events = TQ_EVENT_MUTEX_B_OBTAIN;
+ TQSendAndWaitForExecutionStop( &ctx->tq_ctx, BETA, events );
+ } else {
+ ctx->tq_ctx.busy_wait[ BETA ] = true;
+ events = TQ_EVENT_BUSY_WAIT;
+ TQSendAndSynchronizeRunner( &ctx->tq_ctx, BETA, events );
+ }
+
+ if ( ctx->alpha_idle ) {
+ events = TQ_EVENT_MUTEX_A_OBTAIN;
+ TQSendAndWaitForExecutionStop( &ctx->tq_ctx, ALPHA, events );
+ } else {
+ ctx->tq_ctx.busy_wait[ ALPHA ] = true;
+ events = TQ_EVENT_BUSY_WAIT;
+ TQSendAndSynchronizeRunner( &ctx->tq_ctx, ALPHA, events );
+ }
+
+ if ( ctx->task_pinned ) {
+ SetSelfAffinityOne( 1 );
+ TQSendAndSynchronizeRunner( &ctx->tq_ctx, TASK, TQ_EVENT_PIN );
+ SetSelfAffinityAll();
+ }
+
+ if ( ctx->task_ready ) {
+ ctx->tq_ctx.busy_wait[ TASK ] = true;
+ events = TQ_EVENT_BUSY_WAIT;
+ } else {
+ events = 0;
+ }
+
+ if ( ctx->task_sticky ) {
+ events |= TQ_EVENT_MUTEX_C_OBTAIN;
+ }
+
+ TQSendAndSynchronizeRunner( &ctx->tq_ctx, TASK, events );
+
+ if ( !ctx->task_ready ) {
+ TQWaitForExecutionStop( &ctx->tq_ctx, TASK );
+ }
+
+ (void) _Thread_Dispatch_disable();
+
+ SetAffinity( ctx->tq_ctx.worker_id[ TASK ], &ctx->task_affinity_before );
+ SetAffinity( ctx->tq_ctx.worker_id[ ALPHA ], &ctx->alpha_affinity );
+ SetAffinity( ctx->tq_ctx.worker_id[ BETA ], &ctx->beta_affinity );
+ SetSelfAffinityOne( 1 );
+ TQSetPriority( &ctx->tq_ctx, TASK, ctx->task_priority );
+ SetSelfPriority( PRIO_ULTRA_LOW );
+ TQSetPriority( &ctx->tq_ctx, ALPHA, ctx->alpha_priority );
+ TQSetPriority( &ctx->tq_ctx, BETA, ctx->beta_priority );
+
+ SetAffinity( ctx->tq_ctx.worker_id[ TASK ], &ctx->task_affinity_after );
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_Cleanup(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx
+)
+{
+ rtems_event_set events;
+
+ SetSelfPriority( PRIO_ULTRA_HIGH );
+ _Thread_Dispatch_enable( _Per_CPU_Get() );
+
+ SetSelfAffinityAll();
+
+ ctx->tq_ctx.busy_wait[ TASK ] = false;
+ ctx->tq_ctx.busy_wait[ ALPHA ] = false;
+ ctx->tq_ctx.busy_wait[ BETA ] = false;
+
+ TQSetPriority( &ctx->tq_ctx, TASK, PRIO_NORMAL );
+ TQSetPriority( &ctx->tq_ctx, ALPHA, PRIO_LOW );
+ TQSetPriority( &ctx->tq_ctx, BETA, PRIO_VERY_LOW );
+
+ if ( ctx->task_sticky ) {
+ events = TQ_EVENT_MUTEX_C_RELEASE;
+ } else {
+ events = 0;
+ }
+
+ if ( ctx->task_pinned ) {
+ events |= TQ_EVENT_UNPIN;
+ }
+
+ if ( events != 0 ) {
+ TQSendAndWaitForExecutionStop( &ctx->tq_ctx, TASK, events );
+ } else {
+ TQWaitForExecutionStop( &ctx->tq_ctx, TASK );
+ }
+
+ SetAffinityAll( ctx->tq_ctx.worker_id[ TASK ] );
+ SetAffinityAll( ctx->tq_ctx.worker_id[ ALPHA ] );
+
+ if ( ctx->alpha_idle ) {
+ events = TQ_EVENT_MUTEX_A_RELEASE;
+ } else {
+ events = 0;
+ }
+
+ if ( events != 0 ) {
+ TQSendAndWaitForExecutionStop( &ctx->tq_ctx, ALPHA, events );
+ } else {
+ TQWaitForExecutionStop( &ctx->tq_ctx, ALPHA );
+ }
+
+ SetAffinityAll( ctx->tq_ctx.worker_id[ BETA ] );
+
+ if ( ctx->beta_idle ) {
+ events = TQ_EVENT_MUTEX_B_RELEASE;
+ } else {
+ events = 0;
+ }
+
+ if ( events != 0 ) {
+ TQSendAndWaitForExecutionStop( &ctx->tq_ctx, BETA, events );
+ } else {
+ TQWaitForExecutionStop( &ctx->tq_ctx, BETA );
+ }
+}
+
+static const ScoreSchedSmpEdfReqSetAffinity_Entry
+ScoreSchedSmpEdfReqSetAffinity_Entries[] = {
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_NA,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_AlphaIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_BetaIdle },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_AlphaIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_Beta },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_Alpha,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_BetaIdle },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_Alpha,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_Beta },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_Task,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_BetaIdle },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_Task,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_Beta },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_Task,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_AlphaIdle },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_Task,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_Alpha },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_AlphaIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_Task },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_Alpha,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_Task },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_BetaIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_AlphaIdle },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_Beta,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_AlphaIdle },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_BetaIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_Alpha },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_Beta,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_Alpha },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_AlphaIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_TaskIdle },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_Alpha,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_TaskIdle },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_TaskIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_BetaIdle },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_TaskIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_Beta },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_TaskIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_AlphaIdle },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_TaskIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_Alpha },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_BetaIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_Task },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_Beta,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_Task },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_BetaIdle,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_TaskIdle },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_Beta,
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_TaskIdle }
+};
+
+static const uint8_t
+ScoreSchedSmpEdfReqSetAffinity_Map[] = {
+ 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,
+ 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,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 7, 7, 9, 9, 13, 14, 3, 4,
+ 8, 8, 10, 10, 1, 2, 1, 2, 9, 9, 9, 9, 3, 4, 3, 4, 10, 10, 10, 10, 5, 6, 5, 6,
+ 7, 7, 9, 9, 5, 6, 5, 6, 8, 8, 10, 10, 5, 6, 5, 6, 9, 9, 9, 9, 5, 6, 5, 6, 10,
+ 10, 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 5, 6, 5, 6, 5, 6,
+ 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 7, 7, 7, 7, 5, 6, 5, 6, 8, 8, 8, 8,
+ 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 11, 12, 1, 2, 7, 7, 9, 9, 13,
+ 14, 3, 4, 8, 8, 10, 10, 1, 2, 1, 2, 9, 9, 9, 9, 3, 4, 3, 4, 10, 10, 10, 10,
+ 5, 6, 5, 6, 7, 7, 9, 9, 5, 6, 5, 6, 8, 8, 10, 10, 5, 6, 5, 6, 9, 9, 9, 9, 5,
+ 6, 5, 6, 10, 10, 10, 10, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2,
+ 19, 19, 15, 15, 13, 14, 3, 4, 20, 20, 16, 16, 1, 2, 1, 2, 15, 15, 15, 15, 3,
+ 4, 3, 4, 16, 16, 16, 16, 17, 18, 17, 18, 19, 19, 15, 15, 17, 18, 17, 18, 20,
+ 20, 16, 16, 17, 18, 17, 18, 15, 15, 15, 15, 17, 18, 17, 18, 16, 16, 16, 16,
+ 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4,
+ 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2,
+ 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4,
+ 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2,
+ 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 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, 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, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 11, 12, 1, 2, 13, 14, 3, 4, 13,
+ 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 11, 12,
+ 1, 2, 3, 4, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3,
+ 4, 11, 12, 1, 2, 7, 7, 7, 7, 13, 14, 3, 4, 8, 8, 8, 8, 1, 2, 1, 2, 1, 2, 1,
+ 2, 3, 4, 3, 4, 3, 4, 3, 4, 5, 6, 5, 6, 7, 7, 7, 7, 5, 6, 5, 6, 8, 8, 8, 8, 5,
+ 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 11, 12, 1, 2, 11, 12, 1, 2, 13,
+ 14, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2,
+ 1, 2, 11, 12, 1, 2, 3, 4, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4,
+ 3, 4, 3, 4, 3, 4, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 11, 12,
+ 1, 2, 13, 14, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4,
+ 3, 4, 1, 2, 1, 2, 11, 12, 1, 2, 3, 4, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2,
+ 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4,
+ 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4,
+ 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2,
+ 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4,
+ 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2,
+ 3, 4, 3, 4, 3, 4, 3, 4, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 7,
+ 7, 7, 7, 13, 14, 3, 4, 8, 8, 8, 8, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4,
+ 3, 4, 5, 6, 5, 6, 7, 7, 7, 7, 5, 6, 5, 6, 8, 8, 8, 8, 5, 6, 5, 6, 5, 6, 5, 6,
+ 5, 6, 5, 6, 5, 6, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 5, 6,
+ 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 7, 7, 7, 7, 5, 6, 5, 6,
+ 8, 8, 8, 8, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 11, 12, 1, 2, 7,
+ 7, 7, 7, 13, 14, 3, 4, 8, 8, 8, 8, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4,
+ 3, 4, 5, 6, 5, 6, 7, 7, 7, 7, 5, 6, 5, 6, 8, 8, 8, 8, 5, 6, 5, 6, 5, 6, 5, 6,
+ 5, 6, 5, 6, 5, 6, 5, 6, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 19,
+ 19, 19, 19, 13, 14, 3, 4, 20, 20, 20, 20, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4,
+ 3, 4, 3, 4, 17, 18, 17, 18, 19, 19, 19, 19, 17, 18, 17, 18, 20, 20, 20, 20,
+ 17, 18, 17, 18, 17, 18, 17, 18, 17, 18, 17, 18, 17, 18, 17, 18, 1, 2, 1, 2,
+ 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4,
+ 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2,
+ 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2,
+ 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4,
+ 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 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, 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, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 11, 12, 1, 2, 13, 14, 3, 4, 13, 14, 3, 4, 1,
+ 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 11, 12, 1, 2, 3, 4,
+ 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 11, 12,
+ 1, 2, 7, 7, 7, 7, 13, 14, 3, 4, 8, 8, 8, 8, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3,
+ 4, 3, 4, 3, 4, 5, 6, 5, 6, 7, 7, 7, 7, 5, 6, 5, 6, 8, 8, 8, 8, 5, 6, 5, 6, 5,
+ 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 11, 12, 1, 2, 11, 12, 1, 2, 13, 14, 3, 4,
+ 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 11,
+ 12, 1, 2, 3, 4, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4,
+ 3, 4, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 11, 12, 1, 2, 13, 14,
+ 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1,
+ 2, 11, 12, 1, 2, 3, 4, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3,
+ 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1,
+ 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3,
+ 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3,
+ 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1,
+ 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3,
+ 4, 3, 4, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 9, 9, 9, 9, 13,
+ 14, 3, 4, 10, 10, 10, 10, 1, 2, 1, 2, 9, 9, 9, 9, 3, 4, 3, 4, 10, 10, 10, 10,
+ 21, 22, 1, 2, 9, 9, 9, 9, 21, 22, 3, 4, 10, 10, 10, 10, 21, 22, 1, 2, 9, 9,
+ 9, 9, 21, 22, 3, 4, 10, 10, 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8,
+ 8, 8, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 7, 7, 7, 7,
+ 5, 6, 5, 6, 8, 8, 8, 8, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 11,
+ 12, 1, 2, 9, 9, 9, 9, 13, 14, 3, 4, 10, 10, 10, 10, 1, 2, 1, 2, 9, 9, 9, 9,
+ 3, 4, 3, 4, 10, 10, 10, 10, 21, 22, 1, 2, 9, 9, 9, 9, 21, 22, 3, 4, 10, 10,
+ 10, 10, 21, 22, 1, 2, 9, 9, 9, 9, 21, 22, 3, 4, 10, 10, 10, 10, 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, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 15, 15, 15, 15, 13, 14, 3, 4, 16, 16,
+ 16, 16, 1, 2, 1, 2, 15, 15, 15, 15, 3, 4, 3, 4, 16, 16, 16, 16, 23, 24, 1, 2,
+ 15, 15, 15, 15, 23, 24, 3, 4, 16, 16, 16, 16, 23, 24, 1, 2, 15, 15, 15, 15,
+ 23, 24, 3, 4, 16, 16, 16, 16, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4,
+ 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4,
+ 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2,
+ 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4,
+ 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2,
+ 3, 4, 3, 4, 3, 4, 3, 4, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 11,
+ 12, 1, 2, 13, 14, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3,
+ 4, 3, 4, 1, 2, 1, 2, 11, 12, 1, 2, 3, 4, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1,
+ 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 11, 12, 1, 2, 7, 7, 7, 7, 13, 14, 3, 4, 8,
+ 8, 8, 8, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 5, 6, 5, 6, 7, 7, 7,
+ 7, 5, 6, 5, 6, 8, 8, 8, 8, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6,
+ 11, 12, 1, 2, 11, 12, 1, 2, 13, 14, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1,
+ 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 11, 12, 1, 2, 3, 4, 3, 4, 13, 14, 3,
+ 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 11, 12, 1, 2, 11, 12, 1, 2, 13, 14, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2,
+ 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 11, 12, 1, 2, 3, 4, 3, 4, 13,
+ 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2,
+ 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4,
+ 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4,
+ 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2,
+ 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4,
+ 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 11, 12, 1, 2, 7, 7, 9, 9, 13, 14, 3, 4, 8, 8, 10, 10, 1, 2, 1, 2,
+ 9, 9, 9, 9, 3, 4, 3, 4, 10, 10, 10, 10, 5, 6, 5, 6, 7, 7, 9, 9, 5, 6, 5, 6,
+ 8, 8, 10, 10, 5, 6, 5, 6, 9, 9, 9, 9, 5, 6, 5, 6, 10, 10, 10, 10, 7, 7, 7, 7,
+ 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6,
+ 5, 6, 5, 6, 5, 6, 7, 7, 7, 7, 5, 6, 5, 6, 8, 8, 8, 8, 5, 6, 5, 6, 5, 6, 5, 6,
+ 5, 6, 5, 6, 5, 6, 5, 6, 11, 12, 1, 2, 7, 7, 9, 9, 13, 14, 3, 4, 8, 8, 10, 10,
+ 1, 2, 1, 2, 9, 9, 9, 9, 3, 4, 3, 4, 10, 10, 10, 10, 5, 6, 5, 6, 7, 7, 9, 9,
+ 5, 6, 5, 6, 8, 8, 10, 10, 5, 6, 5, 6, 9, 9, 9, 9, 5, 6, 5, 6, 10, 10, 10, 10,
+ 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,
+ 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,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 19, 19, 15, 15, 13, 14, 3,
+ 4, 20, 20, 16, 16, 1, 2, 1, 2, 15, 15, 15, 15, 3, 4, 3, 4, 16, 16, 16, 16,
+ 17, 18, 17, 18, 19, 19, 15, 15, 17, 18, 17, 18, 20, 20, 16, 16, 17, 18, 17,
+ 18, 15, 15, 15, 15, 17, 18, 17, 18, 16, 16, 16, 16, 1, 2, 1, 2, 1, 2, 1, 2,
+ 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2,
+ 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4,
+ 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2,
+ 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4,
+ 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 11, 12, 1, 2, 11, 12, 1, 2, 13, 14, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1,
+ 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 11, 12, 1, 2, 3, 4, 3, 4, 13,
+ 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 11, 12, 1, 2, 7, 7,
+ 7, 7, 13, 14, 3, 4, 8, 8, 8, 8, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3,
+ 4, 5, 6, 5, 6, 7, 7, 7, 7, 5, 6, 5, 6, 8, 8, 8, 8, 5, 6, 5, 6, 5, 6, 5, 6, 5,
+ 6, 5, 6, 5, 6, 5, 6, 11, 12, 1, 2, 11, 12, 1, 2, 13, 14, 3, 4, 13, 14, 3, 4,
+ 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 11, 12, 1, 2, 3,
+ 4, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 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, 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, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 11, 12, 1, 2, 13, 14, 3, 4, 13,
+ 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 11, 12,
+ 1, 2, 3, 4, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3,
+ 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3,
+ 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1,
+ 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3,
+ 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1,
+ 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 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, 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 7, 7, 7, 7, 13, 14, 3, 4, 8,
+ 8, 8, 8, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 5, 6, 5, 6, 7, 7, 7,
+ 7, 5, 6, 5, 6, 8, 8, 8, 8, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 7,
+ 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5,
+ 6, 5, 6, 5, 6, 5, 6, 5, 6, 7, 7, 7, 7, 5, 6, 5, 6, 8, 8, 8, 8, 5, 6, 5, 6, 5,
+ 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 11, 12, 1, 2, 7, 7, 7, 7, 13, 14, 3, 4, 8,
+ 8, 8, 8, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 5, 6, 5, 6, 7, 7, 7,
+ 7, 5, 6, 5, 6, 8, 8, 8, 8, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 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, 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 19, 19, 19, 19, 13, 14, 3, 4,
+ 20, 20, 20, 20, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 17, 18, 17,
+ 18, 19, 19, 19, 19, 17, 18, 17, 18, 20, 20, 20, 20, 17, 18, 17, 18, 17, 18,
+ 17, 18, 17, 18, 17, 18, 17, 18, 17, 18, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4,
+ 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2,
+ 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4,
+ 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4,
+ 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2,
+ 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11,
+ 12, 1, 2, 11, 12, 1, 2, 13, 14, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2,
+ 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 11, 12, 1, 2, 3, 4, 3, 4, 13, 14, 3, 4,
+ 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 11, 12, 1, 2, 7, 7, 7, 7, 13,
+ 14, 3, 4, 8, 8, 8, 8, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 5, 6,
+ 5, 6, 7, 7, 7, 7, 5, 6, 5, 6, 8, 8, 8, 8, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6,
+ 5, 6, 5, 6, 11, 12, 1, 2, 11, 12, 1, 2, 13, 14, 3, 4, 13, 14, 3, 4, 1, 2, 1,
+ 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 11, 12, 1, 2, 3, 4, 3, 4,
+ 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 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, 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, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 11, 12, 1, 2, 13, 14, 3, 4, 13, 14, 3, 4,
+ 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 11, 12, 1, 2, 3,
+ 4, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2,
+ 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4,
+ 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2,
+ 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4,
+ 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4,
+ 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 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, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 9, 9, 9, 9, 13, 14, 3, 4, 10, 10, 10,
+ 10, 1, 2, 1, 2, 9, 9, 9, 9, 3, 4, 3, 4, 10, 10, 10, 10, 21, 22, 1, 2, 9, 9,
+ 9, 9, 21, 22, 3, 4, 10, 10, 10, 10, 21, 22, 1, 2, 9, 9, 9, 9, 21, 22, 3, 4,
+ 10, 10, 10, 10, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 5, 6, 5, 6,
+ 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 7, 7, 7, 7, 5, 6, 5, 6, 8, 8,
+ 8, 8, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 11, 12, 1, 2, 9, 9, 9,
+ 9, 13, 14, 3, 4, 10, 10, 10, 10, 1, 2, 1, 2, 9, 9, 9, 9, 3, 4, 3, 4, 10, 10,
+ 10, 10, 21, 22, 1, 2, 9, 9, 9, 9, 21, 22, 3, 4, 10, 10, 10, 10, 21, 22, 1, 2,
+ 9, 9, 9, 9, 21, 22, 3, 4, 10, 10, 10, 10, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 11, 12, 1, 2, 15, 15, 15, 15, 13, 14, 3, 4, 16, 16, 16, 16, 1, 2, 1, 2, 15,
+ 15, 15, 15, 3, 4, 3, 4, 16, 16, 16, 16, 23, 24, 1, 2, 15, 15, 15, 15, 23, 24,
+ 3, 4, 16, 16, 16, 16, 23, 24, 1, 2, 15, 15, 15, 15, 23, 24, 3, 4, 16, 16, 16,
+ 16, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2,
+ 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2,
+ 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4,
+ 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2,
+ 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4,
+ 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,
+ 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,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 11, 12, 1, 2, 13, 14, 3, 4,
+ 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 11,
+ 12, 1, 2, 3, 4, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4,
+ 3, 4, 11, 12, 1, 2, 7, 7, 7, 7, 13, 14, 3, 4, 8, 8, 8, 8, 1, 2, 1, 2, 1, 2,
+ 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 5, 6, 5, 6, 7, 7, 7, 7, 5, 6, 5, 6, 8, 8, 8, 8,
+ 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 11, 12, 1, 2, 11, 12, 1, 2,
+ 13, 14, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4,
+ 1, 2, 1, 2, 11, 12, 1, 2, 3, 4, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2,
+ 3, 4, 3, 4, 3, 4, 3, 4, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 12, 1, 2, 11,
+ 12, 1, 2, 13, 14, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3,
+ 4, 3, 4, 1, 2, 1, 2, 11, 12, 1, 2, 3, 4, 3, 4, 13, 14, 3, 4, 1, 2, 1, 2, 1,
+ 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3,
+ 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3,
+ 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1,
+ 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3,
+ 4, 3, 4, 1, 2, 1, 2, 1, 2, 1, 2, 3, 4, 3, 4, 3, 4, 3, 4, 1, 2, 1, 2, 1, 2, 1,
+ 2, 3, 4, 3, 4, 3, 4, 3, 4
+};
+
+static size_t ScoreSchedSmpEdfReqSetAffinity_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ ScoreSchedSmpEdfReqSetAffinity_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreSchedSmpEdfReqSetAffinity_Fixture = {
+ .setup = ScoreSchedSmpEdfReqSetAffinity_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreSchedSmpEdfReqSetAffinity_Teardown_Wrap,
+ .scope = ScoreSchedSmpEdfReqSetAffinity_Scope,
+ .initial_context = &ScoreSchedSmpEdfReqSetAffinity_Instance
+};
+
+static inline ScoreSchedSmpEdfReqSetAffinity_Entry
+ScoreSchedSmpEdfReqSetAffinity_PopEntry(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return ScoreSchedSmpEdfReqSetAffinity_Entries[
+ ScoreSchedSmpEdfReqSetAffinity_Map[ index ]
+ ];
+}
+
+static void ScoreSchedSmpEdfReqSetAffinity_TestVariant(
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx
+)
+{
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Before_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ ScoreSchedSmpEdfReqSetAffinity_Pre_After_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Priority_Prepare(
+ ctx,
+ ctx->Map.pcs[ 2 ]
+ );
+ ScoreSchedSmpEdfReqSetAffinity_Pre_State_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Sticky_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ ScoreSchedSmpEdfReqSetAffinity_Pre_Pinned_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaPriority_Prepare(
+ ctx,
+ ctx->Map.pcs[ 6 ]
+ );
+ ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaAffinity_Prepare(
+ ctx,
+ ctx->Map.pcs[ 7 ]
+ );
+ ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaIdle_Prepare(
+ ctx,
+ ctx->Map.pcs[ 8 ]
+ );
+ ScoreSchedSmpEdfReqSetAffinity_Pre_BetaPriority_Prepare(
+ ctx,
+ ctx->Map.pcs[ 9 ]
+ );
+ ScoreSchedSmpEdfReqSetAffinity_Pre_BetaAffinity_Prepare(
+ ctx,
+ ctx->Map.pcs[ 10 ]
+ );
+ ScoreSchedSmpEdfReqSetAffinity_Pre_BetaIdle_Prepare(
+ ctx,
+ ctx->Map.pcs[ 11 ]
+ );
+ ScoreSchedSmpEdfReqSetAffinity_Action( ctx );
+ ScoreSchedSmpEdfReqSetAffinity_Post_X_Check( ctx, ctx->Map.entry.Post_X );
+ ScoreSchedSmpEdfReqSetAffinity_Post_Y_Check( ctx, ctx->Map.entry.Post_Y );
+}
+
+/**
+ * @fn void T_case_body_ScoreSchedSmpEdfReqSetAffinity( void )
+ */
+T_TEST_CASE_FIXTURE(
+ ScoreSchedSmpEdfReqSetAffinity,
+ &ScoreSchedSmpEdfReqSetAffinity_Fixture
+)
+{
+ ScoreSchedSmpEdfReqSetAffinity_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = ScoreSchedSmpEdfReqSetAffinity_Pre_Before_All;
+ ctx->Map.pcs[ 0 ] < ScoreSchedSmpEdfReqSetAffinity_Pre_Before_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = ScoreSchedSmpEdfReqSetAffinity_Pre_After_All;
+ ctx->Map.pcs[ 1 ] < ScoreSchedSmpEdfReqSetAffinity_Pre_After_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = ScoreSchedSmpEdfReqSetAffinity_Pre_Priority_High;
+ ctx->Map.pcs[ 2 ] < ScoreSchedSmpEdfReqSetAffinity_Pre_Priority_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = ScoreSchedSmpEdfReqSetAffinity_Pre_State_Ready;
+ ctx->Map.pcs[ 3 ] < ScoreSchedSmpEdfReqSetAffinity_Pre_State_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = ScoreSchedSmpEdfReqSetAffinity_Pre_Sticky_Yes;
+ ctx->Map.pcs[ 4 ] < ScoreSchedSmpEdfReqSetAffinity_Pre_Sticky_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 5 ] = ScoreSchedSmpEdfReqSetAffinity_Pre_Pinned_Yes;
+ ctx->Map.pcs[ 5 ] < ScoreSchedSmpEdfReqSetAffinity_Pre_Pinned_NA;
+ ++ctx->Map.pcs[ 5 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 6 ] = ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaPriority_High;
+ ctx->Map.pcs[ 6 ] < ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaPriority_NA;
+ ++ctx->Map.pcs[ 6 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 7 ] = ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaAffinity_All;
+ ctx->Map.pcs[ 7 ] < ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaAffinity_NA;
+ ++ctx->Map.pcs[ 7 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 8 ] = ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaIdle_Yes;
+ ctx->Map.pcs[ 8 ] < ScoreSchedSmpEdfReqSetAffinity_Pre_AlphaIdle_NA;
+ ++ctx->Map.pcs[ 8 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 9 ] = ScoreSchedSmpEdfReqSetAffinity_Pre_BetaPriority_High;
+ ctx->Map.pcs[ 9 ] < ScoreSchedSmpEdfReqSetAffinity_Pre_BetaPriority_NA;
+ ++ctx->Map.pcs[ 9 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 10 ] = ScoreSchedSmpEdfReqSetAffinity_Pre_BetaAffinity_All;
+ ctx->Map.pcs[ 10 ] < ScoreSchedSmpEdfReqSetAffinity_Pre_BetaAffinity_NA;
+ ++ctx->Map.pcs[ 10 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 11 ] = ScoreSchedSmpEdfReqSetAffinity_Pre_BetaIdle_Yes;
+ ctx->Map.pcs[ 11 ] < ScoreSchedSmpEdfReqSetAffinity_Pre_BetaIdle_NA;
+ ++ctx->Map.pcs[ 11 ]
+ ) {
+ ctx->Map.entry =
+ ScoreSchedSmpEdfReqSetAffinity_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ ScoreSchedSmpEdfReqSetAffinity_TestVariant( ctx );
+ ScoreSchedSmpEdfReqSetAffinity_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-sched-smp-edf.c b/testsuites/validation/tc-sched-smp-edf.c
new file mode 100644
index 0000000000..7b07813ee1
--- /dev/null
+++ b/testsuites/validation/tc-sched-smp-edf.c
@@ -0,0 +1,111 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSchedSmpEdfValEdf
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreSchedSmpEdfValEdf spec:/score/sched/smp/edf/val/edf
+ *
+ * @ingroup TestsuitesValidationSmpOnly0
+ *
+ * @brief Tests for operations of the EDF SMP scheduler.
+ *
+ * This test case performs the following actions:
+ *
+ * - Validate a set affinity error case with an unsupported subset.
+ *
+ * @{
+ */
+
+/**
+ * @brief Validate a set affinity error case with an unsupported subset.
+ */
+static void ScoreSchedSmpEdfValEdf_Action_0( void )
+{
+ if ( rtems_scheduler_get_processor_maximum() >= 3 ) {
+ rtems_status_code sc;
+ cpu_set_t affinity;
+
+ CPU_ZERO( &affinity );
+ CPU_SET( 0, &affinity );
+ CPU_SET( 1, &affinity );
+
+ RemoveProcessor( SCHEDULER_B_ID, 1 );
+ RemoveProcessor( SCHEDULER_C_ID, 2 );
+ AddProcessor( SCHEDULER_A_ID, 1 );
+ AddProcessor( SCHEDULER_B_ID, 2 );
+
+ sc = rtems_task_set_affinity( RTEMS_SELF, sizeof( affinity), &affinity );
+ T_rsc( sc, RTEMS_INVALID_NUMBER );
+
+ RemoveProcessor( SCHEDULER_A_ID, 1 );
+ RemoveProcessor( SCHEDULER_B_ID, 2 );
+ AddProcessor( SCHEDULER_B_ID, 1 );
+ AddProcessor( SCHEDULER_C_ID, 2 );
+ }
+}
+
+/**
+ * @fn void T_case_body_ScoreSchedSmpEdfValEdf( void )
+ */
+T_TEST_CASE( ScoreSchedSmpEdfValEdf )
+{
+ ScoreSchedSmpEdfValEdf_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-sched-smp.c b/testsuites/validation/tc-sched-smp.c
new file mode 100644
index 0000000000..3e8e3fe1a2
--- /dev/null
+++ b/testsuites/validation/tc-sched-smp.c
@@ -0,0 +1,1404 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSchedSmpValSmp
+ */
+
+/*
+ * Copyright (C) 2021, 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/test-scheduler.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/schedulersmp.h>
+#include <rtems/score/threadimpl.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreSchedSmpValSmp spec:/score/sched/smp/val/smp
+ *
+ * @ingroup TestsuitesValidationSmpOnly0
+ *
+ * @brief Tests SMP-specific scheduler behaviour.
+ *
+ * This test case performs the following actions:
+ *
+ * - Construct a system state in which a sticky thread is blocked while an idle
+ * thread executes on behalf of the thread.
+ *
+ * - Block the sticky worker A while it uses an idle thread in the home
+ * scheduler.
+ *
+ * - Clean up all used resources.
+ *
+ * - Construct a system state in which a thread is preempted while it is
+ * blocked.
+ *
+ * - Block worker A and preempt it before the withdraw node operations are
+ * performed for worker A.
+ *
+ * - Clean up all used resources.
+ *
+ * - Construct a system state in which a thread is rescheduled while it is not
+ * scheduled on another scheduler.
+ *
+ * - Reschedule worker A by the home scheduler while worker A is not
+ * scheduled on another scheduler.
+ *
+ * - Clean up all used resources.
+ *
+ * - Construct a system state in which an ask for help request is cancelled
+ * while it is processed on another processor.
+ *
+ * - Unblock worker A. It cannot be scheduled on its home scheduler.
+ * Intercept the ask for help request. Block the worker A. This will
+ * cancel the ask for help request. Remove the request while the other
+ * processor tries to cancel the request.
+ *
+ * - Clean up all used resources.
+ *
+ * - Construct a system state in which a scheduler tries to schedule a node
+ * those owner thread is already scheduled during a block operation.
+ *
+ * - Block the runner thread while the owner thread of the highest priority
+ * ready node is already scheduled.
+ *
+ * - Clean up all used resources.
+ *
+ * - Construct a system state in which a scheduler tries to schedule a node
+ * those owner thread is blocked during a block operation.
+ *
+ * - Block the runner thread while the owner thread of the highest priority
+ * ready node is blocked.
+ *
+ * - Clean up all used resources.
+ *
+ * - Construct a system state in which a scheduler tries to schedule a node
+ * those owner thread is already scheduled during a set affinity operation.
+ *
+ * - Set the affinity of the runner thread while the owner thread of the
+ * highest priority ready node is already scheduled.
+ *
+ * - Clean up all used resources.
+ *
+ * - Construct a system state in which a scheduler tries to schedule a node
+ * those owner thread is already scheduled during a set affinity operation
+ * while a sticky node is involved.
+ *
+ * - Set the affinity of the runner thread while the owner thread of the
+ * highest priority ready node is already scheduled.
+ *
+ * - Clean up all used resources.
+ *
+ * - Construct a system state in which a scheduler tries to schedule a node
+ * those owner thread is blocked during a set affinity operation.
+ *
+ * - Set the affinity of the runner thread while the owner thread of the
+ * highest priority ready node is blocked.
+ *
+ * - Clean up all used resources.
+ *
+ * - Construct a system state in which a scheduler tries to schedule a node
+ * those owner thread is blocked during a set affinity operation while a
+ * sticky node is involved.
+ *
+ * - Set the affinity of the runner thread while the owner thread of the
+ * highest priority ready node is blocked.
+ *
+ * - Clean up all used resources.
+ *
+ * - Construct a system state in which a scheduler tries to schedule a node
+ * those owner thread is already scheduled during a set priority operation.
+ *
+ * - Set the priority of the runner thread while the owner thread of the
+ * highest priority ready node is already scheduled.
+ *
+ * - Clean up all used resources.
+ *
+ * - Construct a system state in which a scheduler tries to schedule a node
+ * those owner thread is already scheduled during a set priority operation
+ * while a sticky node is involved.
+ *
+ * - Set the priority of the runner thread while the owner thread of the
+ * highest priority ready node is already scheduled.
+ *
+ * - Clean up all used resources.
+ *
+ * - Construct a system state in which a scheduler tries to schedule a node
+ * those owner thread is blocked during a set priority operation.
+ *
+ * - Set the priority of the runner thread while the owner thread of the
+ * highest priority ready node is blocked.
+ *
+ * - Clean up all used resources.
+ *
+ * - Construct a system state in which a scheduler tries to schedule a node
+ * those owner thread is already scheduled during a yield operation.
+ *
+ * - Yield while the owner thread of the highest priority ready node is
+ * already scheduled.
+ *
+ * - Clean up all used resources.
+ *
+ * - Construct a system state in which a scheduler tries to schedule a node
+ * those owner thread is already scheduled during a yield operation while a
+ * sticky node is involved.
+ *
+ * - Yield while the owner thread of the highest priority ready node is
+ * already scheduled.
+ *
+ * - Clean up all used resources.
+ *
+ * - Construct a system state in which a scheduler tries to schedule a node
+ * those owner thread is blocked during a yield operation.
+ *
+ * - Yield while the owner thread of the highest priority ready node is
+ * blocked.
+ *
+ * - Clean up all used resources.
+ *
+ * - Construct a system state in which a scheduler tries to schedule a node
+ * those owner thread is blocked during a yield operation while a sticky node
+ * is involved.
+ *
+ * - Yield while the owner thread of the highest priority ready node is
+ * blocked.
+ *
+ * - Clean up all used resources.
+ *
+ * - Create three worker threads and a mutex. Use the mutex and the worker to
+ * check that a not scheduled thread does not get removed from the set of
+ * ready threads of a scheduler when a help request is reconsidered.
+ *
+ * - Prevent that worker B can perform a post-switch cleanup.
+ *
+ * - Give worker C a lower priority than worker B. Worker B will try to
+ * finish the thread dispatch by doing a post-switch cleanup. The
+ * post-switch cleanup cannot progress since the runner owns the thread
+ * state lock. Wait until the other processor waits on the thread state
+ * lock of worker B.
+ *
+ * - Give worker C a higher priority than worker B. Let worker B do its
+ * post-switch cleanup which will carry out the reconsider help requests
+ * for a not scheduled thread.
+ *
+ * - Clean up all used resources.
+ *
+ * @{
+ */
+
+typedef enum {
+ WORKER_A,
+ WORKER_B,
+ WORKER_C,
+ WORKER_COUNT
+} WorkerIndex;
+
+/**
+ * @brief Test context for spec:/score/sched/smp/val/smp test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the runner identifier.
+ */
+ rtems_id runner_id;
+
+ /**
+ * @brief This member contains the worker identifiers.
+ */
+ rtems_id worker_id[ WORKER_COUNT ];
+
+ /**
+ * @brief This member contains the mutex identifier.
+ */
+ rtems_id mutex_id;
+
+ /**
+ * @brief This member contains the sticky mutex identifier.
+ */
+ rtems_id sticky_id;
+
+ /**
+ * @brief This member contains the worker busy status.
+ */
+ volatile bool busy[ WORKER_COUNT ];
+
+ /**
+ * @brief This member contains an ISR lock context.
+ */
+ ISR_lock_Context lock_context;
+
+ /**
+ * @brief This member contains a counter.
+ */
+ uint32_t counter;
+
+ /**
+ * @brief If this member is true, then the worker shall be in the busy loop.
+ */
+ volatile bool is_busy[ WORKER_COUNT ];
+
+ /**
+ * @brief This member contains the per-CPU jobs.
+ */
+ Per_CPU_Job job[ 2 ];
+
+ /**
+ * @brief This member contains the per-CPU job contexts.
+ */
+ Per_CPU_Job_context job_context[ 2 ];
+
+ /**
+ * @brief This member contains the call within ISR request.
+ */
+ CallWithinISRRequest request;
+} ScoreSchedSmpValSmp_Context;
+
+static ScoreSchedSmpValSmp_Context
+ ScoreSchedSmpValSmp_Instance;
+
+#define EVENT_OBTAIN RTEMS_EVENT_0
+
+#define EVENT_RELEASE RTEMS_EVENT_1
+
+#define EVENT_STICKY_OBTAIN RTEMS_EVENT_2
+
+#define EVENT_STICKY_RELEASE RTEMS_EVENT_3
+
+#define EVENT_SYNC_RUNNER RTEMS_EVENT_4
+
+#define EVENT_BUSY RTEMS_EVENT_5
+
+typedef ScoreSchedSmpValSmp_Context Context;
+
+static void SendAndSync(
+ Context *ctx,
+ WorkerIndex worker,
+ rtems_event_set event
+)
+{
+ SendEvents( ctx->worker_id[ worker ], EVENT_SYNC_RUNNER | event );
+ ReceiveAllEvents( EVENT_SYNC_RUNNER );
+ WaitForExecutionStop( ctx->worker_id[ worker ] );
+}
+
+static void MakeBusy( Context *ctx, WorkerIndex worker )
+{
+ ctx->is_busy[ worker ] = false;
+ ctx->busy[ worker ] = true;
+ SendEvents( ctx->worker_id[ worker ], EVENT_BUSY );
+}
+
+static void WaitForBusy( Context *ctx, WorkerIndex worker )
+{
+ while ( !ctx->is_busy[ worker ] ) {
+ /* Wait */
+ }
+}
+
+static void StopBusy( Context *ctx, WorkerIndex worker )
+{
+ ctx->busy[ worker ] = false;
+ WaitForExecutionStop( ctx->worker_id[ worker ] );
+}
+
+static void MakeSticky( const Context *ctx )
+{
+ ObtainMutex( ctx->sticky_id );
+}
+
+static void CleanSticky( const Context *ctx )
+{
+ ReleaseMutex( ctx->sticky_id );
+}
+
+static void Block( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ SuspendTask( ctx->runner_id );
+ ResumeTask( ctx->runner_id );
+}
+
+static void OperationStopBusyC(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when,
+ T_scheduler_operation op
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ if ( when == T_SCHEDULER_BEFORE && event->operation == op ) {
+ T_scheduler_set_event_handler( NULL, NULL );
+ StopBusy( ctx, WORKER_C );
+ }
+}
+
+static void BlockStopBusyC(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ OperationStopBusyC( arg, event, when, T_SCHEDULER_BLOCK );
+}
+
+static void SetAffinityStopBusyC(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ OperationStopBusyC( arg, event, when, T_SCHEDULER_SET_AFFINITY );
+}
+
+static void UpdatePriorityStopBusyC(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ OperationStopBusyC( arg, event, when, T_SCHEDULER_UPDATE_PRIORITY );
+}
+
+static void YieldStopBusyC(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ OperationStopBusyC( arg, event, when, T_SCHEDULER_YIELD );
+}
+
+static void SuspendA( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ SuspendTask( ctx->worker_id[ WORKER_A ] );
+}
+
+static void OperationSuspendA(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when,
+ T_scheduler_operation op
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ if ( when == T_SCHEDULER_BEFORE && event->operation == op ) {
+ const rtems_tcb *worker_a;
+
+ T_scheduler_set_event_handler( NULL, NULL );
+ ctx->job_context[ 0 ].handler = SuspendA;
+ _Per_CPU_Submit_job( _Per_CPU_Get_by_index( 1 ), &ctx->job[ 0 ] );
+
+ worker_a = GetThread( ctx->worker_id[ WORKER_A ] );
+
+ while ( worker_a->Scheduler.state != THREAD_SCHEDULER_BLOCKED ) {
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ }
+ }
+}
+
+static void BlockSuspendA(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ OperationSuspendA( arg, event, when, T_SCHEDULER_BLOCK );
+}
+
+static void SetAffinitySuspendA(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ OperationSuspendA( arg, event, when, T_SCHEDULER_SET_AFFINITY );
+}
+
+static void UpdatePrioritySuspendA(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ OperationSuspendA( arg, event, when, T_SCHEDULER_UPDATE_PRIORITY );
+}
+
+static void YieldSuspendA(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ OperationSuspendA( arg, event, when, T_SCHEDULER_YIELD );
+}
+
+static void GuideAskForHelp( void *arg )
+{
+ Context *ctx;
+ Per_CPU_Control *cpu;
+ ISR_lock_Context lock_context;
+
+ ctx = arg;
+ cpu = _Per_CPU_Get_by_index( 0 );
+
+ _ISR_lock_ISR_disable( &lock_context );
+ _Per_CPU_Acquire( cpu, &lock_context );
+
+ ISRLockWaitForOthers( &cpu->Lock, 1 );
+
+ ctx->job_context[ 0 ].handler = SuspendA;
+ _Per_CPU_Submit_job( _Per_CPU_Get_by_index( 1 ), &ctx->job[ 0 ] );
+ ISRLockWaitForOthers( &cpu->Lock, 2 );
+
+ _Per_CPU_Release( cpu, &lock_context );
+ _ISR_lock_ISR_enable( &lock_context );
+}
+
+static void InterceptAskForHelp( void *arg )
+{
+ Context *ctx;
+ Per_CPU_Control *cpu_self;
+
+ ctx = arg;
+ cpu_self = _Per_CPU_Get();
+
+ if ( rtems_scheduler_get_processor_maximum() > 2 ) {
+ ctx->job_context[ 1 ].handler = GuideAskForHelp;
+ _Per_CPU_Submit_job( _Per_CPU_Get_by_index( 2 ), &ctx->job[ 1 ] );
+ ISRLockWaitForOwned( &cpu_self->Lock );
+ } else {
+ ISR_lock_Context lock_context;
+ Chain_Node *node;
+ Thread_Control *thread;
+
+ _ISR_lock_ISR_disable( &lock_context );
+ _Per_CPU_Acquire( cpu_self, &lock_context );
+ ctx->job_context[ 0 ].handler = SuspendA;
+ _Per_CPU_Submit_job( _Per_CPU_Get_by_index( 1 ), &ctx->job[ 0 ] );
+ ISRLockWaitForOthers( &cpu_self->Lock, 1 );
+
+ /* See _Thread_Preemption_intervention() */
+ node = _Chain_Get_first_unprotected( &cpu_self->Threads_in_need_for_help );
+ thread = THREAD_OF_SCHEDULER_HELP_NODE( node );
+ T_assert_eq_ptr( thread, GetThread( ctx->worker_id[ WORKER_A ] ) );
+ thread->Scheduler.ask_for_help_cpu = NULL;
+
+ _Per_CPU_Release( cpu_self, &lock_context );
+ _ISR_lock_ISR_enable( &lock_context );
+ }
+}
+
+static void UnblockAskForHelp(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ if (
+ when == T_SCHEDULER_BEFORE &&
+ event->operation == T_SCHEDULER_UNBLOCK
+ ) {
+ T_scheduler_set_event_handler( NULL, NULL );
+ ctx->request.handler = InterceptAskForHelp;
+ ctx->request.arg = ctx;
+ CallWithinISRSubmit( &ctx->request );
+ }
+}
+
+static void RaiseWorkerPriorityWithIdleRunner( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ SuspendTask( ctx->runner_id );
+ T_scheduler_set_event_handler( UpdatePriorityStopBusyC, ctx );
+ SetPriority( ctx->worker_id[ WORKER_A ], PRIO_HIGH );
+ SetPriority( ctx->worker_id[ WORKER_A ], PRIO_NORMAL );
+ ResumeTask( ctx->runner_id );
+}
+
+static void MakeReady( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ MakeBusy( ctx, WORKER_C );
+}
+
+static void UpdatePriorityMakeReady(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ if (
+ when == T_SCHEDULER_BEFORE &&
+ event->operation == T_SCHEDULER_UPDATE_PRIORITY
+ ) {
+ Thread_Control *thread;
+
+ T_scheduler_set_event_handler( NULL, NULL );
+
+ thread = GetThread( ctx->worker_id[ WORKER_A ] );
+ T_eq_int( thread->Scheduler.state, THREAD_SCHEDULER_SCHEDULED );
+
+ ctx->job_context[ 0 ].handler = MakeReady;
+ _Per_CPU_Submit_job( _Per_CPU_Get_by_index( 1 ), &ctx->job[ 0 ] );
+
+ while ( thread->Scheduler.state != THREAD_SCHEDULER_READY ) {
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ }
+ }
+}
+
+static void ReadyToScheduled( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ SuspendTask( ctx->runner_id );
+
+ T_scheduler_set_event_handler( UpdatePriorityMakeReady, ctx );
+ SetPriority( ctx->worker_id[ WORKER_A ], PRIO_HIGH );
+
+ SetPriority( ctx->runner_id, PRIO_VERY_HIGH );
+ ResumeTask( ctx->runner_id );
+}
+
+static void BlockAndReuseIdle( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ SuspendTask( ctx->runner_id );
+ SuspendTask( ctx->worker_id[ WORKER_A ] );
+ ResumeTask( ctx->worker_id[ WORKER_A ] );
+ SetPriority( ctx->runner_id, PRIO_HIGH );
+ ResumeTask( ctx->runner_id );
+}
+
+static void Preempt( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ MakeBusy( ctx, WORKER_C );
+}
+
+static void BlockAndPreempt(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ if ( when == T_SCHEDULER_AFTER && event->operation == T_SCHEDULER_BLOCK ) {
+ Thread_Control *thread;
+
+ T_scheduler_set_event_handler( NULL, NULL );
+
+ thread = GetThread( ctx->worker_id[ WORKER_A ] );
+ T_eq_int( thread->Scheduler.state, THREAD_SCHEDULER_BLOCKED );
+
+ ctx->job_context[ 0 ].handler = Preempt;
+ _Per_CPU_Submit_job( _Per_CPU_Get_by_index( 1 ), &ctx->job[ 0 ] );
+ _Per_CPU_Wait_for_job( _Per_CPU_Get_by_index( 1 ), &ctx->job[ 0 ] );
+ }
+}
+
+static void PrepareOwnerScheduled( Context *ctx )
+{
+ SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_B_ID, PRIO_NORMAL );
+ SendEvents( ctx->worker_id[ WORKER_A ], EVENT_OBTAIN );
+ SendAndSync( ctx, WORKER_B, EVENT_OBTAIN );
+ SetScheduler( ctx->worker_id[ WORKER_C ], SCHEDULER_B_ID, PRIO_HIGH );
+ SetPriority( ctx->worker_id[ WORKER_A ], PRIO_NORMAL );
+ MakeBusy( ctx, WORKER_C );
+ WaitForBusy( ctx, WORKER_C );
+ MakeBusy( ctx, WORKER_A );
+}
+
+static void CleanupOwnerScheduled( Context *ctx )
+{
+ StopBusy( ctx, WORKER_A );
+ SetPriority( ctx->worker_id[ WORKER_A ], PRIO_HIGH );
+ SendEvents( ctx->worker_id[ WORKER_A ], EVENT_RELEASE );
+ SendAndSync( ctx, WORKER_B, EVENT_RELEASE );
+ SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_A_ID, PRIO_HIGH );
+ SetScheduler( ctx->worker_id[ WORKER_C ], SCHEDULER_A_ID, PRIO_HIGH );
+}
+
+static void PrepareOwnerBlocked( Context *ctx )
+{
+ SetScheduler( ctx->worker_id[ WORKER_A ], SCHEDULER_B_ID, PRIO_NORMAL );
+ SendAndSync( ctx, WORKER_A, EVENT_OBTAIN );
+ SendEvents( ctx->worker_id[ WORKER_B ], EVENT_OBTAIN );
+ SetScheduler( ctx->worker_id[ WORKER_C ], SCHEDULER_B_ID, PRIO_HIGH );
+ MakeBusy( ctx, WORKER_C );
+ SetPriority( ctx->worker_id[ WORKER_B ], PRIO_LOW );
+ MakeBusy( ctx, WORKER_A );
+ SetPriority( ctx->worker_id[ WORKER_B ], PRIO_NORMAL );
+}
+
+static void CleanupOwnerBlocked( Context *ctx )
+{
+ StopBusy( ctx, WORKER_C );
+ ResumeTask( ctx->worker_id[ WORKER_A ] );
+ StopBusy( ctx, WORKER_A );
+ SendAndSync( ctx, WORKER_A, EVENT_RELEASE );
+ SetPriority( ctx->worker_id[ WORKER_B ], PRIO_HIGH );
+ SendEvents( ctx->worker_id[ WORKER_B ], EVENT_RELEASE );
+ SetScheduler( ctx->worker_id[ WORKER_A ], SCHEDULER_A_ID, PRIO_HIGH );
+ SetScheduler( ctx->worker_id[ WORKER_C ], SCHEDULER_A_ID, PRIO_HIGH );
+}
+
+static void ReconsiderHelpRequestB(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ Context *ctx;
+
+ (void) when;
+ ctx = arg;
+
+ if ( event->operation == T_SCHEDULER_RECONSIDER_HELP_REQUEST ) {
+ Scheduler_SMP_Node *node;
+
+ node = (Scheduler_SMP_Node *) event->node;
+ T_eq_int( node->state, SCHEDULER_SMP_NODE_READY );
+ ++ctx->counter;
+ }
+}
+
+static void ReleaseThreadLockB(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ if (
+ when == T_SCHEDULER_AFTER &&
+ event->operation == T_SCHEDULER_UPDATE_PRIORITY
+ ) {
+ Thread_Control *worker_b;
+
+ T_scheduler_set_event_handler( ReconsiderHelpRequestB, ctx );
+
+ worker_b = GetThread( ctx->worker_id[ WORKER_B ] );
+ T_eq_int( worker_b->Scheduler.state, THREAD_SCHEDULER_READY );
+
+ _Thread_State_release_critical( worker_b, &ctx->lock_context );
+ }
+}
+
+static void Worker( rtems_task_argument arg, WorkerIndex worker )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ while ( true ) {
+ rtems_event_set events;
+
+ events = ReceiveAnyEvents();
+
+ if ( ( events & EVENT_SYNC_RUNNER ) != 0 ) {
+ SendEvents( ctx->runner_id, EVENT_SYNC_RUNNER );
+ }
+
+ if ( ( events & EVENT_OBTAIN ) != 0 ) {
+ ObtainMutex( ctx->mutex_id );
+ }
+
+ if ( ( events & EVENT_RELEASE ) != 0 ) {
+ ReleaseMutex( ctx->mutex_id );
+ }
+
+ if ( ( events & EVENT_STICKY_OBTAIN ) != 0 ) {
+ ObtainMutex( ctx->sticky_id );
+ }
+
+ if ( ( events & EVENT_STICKY_RELEASE ) != 0 ) {
+ ReleaseMutex( ctx->sticky_id );
+ }
+
+ if ( ( events & EVENT_BUSY ) != 0 ) {
+ ctx->is_busy[ worker ] = true;
+
+ while ( ctx->busy[ worker ] ) {
+ /* Wait */
+ }
+
+ ctx->is_busy[ worker ] = false;
+ }
+ }
+}
+
+static void WorkerA( rtems_task_argument arg )
+{
+ Worker( arg, WORKER_A );
+}
+
+static void WorkerB( rtems_task_argument arg )
+{
+ Worker( arg, WORKER_B );
+}
+
+static void WorkerC( rtems_task_argument arg )
+{
+ Worker( arg, WORKER_C );
+}
+
+static void ScoreSchedSmpValSmp_Setup( ScoreSchedSmpValSmp_Context *ctx )
+{
+ rtems_status_code sc;
+ size_t i;
+
+ ctx->runner_id = rtems_task_self();
+ ctx->mutex_id = CreateMutex();
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->job ); ++i ) {
+ ctx->job_context[ i ].arg = ctx;
+ ctx->job[ i ].context = &ctx->job_context[ i ];
+ }
+
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'S', 'T', 'K', 'Y' ),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
+ PRIO_NORMAL,
+ &ctx->sticky_id
+ );
+ T_rsc_success( sc );
+
+ SetSelfPriority( PRIO_NORMAL );
+
+ ctx->worker_id[ WORKER_A ] = CreateTask( "WRKA", PRIO_HIGH );
+ StartTask( ctx->worker_id[ WORKER_A ], WorkerA, ctx );
+
+ ctx->worker_id[ WORKER_B ] = CreateTask( "WRKB", PRIO_HIGH );
+ StartTask( ctx->worker_id[ WORKER_B ], WorkerB, ctx );
+
+ ctx->worker_id[ WORKER_C ] = CreateTask( "WRKC", PRIO_HIGH );
+ StartTask( ctx->worker_id[ WORKER_C ], WorkerC, ctx );
+}
+
+static void ScoreSchedSmpValSmp_Setup_Wrap( void *arg )
+{
+ ScoreSchedSmpValSmp_Context *ctx;
+
+ ctx = arg;
+ ScoreSchedSmpValSmp_Setup( ctx );
+}
+
+static void ScoreSchedSmpValSmp_Teardown( ScoreSchedSmpValSmp_Context *ctx )
+{
+ DeleteTask( ctx->worker_id[ WORKER_A ] );
+ DeleteTask( ctx->worker_id[ WORKER_B ] );
+ DeleteTask( ctx->worker_id[ WORKER_C ] );
+ DeleteMutex( ctx->mutex_id );
+ DeleteMutex( ctx->sticky_id );
+ RestoreRunnerPriority();
+}
+
+static void ScoreSchedSmpValSmp_Teardown_Wrap( void *arg )
+{
+ ScoreSchedSmpValSmp_Context *ctx;
+
+ ctx = arg;
+ ScoreSchedSmpValSmp_Teardown( ctx );
+}
+
+static T_fixture ScoreSchedSmpValSmp_Fixture = {
+ .setup = ScoreSchedSmpValSmp_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreSchedSmpValSmp_Teardown_Wrap,
+ .scope = NULL,
+ .initial_context = &ScoreSchedSmpValSmp_Instance
+};
+
+/**
+ * @brief Construct a system state in which a sticky thread is blocked while an
+ * idle thread executes on behalf of the thread.
+ */
+static void ScoreSchedSmpValSmp_Action_0( ScoreSchedSmpValSmp_Context *ctx )
+{
+ SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_B_ID, PRIO_NORMAL );
+ SendEvents( ctx->worker_id[ WORKER_A ], EVENT_OBTAIN );
+ SendAndSync( ctx, WORKER_B, EVENT_OBTAIN );
+ SetPriority( ctx->worker_id[ WORKER_A ], PRIO_NORMAL );
+ SendEvents( ctx->worker_id[ WORKER_A ], EVENT_STICKY_OBTAIN );
+ MakeBusy( ctx, WORKER_A );
+ WaitForBusy( ctx, WORKER_A );
+
+ /*
+ * Block the sticky worker A while it uses an idle thread in the home
+ * scheduler.
+ */
+ CallWithinISR( BlockAndReuseIdle, ctx );
+
+ /*
+ * Clean up all used resources.
+ */
+ StopBusy( ctx, WORKER_A );
+ SendAndSync( ctx, WORKER_A, EVENT_STICKY_RELEASE );
+ SetPriority( ctx->worker_id[ WORKER_A ], PRIO_HIGH );
+ SetSelfPriority( PRIO_NORMAL );
+ SendEvents( ctx->worker_id[ WORKER_A ], EVENT_RELEASE );
+ SendAndSync( ctx, WORKER_B, EVENT_RELEASE );
+ SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_A_ID, PRIO_HIGH );
+}
+
+/**
+ * @brief Construct a system state in which a thread is preempted while it is
+ * blocked.
+ */
+static void ScoreSchedSmpValSmp_Action_1( ScoreSchedSmpValSmp_Context *ctx )
+{
+ SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_B_ID, PRIO_NORMAL );
+ SendEvents( ctx->worker_id[ WORKER_A ], EVENT_OBTAIN );
+ SendAndSync( ctx, WORKER_B, EVENT_OBTAIN );
+ SetScheduler( ctx->worker_id[ WORKER_C ], SCHEDULER_B_ID, PRIO_HIGH );
+ SetPriority( ctx->worker_id[ WORKER_A ], PRIO_NORMAL );
+ MakeBusy( ctx, WORKER_A );
+ WaitForBusy( ctx, WORKER_A );
+
+ /*
+ * Block worker A and preempt it before the withdraw node operations are
+ * performed for worker A.
+ */
+ T_scheduler_set_event_handler( BlockAndPreempt, ctx );
+ SuspendTask( ctx->worker_id[ WORKER_A ] );
+
+ /*
+ * Clean up all used resources.
+ */
+ ResumeTask( ctx->worker_id[ WORKER_A ] );
+ StopBusy( ctx, WORKER_C );
+ StopBusy( ctx, WORKER_A );
+ SetPriority( ctx->worker_id[ WORKER_A ], PRIO_HIGH );
+ SetSelfPriority( PRIO_NORMAL );
+ SendEvents( ctx->worker_id[ WORKER_A ], EVENT_RELEASE );
+ SendAndSync( ctx, WORKER_B, EVENT_RELEASE );
+ SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_A_ID, PRIO_HIGH );
+ SetScheduler( ctx->worker_id[ WORKER_C ], SCHEDULER_A_ID, PRIO_HIGH );
+}
+
+/**
+ * @brief Construct a system state in which a thread is rescheduled while it
+ * is not scheduled on another scheduler.
+ */
+static void ScoreSchedSmpValSmp_Action_2( ScoreSchedSmpValSmp_Context *ctx )
+{
+ SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_B_ID, PRIO_NORMAL );
+ SendEvents( ctx->worker_id[ WORKER_A ], EVENT_OBTAIN );
+ SendAndSync( ctx, WORKER_B, EVENT_OBTAIN );
+ SetScheduler( ctx->worker_id[ WORKER_C ], SCHEDULER_B_ID, PRIO_HIGH );
+ SetPriority( ctx->worker_id[ WORKER_A ], PRIO_NORMAL );
+ SendEvents( ctx->worker_id[ WORKER_A ], EVENT_STICKY_OBTAIN );
+ MakeBusy( ctx, WORKER_A );
+ WaitForBusy( ctx, WORKER_A );
+
+ /*
+ * Reschedule worker A by the home scheduler while worker A is not scheduled
+ * on another scheduler.
+ */
+ CallWithinISR( ReadyToScheduled, ctx );
+
+ /*
+ * Clean up all used resources.
+ */
+ StopBusy( ctx, WORKER_C );
+ StopBusy( ctx, WORKER_A );
+ SendAndSync( ctx, WORKER_A, EVENT_STICKY_RELEASE );
+ SetPriority( ctx->worker_id[ WORKER_A ], PRIO_HIGH );
+ SetSelfPriority( PRIO_NORMAL );
+ SendEvents( ctx->worker_id[ WORKER_A ], EVENT_RELEASE );
+ SendAndSync( ctx, WORKER_B, EVENT_RELEASE );
+ SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_A_ID, PRIO_HIGH );
+ SetScheduler( ctx->worker_id[ WORKER_C ], SCHEDULER_A_ID, PRIO_HIGH );
+}
+
+/**
+ * @brief Construct a system state in which an ask for help request is
+ * cancelled while it is processed on another processor.
+ */
+static void ScoreSchedSmpValSmp_Action_3( ScoreSchedSmpValSmp_Context *ctx )
+{
+ PrepareOwnerScheduled( ctx );
+
+ /*
+ * Unblock worker A. It cannot be scheduled on its home scheduler. Intercept
+ * the ask for help request. Block the worker A. This will cancel the ask
+ * for help request. Remove the request while the other processor tries to
+ * cancel the request.
+ */
+ SuspendTask( ctx->worker_id[ WORKER_A ] );
+ T_scheduler_set_event_handler( UnblockAskForHelp, ctx );
+ ResumeTask( ctx->worker_id[ WORKER_A ] );
+
+ /*
+ * Clean up all used resources.
+ */
+ ResumeTask( ctx->worker_id[ WORKER_A ] );
+ StopBusy( ctx, WORKER_C );
+ CleanupOwnerScheduled( ctx );
+}
+
+/**
+ * @brief Construct a system state in which a scheduler tries to schedule a
+ * node those owner thread is already scheduled during a block operation.
+ */
+static void ScoreSchedSmpValSmp_Action_4( ScoreSchedSmpValSmp_Context *ctx )
+{
+ PrepareOwnerScheduled( ctx );
+
+ /*
+ * Block the runner thread while the owner thread of the highest priority
+ * ready node is already scheduled.
+ */
+ T_scheduler_set_event_handler( BlockStopBusyC, ctx );
+ CallWithinISR( Block, ctx );
+
+ /*
+ * Clean up all used resources.
+ */
+ CleanupOwnerScheduled( ctx );
+}
+
+/**
+ * @brief Construct a system state in which a scheduler tries to schedule a
+ * node those owner thread is blocked during a block operation.
+ */
+static void ScoreSchedSmpValSmp_Action_5( ScoreSchedSmpValSmp_Context *ctx )
+{
+ PrepareOwnerBlocked( ctx );
+
+ /*
+ * Block the runner thread while the owner thread of the highest priority
+ * ready node is blocked.
+ */
+ T_scheduler_set_event_handler( BlockSuspendA, ctx );
+ CallWithinISR( Block, ctx );
+
+ /*
+ * Clean up all used resources.
+ */
+ CleanupOwnerBlocked( ctx );
+}
+
+/**
+ * @brief Construct a system state in which a scheduler tries to schedule a
+ * node those owner thread is already scheduled during a set affinity
+ * operation.
+ */
+static void ScoreSchedSmpValSmp_Action_6( ScoreSchedSmpValSmp_Context *ctx )
+{
+ PrepareOwnerScheduled( ctx );
+
+ /*
+ * Set the affinity of the runner thread while the owner thread of the
+ * highest priority ready node is already scheduled.
+ */
+ T_scheduler_set_event_handler( SetAffinityStopBusyC, ctx );
+ SetSelfAffinityAll();
+
+ /*
+ * Clean up all used resources.
+ */
+ CleanupOwnerScheduled( ctx );
+}
+
+/**
+ * @brief Construct a system state in which a scheduler tries to schedule a
+ * node those owner thread is already scheduled during a set affinity
+ * operation while a sticky node is involved.
+ */
+static void ScoreSchedSmpValSmp_Action_7( ScoreSchedSmpValSmp_Context *ctx )
+{
+ PrepareOwnerScheduled( ctx );
+
+ /*
+ * Set the affinity of the runner thread while the owner thread of the
+ * highest priority ready node is already scheduled.
+ */
+ MakeSticky( ctx );
+ T_scheduler_set_event_handler( SetAffinityStopBusyC, ctx );
+ SetSelfAffinityAll();
+ CleanSticky( ctx );
+
+ /*
+ * Clean up all used resources.
+ */
+ CleanupOwnerScheduled( ctx );
+}
+
+/**
+ * @brief Construct a system state in which a scheduler tries to schedule a
+ * node those owner thread is blocked during a set affinity operation.
+ */
+static void ScoreSchedSmpValSmp_Action_8( ScoreSchedSmpValSmp_Context *ctx )
+{
+ PrepareOwnerBlocked( ctx );
+
+ /*
+ * Set the affinity of the runner thread while the owner thread of the
+ * highest priority ready node is blocked.
+ */
+ T_scheduler_set_event_handler( SetAffinitySuspendA, ctx );
+ SetSelfAffinityAll();
+
+ /*
+ * Clean up all used resources.
+ */
+ CleanupOwnerBlocked( ctx );
+}
+
+/**
+ * @brief Construct a system state in which a scheduler tries to schedule a
+ * node those owner thread is blocked during a set affinity operation while a
+ * sticky node is involved.
+ */
+static void ScoreSchedSmpValSmp_Action_9( ScoreSchedSmpValSmp_Context *ctx )
+{
+ PrepareOwnerBlocked( ctx );
+
+ /*
+ * Set the affinity of the runner thread while the owner thread of the
+ * highest priority ready node is blocked.
+ */
+ MakeSticky( ctx );
+ T_scheduler_set_event_handler( SetAffinitySuspendA, ctx );
+ SetSelfAffinityAll();
+ CleanSticky( ctx );
+
+ /*
+ * Clean up all used resources.
+ */
+ CleanupOwnerBlocked( ctx );
+}
+
+/**
+ * @brief Construct a system state in which a scheduler tries to schedule a
+ * node those owner thread is already scheduled during a set priority
+ * operation.
+ */
+static void ScoreSchedSmpValSmp_Action_10( ScoreSchedSmpValSmp_Context *ctx )
+{
+ PrepareOwnerScheduled( ctx );
+
+ /*
+ * Set the priority of the runner thread while the owner thread of the
+ * highest priority ready node is already scheduled.
+ */
+ SetSelfPriority( PRIO_HIGH );
+ T_scheduler_set_event_handler( UpdatePriorityStopBusyC, ctx );
+ SetSelfPriority( PRIO_NORMAL );
+
+ /*
+ * Clean up all used resources.
+ */
+ CleanupOwnerScheduled( ctx );
+}
+
+/**
+ * @brief Construct a system state in which a scheduler tries to schedule a
+ * node those owner thread is already scheduled during a set priority
+ * operation while a sticky node is involved.
+ */
+static void ScoreSchedSmpValSmp_Action_11( ScoreSchedSmpValSmp_Context *ctx )
+{
+ PrepareOwnerScheduled( ctx );
+
+ /*
+ * Set the priority of the runner thread while the owner thread of the
+ * highest priority ready node is already scheduled.
+ */
+ MakeSticky( ctx );
+ CallWithinISR( RaiseWorkerPriorityWithIdleRunner, ctx );
+ CleanSticky( ctx );
+
+ /*
+ * Clean up all used resources.
+ */
+ CleanupOwnerScheduled( ctx );
+}
+
+/**
+ * @brief Construct a system state in which a scheduler tries to schedule a
+ * node those owner thread is blocked during a set priority operation.
+ */
+static void ScoreSchedSmpValSmp_Action_12( ScoreSchedSmpValSmp_Context *ctx )
+{
+ PrepareOwnerBlocked( ctx );
+
+ /*
+ * Set the priority of the runner thread while the owner thread of the
+ * highest priority ready node is blocked.
+ */
+ SetSelfPriority( PRIO_HIGH );
+ T_scheduler_set_event_handler( UpdatePrioritySuspendA, ctx );
+ SetSelfPriority( PRIO_NORMAL );
+
+ /*
+ * Clean up all used resources.
+ */
+ CleanupOwnerBlocked( ctx );
+}
+
+/**
+ * @brief Construct a system state in which a scheduler tries to schedule a
+ * node those owner thread is already scheduled during a yield operation.
+ */
+static void ScoreSchedSmpValSmp_Action_13( ScoreSchedSmpValSmp_Context *ctx )
+{
+ PrepareOwnerScheduled( ctx );
+
+ /*
+ * Yield while the owner thread of the highest priority ready node is already
+ * scheduled.
+ */
+ T_scheduler_set_event_handler( YieldStopBusyC, ctx );
+ Yield();
+
+ /*
+ * Clean up all used resources.
+ */
+ CleanupOwnerScheduled( ctx );
+}
+
+/**
+ * @brief Construct a system state in which a scheduler tries to schedule a
+ * node those owner thread is already scheduled during a yield operation
+ * while a sticky node is involved.
+ */
+static void ScoreSchedSmpValSmp_Action_14( ScoreSchedSmpValSmp_Context *ctx )
+{
+ PrepareOwnerScheduled( ctx );
+
+ /*
+ * Yield while the owner thread of the highest priority ready node is already
+ * scheduled.
+ */
+ MakeSticky( ctx );
+ T_scheduler_set_event_handler( YieldStopBusyC, ctx );
+ Yield();
+ CleanSticky( ctx );
+
+ /*
+ * Clean up all used resources.
+ */
+ CleanupOwnerScheduled( ctx );
+}
+
+/**
+ * @brief Construct a system state in which a scheduler tries to schedule a
+ * node those owner thread is blocked during a yield operation.
+ */
+static void ScoreSchedSmpValSmp_Action_15( ScoreSchedSmpValSmp_Context *ctx )
+{
+ PrepareOwnerBlocked( ctx );
+
+ /*
+ * Yield while the owner thread of the highest priority ready node is
+ * blocked.
+ */
+ T_scheduler_set_event_handler( YieldSuspendA, ctx );
+ Yield();
+
+ /*
+ * Clean up all used resources.
+ */
+ CleanupOwnerBlocked( ctx );
+}
+
+/**
+ * @brief Construct a system state in which a scheduler tries to schedule a
+ * node those owner thread is blocked during a yield operation while a sticky
+ * node is involved.
+ */
+static void ScoreSchedSmpValSmp_Action_16( ScoreSchedSmpValSmp_Context *ctx )
+{
+ PrepareOwnerBlocked( ctx );
+
+ /*
+ * Yield while the owner thread of the highest priority ready node is
+ * blocked.
+ */
+ MakeSticky( ctx );
+ T_scheduler_set_event_handler( YieldSuspendA, ctx );
+ Yield();
+ CleanSticky( ctx );
+
+ /*
+ * Clean up all used resources.
+ */
+ CleanupOwnerBlocked( ctx );
+}
+
+/**
+ * @brief Create three worker threads and a mutex. Use the mutex and the
+ * worker to check that a not scheduled thread does not get removed from the
+ * set of ready threads of a scheduler when a help request is reconsidered.
+ */
+static void ScoreSchedSmpValSmp_Action_17( ScoreSchedSmpValSmp_Context *ctx )
+{
+ Thread_Control *worker_b;
+
+ SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_B_ID, PRIO_NORMAL );
+ SetScheduler( ctx->worker_id[ WORKER_C ], SCHEDULER_B_ID, PRIO_HIGH );
+ SendAndSync( ctx, WORKER_B, EVENT_OBTAIN );
+ SendEvents( ctx->worker_id[ WORKER_A ], EVENT_OBTAIN );
+ SetPriority( ctx->worker_id[ WORKER_A ], PRIO_LOW );
+ MakeBusy( ctx, WORKER_B );
+ WaitForBusy( ctx, WORKER_B );
+ MakeBusy( ctx, WORKER_C );
+ WaitForBusy( ctx, WORKER_C );
+
+ /*
+ * Prevent that worker B can perform a post-switch cleanup.
+ */
+ worker_b = GetThread( ctx->worker_id[ WORKER_B ] );
+ _Thread_State_acquire( worker_b, &ctx->lock_context );
+ _ISR_lock_ISR_enable( &ctx->lock_context );
+
+ /*
+ * Give worker C a lower priority than worker B. Worker B will try to finish
+ * the thread dispatch by doing a post-switch cleanup. The post-switch
+ * cleanup cannot progress since the runner owns the thread state lock. Wait
+ * until the other processor waits on the thread state lock of worker B.
+ */
+ SetPriority( ctx->worker_id[ WORKER_C ], PRIO_LOW );
+ TicketLockWaitForOthers( &worker_b->Join_queue.Queue.Lock, 1 );
+
+ /*
+ * Give worker C a higher priority than worker B. Let worker B do its
+ * post-switch cleanup which will carry out the reconsider help requests for
+ * a not scheduled thread.
+ */
+ ctx->counter = 0;
+ T_scheduler_set_event_handler( ReleaseThreadLockB, ctx );
+ SetPriority( ctx->worker_id[ WORKER_C ], PRIO_HIGH );
+ T_scheduler_set_event_handler( NULL, NULL );
+ T_eq_u32( ctx->counter, 4 );
+
+ /*
+ * Clean up all used resources.
+ */
+ StopBusy( ctx, WORKER_B );
+ StopBusy( ctx, WORKER_C );
+ SendAndSync( ctx, WORKER_B, EVENT_RELEASE );
+ SetPriority( ctx->worker_id[ WORKER_A ], PRIO_HIGH );
+ SendEvents( ctx->worker_id[ WORKER_A ], EVENT_RELEASE );
+ SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_A_ID, PRIO_HIGH );
+ SetScheduler( ctx->worker_id[ WORKER_C ], SCHEDULER_A_ID, PRIO_HIGH );
+}
+
+/**
+ * @fn void T_case_body_ScoreSchedSmpValSmp( void )
+ */
+T_TEST_CASE_FIXTURE( ScoreSchedSmpValSmp, &ScoreSchedSmpValSmp_Fixture )
+{
+ ScoreSchedSmpValSmp_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ ScoreSchedSmpValSmp_Action_0( ctx );
+ ScoreSchedSmpValSmp_Action_1( ctx );
+ ScoreSchedSmpValSmp_Action_2( ctx );
+ ScoreSchedSmpValSmp_Action_3( ctx );
+ ScoreSchedSmpValSmp_Action_4( ctx );
+ ScoreSchedSmpValSmp_Action_5( ctx );
+ ScoreSchedSmpValSmp_Action_6( ctx );
+ ScoreSchedSmpValSmp_Action_7( ctx );
+ ScoreSchedSmpValSmp_Action_8( ctx );
+ ScoreSchedSmpValSmp_Action_9( ctx );
+ ScoreSchedSmpValSmp_Action_10( ctx );
+ ScoreSchedSmpValSmp_Action_11( ctx );
+ ScoreSchedSmpValSmp_Action_12( ctx );
+ ScoreSchedSmpValSmp_Action_13( ctx );
+ ScoreSchedSmpValSmp_Action_14( ctx );
+ ScoreSchedSmpValSmp_Action_15( ctx );
+ ScoreSchedSmpValSmp_Action_16( ctx );
+ ScoreSchedSmpValSmp_Action_17( ctx );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-sched-yield.c b/testsuites/validation/tc-sched-yield.c
new file mode 100644
index 0000000000..057579fd1c
--- /dev/null
+++ b/testsuites/validation/tc-sched-yield.c
@@ -0,0 +1,845 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSchedReqYield
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/test-scheduler.h>
+#include <rtems/score/percpu.h>
+
+#include "tx-support.h"
+#include "tx-thread-queue.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreSchedReqYield spec:/score/sched/req/yield
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreSchedReqYield_Pre_EligibleScheduler_Home,
+ ScoreSchedReqYield_Pre_EligibleScheduler_Helping,
+ ScoreSchedReqYield_Pre_EligibleScheduler_NA
+} ScoreSchedReqYield_Pre_EligibleScheduler;
+
+typedef enum {
+ ScoreSchedReqYield_Pre_UsedScheduler_Home,
+ ScoreSchedReqYield_Pre_UsedScheduler_Helping,
+ ScoreSchedReqYield_Pre_UsedScheduler_NA
+} ScoreSchedReqYield_Pre_UsedScheduler;
+
+typedef enum {
+ ScoreSchedReqYield_Pre_HomeSchedulerState_Blocked,
+ ScoreSchedReqYield_Pre_HomeSchedulerState_Scheduled,
+ ScoreSchedReqYield_Pre_HomeSchedulerState_Ready,
+ ScoreSchedReqYield_Pre_HomeSchedulerState_NA
+} ScoreSchedReqYield_Pre_HomeSchedulerState;
+
+typedef enum {
+ ScoreSchedReqYield_Pre_Sticky_Yes,
+ ScoreSchedReqYield_Pre_Sticky_No,
+ ScoreSchedReqYield_Pre_Sticky_NA
+} ScoreSchedReqYield_Pre_Sticky;
+
+typedef enum {
+ ScoreSchedReqYield_Pre_Other_Yes,
+ ScoreSchedReqYield_Pre_Other_No,
+ ScoreSchedReqYield_Pre_Other_NA
+} ScoreSchedReqYield_Pre_Other;
+
+typedef enum {
+ ScoreSchedReqYield_Post_HomeSchedulerState_Blocked,
+ ScoreSchedReqYield_Post_HomeSchedulerState_Scheduled,
+ ScoreSchedReqYield_Post_HomeSchedulerState_Ready,
+ ScoreSchedReqYield_Post_HomeSchedulerState_Idle,
+ ScoreSchedReqYield_Post_HomeSchedulerState_NA
+} ScoreSchedReqYield_Post_HomeSchedulerState;
+
+typedef enum {
+ ScoreSchedReqYield_Post_AskForHelp_Yes,
+ ScoreSchedReqYield_Post_AskForHelp_No,
+ ScoreSchedReqYield_Post_AskForHelp_NA
+} ScoreSchedReqYield_Post_AskForHelp;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_EligibleScheduler_NA : 1;
+ uint16_t Pre_UsedScheduler_NA : 1;
+ uint16_t Pre_HomeSchedulerState_NA : 1;
+ uint16_t Pre_Sticky_NA : 1;
+ uint16_t Pre_Other_NA : 1;
+ uint16_t Post_HomeSchedulerState : 3;
+ uint16_t Post_AskForHelp : 2;
+} ScoreSchedReqYield_Entry;
+
+/**
+ * @brief Test context for spec:/score/sched/req/yield test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the thread queue test context.
+ */
+ TQContext tq_ctx;
+
+ /**
+ * @brief This member contains the identifier of a sticky mutex.
+ */
+ rtems_id sticky_mutex;
+
+ /**
+ * @brief This member contains the processor index after yielding.
+ */
+ uint32_t cpu_after_yield;
+
+ /**
+ * @brief If this member is true, then the runner shall have a helping
+ * scheduler.
+ */
+ bool has_helping;
+
+ /**
+ * @brief If this member is true, then the runner shall use a helping
+ * scheduler.
+ */
+ bool use_helping;
+
+ /**
+ * @brief If this member is true, then the runner shall be ready in its home
+ * scheduler.
+ */
+ bool ready;
+
+ /**
+ * @brief If this member is true, then the runner shall be sticky.
+ */
+ bool sticky;
+
+ /**
+ * @brief If this member is true, then another ready task in the home
+ * scheduler of the runner shall be ready with an equal priority.
+ */
+ bool other_ready;
+
+ /**
+ * @brief If this member is true, then the processor zero was idle before
+ * yielding.
+ */
+ bool is_idle_before_yield;
+
+ /**
+ * @brief If this member is true, then the processor zero was idle after
+ * yielding.
+ */
+ bool is_idle_after_yield;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 5 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreSchedReqYield_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreSchedReqYield_Context;
+
+static ScoreSchedReqYield_Context
+ ScoreSchedReqYield_Instance;
+
+static const char * const ScoreSchedReqYield_PreDesc_EligibleScheduler[] = {
+ "Home",
+ "Helping",
+ "NA"
+};
+
+static const char * const ScoreSchedReqYield_PreDesc_UsedScheduler[] = {
+ "Home",
+ "Helping",
+ "NA"
+};
+
+static const char * const ScoreSchedReqYield_PreDesc_HomeSchedulerState[] = {
+ "Blocked",
+ "Scheduled",
+ "Ready",
+ "NA"
+};
+
+static const char * const ScoreSchedReqYield_PreDesc_Sticky[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const ScoreSchedReqYield_PreDesc_Other[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const ScoreSchedReqYield_PreDesc[] = {
+ ScoreSchedReqYield_PreDesc_EligibleScheduler,
+ ScoreSchedReqYield_PreDesc_UsedScheduler,
+ ScoreSchedReqYield_PreDesc_HomeSchedulerState,
+ ScoreSchedReqYield_PreDesc_Sticky,
+ ScoreSchedReqYield_PreDesc_Other,
+ NULL
+};
+
+#define COUNTER TQ_BLOCKER_A
+
+#define HELPER TQ_BLOCKER_B
+
+#define MOVER TQ_BLOCKER_C
+
+typedef ScoreSchedReqYield_Context Context;
+
+static void MoveToHelping( Context *ctx )
+{
+ ctx->tq_ctx.busy_wait[ MOVER ] = true;
+ TQSend( &ctx->tq_ctx, MOVER, TQ_EVENT_BUSY_WAIT );
+ TQWaitForEventsReceived( &ctx->tq_ctx, MOVER );
+ T_eq_u32( rtems_scheduler_get_processor(), 1 );
+ ctx->tq_ctx.busy_wait[ MOVER ] = false;
+ TQWaitForExecutionStop( &ctx->tq_ctx, MOVER );
+}
+
+static uint32_t GetCounter( const Context *ctx )
+{
+ return TQGetWorkerCounter( &ctx->tq_ctx, COUNTER );
+}
+
+static void ScoreSchedReqYield_Pre_EligibleScheduler_Prepare(
+ ScoreSchedReqYield_Context *ctx,
+ ScoreSchedReqYield_Pre_EligibleScheduler state
+)
+{
+ switch ( state ) {
+ case ScoreSchedReqYield_Pre_EligibleScheduler_Home: {
+ /*
+ * While the only eligible scheduler of the thread is the home scheduler.
+ */
+ ctx->has_helping = false;
+ break;
+ }
+
+ case ScoreSchedReqYield_Pre_EligibleScheduler_Helping: {
+ /*
+ * While the thread has at least one helping scheduler.
+ */
+ ctx->has_helping = true;
+ break;
+ }
+
+ case ScoreSchedReqYield_Pre_EligibleScheduler_NA:
+ break;
+ }
+}
+
+static void ScoreSchedReqYield_Pre_UsedScheduler_Prepare(
+ ScoreSchedReqYield_Context *ctx,
+ ScoreSchedReqYield_Pre_UsedScheduler state
+)
+{
+ switch ( state ) {
+ case ScoreSchedReqYield_Pre_UsedScheduler_Home: {
+ /*
+ * While the thread is scheduled on the home scheduler.
+ */
+ ctx->use_helping = false;
+ break;
+ }
+
+ case ScoreSchedReqYield_Pre_UsedScheduler_Helping: {
+ /*
+ * While the thread is scheduled on a helping scheduler.
+ */
+ ctx->use_helping = true;
+ break;
+ }
+
+ case ScoreSchedReqYield_Pre_UsedScheduler_NA:
+ break;
+ }
+}
+
+static void ScoreSchedReqYield_Pre_HomeSchedulerState_Prepare(
+ ScoreSchedReqYield_Context *ctx,
+ ScoreSchedReqYield_Pre_HomeSchedulerState state
+)
+{
+ switch ( state ) {
+ case ScoreSchedReqYield_Pre_HomeSchedulerState_Blocked: {
+ /*
+ * The thread shall be blocked in its home scheduler.
+ */
+ ctx->ready = false;
+ break;
+ }
+
+ case ScoreSchedReqYield_Pre_HomeSchedulerState_Scheduled: {
+ /*
+ * The thread shall be scheduled in its home scheduler.
+ */
+ ctx->ready = false;
+ break;
+ }
+
+ case ScoreSchedReqYield_Pre_HomeSchedulerState_Ready: {
+ /*
+ * The thread shall be ready in its home scheduler.
+ */
+ ctx->ready = true;
+ break;
+ }
+
+ case ScoreSchedReqYield_Pre_HomeSchedulerState_NA:
+ break;
+ }
+}
+
+static void ScoreSchedReqYield_Pre_Sticky_Prepare(
+ ScoreSchedReqYield_Context *ctx,
+ ScoreSchedReqYield_Pre_Sticky state
+)
+{
+ switch ( state ) {
+ case ScoreSchedReqYield_Pre_Sticky_Yes: {
+ /*
+ * While the thread is sticky.
+ */
+ ctx->sticky = true;
+ break;
+ }
+
+ case ScoreSchedReqYield_Pre_Sticky_No: {
+ /*
+ * While the thread not sticky.
+ */
+ ctx->sticky = false;
+ break;
+ }
+
+ case ScoreSchedReqYield_Pre_Sticky_NA:
+ break;
+ }
+}
+
+static void ScoreSchedReqYield_Pre_Other_Prepare(
+ ScoreSchedReqYield_Context *ctx,
+ ScoreSchedReqYield_Pre_Other state
+)
+{
+ switch ( state ) {
+ case ScoreSchedReqYield_Pre_Other_Yes: {
+ /*
+ * While at least one ready thread with a priority equal to the priority
+ * of the thread exists in the home scheduler of the thread.
+ */
+ ctx->other_ready = true;
+ break;
+ }
+
+ case ScoreSchedReqYield_Pre_Other_No: {
+ /*
+ * While no ready thread with a priority equal to the priority of the
+ * thread exists in the home scheduler of the thread.
+ */
+ ctx->other_ready = false;
+ break;
+ }
+
+ case ScoreSchedReqYield_Pre_Other_NA:
+ break;
+ }
+}
+
+static void ScoreSchedReqYield_Post_HomeSchedulerState_Check(
+ ScoreSchedReqYield_Context *ctx,
+ ScoreSchedReqYield_Post_HomeSchedulerState state
+)
+{
+ switch ( state ) {
+ case ScoreSchedReqYield_Post_HomeSchedulerState_Blocked: {
+ /*
+ * The thread shall be blocked in its home scheduler.
+ */
+ T_true( ctx->is_idle_after_yield );
+ T_eq_u32( ctx->cpu_after_yield, 1 );
+ break;
+ }
+
+ case ScoreSchedReqYield_Post_HomeSchedulerState_Scheduled: {
+ /*
+ * The thread shall be scheduled in its home scheduler.
+ */
+ T_false( ctx->is_idle_before_yield );
+ T_false( ctx->is_idle_after_yield );
+ T_eq_u32( GetCounter( ctx ), 0 );
+ T_eq_u32( ctx->cpu_after_yield, 0 );
+ break;
+ }
+
+ case ScoreSchedReqYield_Post_HomeSchedulerState_Ready: {
+ /*
+ * The thread shall be ready in its home scheduler.
+ */
+ T_eq_u32( GetCounter( ctx ), 1 );
+ break;
+ }
+
+ case ScoreSchedReqYield_Post_HomeSchedulerState_Idle: {
+ /*
+ * An idle thread shall execute on behalf of the thread in its home
+ * scheduler.
+ */
+ T_true( ctx->is_idle_before_yield );
+ T_true( ctx->is_idle_after_yield );
+ T_eq_u32( GetCounter( ctx ), 0 );
+ T_eq_u32( ctx->cpu_after_yield, 1 );
+ break;
+ }
+
+ case ScoreSchedReqYield_Post_HomeSchedulerState_NA:
+ break;
+ }
+}
+
+static void ScoreSchedReqYield_Post_AskForHelp_Check(
+ ScoreSchedReqYield_Context *ctx,
+ ScoreSchedReqYield_Post_AskForHelp state
+)
+{
+ size_t index;
+ const T_scheduler_event *event;
+
+ index = 0;
+
+ switch ( state ) {
+ case ScoreSchedReqYield_Post_AskForHelp_Yes: {
+ /*
+ * The thread shall ask all its eligible scheduler for help.
+ */
+ event = TQGetNextAskForHelp( &ctx->tq_ctx, &index );
+ T_eq_ptr( event->thread, ctx->tq_ctx.runner_tcb );
+
+ event = TQGetNextAskForHelp( &ctx->tq_ctx, &index );
+ T_eq_ptr( event->thread, ctx->tq_ctx.runner_tcb );
+
+ event = TQGetNextAskForHelp( &ctx->tq_ctx, &index );
+ T_eq_ptr( event, &T_scheduler_event_null );
+ break;
+ }
+
+ case ScoreSchedReqYield_Post_AskForHelp_No: {
+ /*
+ * The thread shall not ask for help.
+ */
+ event = TQGetNextAskForHelp( &ctx->tq_ctx, &index );
+ T_eq_ptr( event, &T_scheduler_event_null );
+ break;
+ }
+
+ case ScoreSchedReqYield_Post_AskForHelp_NA:
+ break;
+ }
+}
+
+static void ScoreSchedReqYield_Setup( ScoreSchedReqYield_Context *ctx )
+{
+ rtems_status_code sc;
+
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->tq_ctx.enqueue_prepare = TQEnqueuePrepareDefault;
+ ctx->tq_ctx.enqueue_done = TQEnqueueDoneDefault;
+ ctx->tq_ctx.enqueue = TQEnqueueClassicSem;
+ ctx->tq_ctx.surrender = TQSurrenderClassicSem;
+ ctx->tq_ctx.convert_status = TQConvertStatusClassic;
+ TQInitialize( &ctx->tq_ctx );
+
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'M', 'U', 'T', 'X' ),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
+ PRIO_NORMAL,
+ &ctx->sticky_mutex
+ );
+ T_rsc_success( sc );
+
+ TQSetPriority( &ctx->tq_ctx, COUNTER, PRIO_NORMAL );
+
+ #if defined(RTEMS_SMP)
+ TQSetScheduler( &ctx->tq_ctx, HELPER, SCHEDULER_B_ID, PRIO_NORMAL );
+ TQSetPriority( &ctx->tq_ctx, MOVER, PRIO_HIGH );
+ #endif
+}
+
+static void ScoreSchedReqYield_Setup_Wrap( void *arg )
+{
+ ScoreSchedReqYield_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreSchedReqYield_Setup( ctx );
+}
+
+static void ScoreSchedReqYield_Teardown( ScoreSchedReqYield_Context *ctx )
+{
+ TQDestroy( &ctx->tq_ctx );
+ DeleteMutex( ctx->sticky_mutex );
+}
+
+static void ScoreSchedReqYield_Teardown_Wrap( void *arg )
+{
+ ScoreSchedReqYield_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreSchedReqYield_Teardown( ctx );
+}
+
+static void ScoreSchedReqYield_Action( ScoreSchedReqYield_Context *ctx )
+{
+ const Per_CPU_Control *cpu;
+ bool other_busy;
+
+ if ( ctx->has_helping ) {
+ TQMutexObtain( &ctx->tq_ctx, TQ_MUTEX_A );
+ TQSendAndWaitForExecutionStop(
+ &ctx->tq_ctx,
+ HELPER,
+ TQ_EVENT_MUTEX_A_OBTAIN
+ );
+ }
+
+ if ( ctx->use_helping ) {
+ MoveToHelping( ctx );
+ }
+
+ TQResetCounter( &ctx->tq_ctx );
+
+ if ( ctx->use_helping && ctx->ready ) {
+ ctx->tq_ctx.busy_wait[ COUNTER ] = true;
+ TQSend( &ctx->tq_ctx, COUNTER, TQ_EVENT_COUNT | TQ_EVENT_BUSY_WAIT );
+ other_busy = true;
+ } else {
+ other_busy = false;
+ }
+
+ if ( ctx->sticky ) {
+ ObtainMutex( ctx->sticky_mutex );
+ }
+
+ if ( ctx->other_ready && !other_busy ) {
+ TQSend( &ctx->tq_ctx, COUNTER, TQ_EVENT_COUNT );
+ }
+
+ cpu = _Per_CPU_Get_by_index( 0 );
+ ctx->is_idle_before_yield = cpu->heir->is_idle;
+
+ TQSchedulerRecordStart( &ctx->tq_ctx );
+ Yield();
+ TQSchedulerRecordStop( &ctx->tq_ctx );
+
+ #if defined(RTEMS_SMP)
+ ctx->tq_ctx.busy_wait[ COUNTER ] = false;
+
+ while ( cpu->heir == ctx->tq_ctx.worker_tcb[ COUNTER ] ) {
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ }
+ #endif
+
+ ctx->is_idle_after_yield = cpu->heir->is_idle;
+ ctx->cpu_after_yield = rtems_scheduler_get_processor();
+
+ if ( ctx->sticky ) {
+ ReleaseMutex( ctx->sticky_mutex );
+ }
+
+ if ( ctx->has_helping ) {
+ TQMutexRelease( &ctx->tq_ctx, TQ_MUTEX_A );
+ TQSendAndWaitForExecutionStop(
+ &ctx->tq_ctx,
+ HELPER,
+ TQ_EVENT_MUTEX_A_RELEASE
+ );
+ }
+}
+
+static const ScoreSchedReqYield_Entry
+ScoreSchedReqYield_Entries[] = {
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+#endif
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Ready,
+ ScoreSchedReqYield_Post_AskForHelp_No },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Scheduled,
+ ScoreSchedReqYield_Post_AskForHelp_No },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Blocked,
+ ScoreSchedReqYield_Post_AskForHelp_No },
+#endif
+ { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Ready,
+ ScoreSchedReqYield_Post_AskForHelp_No },
+ { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Scheduled,
+ ScoreSchedReqYield_Post_AskForHelp_No },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Ready,
+ ScoreSchedReqYield_Post_AskForHelp_Yes },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Ready,
+ ScoreSchedReqYield_Post_AskForHelp_Yes },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Scheduled,
+ ScoreSchedReqYield_Post_AskForHelp_No },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_NA,
+ ScoreSchedReqYield_Post_AskForHelp_NA }
+#else
+ { 0, 0, 0, 0, 0, 0, ScoreSchedReqYield_Post_HomeSchedulerState_Idle,
+ ScoreSchedReqYield_Post_AskForHelp_No }
+#endif
+};
+
+static const uint8_t
+ScoreSchedReqYield_Map[] = {
+ 0, 0, 2, 2, 3, 8, 10, 11, 0, 0, 2, 2, 4, 4, 1, 1, 5, 5, 1, 1, 5, 5, 1, 1, 0,
+ 0, 6, 6, 12, 8, 13, 14, 0, 0, 6, 6, 4, 4, 9, 9, 3, 15, 7, 7, 3, 3, 7, 7
+};
+
+static size_t ScoreSchedReqYield_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreSchedReqYield_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( ScoreSchedReqYield_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreSchedReqYield_Fixture = {
+ .setup = ScoreSchedReqYield_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreSchedReqYield_Teardown_Wrap,
+ .scope = ScoreSchedReqYield_Scope,
+ .initial_context = &ScoreSchedReqYield_Instance
+};
+
+static inline ScoreSchedReqYield_Entry ScoreSchedReqYield_PopEntry(
+ ScoreSchedReqYield_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return ScoreSchedReqYield_Entries[
+ ScoreSchedReqYield_Map[ index ]
+ ];
+}
+
+static void ScoreSchedReqYield_TestVariant( ScoreSchedReqYield_Context *ctx )
+{
+ ScoreSchedReqYield_Pre_EligibleScheduler_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ ScoreSchedReqYield_Pre_UsedScheduler_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ ScoreSchedReqYield_Pre_HomeSchedulerState_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ ScoreSchedReqYield_Pre_Sticky_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ ScoreSchedReqYield_Pre_Other_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ ScoreSchedReqYield_Action( ctx );
+ ScoreSchedReqYield_Post_HomeSchedulerState_Check(
+ ctx,
+ ctx->Map.entry.Post_HomeSchedulerState
+ );
+ ScoreSchedReqYield_Post_AskForHelp_Check(
+ ctx,
+ ctx->Map.entry.Post_AskForHelp
+ );
+}
+
+/**
+ * @fn void T_case_body_ScoreSchedReqYield( void )
+ */
+T_TEST_CASE_FIXTURE( ScoreSchedReqYield, &ScoreSchedReqYield_Fixture )
+{
+ ScoreSchedReqYield_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = ScoreSchedReqYield_Pre_EligibleScheduler_Home;
+ ctx->Map.pcs[ 0 ] < ScoreSchedReqYield_Pre_EligibleScheduler_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = ScoreSchedReqYield_Pre_UsedScheduler_Home;
+ ctx->Map.pcs[ 1 ] < ScoreSchedReqYield_Pre_UsedScheduler_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = ScoreSchedReqYield_Pre_HomeSchedulerState_Blocked;
+ ctx->Map.pcs[ 2 ] < ScoreSchedReqYield_Pre_HomeSchedulerState_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = ScoreSchedReqYield_Pre_Sticky_Yes;
+ ctx->Map.pcs[ 3 ] < ScoreSchedReqYield_Pre_Sticky_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = ScoreSchedReqYield_Pre_Other_Yes;
+ ctx->Map.pcs[ 4 ] < ScoreSchedReqYield_Pre_Other_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ ctx->Map.entry = ScoreSchedReqYield_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ ScoreSchedReqYield_TestVariant( ctx );
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-scheduler-add-processor.c b/testsuites/validation/tc-scheduler-add-processor.c
new file mode 100644
index 0000000000..a26132aea0
--- /dev/null
+++ b/testsuites/validation/tc-scheduler-add-processor.c
@@ -0,0 +1,790 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSchedulerReqAddProcessor
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/test-scheduler.h>
+#include <rtems/score/percpu.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSchedulerReqAddProcessor \
+ * spec:/rtems/scheduler/req/add-processor
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsSchedulerReqAddProcessor_Pre_HasReady_Ready,
+ RtemsSchedulerReqAddProcessor_Pre_HasReady_Empty,
+ RtemsSchedulerReqAddProcessor_Pre_HasReady_NA
+} RtemsSchedulerReqAddProcessor_Pre_HasReady;
+
+typedef enum {
+ RtemsSchedulerReqAddProcessor_Pre_Id_Invalid,
+ RtemsSchedulerReqAddProcessor_Pre_Id_Scheduler,
+ RtemsSchedulerReqAddProcessor_Pre_Id_NA
+} RtemsSchedulerReqAddProcessor_Pre_Id;
+
+typedef enum {
+ RtemsSchedulerReqAddProcessor_Pre_CPUIndex_Valid,
+ RtemsSchedulerReqAddProcessor_Pre_CPUIndex_Invalid,
+ RtemsSchedulerReqAddProcessor_Pre_CPUIndex_NA
+} RtemsSchedulerReqAddProcessor_Pre_CPUIndex;
+
+typedef enum {
+ RtemsSchedulerReqAddProcessor_Pre_CPUState_Idle,
+ RtemsSchedulerReqAddProcessor_Pre_CPUState_InUse,
+ RtemsSchedulerReqAddProcessor_Pre_CPUState_NotOnline,
+ RtemsSchedulerReqAddProcessor_Pre_CPUState_NotUsable,
+ RtemsSchedulerReqAddProcessor_Pre_CPUState_NA
+} RtemsSchedulerReqAddProcessor_Pre_CPUState;
+
+typedef enum {
+ RtemsSchedulerReqAddProcessor_Post_Status_Ok,
+ RtemsSchedulerReqAddProcessor_Post_Status_InvId,
+ RtemsSchedulerReqAddProcessor_Post_Status_NotConf,
+ RtemsSchedulerReqAddProcessor_Post_Status_IncStat,
+ RtemsSchedulerReqAddProcessor_Post_Status_InUse,
+ RtemsSchedulerReqAddProcessor_Post_Status_NA
+} RtemsSchedulerReqAddProcessor_Post_Status;
+
+typedef enum {
+ RtemsSchedulerReqAddProcessor_Post_Added_Yes,
+ RtemsSchedulerReqAddProcessor_Post_Added_Nop,
+ RtemsSchedulerReqAddProcessor_Post_Added_NA
+} RtemsSchedulerReqAddProcessor_Post_Added;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_HasReady_NA : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_CPUIndex_NA : 1;
+ uint16_t Pre_CPUState_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_Added : 2;
+} RtemsSchedulerReqAddProcessor_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/scheduler/req/add-processor test case.
+ */
+typedef struct {
+ /**
+ * @brief This member specifies the scheduler used to add the processor.
+ */
+ rtems_id scheduler_id;
+
+ /**
+ * @brief This member contains the identifier of scheduler A.
+ */
+ rtems_id scheduler_a_id;
+
+ /**
+ * @brief This member contains the identifier of scheduler B.
+ */
+ rtems_id scheduler_b_id;
+
+ /**
+ * @brief This member contains the identifier of scheduler C.
+ */
+ rtems_id scheduler_c_id;
+
+ /**
+ * @brief This member references the processor control of the processor to
+ * add.
+ */
+ Per_CPU_Control *cpu;
+
+ /**
+ * @brief This member contains the online status of the processor to add
+ * before the rtems_scheduler_add_processor() call is prepared.
+ */
+ bool online;
+
+ /**
+ * @brief If this member is true, then the processor should be added to the
+ * scheduler B during cleanup.
+ */
+ bool add_cpu_to_scheduler_b;
+
+ /**
+ * @brief This member provides the scheduler operation records.
+ */
+ T_scheduler_log_2 scheduler_log;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_scheduler_add_processor() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``scheduler_id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member specifies if the ``cpu_index`` parameter value.
+ */
+ uint32_t cpu_index;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 4 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 4 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsSchedulerReqAddProcessor_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsSchedulerReqAddProcessor_Context;
+
+static RtemsSchedulerReqAddProcessor_Context
+ RtemsSchedulerReqAddProcessor_Instance;
+
+static const char * const RtemsSchedulerReqAddProcessor_PreDesc_HasReady[] = {
+ "Ready",
+ "Empty",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqAddProcessor_PreDesc_Id[] = {
+ "Invalid",
+ "Scheduler",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqAddProcessor_PreDesc_CPUIndex[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqAddProcessor_PreDesc_CPUState[] = {
+ "Idle",
+ "InUse",
+ "NotOnline",
+ "NotUsable",
+ "NA"
+};
+
+static const char * const * const RtemsSchedulerReqAddProcessor_PreDesc[] = {
+ RtemsSchedulerReqAddProcessor_PreDesc_HasReady,
+ RtemsSchedulerReqAddProcessor_PreDesc_Id,
+ RtemsSchedulerReqAddProcessor_PreDesc_CPUIndex,
+ RtemsSchedulerReqAddProcessor_PreDesc_CPUState,
+ NULL
+};
+
+#define CPU_TO_ADD 1
+
+static void RtemsSchedulerReqAddProcessor_Pre_HasReady_Prepare(
+ RtemsSchedulerReqAddProcessor_Context *ctx,
+ RtemsSchedulerReqAddProcessor_Pre_HasReady state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqAddProcessor_Pre_HasReady_Ready: {
+ /*
+ * While the scheduler has at least one ready thread.
+ */
+ ctx->scheduler_id = ctx->scheduler_a_id;
+ break;
+ }
+
+ case RtemsSchedulerReqAddProcessor_Pre_HasReady_Empty: {
+ /*
+ * While the scheduler has no ready threads.
+ */
+ #if defined(RTEMS_SMP)
+ ctx->scheduler_id = ctx->scheduler_c_id;
+ #else
+ ctx->scheduler_id = ctx->scheduler_a_id;
+ #endif
+ break;
+ }
+
+ case RtemsSchedulerReqAddProcessor_Pre_HasReady_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqAddProcessor_Pre_Id_Prepare(
+ RtemsSchedulerReqAddProcessor_Context *ctx,
+ RtemsSchedulerReqAddProcessor_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqAddProcessor_Pre_Id_Invalid: {
+ /*
+ * While the ``scheduler_id`` parameter is not associated with a
+ * scheduler.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsSchedulerReqAddProcessor_Pre_Id_Scheduler: {
+ /*
+ * While the ``scheduler_id`` parameter is associated with a scheduler.
+ */
+ ctx->id = ctx->scheduler_id;
+ break;
+ }
+
+ case RtemsSchedulerReqAddProcessor_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqAddProcessor_Pre_CPUIndex_Prepare(
+ RtemsSchedulerReqAddProcessor_Context *ctx,
+ RtemsSchedulerReqAddProcessor_Pre_CPUIndex state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqAddProcessor_Pre_CPUIndex_Valid: {
+ /*
+ * While the ``cpu_index`` parameter is less than the configured
+ * processor maximum.
+ */
+ #if defined(RTEMS_SMP)
+ ctx->cpu_index = CPU_TO_ADD;
+ #else
+ ctx->cpu_index = 0;
+ #endif
+ break;
+ }
+
+ case RtemsSchedulerReqAddProcessor_Pre_CPUIndex_Invalid: {
+ /*
+ * While the ``cpu_index`` parameter is greater than or equal to the
+ * configured processor maximum.
+ */
+ ctx->cpu_index = rtems_configuration_get_maximum_processors();
+ break;
+ }
+
+ case RtemsSchedulerReqAddProcessor_Pre_CPUIndex_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqAddProcessor_Pre_CPUState_Prepare(
+ RtemsSchedulerReqAddProcessor_Context *ctx,
+ RtemsSchedulerReqAddProcessor_Pre_CPUState state
+)
+{
+ rtems_status_code sc;
+
+ switch ( state ) {
+ case RtemsSchedulerReqAddProcessor_Pre_CPUState_Idle: {
+ /*
+ * While the processor associated with the ``cpu_index`` parameter is
+ * configured to be used by a scheduler, while the processor associated
+ * with the ``cpu_index`` parameter is online, while the processor
+ * associated with the ``cpu_index`` parameter is not owned by a
+ * scheduler.
+ */
+ sc = rtems_scheduler_remove_processor(
+ ctx->scheduler_b_id,
+ CPU_TO_ADD
+ );
+ T_rsc_success( sc );
+ ctx->add_cpu_to_scheduler_b = true;
+ break;
+ }
+
+ case RtemsSchedulerReqAddProcessor_Pre_CPUState_InUse: {
+ /*
+ * While the processor associated with the ``cpu_index`` parameter is
+ * owned by a scheduler.
+ */
+ /* Nothing to do */
+ break;
+ }
+
+ case RtemsSchedulerReqAddProcessor_Pre_CPUState_NotOnline: {
+ /*
+ * While the processor associated with the ``cpu_index`` parameter is not
+ * online.
+ */
+ sc = rtems_scheduler_remove_processor(
+ ctx->scheduler_b_id,
+ CPU_TO_ADD
+ );
+ T_rsc_success( sc );
+ ctx->add_cpu_to_scheduler_b = true;
+ #if defined(RTEMS_SMP)
+ ctx->cpu->online = false;
+ #endif
+ break;
+ }
+
+ case RtemsSchedulerReqAddProcessor_Pre_CPUState_NotUsable: {
+ /*
+ * While the processor associated with the ``cpu_index`` parameter is not
+ * configured to be used by a scheduler.
+ */
+ ctx->cpu_index = rtems_configuration_get_maximum_processors() - 1;
+ break;
+ }
+
+ case RtemsSchedulerReqAddProcessor_Pre_CPUState_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqAddProcessor_Post_Status_Check(
+ RtemsSchedulerReqAddProcessor_Context *ctx,
+ RtemsSchedulerReqAddProcessor_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqAddProcessor_Post_Status_Ok: {
+ /*
+ * The return status of rtems_scheduler_add_processor() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsSchedulerReqAddProcessor_Post_Status_InvId: {
+ /*
+ * The return status of rtems_scheduler_add_processor() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsSchedulerReqAddProcessor_Post_Status_NotConf: {
+ /*
+ * The return status of rtems_scheduler_add_processor() shall be
+ * RTEMS_NOT_CONFIGURED.
+ */
+ T_rsc( ctx->status, RTEMS_NOT_CONFIGURED );
+ break;
+ }
+
+ case RtemsSchedulerReqAddProcessor_Post_Status_IncStat: {
+ /*
+ * The return status of rtems_scheduler_add_processor() shall be
+ * RTEMS_INCORRECT_STATE.
+ */
+ T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
+ break;
+ }
+
+ case RtemsSchedulerReqAddProcessor_Post_Status_InUse: {
+ /*
+ * The return status of rtems_scheduler_add_processor() shall be
+ * RTEMS_RESOURCE_IN_USE.
+ */
+ T_rsc( ctx->status, RTEMS_RESOURCE_IN_USE );
+ break;
+ }
+
+ case RtemsSchedulerReqAddProcessor_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqAddProcessor_Post_Added_Check(
+ RtemsSchedulerReqAddProcessor_Context *ctx,
+ RtemsSchedulerReqAddProcessor_Post_Added state
+)
+{
+ rtems_status_code sc;
+ cpu_set_t set;
+ rtems_task_priority priority;
+
+ switch ( state ) {
+ case RtemsSchedulerReqAddProcessor_Post_Added_Yes: {
+ /*
+ * The processor specified by the ``cpu_index`` parameter shall be added
+ * to the scheduler specified by the ``scheduler_id`` by the
+ * rtems_scheduler_add_processor() call.
+ */
+ T_eq_sz( ctx->scheduler_log.header.recorded, 2 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_MAP_PRIORITY
+ );
+ T_eq_int(
+ ctx->scheduler_log.events[ 1 ].operation,
+ T_SCHEDULER_ADD_PROCESSOR
+ );
+
+ priority = GetSelfPriority();
+
+ if ( ctx->scheduler_id == ctx->scheduler_c_id ) {
+ SetSelfScheduler( ctx->scheduler_c_id, priority );
+ }
+
+ SetSelfAffinityOne( CPU_TO_ADD );
+ T_eq_u32( rtems_scheduler_get_processor(), CPU_TO_ADD );
+ SetSelfAffinityAll();
+
+ if ( ctx->scheduler_id == ctx->scheduler_c_id ) {
+ SetSelfScheduler( ctx->scheduler_a_id, priority );
+ }
+ break;
+ }
+
+ case RtemsSchedulerReqAddProcessor_Post_Added_Nop: {
+ /*
+ * No processor shall be added to a scheduler by the
+ * rtems_scheduler_add_processor() call.
+ */
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+
+ CPU_ZERO( &set );
+ CPU_SET( CPU_TO_ADD, &set );
+ sc = rtems_task_set_affinity( RTEMS_SELF, sizeof( set ), &set );
+ T_rsc( sc, RTEMS_INVALID_NUMBER );
+ break;
+ }
+
+ case RtemsSchedulerReqAddProcessor_Post_Added_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqAddProcessor_Setup(
+ RtemsSchedulerReqAddProcessor_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ sc = rtems_scheduler_ident(
+ TEST_SCHEDULER_A_NAME,
+ &ctx->scheduler_a_id
+ );
+ T_rsc_success( sc );
+
+ #if defined(RTEMS_SMP)
+ ctx->cpu = _Per_CPU_Get_by_index( CPU_TO_ADD );
+
+ sc = rtems_scheduler_ident( TEST_SCHEDULER_B_NAME, &ctx->scheduler_b_id );
+ T_rsc_success( sc );
+
+ sc = rtems_scheduler_ident( TEST_SCHEDULER_C_NAME, &ctx->scheduler_c_id );
+ T_rsc_success( sc );
+ #else
+ ctx->scheduler_b_id = INVALID_ID;
+ ctx->scheduler_c_id = INVALID_ID;
+ #endif
+}
+
+static void RtemsSchedulerReqAddProcessor_Setup_Wrap( void *arg )
+{
+ RtemsSchedulerReqAddProcessor_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSchedulerReqAddProcessor_Setup( ctx );
+}
+
+static void RtemsSchedulerReqAddProcessor_Prepare(
+ RtemsSchedulerReqAddProcessor_Context *ctx
+)
+{
+ #if defined(RTEMS_SMP)
+ ctx->add_cpu_to_scheduler_b = false;
+ ctx->online = _Per_CPU_Is_processor_online( ctx->cpu );
+ #endif
+}
+
+static void RtemsSchedulerReqAddProcessor_Action(
+ RtemsSchedulerReqAddProcessor_Context *ctx
+)
+{
+ T_scheduler_log *log;
+
+ log = T_scheduler_record_2( &ctx->scheduler_log );
+ T_null( log );
+
+ ctx->status = rtems_scheduler_add_processor( ctx->id, ctx->cpu_index );
+
+ log = T_scheduler_record( NULL );
+ T_eq_ptr( &log->header, &ctx->scheduler_log.header );
+}
+
+static void RtemsSchedulerReqAddProcessor_Cleanup(
+ RtemsSchedulerReqAddProcessor_Context *ctx
+)
+{
+ #if defined(RTEMS_SMP)
+ rtems_status_code sc;
+
+ ctx->cpu->online = ctx->online;
+
+ if ( ctx->status == RTEMS_SUCCESSFUL ) {
+ sc = rtems_scheduler_remove_processor( ctx->scheduler_id, CPU_TO_ADD );
+ T_rsc_success( sc );
+ }
+
+ if ( ctx->add_cpu_to_scheduler_b ) {
+ sc = rtems_scheduler_add_processor( ctx->scheduler_b_id, CPU_TO_ADD );
+ T_rsc_success( sc );
+ }
+ #endif
+}
+
+static const RtemsSchedulerReqAddProcessor_Entry
+RtemsSchedulerReqAddProcessor_Entries[] = {
+ { 0, 0, 0, 0, 1, RtemsSchedulerReqAddProcessor_Post_Status_InvId,
+ RtemsSchedulerReqAddProcessor_Post_Added_Nop },
+ { 0, 0, 0, 0, 1, RtemsSchedulerReqAddProcessor_Post_Status_NotConf,
+ RtemsSchedulerReqAddProcessor_Post_Added_Nop },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, RtemsSchedulerReqAddProcessor_Post_Status_InvId,
+ RtemsSchedulerReqAddProcessor_Post_Added_Nop },
+#else
+ { 1, 0, 0, 0, 0, RtemsSchedulerReqAddProcessor_Post_Status_NA,
+ RtemsSchedulerReqAddProcessor_Post_Added_NA },
+#endif
+ { 0, 0, 0, 0, 0, RtemsSchedulerReqAddProcessor_Post_Status_InvId,
+ RtemsSchedulerReqAddProcessor_Post_Added_Nop },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, RtemsSchedulerReqAddProcessor_Post_Status_Ok,
+ RtemsSchedulerReqAddProcessor_Post_Added_Yes },
+#else
+ { 1, 0, 0, 0, 0, RtemsSchedulerReqAddProcessor_Post_Status_NA,
+ RtemsSchedulerReqAddProcessor_Post_Added_NA },
+#endif
+ { 0, 0, 0, 0, 0, RtemsSchedulerReqAddProcessor_Post_Status_InUse,
+ RtemsSchedulerReqAddProcessor_Post_Added_Nop },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, RtemsSchedulerReqAddProcessor_Post_Status_IncStat,
+ RtemsSchedulerReqAddProcessor_Post_Added_Nop },
+#else
+ { 1, 0, 0, 0, 0, RtemsSchedulerReqAddProcessor_Post_Status_NA,
+ RtemsSchedulerReqAddProcessor_Post_Added_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, RtemsSchedulerReqAddProcessor_Post_Status_NotConf,
+ RtemsSchedulerReqAddProcessor_Post_Added_Nop }
+#else
+ { 1, 0, 0, 0, 0, RtemsSchedulerReqAddProcessor_Post_Status_NA,
+ RtemsSchedulerReqAddProcessor_Post_Added_NA }
+#endif
+};
+
+static const uint8_t
+RtemsSchedulerReqAddProcessor_Map[] = {
+ 2, 3, 2, 2, 0, 0, 0, 0, 4, 5, 6, 7, 1, 1, 1, 1, 2, 3, 2, 2, 0, 0, 0, 0, 4, 5,
+ 6, 7, 1, 1, 1, 1
+};
+
+static size_t RtemsSchedulerReqAddProcessor_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ RtemsSchedulerReqAddProcessor_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsSchedulerReqAddProcessor_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsSchedulerReqAddProcessor_Fixture = {
+ .setup = RtemsSchedulerReqAddProcessor_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsSchedulerReqAddProcessor_Scope,
+ .initial_context = &RtemsSchedulerReqAddProcessor_Instance
+};
+
+static inline RtemsSchedulerReqAddProcessor_Entry
+RtemsSchedulerReqAddProcessor_PopEntry(
+ RtemsSchedulerReqAddProcessor_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsSchedulerReqAddProcessor_Entries[
+ RtemsSchedulerReqAddProcessor_Map[ index ]
+ ];
+}
+
+static void RtemsSchedulerReqAddProcessor_SetPreConditionStates(
+ RtemsSchedulerReqAddProcessor_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+
+ if ( ctx->Map.entry.Pre_CPUState_NA ) {
+ ctx->Map.pcs[ 3 ] = RtemsSchedulerReqAddProcessor_Pre_CPUState_NA;
+ } else {
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ }
+}
+
+static void RtemsSchedulerReqAddProcessor_TestVariant(
+ RtemsSchedulerReqAddProcessor_Context *ctx
+)
+{
+ RtemsSchedulerReqAddProcessor_Pre_HasReady_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsSchedulerReqAddProcessor_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsSchedulerReqAddProcessor_Pre_CPUIndex_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsSchedulerReqAddProcessor_Pre_CPUState_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsSchedulerReqAddProcessor_Action( ctx );
+ RtemsSchedulerReqAddProcessor_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ RtemsSchedulerReqAddProcessor_Post_Added_Check(
+ ctx,
+ ctx->Map.entry.Post_Added
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsSchedulerReqAddProcessor( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsSchedulerReqAddProcessor,
+ &RtemsSchedulerReqAddProcessor_Fixture
+)
+{
+ RtemsSchedulerReqAddProcessor_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsSchedulerReqAddProcessor_Pre_HasReady_Ready;
+ ctx->Map.pci[ 0 ] < RtemsSchedulerReqAddProcessor_Pre_HasReady_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsSchedulerReqAddProcessor_Pre_Id_Invalid;
+ ctx->Map.pci[ 1 ] < RtemsSchedulerReqAddProcessor_Pre_Id_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsSchedulerReqAddProcessor_Pre_CPUIndex_Valid;
+ ctx->Map.pci[ 2 ] < RtemsSchedulerReqAddProcessor_Pre_CPUIndex_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = RtemsSchedulerReqAddProcessor_Pre_CPUState_Idle;
+ ctx->Map.pci[ 3 ] < RtemsSchedulerReqAddProcessor_Pre_CPUState_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ ctx->Map.entry = RtemsSchedulerReqAddProcessor_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsSchedulerReqAddProcessor_SetPreConditionStates( ctx );
+ RtemsSchedulerReqAddProcessor_Prepare( ctx );
+ RtemsSchedulerReqAddProcessor_TestVariant( ctx );
+ RtemsSchedulerReqAddProcessor_Cleanup( ctx );
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-scheduler-get-maximum-priority.c b/testsuites/validation/tc-scheduler-get-maximum-priority.c
new file mode 100644
index 0000000000..82aef23b67
--- /dev/null
+++ b/testsuites/validation/tc-scheduler-get-maximum-priority.c
@@ -0,0 +1,463 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSchedulerReqGetMaximumPriority
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <rtems.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSchedulerReqGetMaximumPriority \
+ * spec:/rtems/scheduler/req/get-maximum-priority
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsSchedulerReqGetMaximumPriority_Pre_Id_Invalid,
+ RtemsSchedulerReqGetMaximumPriority_Pre_Id_Scheduler,
+ RtemsSchedulerReqGetMaximumPriority_Pre_Id_NA
+} RtemsSchedulerReqGetMaximumPriority_Pre_Id;
+
+typedef enum {
+ RtemsSchedulerReqGetMaximumPriority_Pre_Prio_Valid,
+ RtemsSchedulerReqGetMaximumPriority_Pre_Prio_Null,
+ RtemsSchedulerReqGetMaximumPriority_Pre_Prio_NA
+} RtemsSchedulerReqGetMaximumPriority_Pre_Prio;
+
+typedef enum {
+ RtemsSchedulerReqGetMaximumPriority_Post_Status_Ok,
+ RtemsSchedulerReqGetMaximumPriority_Post_Status_InvAddr,
+ RtemsSchedulerReqGetMaximumPriority_Post_Status_InvId,
+ RtemsSchedulerReqGetMaximumPriority_Post_Status_NA
+} RtemsSchedulerReqGetMaximumPriority_Post_Status;
+
+typedef enum {
+ RtemsSchedulerReqGetMaximumPriority_Post_PrioObj_Set,
+ RtemsSchedulerReqGetMaximumPriority_Post_PrioObj_Nop,
+ RtemsSchedulerReqGetMaximumPriority_Post_PrioObj_NA
+} RtemsSchedulerReqGetMaximumPriority_Post_PrioObj;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Pre_Prio_NA : 1;
+ uint8_t Post_Status : 2;
+ uint8_t Post_PrioObj : 2;
+} RtemsSchedulerReqGetMaximumPriority_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/scheduler/req/get-maximum-priority test
+ * case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the identifier of a scheduler.
+ */
+ rtems_id scheduler_id;
+
+ /**
+ * @brief This member provides the object referenced by the ``priority``
+ * parameter.
+ */
+ rtems_task_priority priority_obj;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_scheduler_get_maximum_priority() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``scheduler_id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member specifies if the ``priority`` parameter value.
+ */
+ rtems_task_priority *priority;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsSchedulerReqGetMaximumPriority_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsSchedulerReqGetMaximumPriority_Context;
+
+static RtemsSchedulerReqGetMaximumPriority_Context
+ RtemsSchedulerReqGetMaximumPriority_Instance;
+
+static const char * const RtemsSchedulerReqGetMaximumPriority_PreDesc_Id[] = {
+ "Invalid",
+ "Scheduler",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqGetMaximumPriority_PreDesc_Prio[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsSchedulerReqGetMaximumPriority_PreDesc[] = {
+ RtemsSchedulerReqGetMaximumPriority_PreDesc_Id,
+ RtemsSchedulerReqGetMaximumPriority_PreDesc_Prio,
+ NULL
+};
+
+static void RtemsSchedulerReqGetMaximumPriority_Pre_Id_Prepare(
+ RtemsSchedulerReqGetMaximumPriority_Context *ctx,
+ RtemsSchedulerReqGetMaximumPriority_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqGetMaximumPriority_Pre_Id_Invalid: {
+ /*
+ * While the ``scheduler_id`` parameter is not associated with a
+ * scheduler.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsSchedulerReqGetMaximumPriority_Pre_Id_Scheduler: {
+ /*
+ * While the ``scheduler_id`` parameter is associated with a scheduler.
+ */
+ ctx->id = ctx->scheduler_id;
+ break;
+ }
+
+ case RtemsSchedulerReqGetMaximumPriority_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqGetMaximumPriority_Pre_Prio_Prepare(
+ RtemsSchedulerReqGetMaximumPriority_Context *ctx,
+ RtemsSchedulerReqGetMaximumPriority_Pre_Prio state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqGetMaximumPriority_Pre_Prio_Valid: {
+ /*
+ * While the ``priority`` parameter references an object of type
+ * rtems_task_priority.
+ */
+ ctx->priority = &ctx->priority_obj;
+ break;
+ }
+
+ case RtemsSchedulerReqGetMaximumPriority_Pre_Prio_Null: {
+ /*
+ * While the ``priority`` parameter is equal to NULL.
+ */
+ ctx->priority = NULL;
+ break;
+ }
+
+ case RtemsSchedulerReqGetMaximumPriority_Pre_Prio_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqGetMaximumPriority_Post_Status_Check(
+ RtemsSchedulerReqGetMaximumPriority_Context *ctx,
+ RtemsSchedulerReqGetMaximumPriority_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqGetMaximumPriority_Post_Status_Ok: {
+ /*
+ * The return status of rtems_scheduler_get_maximum_priority() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsSchedulerReqGetMaximumPriority_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_scheduler_get_maximum_priority() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsSchedulerReqGetMaximumPriority_Post_Status_InvId: {
+ /*
+ * The return status of rtems_scheduler_get_maximum_priority() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsSchedulerReqGetMaximumPriority_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqGetMaximumPriority_Post_PrioObj_Check(
+ RtemsSchedulerReqGetMaximumPriority_Context *ctx,
+ RtemsSchedulerReqGetMaximumPriority_Post_PrioObj state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqGetMaximumPriority_Post_PrioObj_Set: {
+ /*
+ * The value of the object referenced by the ``priority`` parameter shall
+ * be set to the maximum priority value of the scheduler specified by the
+ * ``scheduler_id`` parameter after the return of the
+ * rtems_scheduler_get_maximum_priority() call.
+ */
+ #if defined(RTEMS_SMP)
+ T_eq_u32( ctx->priority_obj, INT_MAX );
+ #else
+ T_eq_u32( ctx->priority_obj, 127 );
+ #endif
+ break;
+ }
+
+ case RtemsSchedulerReqGetMaximumPriority_Post_PrioObj_Nop: {
+ /*
+ * Objects referenced by the ``priority`` parameter in past calls to
+ * rtems_scheduler_get_maximum_priority() shall not be accessed by the
+ * rtems_scheduler_get_maximum_priority() call.
+ */
+ T_eq_u32( ctx->priority_obj, PRIO_INVALID );
+ break;
+ }
+
+ case RtemsSchedulerReqGetMaximumPriority_Post_PrioObj_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqGetMaximumPriority_Setup(
+ RtemsSchedulerReqGetMaximumPriority_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ sc = rtems_scheduler_ident(
+ TEST_SCHEDULER_A_NAME,
+ &ctx->scheduler_id
+ );
+ T_rsc_success( sc );
+}
+
+static void RtemsSchedulerReqGetMaximumPriority_Setup_Wrap( void *arg )
+{
+ RtemsSchedulerReqGetMaximumPriority_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSchedulerReqGetMaximumPriority_Setup( ctx );
+}
+
+static void RtemsSchedulerReqGetMaximumPriority_Prepare(
+ RtemsSchedulerReqGetMaximumPriority_Context *ctx
+)
+{
+ ctx->priority_obj = PRIO_INVALID;
+}
+
+static void RtemsSchedulerReqGetMaximumPriority_Action(
+ RtemsSchedulerReqGetMaximumPriority_Context *ctx
+)
+{
+ ctx->status = rtems_scheduler_get_maximum_priority( ctx->id, ctx->priority );
+}
+
+static const RtemsSchedulerReqGetMaximumPriority_Entry
+RtemsSchedulerReqGetMaximumPriority_Entries[] = {
+ { 0, 0, 0, RtemsSchedulerReqGetMaximumPriority_Post_Status_InvAddr,
+ RtemsSchedulerReqGetMaximumPriority_Post_PrioObj_Nop },
+ { 0, 0, 0, RtemsSchedulerReqGetMaximumPriority_Post_Status_InvId,
+ RtemsSchedulerReqGetMaximumPriority_Post_PrioObj_Nop },
+ { 0, 0, 0, RtemsSchedulerReqGetMaximumPriority_Post_Status_Ok,
+ RtemsSchedulerReqGetMaximumPriority_Post_PrioObj_Set }
+};
+
+static const uint8_t
+RtemsSchedulerReqGetMaximumPriority_Map[] = {
+ 1, 0, 2, 0
+};
+
+static size_t RtemsSchedulerReqGetMaximumPriority_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ RtemsSchedulerReqGetMaximumPriority_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsSchedulerReqGetMaximumPriority_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsSchedulerReqGetMaximumPriority_Fixture = {
+ .setup = RtemsSchedulerReqGetMaximumPriority_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsSchedulerReqGetMaximumPriority_Scope,
+ .initial_context = &RtemsSchedulerReqGetMaximumPriority_Instance
+};
+
+static inline RtemsSchedulerReqGetMaximumPriority_Entry
+RtemsSchedulerReqGetMaximumPriority_PopEntry(
+ RtemsSchedulerReqGetMaximumPriority_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsSchedulerReqGetMaximumPriority_Entries[
+ RtemsSchedulerReqGetMaximumPriority_Map[ index ]
+ ];
+}
+
+static void RtemsSchedulerReqGetMaximumPriority_TestVariant(
+ RtemsSchedulerReqGetMaximumPriority_Context *ctx
+)
+{
+ RtemsSchedulerReqGetMaximumPriority_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsSchedulerReqGetMaximumPriority_Pre_Prio_Prepare(
+ ctx,
+ ctx->Map.pcs[ 1 ]
+ );
+ RtemsSchedulerReqGetMaximumPriority_Action( ctx );
+ RtemsSchedulerReqGetMaximumPriority_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ RtemsSchedulerReqGetMaximumPriority_Post_PrioObj_Check(
+ ctx,
+ ctx->Map.entry.Post_PrioObj
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsSchedulerReqGetMaximumPriority( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsSchedulerReqGetMaximumPriority,
+ &RtemsSchedulerReqGetMaximumPriority_Fixture
+)
+{
+ RtemsSchedulerReqGetMaximumPriority_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsSchedulerReqGetMaximumPriority_Pre_Id_Invalid;
+ ctx->Map.pcs[ 0 ] < RtemsSchedulerReqGetMaximumPriority_Pre_Id_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsSchedulerReqGetMaximumPriority_Pre_Prio_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsSchedulerReqGetMaximumPriority_Pre_Prio_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ ctx->Map.entry = RtemsSchedulerReqGetMaximumPriority_PopEntry( ctx );
+ RtemsSchedulerReqGetMaximumPriority_Prepare( ctx );
+ RtemsSchedulerReqGetMaximumPriority_TestVariant( ctx );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-scheduler-get-processor-set.c b/testsuites/validation/tc-scheduler-get-processor-set.c
new file mode 100644
index 0000000000..ecc0254106
--- /dev/null
+++ b/testsuites/validation/tc-scheduler-get-processor-set.c
@@ -0,0 +1,550 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSchedulerReqGetProcessorSet
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSchedulerReqGetProcessorSet \
+ * spec:/rtems/scheduler/req/get-processor-set
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsSchedulerReqGetProcessorSet_Pre_Id_Invalid,
+ RtemsSchedulerReqGetProcessorSet_Pre_Id_Scheduler,
+ RtemsSchedulerReqGetProcessorSet_Pre_Id_NA
+} RtemsSchedulerReqGetProcessorSet_Pre_Id;
+
+typedef enum {
+ RtemsSchedulerReqGetProcessorSet_Pre_CPUSetSize_Valid,
+ RtemsSchedulerReqGetProcessorSet_Pre_CPUSetSize_TooSmall,
+ RtemsSchedulerReqGetProcessorSet_Pre_CPUSetSize_Askew,
+ RtemsSchedulerReqGetProcessorSet_Pre_CPUSetSize_NA
+} RtemsSchedulerReqGetProcessorSet_Pre_CPUSetSize;
+
+typedef enum {
+ RtemsSchedulerReqGetProcessorSet_Pre_CPUSet_Valid,
+ RtemsSchedulerReqGetProcessorSet_Pre_CPUSet_Null,
+ RtemsSchedulerReqGetProcessorSet_Pre_CPUSet_NA
+} RtemsSchedulerReqGetProcessorSet_Pre_CPUSet;
+
+typedef enum {
+ RtemsSchedulerReqGetProcessorSet_Post_Status_Ok,
+ RtemsSchedulerReqGetProcessorSet_Post_Status_InvAddr,
+ RtemsSchedulerReqGetProcessorSet_Post_Status_InvId,
+ RtemsSchedulerReqGetProcessorSet_Post_Status_InvSize,
+ RtemsSchedulerReqGetProcessorSet_Post_Status_NA
+} RtemsSchedulerReqGetProcessorSet_Post_Status;
+
+typedef enum {
+ RtemsSchedulerReqGetProcessorSet_Post_CPUSetVar_Set,
+ RtemsSchedulerReqGetProcessorSet_Post_CPUSetVar_Nop,
+ RtemsSchedulerReqGetProcessorSet_Post_CPUSetVar_NA
+} RtemsSchedulerReqGetProcessorSet_Post_CPUSetVar;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_CPUSetSize_NA : 1;
+ uint16_t Pre_CPUSet_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_CPUSetVar : 2;
+} RtemsSchedulerReqGetProcessorSet_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/scheduler/req/get-processor-set test
+ * case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the identifier of a scheduler.
+ */
+ rtems_id scheduler_id;
+
+ /**
+ * @brief This member provides the object referenced by the ``cpusetsize``
+ * parameter.
+ */
+ cpu_set_t cpuset_value;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_scheduler_get_processor_set() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``scheduler_id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member specifies if the ``cpusetsize`` parameter value.
+ */
+ size_t cpusetsize;
+
+ /**
+ * @brief This member specifies if the ``cpuset`` parameter value.
+ */
+ cpu_set_t *cpuset;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsSchedulerReqGetProcessorSet_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsSchedulerReqGetProcessorSet_Context;
+
+static RtemsSchedulerReqGetProcessorSet_Context
+ RtemsSchedulerReqGetProcessorSet_Instance;
+
+static const char * const RtemsSchedulerReqGetProcessorSet_PreDesc_Id[] = {
+ "Invalid",
+ "Scheduler",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqGetProcessorSet_PreDesc_CPUSetSize[] = {
+ "Valid",
+ "TooSmall",
+ "Askew",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqGetProcessorSet_PreDesc_CPUSet[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsSchedulerReqGetProcessorSet_PreDesc[] = {
+ RtemsSchedulerReqGetProcessorSet_PreDesc_Id,
+ RtemsSchedulerReqGetProcessorSet_PreDesc_CPUSetSize,
+ RtemsSchedulerReqGetProcessorSet_PreDesc_CPUSet,
+ NULL
+};
+
+static void RtemsSchedulerReqGetProcessorSet_Pre_Id_Prepare(
+ RtemsSchedulerReqGetProcessorSet_Context *ctx,
+ RtemsSchedulerReqGetProcessorSet_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqGetProcessorSet_Pre_Id_Invalid: {
+ /*
+ * While the ``scheduler_id`` parameter is not associated with a
+ * scheduler.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsSchedulerReqGetProcessorSet_Pre_Id_Scheduler: {
+ /*
+ * While the ``scheduler_id`` parameter is associated with a scheduler.
+ */
+ ctx->id = ctx->scheduler_id;
+ break;
+ }
+
+ case RtemsSchedulerReqGetProcessorSet_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqGetProcessorSet_Pre_CPUSetSize_Prepare(
+ RtemsSchedulerReqGetProcessorSet_Context *ctx,
+ RtemsSchedulerReqGetProcessorSet_Pre_CPUSetSize state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqGetProcessorSet_Pre_CPUSetSize_Valid: {
+ /*
+ * While the ``cpusetsize`` parameter is an integral multiple of the size
+ * of long, while the ``cpusetsize`` parameter specifies a processor set
+ * which is large enough to contain the processor set of the scheduler.
+ */
+ ctx->cpusetsize = sizeof( ctx->cpuset_value );
+ break;
+ }
+
+ case RtemsSchedulerReqGetProcessorSet_Pre_CPUSetSize_TooSmall: {
+ /*
+ * While the ``cpusetsize`` parameter is an integral multiple of the size
+ * of long, while the ``cpusetsize`` parameter specifies a processor set
+ * which is not large enough to contain the processor set of the
+ * scheduler.
+ */
+ ctx->cpusetsize = 0;
+ break;
+ }
+
+ case RtemsSchedulerReqGetProcessorSet_Pre_CPUSetSize_Askew: {
+ /*
+ * While the ``cpusetsize`` parameter is not an integral multiple of the
+ * size of long.
+ */
+ ctx->cpusetsize = SIZE_MAX;
+ break;
+ }
+
+ case RtemsSchedulerReqGetProcessorSet_Pre_CPUSetSize_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqGetProcessorSet_Pre_CPUSet_Prepare(
+ RtemsSchedulerReqGetProcessorSet_Context *ctx,
+ RtemsSchedulerReqGetProcessorSet_Pre_CPUSet state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqGetProcessorSet_Pre_CPUSet_Valid: {
+ /*
+ * While the ``cpuset`` parameter references an object of type cpu_set_t.
+ */
+ ctx->cpuset = &ctx->cpuset_value;
+ break;
+ }
+
+ case RtemsSchedulerReqGetProcessorSet_Pre_CPUSet_Null: {
+ /*
+ * While the ``cpuset`` parameter is equal to NULL.
+ */
+ ctx->cpuset = NULL;
+ break;
+ }
+
+ case RtemsSchedulerReqGetProcessorSet_Pre_CPUSet_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqGetProcessorSet_Post_Status_Check(
+ RtemsSchedulerReqGetProcessorSet_Context *ctx,
+ RtemsSchedulerReqGetProcessorSet_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqGetProcessorSet_Post_Status_Ok: {
+ /*
+ * The return status of rtems_scheduler_get_processor_set() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsSchedulerReqGetProcessorSet_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_scheduler_get_processor_set() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsSchedulerReqGetProcessorSet_Post_Status_InvId: {
+ /*
+ * The return status of rtems_scheduler_get_processor_set() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsSchedulerReqGetProcessorSet_Post_Status_InvSize: {
+ /*
+ * The return status of rtems_scheduler_get_processor_set() shall be
+ * RTEMS_INVALID_SIZE.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_SIZE );
+ break;
+ }
+
+ case RtemsSchedulerReqGetProcessorSet_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqGetProcessorSet_Post_CPUSetVar_Check(
+ RtemsSchedulerReqGetProcessorSet_Context *ctx,
+ RtemsSchedulerReqGetProcessorSet_Post_CPUSetVar state
+)
+{
+ cpu_set_t set;
+
+ switch ( state ) {
+ case RtemsSchedulerReqGetProcessorSet_Post_CPUSetVar_Set: {
+ /*
+ * The value of the object referenced by the ``cpuset`` parameter shall
+ * be set to the processor set owned by the scheduler specified by the
+ * ``scheduler_id`` parameter at some point during the call after the
+ * return of the rtems_scheduler_get_processor_set() call.
+ */
+ CPU_ZERO( &set );
+ CPU_SET( 0, &set );
+ T_eq_int( CPU_CMP( &ctx->cpuset_value, &set ), 0 );
+ break;
+ }
+
+ case RtemsSchedulerReqGetProcessorSet_Post_CPUSetVar_Nop: {
+ /*
+ * Objects referenced by the ``cpuset`` parameter in past calls to
+ * rtems_scheduler_get_processor_set() shall not be accessed by the
+ * rtems_scheduler_get_processor_set() call.
+ */
+ CPU_FILL( &set );
+ T_eq_int( CPU_CMP( &ctx->cpuset_value, &set ), 0 );
+ break;
+ }
+
+ case RtemsSchedulerReqGetProcessorSet_Post_CPUSetVar_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqGetProcessorSet_Setup(
+ RtemsSchedulerReqGetProcessorSet_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ sc = rtems_scheduler_ident(
+ TEST_SCHEDULER_A_NAME,
+ &ctx->scheduler_id
+ );
+ T_rsc_success( sc );
+}
+
+static void RtemsSchedulerReqGetProcessorSet_Setup_Wrap( void *arg )
+{
+ RtemsSchedulerReqGetProcessorSet_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSchedulerReqGetProcessorSet_Setup( ctx );
+}
+
+static void RtemsSchedulerReqGetProcessorSet_Prepare(
+ RtemsSchedulerReqGetProcessorSet_Context *ctx
+)
+{
+ CPU_FILL( &ctx->cpuset_value );
+}
+
+static void RtemsSchedulerReqGetProcessorSet_Action(
+ RtemsSchedulerReqGetProcessorSet_Context *ctx
+)
+{
+ ctx->status = rtems_scheduler_get_processor_set(
+ ctx->id,
+ ctx->cpusetsize,
+ ctx->cpuset
+ );
+}
+
+static const RtemsSchedulerReqGetProcessorSet_Entry
+RtemsSchedulerReqGetProcessorSet_Entries[] = {
+ { 0, 0, 0, 0, RtemsSchedulerReqGetProcessorSet_Post_Status_InvAddr,
+ RtemsSchedulerReqGetProcessorSet_Post_CPUSetVar_Nop },
+ { 0, 0, 0, 0, RtemsSchedulerReqGetProcessorSet_Post_Status_InvId,
+ RtemsSchedulerReqGetProcessorSet_Post_CPUSetVar_Nop },
+ { 0, 0, 0, 0, RtemsSchedulerReqGetProcessorSet_Post_Status_InvSize,
+ RtemsSchedulerReqGetProcessorSet_Post_CPUSetVar_Nop },
+ { 0, 0, 0, 0, RtemsSchedulerReqGetProcessorSet_Post_Status_Ok,
+ RtemsSchedulerReqGetProcessorSet_Post_CPUSetVar_Set }
+};
+
+static const uint8_t
+RtemsSchedulerReqGetProcessorSet_Map[] = {
+ 1, 0, 1, 0, 1, 0, 3, 0, 2, 0, 2, 0
+};
+
+static size_t RtemsSchedulerReqGetProcessorSet_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ RtemsSchedulerReqGetProcessorSet_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsSchedulerReqGetProcessorSet_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsSchedulerReqGetProcessorSet_Fixture = {
+ .setup = RtemsSchedulerReqGetProcessorSet_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsSchedulerReqGetProcessorSet_Scope,
+ .initial_context = &RtemsSchedulerReqGetProcessorSet_Instance
+};
+
+static inline RtemsSchedulerReqGetProcessorSet_Entry
+RtemsSchedulerReqGetProcessorSet_PopEntry(
+ RtemsSchedulerReqGetProcessorSet_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsSchedulerReqGetProcessorSet_Entries[
+ RtemsSchedulerReqGetProcessorSet_Map[ index ]
+ ];
+}
+
+static void RtemsSchedulerReqGetProcessorSet_TestVariant(
+ RtemsSchedulerReqGetProcessorSet_Context *ctx
+)
+{
+ RtemsSchedulerReqGetProcessorSet_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsSchedulerReqGetProcessorSet_Pre_CPUSetSize_Prepare(
+ ctx,
+ ctx->Map.pcs[ 1 ]
+ );
+ RtemsSchedulerReqGetProcessorSet_Pre_CPUSet_Prepare(
+ ctx,
+ ctx->Map.pcs[ 2 ]
+ );
+ RtemsSchedulerReqGetProcessorSet_Action( ctx );
+ RtemsSchedulerReqGetProcessorSet_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ RtemsSchedulerReqGetProcessorSet_Post_CPUSetVar_Check(
+ ctx,
+ ctx->Map.entry.Post_CPUSetVar
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsSchedulerReqGetProcessorSet( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsSchedulerReqGetProcessorSet,
+ &RtemsSchedulerReqGetProcessorSet_Fixture
+)
+{
+ RtemsSchedulerReqGetProcessorSet_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsSchedulerReqGetProcessorSet_Pre_Id_Invalid;
+ ctx->Map.pcs[ 0 ] < RtemsSchedulerReqGetProcessorSet_Pre_Id_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsSchedulerReqGetProcessorSet_Pre_CPUSetSize_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsSchedulerReqGetProcessorSet_Pre_CPUSetSize_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsSchedulerReqGetProcessorSet_Pre_CPUSet_Valid;
+ ctx->Map.pcs[ 2 ] < RtemsSchedulerReqGetProcessorSet_Pre_CPUSet_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ ctx->Map.entry = RtemsSchedulerReqGetProcessorSet_PopEntry( ctx );
+ RtemsSchedulerReqGetProcessorSet_Prepare( ctx );
+ RtemsSchedulerReqGetProcessorSet_TestVariant( ctx );
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-scheduler-ident-by-processor-set.c b/testsuites/validation/tc-scheduler-ident-by-processor-set.c
new file mode 100644
index 0000000000..43c3b660a7
--- /dev/null
+++ b/testsuites/validation/tc-scheduler-ident-by-processor-set.c
@@ -0,0 +1,743 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSchedulerReqIdentByProcessorSet
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSchedulerReqIdentByProcessorSet \
+ * spec:/rtems/scheduler/req/ident-by-processor-set
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUOwnedByScheduler_Yes,
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUOwnedByScheduler_No,
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUOwnedByScheduler_NA
+} RtemsSchedulerReqIdentByProcessorSet_Pre_CPUOwnedByScheduler;
+
+typedef enum {
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetObj_Invalid,
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetObj_Valid,
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetObj_NA
+} RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetObj;
+
+typedef enum {
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetSize_Valid,
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetSize_Invalid,
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetSize_NA
+} RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetSize;
+
+typedef enum {
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSet_Valid,
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSet_Null,
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSet_NA
+} RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSet;
+
+typedef enum {
+ RtemsSchedulerReqIdentByProcessorSet_Pre_Id_Valid,
+ RtemsSchedulerReqIdentByProcessorSet_Pre_Id_Null,
+ RtemsSchedulerReqIdentByProcessorSet_Pre_Id_NA
+} RtemsSchedulerReqIdentByProcessorSet_Pre_Id;
+
+typedef enum {
+ RtemsSchedulerReqIdentByProcessorSet_Post_Status_Ok,
+ RtemsSchedulerReqIdentByProcessorSet_Post_Status_InvAddr,
+ RtemsSchedulerReqIdentByProcessorSet_Post_Status_InvSize,
+ RtemsSchedulerReqIdentByProcessorSet_Post_Status_InvName,
+ RtemsSchedulerReqIdentByProcessorSet_Post_Status_IncStat,
+ RtemsSchedulerReqIdentByProcessorSet_Post_Status_NA
+} RtemsSchedulerReqIdentByProcessorSet_Post_Status;
+
+typedef enum {
+ RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_Set,
+ RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_Nop,
+ RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_NA
+} RtemsSchedulerReqIdentByProcessorSet_Post_IdVar;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_CPUOwnedByScheduler_NA : 1;
+ uint16_t Pre_CPUSetObj_NA : 1;
+ uint16_t Pre_CPUSetSize_NA : 1;
+ uint16_t Pre_CPUSet_NA : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_IdVar : 2;
+} RtemsSchedulerReqIdentByProcessorSet_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/scheduler/req/ident-by-processor-set
+ * test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the identifier of a second scheduler.
+ */
+ rtems_id second_scheduler_id;
+
+ /**
+ * @brief This member provides the object referenced by the ``cpuset``
+ * parameter.
+ */
+ cpu_set_t cpuset_value;
+
+ /**
+ * @brief This member provides the object referenced by the ``id`` parameter.
+ */
+ rtems_id id_value;
+
+ /**
+ * @brief If this member is true, then the processor specified by the
+ * ``cpusetsize`` parameter shall be owned by a scheduler.
+ */
+ bool cpu_has_scheduler;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_scheduler_ident_by_processor_set() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``cpusetsize`` parameter value.
+ */
+ size_t cpusetsize;
+
+ /**
+ * @brief This member specifies if the ``cpuset`` parameter value.
+ */
+ const cpu_set_t *cpuset;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id *id;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 5 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 5 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsSchedulerReqIdentByProcessorSet_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsSchedulerReqIdentByProcessorSet_Context;
+
+static RtemsSchedulerReqIdentByProcessorSet_Context
+ RtemsSchedulerReqIdentByProcessorSet_Instance;
+
+static const char * const RtemsSchedulerReqIdentByProcessorSet_PreDesc_CPUOwnedByScheduler[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqIdentByProcessorSet_PreDesc_CPUSetObj[] = {
+ "Invalid",
+ "Valid",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqIdentByProcessorSet_PreDesc_CPUSetSize[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqIdentByProcessorSet_PreDesc_CPUSet[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqIdentByProcessorSet_PreDesc_Id[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsSchedulerReqIdentByProcessorSet_PreDesc[] = {
+ RtemsSchedulerReqIdentByProcessorSet_PreDesc_CPUOwnedByScheduler,
+ RtemsSchedulerReqIdentByProcessorSet_PreDesc_CPUSetObj,
+ RtemsSchedulerReqIdentByProcessorSet_PreDesc_CPUSetSize,
+ RtemsSchedulerReqIdentByProcessorSet_PreDesc_CPUSet,
+ RtemsSchedulerReqIdentByProcessorSet_PreDesc_Id,
+ NULL
+};
+
+static void
+RtemsSchedulerReqIdentByProcessorSet_Pre_CPUOwnedByScheduler_Prepare(
+ RtemsSchedulerReqIdentByProcessorSet_Context *ctx,
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUOwnedByScheduler state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqIdentByProcessorSet_Pre_CPUOwnedByScheduler_Yes: {
+ /*
+ * While the highest numbered online processor specified by the processor
+ * set is owned by a scheduler.
+ */
+ ctx->cpu_has_scheduler = true;
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessorSet_Pre_CPUOwnedByScheduler_No: {
+ /*
+ * While the highest numbered online processor specified by the processor
+ * set is not owned by a scheduler.
+ */
+ ctx->cpu_has_scheduler = false;
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessorSet_Pre_CPUOwnedByScheduler_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetObj_Prepare(
+ RtemsSchedulerReqIdentByProcessorSet_Context *ctx,
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetObj state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetObj_Invalid: {
+ /*
+ * While the processor set contains no online processor.
+ */
+ CPU_ZERO( &ctx->cpuset_value );
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetObj_Valid: {
+ /*
+ * While the processor set contains at least one online processor.
+ */
+ CPU_ZERO( &ctx->cpuset_value );
+
+ if ( ctx->cpu_has_scheduler ) {
+ CPU_SET( 0, &ctx->cpuset_value );
+ } else {
+ CPU_SET( 1, &ctx->cpuset_value );
+ }
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetObj_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetSize_Prepare(
+ RtemsSchedulerReqIdentByProcessorSet_Context *ctx,
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetSize state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetSize_Valid: {
+ /*
+ * While the ``cpusetsize`` parameter is an integral multiple of the size
+ * of long.
+ */
+ ctx->cpusetsize = sizeof( ctx->cpuset_value );
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetSize_Invalid: {
+ /*
+ * While the ``cpusetsize`` parameter is not an integral multiple of the
+ * size of long.
+ */
+ ctx->cpusetsize = 1;
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetSize_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSet_Prepare(
+ RtemsSchedulerReqIdentByProcessorSet_Context *ctx,
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSet state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSet_Valid: {
+ /*
+ * While the ``cpuset`` parameter references an object of type cpu_set_t.
+ */
+ ctx->cpuset = &ctx->cpuset_value;
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSet_Null: {
+ /*
+ * While the ``cpuset`` parameter is equal to NULL.
+ */
+ ctx->cpuset = NULL;
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSet_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqIdentByProcessorSet_Pre_Id_Prepare(
+ RtemsSchedulerReqIdentByProcessorSet_Context *ctx,
+ RtemsSchedulerReqIdentByProcessorSet_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqIdentByProcessorSet_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter references an object of type rtems_id.
+ */
+ ctx->id_value = INVALID_ID;
+ ctx->id = &ctx->id_value;
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessorSet_Pre_Id_Null: {
+ /*
+ * While the ``id`` parameter is equal to NULL.
+ */
+ ctx->id = NULL;
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessorSet_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqIdentByProcessorSet_Post_Status_Check(
+ RtemsSchedulerReqIdentByProcessorSet_Context *ctx,
+ RtemsSchedulerReqIdentByProcessorSet_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqIdentByProcessorSet_Post_Status_Ok: {
+ /*
+ * The return status of rtems_scheduler_ident_by_processor_set() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessorSet_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_scheduler_ident_by_processor_set() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessorSet_Post_Status_InvSize: {
+ /*
+ * The return status of rtems_scheduler_ident_by_processor_set() shall be
+ * RTEMS_INVALID_SIZE.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_SIZE );
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessorSet_Post_Status_InvName: {
+ /*
+ * The return status of rtems_scheduler_ident_by_processor_set() shall be
+ * RTEMS_INVALID_NAME.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessorSet_Post_Status_IncStat: {
+ /*
+ * The return status of rtems_scheduler_ident_by_processor_set() shall be
+ * RTEMS_INVALID_NAME.
+ */
+ T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessorSet_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_Check(
+ RtemsSchedulerReqIdentByProcessorSet_Context *ctx,
+ RtemsSchedulerReqIdentByProcessorSet_Post_IdVar state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_Set: {
+ /*
+ * The value of the object referenced by the ``id`` parameter shall be
+ * set to the identifier of the scheduler which owned the highest
+ * numbered online processor specified by the ``cpusetsize`` ``cpuset``
+ * parameters at some point during the call after the return of the
+ * rtems_scheduler_ident_by_processor_set() call.
+ */
+ T_eq_u32( ctx->id_value, 0x0f010001 );
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past calls to
+ * rtems_scheduler_ident_by_processor_set() shall not be accessed by the
+ * rtems_scheduler_ident_by_processor_set() call.
+ */
+ T_eq_u32( ctx->id_value, INVALID_ID );
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqIdentByProcessorSet_Setup(
+ RtemsSchedulerReqIdentByProcessorSet_Context *ctx
+)
+{
+ #if defined(RTEMS_SMP)
+ rtems_status_code sc;
+
+ sc = rtems_scheduler_ident(
+ TEST_SCHEDULER_B_NAME,
+ &ctx->second_scheduler_id
+ );
+ T_rsc_success( sc );
+ #else
+ ctx->second_scheduler_id = INVALID_ID;
+ #endif
+}
+
+static void RtemsSchedulerReqIdentByProcessorSet_Setup_Wrap( void *arg )
+{
+ RtemsSchedulerReqIdentByProcessorSet_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSchedulerReqIdentByProcessorSet_Setup( ctx );
+}
+
+static void RtemsSchedulerReqIdentByProcessorSet_Prepare(
+ RtemsSchedulerReqIdentByProcessorSet_Context *ctx
+)
+{
+ ctx->id_value = INVALID_ID;
+}
+
+static void RtemsSchedulerReqIdentByProcessorSet_Action(
+ RtemsSchedulerReqIdentByProcessorSet_Context *ctx
+)
+{
+ #if defined(RTEMS_SMP)
+ rtems_status_code sc;
+
+ if ( !ctx->cpu_has_scheduler ) {
+ sc = rtems_scheduler_remove_processor( ctx->second_scheduler_id, 1 );
+ T_rsc_success( sc );
+ }
+ #endif
+
+ ctx->status = rtems_scheduler_ident_by_processor_set(
+ ctx->cpusetsize,
+ ctx->cpuset,
+ ctx->id
+ );
+
+ #if defined(RTEMS_SMP)
+ if ( !ctx->cpu_has_scheduler ) {
+ sc = rtems_scheduler_add_processor( ctx->second_scheduler_id, 1 );
+ T_rsc_success( sc );
+ }
+ #endif
+}
+
+static const RtemsSchedulerReqIdentByProcessorSet_Entry
+RtemsSchedulerReqIdentByProcessorSet_Entries[] = {
+ { 0, 1, 0, 0, 0, 0, RtemsSchedulerReqIdentByProcessorSet_Post_Status_InvAddr,
+ RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_Nop },
+ { 0, 0, 0, 0, 0, 0, RtemsSchedulerReqIdentByProcessorSet_Post_Status_InvAddr,
+ RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_Nop },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, RtemsSchedulerReqIdentByProcessorSet_Post_Status_InvAddr,
+ RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_Nop },
+#else
+ { 1, 0, 0, 0, 0, 0, RtemsSchedulerReqIdentByProcessorSet_Post_Status_NA,
+ RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_NA },
+#endif
+ { 0, 1, 0, 0, 0, 0, RtemsSchedulerReqIdentByProcessorSet_Post_Status_InvName,
+ RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_Nop },
+ { 0, 1, 0, 0, 0, 0, RtemsSchedulerReqIdentByProcessorSet_Post_Status_InvSize,
+ RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_Nop },
+ { 0, 0, 0, 0, 0, 0, RtemsSchedulerReqIdentByProcessorSet_Post_Status_Ok,
+ RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_Set },
+ { 0, 0, 0, 0, 0, 0, RtemsSchedulerReqIdentByProcessorSet_Post_Status_InvSize,
+ RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_Nop },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, RtemsSchedulerReqIdentByProcessorSet_Post_Status_IncStat,
+ RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_Nop },
+#else
+ { 1, 0, 0, 0, 0, 0, RtemsSchedulerReqIdentByProcessorSet_Post_Status_NA,
+ RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, RtemsSchedulerReqIdentByProcessorSet_Post_Status_InvSize,
+ RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_Nop }
+#else
+ { 1, 0, 0, 0, 0, 0, RtemsSchedulerReqIdentByProcessorSet_Post_Status_NA,
+ RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_NA }
+#endif
+};
+
+static const uint8_t
+RtemsSchedulerReqIdentByProcessorSet_Map[] = {
+ 3, 0, 0, 0, 4, 0, 0, 0, 5, 1, 1, 1, 6, 1, 1, 1, 3, 0, 0, 0, 4, 0, 0, 0, 7, 2,
+ 2, 2, 8, 2, 2, 2
+};
+
+static size_t RtemsSchedulerReqIdentByProcessorSet_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ RtemsSchedulerReqIdentByProcessorSet_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsSchedulerReqIdentByProcessorSet_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsSchedulerReqIdentByProcessorSet_Fixture = {
+ .setup = RtemsSchedulerReqIdentByProcessorSet_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsSchedulerReqIdentByProcessorSet_Scope,
+ .initial_context = &RtemsSchedulerReqIdentByProcessorSet_Instance
+};
+
+static inline RtemsSchedulerReqIdentByProcessorSet_Entry
+RtemsSchedulerReqIdentByProcessorSet_PopEntry(
+ RtemsSchedulerReqIdentByProcessorSet_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsSchedulerReqIdentByProcessorSet_Entries[
+ RtemsSchedulerReqIdentByProcessorSet_Map[ index ]
+ ];
+}
+
+static void RtemsSchedulerReqIdentByProcessorSet_SetPreConditionStates(
+ RtemsSchedulerReqIdentByProcessorSet_Context *ctx
+)
+{
+ if ( ctx->Map.entry.Pre_CPUOwnedByScheduler_NA ) {
+ ctx->Map.pcs[ 0 ] = RtemsSchedulerReqIdentByProcessorSet_Pre_CPUOwnedByScheduler_NA;
+ } else {
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ }
+
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+}
+
+static void RtemsSchedulerReqIdentByProcessorSet_TestVariant(
+ RtemsSchedulerReqIdentByProcessorSet_Context *ctx
+)
+{
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUOwnedByScheduler_Prepare(
+ ctx,
+ ctx->Map.pcs[ 0 ]
+ );
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetObj_Prepare(
+ ctx,
+ ctx->Map.pcs[ 1 ]
+ );
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetSize_Prepare(
+ ctx,
+ ctx->Map.pcs[ 2 ]
+ );
+ RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSet_Prepare(
+ ctx,
+ ctx->Map.pcs[ 3 ]
+ );
+ RtemsSchedulerReqIdentByProcessorSet_Pre_Id_Prepare(
+ ctx,
+ ctx->Map.pcs[ 4 ]
+ );
+ RtemsSchedulerReqIdentByProcessorSet_Action( ctx );
+ RtemsSchedulerReqIdentByProcessorSet_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ RtemsSchedulerReqIdentByProcessorSet_Post_IdVar_Check(
+ ctx,
+ ctx->Map.entry.Post_IdVar
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsSchedulerReqIdentByProcessorSet( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsSchedulerReqIdentByProcessorSet,
+ &RtemsSchedulerReqIdentByProcessorSet_Fixture
+)
+{
+ RtemsSchedulerReqIdentByProcessorSet_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsSchedulerReqIdentByProcessorSet_Pre_CPUOwnedByScheduler_Yes;
+ ctx->Map.pci[ 0 ] < RtemsSchedulerReqIdentByProcessorSet_Pre_CPUOwnedByScheduler_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetObj_Invalid;
+ ctx->Map.pci[ 1 ] < RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetObj_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetSize_Valid;
+ ctx->Map.pci[ 2 ] < RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSetSize_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSet_Valid;
+ ctx->Map.pci[ 3 ] < RtemsSchedulerReqIdentByProcessorSet_Pre_CPUSet_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ for (
+ ctx->Map.pci[ 4 ] = RtemsSchedulerReqIdentByProcessorSet_Pre_Id_Valid;
+ ctx->Map.pci[ 4 ] < RtemsSchedulerReqIdentByProcessorSet_Pre_Id_NA;
+ ++ctx->Map.pci[ 4 ]
+ ) {
+ ctx->Map.entry = RtemsSchedulerReqIdentByProcessorSet_PopEntry(
+ ctx
+ );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsSchedulerReqIdentByProcessorSet_SetPreConditionStates( ctx );
+ RtemsSchedulerReqIdentByProcessorSet_Prepare( ctx );
+ RtemsSchedulerReqIdentByProcessorSet_TestVariant( ctx );
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-scheduler-ident-by-processor.c b/testsuites/validation/tc-scheduler-ident-by-processor.c
new file mode 100644
index 0000000000..8cfe25a70e
--- /dev/null
+++ b/testsuites/validation/tc-scheduler-ident-by-processor.c
@@ -0,0 +1,593 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSchedulerReqIdentByProcessor
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSchedulerReqIdentByProcessor \
+ * spec:/rtems/scheduler/req/ident-by-processor
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsSchedulerReqIdentByProcessor_Pre_CPUOwnedByScheduler_Yes,
+ RtemsSchedulerReqIdentByProcessor_Pre_CPUOwnedByScheduler_No,
+ RtemsSchedulerReqIdentByProcessor_Pre_CPUOwnedByScheduler_NA
+} RtemsSchedulerReqIdentByProcessor_Pre_CPUOwnedByScheduler;
+
+typedef enum {
+ RtemsSchedulerReqIdentByProcessor_Pre_CPUIndex_Invalid,
+ RtemsSchedulerReqIdentByProcessor_Pre_CPUIndex_Valid,
+ RtemsSchedulerReqIdentByProcessor_Pre_CPUIndex_NA
+} RtemsSchedulerReqIdentByProcessor_Pre_CPUIndex;
+
+typedef enum {
+ RtemsSchedulerReqIdentByProcessor_Pre_Id_Valid,
+ RtemsSchedulerReqIdentByProcessor_Pre_Id_Null,
+ RtemsSchedulerReqIdentByProcessor_Pre_Id_NA
+} RtemsSchedulerReqIdentByProcessor_Pre_Id;
+
+typedef enum {
+ RtemsSchedulerReqIdentByProcessor_Post_Status_Ok,
+ RtemsSchedulerReqIdentByProcessor_Post_Status_InvAddr,
+ RtemsSchedulerReqIdentByProcessor_Post_Status_InvName,
+ RtemsSchedulerReqIdentByProcessor_Post_Status_IncStat,
+ RtemsSchedulerReqIdentByProcessor_Post_Status_NA
+} RtemsSchedulerReqIdentByProcessor_Post_Status;
+
+typedef enum {
+ RtemsSchedulerReqIdentByProcessor_Post_IdVar_Set,
+ RtemsSchedulerReqIdentByProcessor_Post_IdVar_Nop,
+ RtemsSchedulerReqIdentByProcessor_Post_IdVar_NA
+} RtemsSchedulerReqIdentByProcessor_Post_IdVar;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_CPUOwnedByScheduler_NA : 1;
+ uint16_t Pre_CPUIndex_NA : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_IdVar : 2;
+} RtemsSchedulerReqIdentByProcessor_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/scheduler/req/ident-by-processor test
+ * case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the identifier of a second scheduler.
+ */
+ rtems_id second_scheduler_id;
+
+ /**
+ * @brief This member provides the object referenced by the ``id`` parameter.
+ */
+ rtems_id id_value;
+
+ /**
+ * @brief If this member is true, then the processor specified by the
+ * ``cpu_index`` parameter shall be owned by a scheduler.
+ */
+ bool cpu_has_scheduler;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_scheduler_ident_by_processor() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``cpu_index`` parameter value.
+ */
+ uint32_t cpu_index;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id *id;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 3 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsSchedulerReqIdentByProcessor_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsSchedulerReqIdentByProcessor_Context;
+
+static RtemsSchedulerReqIdentByProcessor_Context
+ RtemsSchedulerReqIdentByProcessor_Instance;
+
+static const char * const RtemsSchedulerReqIdentByProcessor_PreDesc_CPUOwnedByScheduler[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqIdentByProcessor_PreDesc_CPUIndex[] = {
+ "Invalid",
+ "Valid",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqIdentByProcessor_PreDesc_Id[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsSchedulerReqIdentByProcessor_PreDesc[] = {
+ RtemsSchedulerReqIdentByProcessor_PreDesc_CPUOwnedByScheduler,
+ RtemsSchedulerReqIdentByProcessor_PreDesc_CPUIndex,
+ RtemsSchedulerReqIdentByProcessor_PreDesc_Id,
+ NULL
+};
+
+static void RtemsSchedulerReqIdentByProcessor_Pre_CPUOwnedByScheduler_Prepare(
+ RtemsSchedulerReqIdentByProcessor_Context *ctx,
+ RtemsSchedulerReqIdentByProcessor_Pre_CPUOwnedByScheduler state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqIdentByProcessor_Pre_CPUOwnedByScheduler_Yes: {
+ /*
+ * While the processor specified by the ``cpu_index`` parameter is owned
+ * by a scheduler.
+ */
+ ctx->cpu_has_scheduler = true;
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessor_Pre_CPUOwnedByScheduler_No: {
+ /*
+ * While the processor specified by the ``cpu_index`` parameter is not
+ * owned by a scheduler.
+ */
+ ctx->cpu_has_scheduler = false;
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessor_Pre_CPUOwnedByScheduler_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqIdentByProcessor_Pre_CPUIndex_Prepare(
+ RtemsSchedulerReqIdentByProcessor_Context *ctx,
+ RtemsSchedulerReqIdentByProcessor_Pre_CPUIndex state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqIdentByProcessor_Pre_CPUIndex_Invalid: {
+ /*
+ * While the ``cpu_index`` parameter is greater than or equal to the
+ * processor maximum.
+ */
+ ctx->cpu_index = rtems_scheduler_get_processor_maximum();
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessor_Pre_CPUIndex_Valid: {
+ /*
+ * While the ``cpu_index`` parameter is less than the processor maximum.
+ */
+ if ( ctx->cpu_has_scheduler ) {
+ ctx->cpu_index = 0;
+ } else {
+ ctx->cpu_index = 1;
+ }
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessor_Pre_CPUIndex_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqIdentByProcessor_Pre_Id_Prepare(
+ RtemsSchedulerReqIdentByProcessor_Context *ctx,
+ RtemsSchedulerReqIdentByProcessor_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqIdentByProcessor_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter references an object of type rtems_id.
+ */
+ ctx->id_value = INVALID_ID;
+ ctx->id = &ctx->id_value;
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessor_Pre_Id_Null: {
+ /*
+ * While the ``id`` parameter is equal to NULL.
+ */
+ ctx->id = NULL;
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessor_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqIdentByProcessor_Post_Status_Check(
+ RtemsSchedulerReqIdentByProcessor_Context *ctx,
+ RtemsSchedulerReqIdentByProcessor_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqIdentByProcessor_Post_Status_Ok: {
+ /*
+ * The return status of rtems_scheduler_ident_by_processor() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessor_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_scheduler_ident_by_processor() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessor_Post_Status_InvName: {
+ /*
+ * The return status of rtems_scheduler_ident_by_processor() shall be
+ * RTEMS_INVALID_NAME.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessor_Post_Status_IncStat: {
+ /*
+ * The return status of rtems_scheduler_ident_by_processor() shall be
+ * RTEMS_INVALID_NAME.
+ */
+ T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessor_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqIdentByProcessor_Post_IdVar_Check(
+ RtemsSchedulerReqIdentByProcessor_Context *ctx,
+ RtemsSchedulerReqIdentByProcessor_Post_IdVar state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqIdentByProcessor_Post_IdVar_Set: {
+ /*
+ * The value of the object referenced by the ``id`` parameter shall be
+ * set to the identifier of the scheduler which owned the processor
+ * specified by the ``cpu_index`` parameter at some point during the call
+ * after the return of the rtems_scheduler_ident_by_processor() call.
+ */
+ T_eq_ptr( ctx->id, &ctx->id_value );
+ T_eq_u32( ctx->id_value, 0x0f010001 );
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessor_Post_IdVar_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past calls to
+ * rtems_scheduler_ident_by_processor() shall not be accessed by the
+ * rtems_scheduler_ident_by_processor() call.
+ */
+ T_eq_u32( ctx->id_value, INVALID_ID );
+ break;
+ }
+
+ case RtemsSchedulerReqIdentByProcessor_Post_IdVar_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqIdentByProcessor_Setup(
+ RtemsSchedulerReqIdentByProcessor_Context *ctx
+)
+{
+ #if defined(RTEMS_SMP)
+ rtems_status_code sc;
+
+ sc = rtems_scheduler_ident(
+ TEST_SCHEDULER_B_NAME,
+ &ctx->second_scheduler_id
+ );
+ T_rsc_success( sc );
+ #else
+ ctx->second_scheduler_id = INVALID_ID;
+ #endif
+}
+
+static void RtemsSchedulerReqIdentByProcessor_Setup_Wrap( void *arg )
+{
+ RtemsSchedulerReqIdentByProcessor_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSchedulerReqIdentByProcessor_Setup( ctx );
+}
+
+static void RtemsSchedulerReqIdentByProcessor_Prepare(
+ RtemsSchedulerReqIdentByProcessor_Context *ctx
+)
+{
+ ctx->id_value = INVALID_ID;
+}
+
+static void RtemsSchedulerReqIdentByProcessor_Action(
+ RtemsSchedulerReqIdentByProcessor_Context *ctx
+)
+{
+ #if defined(RTEMS_SMP)
+ rtems_status_code sc;
+
+ if ( !ctx->cpu_has_scheduler ) {
+ sc = rtems_scheduler_remove_processor( ctx->second_scheduler_id, 1 );
+ T_rsc_success( sc );
+ }
+ #endif
+
+ ctx->status = rtems_scheduler_ident_by_processor( ctx->cpu_index, ctx->id );
+
+ #if defined(RTEMS_SMP)
+ if ( !ctx->cpu_has_scheduler ) {
+ sc = rtems_scheduler_add_processor( ctx->second_scheduler_id, 1 );
+ T_rsc_success( sc );
+ }
+ #endif
+}
+
+static const RtemsSchedulerReqIdentByProcessor_Entry
+RtemsSchedulerReqIdentByProcessor_Entries[] = {
+ { 0, 1, 0, 0, RtemsSchedulerReqIdentByProcessor_Post_Status_InvName,
+ RtemsSchedulerReqIdentByProcessor_Post_IdVar_Nop },
+ { 0, 1, 0, 0, RtemsSchedulerReqIdentByProcessor_Post_Status_InvAddr,
+ RtemsSchedulerReqIdentByProcessor_Post_IdVar_Nop },
+ { 0, 0, 0, 0, RtemsSchedulerReqIdentByProcessor_Post_Status_Ok,
+ RtemsSchedulerReqIdentByProcessor_Post_IdVar_Set },
+ { 0, 0, 0, 0, RtemsSchedulerReqIdentByProcessor_Post_Status_InvAddr,
+ RtemsSchedulerReqIdentByProcessor_Post_IdVar_Nop },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, RtemsSchedulerReqIdentByProcessor_Post_Status_IncStat,
+ RtemsSchedulerReqIdentByProcessor_Post_IdVar_Nop },
+#else
+ { 1, 0, 0, 0, RtemsSchedulerReqIdentByProcessor_Post_Status_NA,
+ RtemsSchedulerReqIdentByProcessor_Post_IdVar_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, RtemsSchedulerReqIdentByProcessor_Post_Status_InvAddr,
+ RtemsSchedulerReqIdentByProcessor_Post_IdVar_Nop }
+#else
+ { 1, 0, 0, 0, RtemsSchedulerReqIdentByProcessor_Post_Status_NA,
+ RtemsSchedulerReqIdentByProcessor_Post_IdVar_NA }
+#endif
+};
+
+static const uint8_t
+RtemsSchedulerReqIdentByProcessor_Map[] = {
+ 0, 1, 2, 3, 0, 1, 4, 5
+};
+
+static size_t RtemsSchedulerReqIdentByProcessor_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ RtemsSchedulerReqIdentByProcessor_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsSchedulerReqIdentByProcessor_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsSchedulerReqIdentByProcessor_Fixture = {
+ .setup = RtemsSchedulerReqIdentByProcessor_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsSchedulerReqIdentByProcessor_Scope,
+ .initial_context = &RtemsSchedulerReqIdentByProcessor_Instance
+};
+
+static inline RtemsSchedulerReqIdentByProcessor_Entry
+RtemsSchedulerReqIdentByProcessor_PopEntry(
+ RtemsSchedulerReqIdentByProcessor_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsSchedulerReqIdentByProcessor_Entries[
+ RtemsSchedulerReqIdentByProcessor_Map[ index ]
+ ];
+}
+
+static void RtemsSchedulerReqIdentByProcessor_SetPreConditionStates(
+ RtemsSchedulerReqIdentByProcessor_Context *ctx
+)
+{
+ if ( ctx->Map.entry.Pre_CPUOwnedByScheduler_NA ) {
+ ctx->Map.pcs[ 0 ] = RtemsSchedulerReqIdentByProcessor_Pre_CPUOwnedByScheduler_NA;
+ } else {
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ }
+
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+}
+
+static void RtemsSchedulerReqIdentByProcessor_TestVariant(
+ RtemsSchedulerReqIdentByProcessor_Context *ctx
+)
+{
+ RtemsSchedulerReqIdentByProcessor_Pre_CPUOwnedByScheduler_Prepare(
+ ctx,
+ ctx->Map.pcs[ 0 ]
+ );
+ RtemsSchedulerReqIdentByProcessor_Pre_CPUIndex_Prepare(
+ ctx,
+ ctx->Map.pcs[ 1 ]
+ );
+ RtemsSchedulerReqIdentByProcessor_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsSchedulerReqIdentByProcessor_Action( ctx );
+ RtemsSchedulerReqIdentByProcessor_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ RtemsSchedulerReqIdentByProcessor_Post_IdVar_Check(
+ ctx,
+ ctx->Map.entry.Post_IdVar
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsSchedulerReqIdentByProcessor( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsSchedulerReqIdentByProcessor,
+ &RtemsSchedulerReqIdentByProcessor_Fixture
+)
+{
+ RtemsSchedulerReqIdentByProcessor_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsSchedulerReqIdentByProcessor_Pre_CPUOwnedByScheduler_Yes;
+ ctx->Map.pci[ 0 ] < RtemsSchedulerReqIdentByProcessor_Pre_CPUOwnedByScheduler_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsSchedulerReqIdentByProcessor_Pre_CPUIndex_Invalid;
+ ctx->Map.pci[ 1 ] < RtemsSchedulerReqIdentByProcessor_Pre_CPUIndex_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsSchedulerReqIdentByProcessor_Pre_Id_Valid;
+ ctx->Map.pci[ 2 ] < RtemsSchedulerReqIdentByProcessor_Pre_Id_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ ctx->Map.entry = RtemsSchedulerReqIdentByProcessor_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsSchedulerReqIdentByProcessor_SetPreConditionStates( ctx );
+ RtemsSchedulerReqIdentByProcessor_Prepare( ctx );
+ RtemsSchedulerReqIdentByProcessor_TestVariant( ctx );
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-scheduler-ident.c b/testsuites/validation/tc-scheduler-ident.c
new file mode 100644
index 0000000000..7b19f4a08e
--- /dev/null
+++ b/testsuites/validation/tc-scheduler-ident.c
@@ -0,0 +1,405 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSchedulerReqIdent
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSchedulerReqIdent spec:/rtems/scheduler/req/ident
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsSchedulerReqIdent_Pre_Name_Invalid,
+ RtemsSchedulerReqIdent_Pre_Name_Valid,
+ RtemsSchedulerReqIdent_Pre_Name_NA
+} RtemsSchedulerReqIdent_Pre_Name;
+
+typedef enum {
+ RtemsSchedulerReqIdent_Pre_Id_Valid,
+ RtemsSchedulerReqIdent_Pre_Id_Null,
+ RtemsSchedulerReqIdent_Pre_Id_NA
+} RtemsSchedulerReqIdent_Pre_Id;
+
+typedef enum {
+ RtemsSchedulerReqIdent_Post_Status_Ok,
+ RtemsSchedulerReqIdent_Post_Status_InvAddr,
+ RtemsSchedulerReqIdent_Post_Status_InvName,
+ RtemsSchedulerReqIdent_Post_Status_NA
+} RtemsSchedulerReqIdent_Post_Status;
+
+typedef enum {
+ RtemsSchedulerReqIdent_Post_IdVar_Set,
+ RtemsSchedulerReqIdent_Post_IdVar_Nop,
+ RtemsSchedulerReqIdent_Post_IdVar_NA
+} RtemsSchedulerReqIdent_Post_IdVar;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Name_NA : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Post_Status : 2;
+ uint8_t Post_IdVar : 2;
+} RtemsSchedulerReqIdent_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/scheduler/req/ident test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides the object referenced by the ``id`` parameter.
+ */
+ rtems_id id_value;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_scheduler_ident() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``name`` parameter value.
+ */
+ rtems_name name;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id *id;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsSchedulerReqIdent_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsSchedulerReqIdent_Context;
+
+static RtemsSchedulerReqIdent_Context
+ RtemsSchedulerReqIdent_Instance;
+
+static const char * const RtemsSchedulerReqIdent_PreDesc_Name[] = {
+ "Invalid",
+ "Valid",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqIdent_PreDesc_Id[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsSchedulerReqIdent_PreDesc[] = {
+ RtemsSchedulerReqIdent_PreDesc_Name,
+ RtemsSchedulerReqIdent_PreDesc_Id,
+ NULL
+};
+
+static void RtemsSchedulerReqIdent_Pre_Name_Prepare(
+ RtemsSchedulerReqIdent_Context *ctx,
+ RtemsSchedulerReqIdent_Pre_Name state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqIdent_Pre_Name_Invalid: {
+ /*
+ * While the ``name`` parameter is not associated with a scheduler.
+ */
+ ctx->name = 0;
+ break;
+ }
+
+ case RtemsSchedulerReqIdent_Pre_Name_Valid: {
+ /*
+ * While the ``name`` parameter is associated with a scheduler.
+ */
+ ctx->name = TEST_SCHEDULER_A_NAME;
+ break;
+ }
+
+ case RtemsSchedulerReqIdent_Pre_Name_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqIdent_Pre_Id_Prepare(
+ RtemsSchedulerReqIdent_Context *ctx,
+ RtemsSchedulerReqIdent_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqIdent_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter references an object of type rtems_id.
+ */
+ ctx->id = &ctx->id_value;
+ break;
+ }
+
+ case RtemsSchedulerReqIdent_Pre_Id_Null: {
+ /*
+ * While the ``id`` parameter is equal to NULL.
+ */
+ ctx->id = NULL;
+ break;
+ }
+
+ case RtemsSchedulerReqIdent_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqIdent_Post_Status_Check(
+ RtemsSchedulerReqIdent_Context *ctx,
+ RtemsSchedulerReqIdent_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqIdent_Post_Status_Ok: {
+ /*
+ * The return status of rtems_scheduler_ident() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsSchedulerReqIdent_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_scheduler_ident() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsSchedulerReqIdent_Post_Status_InvName: {
+ /*
+ * The return status of rtems_scheduler_ident() shall be
+ * RTEMS_INVALID_NAME.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsSchedulerReqIdent_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqIdent_Post_IdVar_Check(
+ RtemsSchedulerReqIdent_Context *ctx,
+ RtemsSchedulerReqIdent_Post_IdVar state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqIdent_Post_IdVar_Set: {
+ /*
+ * The value of the object referenced by the ``id`` parameter shall be
+ * set to the identifier of the scheduler with the lowest scheduler index
+ * and a name equal to the ``name`` parameter after the return of the
+ * rtems_scheduler_ident() call.
+ */
+ T_eq_ptr( ctx->id, &ctx->id_value );
+ T_eq_u32( ctx->id_value, 0x0f010001 );
+ break;
+ }
+
+ case RtemsSchedulerReqIdent_Post_IdVar_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past calls to
+ * rtems_scheduler_ident() shall not be accessed by the
+ * rtems_scheduler_ident() call.
+ */
+ T_eq_u32( ctx->id_value, INVALID_ID );
+ break;
+ }
+
+ case RtemsSchedulerReqIdent_Post_IdVar_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqIdent_Prepare(
+ RtemsSchedulerReqIdent_Context *ctx
+)
+{
+ ctx->id_value = INVALID_ID;
+}
+
+static void RtemsSchedulerReqIdent_Action(
+ RtemsSchedulerReqIdent_Context *ctx
+)
+{
+ ctx->status = rtems_scheduler_ident( ctx->name, ctx->id );
+}
+
+static const RtemsSchedulerReqIdent_Entry
+RtemsSchedulerReqIdent_Entries[] = {
+ { 0, 0, 0, RtemsSchedulerReqIdent_Post_Status_InvAddr,
+ RtemsSchedulerReqIdent_Post_IdVar_Nop },
+ { 0, 0, 0, RtemsSchedulerReqIdent_Post_Status_InvName,
+ RtemsSchedulerReqIdent_Post_IdVar_Nop },
+ { 0, 0, 0, RtemsSchedulerReqIdent_Post_Status_Ok,
+ RtemsSchedulerReqIdent_Post_IdVar_Set }
+};
+
+static const uint8_t
+RtemsSchedulerReqIdent_Map[] = {
+ 1, 0, 2, 0
+};
+
+static size_t RtemsSchedulerReqIdent_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsSchedulerReqIdent_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsSchedulerReqIdent_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsSchedulerReqIdent_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsSchedulerReqIdent_Scope,
+ .initial_context = &RtemsSchedulerReqIdent_Instance
+};
+
+static inline RtemsSchedulerReqIdent_Entry RtemsSchedulerReqIdent_PopEntry(
+ RtemsSchedulerReqIdent_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsSchedulerReqIdent_Entries[
+ RtemsSchedulerReqIdent_Map[ index ]
+ ];
+}
+
+static void RtemsSchedulerReqIdent_TestVariant(
+ RtemsSchedulerReqIdent_Context *ctx
+)
+{
+ RtemsSchedulerReqIdent_Pre_Name_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsSchedulerReqIdent_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsSchedulerReqIdent_Action( ctx );
+ RtemsSchedulerReqIdent_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsSchedulerReqIdent_Post_IdVar_Check( ctx, ctx->Map.entry.Post_IdVar );
+}
+
+/**
+ * @fn void T_case_body_RtemsSchedulerReqIdent( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsSchedulerReqIdent, &RtemsSchedulerReqIdent_Fixture )
+{
+ RtemsSchedulerReqIdent_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsSchedulerReqIdent_Pre_Name_Invalid;
+ ctx->Map.pcs[ 0 ] < RtemsSchedulerReqIdent_Pre_Name_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsSchedulerReqIdent_Pre_Id_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsSchedulerReqIdent_Pre_Id_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ ctx->Map.entry = RtemsSchedulerReqIdent_PopEntry( ctx );
+ RtemsSchedulerReqIdent_Prepare( ctx );
+ RtemsSchedulerReqIdent_TestVariant( ctx );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-scheduler-non-smp.c b/testsuites/validation/tc-scheduler-non-smp.c
new file mode 100644
index 0000000000..4e805769a0
--- /dev/null
+++ b/testsuites/validation/tc-scheduler-non-smp.c
@@ -0,0 +1,131 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSchedulerValNonSmp
+ */
+
+/*
+ * Copyright (C) 2021, 2023 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSchedulerValNonSmp spec:/rtems/scheduler/val/non-smp
+ *
+ * @ingroup TestsuitesValidationNonSmp
+ *
+ * @brief This test case collection provides validation test cases for non-SMP
+ * requirements of the @ref RTEMSAPIClassicScheduler.
+ *
+ * This test case performs the following actions:
+ *
+ * - Assert that rtems_scheduler_get_processor() is a constant expression which
+ * evaluates to zero.
+ *
+ * - Check that calling rtems_scheduler_get_processor() returns zero.
+ *
+ * - Assert that rtems_scheduler_get_processor_maximum() is a constant
+ * expression which evaluates to zero.
+ *
+ * - Check that calling rtems_scheduler_get_processor_maximum() returns one.
+ *
+ * @{
+ */
+
+/**
+ * @brief Assert that rtems_scheduler_get_processor() is a constant expression
+ * which evaluates to zero.
+ */
+static void RtemsSchedulerValNonSmp_Action_0( void )
+{
+ RTEMS_STATIC_ASSERT( rtems_scheduler_get_processor() == 0, GET_PROCESSOR );
+}
+
+/**
+ * @brief Check that calling rtems_scheduler_get_processor() returns zero.
+ */
+static void RtemsSchedulerValNonSmp_Action_1( void )
+{
+ T_eq_u32( rtems_scheduler_get_processor(), 0 );
+}
+
+/**
+ * @brief Assert that rtems_scheduler_get_processor_maximum() is a constant
+ * expression which evaluates to zero.
+ */
+static void RtemsSchedulerValNonSmp_Action_2( void )
+{
+ RTEMS_STATIC_ASSERT(
+ rtems_scheduler_get_processor_maximum() == 1,
+ GET_PROCESSOR_MAXIMUM
+ );
+}
+
+/**
+ * @brief Check that calling rtems_scheduler_get_processor_maximum() returns
+ * one.
+ */
+static void RtemsSchedulerValNonSmp_Action_3( void )
+{
+ T_eq_u32( rtems_scheduler_get_processor_maximum(), 1 );
+}
+
+/**
+ * @fn void T_case_body_RtemsSchedulerValNonSmp( void )
+ */
+T_TEST_CASE( RtemsSchedulerValNonSmp )
+{
+ RtemsSchedulerValNonSmp_Action_0();
+ RtemsSchedulerValNonSmp_Action_1();
+ RtemsSchedulerValNonSmp_Action_2();
+ RtemsSchedulerValNonSmp_Action_3();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-scheduler-remove-processor.c b/testsuites/validation/tc-scheduler-remove-processor.c
new file mode 100644
index 0000000000..f199389a33
--- /dev/null
+++ b/testsuites/validation/tc-scheduler-remove-processor.c
@@ -0,0 +1,1485 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSchedulerReqRemoveProcessor
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/test-scheduler.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/smpbarrier.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSchedulerReqRemoveProcessor \
+ * spec:/rtems/scheduler/req/remove-processor
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsSchedulerReqRemoveProcessor_Pre_Id_Invalid,
+ RtemsSchedulerReqRemoveProcessor_Pre_Id_Scheduler,
+ RtemsSchedulerReqRemoveProcessor_Pre_Id_NA
+} RtemsSchedulerReqRemoveProcessor_Pre_Id;
+
+typedef enum {
+ RtemsSchedulerReqRemoveProcessor_Pre_CPUIndex_Valid,
+ RtemsSchedulerReqRemoveProcessor_Pre_CPUIndex_Invalid,
+ RtemsSchedulerReqRemoveProcessor_Pre_CPUIndex_NA
+} RtemsSchedulerReqRemoveProcessor_Pre_CPUIndex;
+
+typedef enum {
+ RtemsSchedulerReqRemoveProcessor_Pre_Owned_Yes,
+ RtemsSchedulerReqRemoveProcessor_Pre_Owned_No,
+ RtemsSchedulerReqRemoveProcessor_Pre_Owned_NA
+} RtemsSchedulerReqRemoveProcessor_Pre_Owned;
+
+typedef enum {
+ RtemsSchedulerReqRemoveProcessor_Pre_Last_Yes,
+ RtemsSchedulerReqRemoveProcessor_Pre_Last_No,
+ RtemsSchedulerReqRemoveProcessor_Pre_Last_NA
+} RtemsSchedulerReqRemoveProcessor_Pre_Last;
+
+typedef enum {
+ RtemsSchedulerReqRemoveProcessor_Pre_Home_Yes,
+ RtemsSchedulerReqRemoveProcessor_Pre_Home_No,
+ RtemsSchedulerReqRemoveProcessor_Pre_Home_NA
+} RtemsSchedulerReqRemoveProcessor_Pre_Home;
+
+typedef enum {
+ RtemsSchedulerReqRemoveProcessor_Pre_RequiredByAffinity_Yes,
+ RtemsSchedulerReqRemoveProcessor_Pre_RequiredByAffinity_No,
+ RtemsSchedulerReqRemoveProcessor_Pre_RequiredByAffinity_NA
+} RtemsSchedulerReqRemoveProcessor_Pre_RequiredByAffinity;
+
+typedef enum {
+ RtemsSchedulerReqRemoveProcessor_Pre_UsedBy_Idle,
+ RtemsSchedulerReqRemoveProcessor_Pre_UsedBy_Task,
+ RtemsSchedulerReqRemoveProcessor_Pre_UsedBy_TaskIdle,
+ RtemsSchedulerReqRemoveProcessor_Pre_UsedBy_Helping,
+ RtemsSchedulerReqRemoveProcessor_Pre_UsedBy_NA
+} RtemsSchedulerReqRemoveProcessor_Pre_UsedBy;
+
+typedef enum {
+ RtemsSchedulerReqRemoveProcessor_Post_Status_Ok,
+ RtemsSchedulerReqRemoveProcessor_Post_Status_InvId,
+ RtemsSchedulerReqRemoveProcessor_Post_Status_InvNum,
+ RtemsSchedulerReqRemoveProcessor_Post_Status_InUse,
+ RtemsSchedulerReqRemoveProcessor_Post_Status_NA
+} RtemsSchedulerReqRemoveProcessor_Post_Status;
+
+typedef enum {
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_Yes,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_Nop,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_NA
+} RtemsSchedulerReqRemoveProcessor_Post_Removed;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_CPUIndex_NA : 1;
+ uint16_t Pre_Owned_NA : 1;
+ uint16_t Pre_Last_NA : 1;
+ uint16_t Pre_Home_NA : 1;
+ uint16_t Pre_RequiredByAffinity_NA : 1;
+ uint16_t Pre_UsedBy_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_Removed : 2;
+} RtemsSchedulerReqRemoveProcessor_Entry;
+
+typedef enum {
+ WORKER_A,
+ WORKER_B,
+ WORKER_C,
+ WORKER_COUNT
+} WorkerIndex;
+
+/**
+ * @brief Test context for spec:/rtems/scheduler/req/remove-processor test
+ * case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the runner identifier.
+ */
+ rtems_id runner_id;
+
+ /**
+ * @brief This member contains the worker identifiers.
+ */
+ rtems_id worker_id[ WORKER_COUNT ];
+
+ /**
+ * @brief This member contains the mutex identifier.
+ */
+ rtems_id mutex_id;
+
+ /**
+ * @brief This member contains the sticky mutex identifier.
+ */
+ rtems_id sticky_id;
+
+ /**
+ * @brief This member contains the worker busy status.
+ */
+ volatile bool busy[ WORKER_COUNT ];
+
+ /**
+ * @brief This member contains the worker busy status.
+ */
+ volatile uint32_t busy_counter[ WORKER_COUNT ];
+
+ /**
+ * @brief This member contains the barrier to synchronize the runner and the
+ * workers.
+ */
+ SMP_barrier_Control barrier;
+
+ /**
+ * @brief This member contains the call within ISR request.
+ */
+ CallWithinISRRequest request;
+
+ /**
+ * @brief This member provides the context to wrap thread queue operations.
+ */
+ WrapThreadQueueContext wrap_tq_ctx;
+
+ /**
+ * @brief If this member is true, then the processor to remove shall be owned
+ * by the scheduler.
+ */
+ bool owned;
+
+ /**
+ * @brief If this member is true, then the processor to remove shall be the
+ * last processor of the scheduler.
+ */
+ bool last;
+
+ /**
+ * @brief If this member is true, then at least one non-idle task shall use
+ * the scheduler as its home scheduler.
+ */
+ bool home;
+
+ /**
+ * @brief If this member is true, then at least one non-idle task shall
+ * required the processor to remove due to its affinity set.
+ */
+ bool required_by_affinity;
+
+ /**
+ * @brief If this member is true, then the processor to remove shall be used
+ * by an idle task.
+ */
+ bool idle;
+
+ /**
+ * @brief If this member is true, then the processor to remove shall be used
+ * by a task or on behalf of a task which uses the scheduler as its home
+ * scheduler.
+ */
+ bool task;
+
+ /**
+ * @brief If this member is true, then the processor to remove shall be used
+ * by a task which uses the scheduler as a helping scheduler.
+ */
+ bool helping;
+
+ /**
+ * @brief This member provides the scheduler operation records.
+ */
+ T_scheduler_log_4 scheduler_log;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_scheduler_remove_processor() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies the ``scheduler_id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member specifies the ``cpu_index`` parameter value.
+ */
+ uint32_t cpu_index;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 7 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 7 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsSchedulerReqRemoveProcessor_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsSchedulerReqRemoveProcessor_Context;
+
+static RtemsSchedulerReqRemoveProcessor_Context
+ RtemsSchedulerReqRemoveProcessor_Instance;
+
+static const char * const RtemsSchedulerReqRemoveProcessor_PreDesc_Id[] = {
+ "Invalid",
+ "Scheduler",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqRemoveProcessor_PreDesc_CPUIndex[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqRemoveProcessor_PreDesc_Owned[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqRemoveProcessor_PreDesc_Last[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqRemoveProcessor_PreDesc_Home[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqRemoveProcessor_PreDesc_RequiredByAffinity[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsSchedulerReqRemoveProcessor_PreDesc_UsedBy[] = {
+ "Idle",
+ "Task",
+ "TaskIdle",
+ "Helping",
+ "NA"
+};
+
+static const char * const * const RtemsSchedulerReqRemoveProcessor_PreDesc[] = {
+ RtemsSchedulerReqRemoveProcessor_PreDesc_Id,
+ RtemsSchedulerReqRemoveProcessor_PreDesc_CPUIndex,
+ RtemsSchedulerReqRemoveProcessor_PreDesc_Owned,
+ RtemsSchedulerReqRemoveProcessor_PreDesc_Last,
+ RtemsSchedulerReqRemoveProcessor_PreDesc_Home,
+ RtemsSchedulerReqRemoveProcessor_PreDesc_RequiredByAffinity,
+ RtemsSchedulerReqRemoveProcessor_PreDesc_UsedBy,
+ NULL
+};
+
+typedef RtemsSchedulerReqRemoveProcessor_Context Context;
+
+static void DoRemoveProcessor( Context *ctx )
+{
+ T_scheduler_log *log;
+
+ log = T_scheduler_record_4( &ctx->scheduler_log );
+ T_null( log );
+
+ ctx->status = rtems_scheduler_remove_processor( ctx->id, ctx->cpu_index );
+
+ log = T_scheduler_record( NULL );
+ T_eq_ptr( &log->header, &ctx->scheduler_log.header );
+
+ if ( ctx->status == RTEMS_SUCCESSFUL ) {
+ AddProcessor( ctx->id, ctx->cpu_index );
+ }
+}
+
+#if defined(RTEMS_SMP)
+
+#define EVENT_SYNC_RUNNER RTEMS_EVENT_0
+
+#define EVENT_OBTAIN RTEMS_EVENT_1
+
+#define EVENT_RELEASE RTEMS_EVENT_2
+
+#define EVENT_STICKY_OBTAIN RTEMS_EVENT_3
+
+#define EVENT_STICKY_RELEASE RTEMS_EVENT_4
+
+#define EVENT_RESTART RTEMS_EVENT_5
+
+#define EVENT_BUSY RTEMS_EVENT_6
+
+#define EVENT_SYNC_RUNNER_LATE RTEMS_EVENT_7
+
+static void Barriers( void *arg )
+{
+ Context *ctx;
+ SMP_barrier_State barrier_state;
+
+ ctx = arg;
+ _SMP_barrier_State_initialize( &barrier_state );
+
+ /* A */
+ _SMP_barrier_Wait( &ctx->barrier, &barrier_state, 2 );
+
+ /* B */
+ _SMP_barrier_Wait( &ctx->barrier, &barrier_state, 2 );
+}
+
+static void RequestISR( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ ctx->request.handler = Barriers;
+ ctx->request.arg = ctx;
+ CallWithinISRSubmit( &ctx->request );
+}
+
+static void SendAndSync(
+ Context *ctx,
+ WorkerIndex worker,
+ rtems_event_set event
+)
+{
+ SendEvents( ctx->worker_id[ worker ], EVENT_SYNC_RUNNER | event );
+ ReceiveAllEvents( EVENT_SYNC_RUNNER );
+ WaitForExecutionStop( ctx->worker_id[ worker ] );
+}
+
+static void MakeBusy( Context *ctx, WorkerIndex worker )
+{
+ ctx->busy_counter[ worker ] = 0;
+ ctx->busy[ worker ] = true;
+ SendEvents( ctx->worker_id[ worker ], EVENT_BUSY );
+}
+
+static void MakeBusyAndSync( Context *ctx, WorkerIndex worker )
+{
+ ctx->busy_counter[ worker ] = 0;
+ ctx->busy[ worker ] = true;
+ SendEvents( ctx->worker_id[ worker ], EVENT_SYNC_RUNNER | EVENT_BUSY );
+ ReceiveAllEvents( EVENT_SYNC_RUNNER );
+}
+
+static void StopBusy( Context *ctx, WorkerIndex worker )
+{
+ ctx->busy[ worker ] = false;
+}
+
+static void StopBusyAndWait( Context *ctx, WorkerIndex worker )
+{
+ StopBusy( ctx, worker );
+ WaitForExecutionStop( ctx->worker_id[ worker ] );
+}
+
+static void WaitForBusy( Context *ctx, WorkerIndex worker )
+{
+ while ( ctx->busy_counter[ worker ] == 0 ) {
+ /* Wait */
+ }
+}
+
+static void RemoveWithHelpingOnly( Context *ctx )
+{
+ SMP_barrier_State barrier_state;
+
+ /*
+ * Use the mutex and the worker to construct the removal of the last
+ * processor of a scheduler while a thread is scheduled.
+ */
+
+ _SMP_barrier_Control_initialize( &ctx->barrier );
+ _SMP_barrier_State_initialize( &barrier_state );
+
+ SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_B_ID, PRIO_NORMAL );
+
+ /* Let worker B help worker A */
+ SendEvents( ctx->worker_id[ WORKER_A ], EVENT_OBTAIN );
+ SendAndSync( ctx, WORKER_B, EVENT_OBTAIN );
+
+ /*
+ * Restart the worker B to withdraw the help offer and wait on barriers.
+ * Move worker B to scheduler A. Remove the processor while worker A is
+ * scheduled.
+ */
+
+ SendEvents( ctx->worker_id[ WORKER_A ], EVENT_RESTART );
+
+ /* A */
+ _SMP_barrier_Wait( &ctx->barrier, &barrier_state, 2 );
+
+ SetScheduler( ctx->worker_id[ WORKER_B ], SCHEDULER_A_ID, PRIO_HIGH );
+
+ ctx->id = SCHEDULER_B_ID;
+ ctx->cpu_index = 1;
+ DoRemoveProcessor( ctx );
+
+ /* B */
+ _SMP_barrier_Wait( &ctx->barrier, &barrier_state, 2 );
+
+ /* Clean up all used resources */
+ SetSelfPriority( PRIO_NORMAL );
+ SendEvents( ctx->worker_id[ WORKER_A ], EVENT_RELEASE );
+ T_busy(100000);
+}
+
+static void Worker( rtems_task_argument arg, WorkerIndex worker )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ while ( true ) {
+ rtems_event_set events;
+
+ events = ReceiveAnyEvents();
+
+ if ( ( events & EVENT_SYNC_RUNNER ) != 0 ) {
+ SendEvents( ctx->runner_id, EVENT_SYNC_RUNNER );
+ }
+
+ if ( ( events & EVENT_OBTAIN ) != 0 ) {
+ ObtainMutex( ctx->mutex_id );
+ }
+
+ if ( ( events & EVENT_RELEASE ) != 0 ) {
+ ReleaseMutex( ctx->mutex_id );
+ }
+
+ if ( ( events & EVENT_STICKY_OBTAIN ) != 0 ) {
+ ObtainMutex( ctx->sticky_id );
+ }
+
+ if ( ( events & EVENT_STICKY_RELEASE ) != 0 ) {
+ ReleaseMutex( ctx->sticky_id );
+ }
+
+ if ( ( events & EVENT_RESTART ) != 0 ) {
+ rtems_status_code sc;
+
+ T_eq_u32( rtems_scheduler_get_processor(), 0 );
+ SetPriority( ctx->runner_id, PRIO_VERY_HIGH );
+ T_eq_u32( rtems_scheduler_get_processor(), 1 );
+
+ if ( !ctx->last ) {
+ SetScheduler( ctx->worker_id[ WORKER_C ], SCHEDULER_A_ID, PRIO_LOW );
+ RemoveProcessor( SCHEDULER_C_ID, 2 );
+ AddProcessor( SCHEDULER_B_ID, 2 );
+ }
+
+ WrapThreadQueueExtract(
+ &ctx->wrap_tq_ctx,
+ GetThread( ctx->worker_id[ WORKER_B ] )
+ );
+
+ sc = rtems_task_restart(
+ ctx->worker_id[ WORKER_B ],
+ (rtems_task_argument) ctx
+ );
+ T_rsc_success( sc );
+
+ T_eq_u32( rtems_scheduler_get_processor(), 0 );
+
+ if ( !ctx->last ) {
+ RemoveProcessor( SCHEDULER_B_ID, 2 );
+ AddProcessor( SCHEDULER_C_ID, 2 );
+ SetScheduler( ctx->worker_id[ WORKER_C ], SCHEDULER_C_ID, PRIO_NORMAL );
+ }
+ }
+
+ if ( ( events & EVENT_BUSY ) != 0 ) {
+ while ( ctx->busy[ worker ] ) {
+ ++ctx->busy_counter[ worker ];
+ }
+ }
+
+ if ( ( events & EVENT_SYNC_RUNNER_LATE ) != 0 ) {
+ SendEvents( ctx->runner_id, EVENT_SYNC_RUNNER );
+ }
+ }
+}
+
+static void WorkerA( rtems_task_argument arg )
+{
+ Worker( arg, WORKER_A );
+}
+
+static void WorkerB( rtems_task_argument arg )
+{
+ Worker( arg, WORKER_B );
+}
+
+static void WorkerC( rtems_task_argument arg )
+{
+ Worker( arg, WORKER_C );
+}
+#endif
+
+static void RtemsSchedulerReqRemoveProcessor_Pre_Id_Prepare(
+ RtemsSchedulerReqRemoveProcessor_Context *ctx,
+ RtemsSchedulerReqRemoveProcessor_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqRemoveProcessor_Pre_Id_Invalid: {
+ /*
+ * While the ``scheduler_id`` parameter is not associated with a
+ * scheduler.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Pre_Id_Scheduler: {
+ /*
+ * While the ``scheduler_id`` parameter is associated with a scheduler.
+ */
+ ctx->id = SCHEDULER_A_ID;
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqRemoveProcessor_Pre_CPUIndex_Prepare(
+ RtemsSchedulerReqRemoveProcessor_Context *ctx,
+ RtemsSchedulerReqRemoveProcessor_Pre_CPUIndex state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqRemoveProcessor_Pre_CPUIndex_Valid: {
+ /*
+ * While the ``cpu_index`` parameter is less than the configured
+ * processor maximum.
+ */
+ ctx->cpu_index = 0;
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Pre_CPUIndex_Invalid: {
+ /*
+ * While the ``cpu_index`` parameter is greater than or equal to the
+ * configured processor maximum.
+ */
+ ctx->cpu_index = rtems_configuration_get_maximum_processors();
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Pre_CPUIndex_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqRemoveProcessor_Pre_Owned_Prepare(
+ RtemsSchedulerReqRemoveProcessor_Context *ctx,
+ RtemsSchedulerReqRemoveProcessor_Pre_Owned state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqRemoveProcessor_Pre_Owned_Yes: {
+ /*
+ * While the processor specified by the ``cpu_index`` parameter is owned
+ * by the scheduler specified by the ``scheduler_id`` parameter.
+ */
+ ctx->owned = true;
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Pre_Owned_No: {
+ /*
+ * While the processor specified by the ``cpu_index`` parameter is not
+ * owned by the scheduler specified by the ``scheduler_id`` parameter.
+ */
+ ctx->owned = false;
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Pre_Owned_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqRemoveProcessor_Pre_Last_Prepare(
+ RtemsSchedulerReqRemoveProcessor_Context *ctx,
+ RtemsSchedulerReqRemoveProcessor_Pre_Last state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqRemoveProcessor_Pre_Last_Yes: {
+ /*
+ * While the processor specified by the ``cpu_index`` parameter is the
+ * last processor owned by the scheduler specified by the
+ * ``scheduler_id`` parameter.
+ */
+ ctx->last = true;
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Pre_Last_No: {
+ /*
+ * While the processor specified by the ``cpu_index`` parameter is not
+ * the last processor owned by the scheduler specified by the
+ * ``scheduler_id`` parameter.
+ */
+ ctx->last = false;
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Pre_Last_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqRemoveProcessor_Pre_Home_Prepare(
+ RtemsSchedulerReqRemoveProcessor_Context *ctx,
+ RtemsSchedulerReqRemoveProcessor_Pre_Home state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqRemoveProcessor_Pre_Home_Yes: {
+ /*
+ * While at least one non-idle task exists which uses the scheduler
+ * specified by the ``scheduler_id`` parameter as its home scheduler.
+ */
+ ctx->home = true;
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Pre_Home_No: {
+ /*
+ * While no non-idle task exists which uses the scheduler specified by
+ * the ``scheduler_id`` parameter as its home scheduler.
+ */
+ ctx->home = false;
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Pre_Home_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqRemoveProcessor_Pre_RequiredByAffinity_Prepare(
+ RtemsSchedulerReqRemoveProcessor_Context *ctx,
+ RtemsSchedulerReqRemoveProcessor_Pre_RequiredByAffinity state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqRemoveProcessor_Pre_RequiredByAffinity_Yes: {
+ /*
+ * While at least one non-idle task which uses the scheduler specified by
+ * the ``scheduler_id`` parameter as its home scheduler exists those
+ * processor affinity set requires the processor specified by the
+ * ``cpu_index`` parameter.
+ */
+ ctx->required_by_affinity = true;
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Pre_RequiredByAffinity_No: {
+ /*
+ * While no non-idle task which uses the scheduler specified by the
+ * ``scheduler_id`` parameter as its home scheduler exists those
+ * processor affinity set requires the processor specified by the
+ * ``cpu_index`` parameter.
+ */
+ ctx->required_by_affinity = false;
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Pre_RequiredByAffinity_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqRemoveProcessor_Pre_UsedBy_Prepare(
+ RtemsSchedulerReqRemoveProcessor_Context *ctx,
+ RtemsSchedulerReqRemoveProcessor_Pre_UsedBy state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqRemoveProcessor_Pre_UsedBy_Idle: {
+ /*
+ * While the processor specified by the ``cpu_index`` parameter is used
+ * by an idle task.
+ */
+ ctx->idle = true;
+ ctx->task = false;
+ ctx->helping = false;
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Pre_UsedBy_Task: {
+ /*
+ * While the processor specified by the ``cpu_index`` parameter is used
+ * by a task task which uses the scheduler specified by the
+ * ``scheduler_id`` parameter as its home scheduler.
+ */
+ ctx->idle = false;
+ ctx->task = true;
+ ctx->helping = false;
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Pre_UsedBy_TaskIdle: {
+ /*
+ * While the processor specified by the ``cpu_index`` parameter is used
+ * by an idle task on behalf of a task task which uses the scheduler
+ * specified by the ``scheduler_id`` parameter as its home scheduler.
+ */
+ ctx->idle = true;
+ ctx->task = true;
+ ctx->helping = false;
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Pre_UsedBy_Helping: {
+ /*
+ * While the processor specified by the ``cpu_index`` parameter is used
+ * by a task task which uses the scheduler specified by the
+ * ``scheduler_id`` parameter as a helping scheduler.
+ */
+ if ( !ctx->last && rtems_scheduler_get_processor_maximum() < 3 ) {
+ ctx->Map.skip = true;
+ } else {
+ ctx->idle = false;
+ ctx->task = false;
+ ctx->helping = true;
+ }
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Pre_UsedBy_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqRemoveProcessor_Post_Status_Check(
+ RtemsSchedulerReqRemoveProcessor_Context *ctx,
+ RtemsSchedulerReqRemoveProcessor_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqRemoveProcessor_Post_Status_Ok: {
+ /*
+ * The return status of rtems_scheduler_remove_processor() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Post_Status_InvId: {
+ /*
+ * The return status of rtems_scheduler_remove_processor() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Post_Status_InvNum: {
+ /*
+ * The return status of rtems_scheduler_remove_processor() shall be
+ * RTEMS_INVALID_NUMBER.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NUMBER );
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Post_Status_InUse: {
+ /*
+ * The return status of rtems_scheduler_remove_processor() shall be
+ * RTEMS_RESOURCE_IN_USE.
+ */
+ T_rsc( ctx->status, RTEMS_RESOURCE_IN_USE );
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqRemoveProcessor_Post_Removed_Check(
+ RtemsSchedulerReqRemoveProcessor_Context *ctx,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed state
+)
+{
+ switch ( state ) {
+ case RtemsSchedulerReqRemoveProcessor_Post_Removed_Yes: {
+ /*
+ * The processor specified by the ``cpu_index`` parameter shall be
+ * removed from the scheduler specified by the ``scheduler_id`` by the
+ * rtems_scheduler_remove_processor() call.
+ */
+ if ( ctx->home && ctx->helping ) {
+ /*
+ * For these test scenarios we use scheduler A in which the runner
+ * remains scheduled. So, an ask for help request is issued, when the
+ * processor allocated to a task which uses the scheduler as a helping
+ * scheduler is removed.
+ */
+ T_eq_u32( ctx->id, SCHEDULER_A_ID );
+ T_eq_sz( ctx->scheduler_log.header.recorded, 3 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_REMOVE_PROCESSOR
+ );
+ T_eq_int(
+ ctx->scheduler_log.events[ 1 ].operation,
+ T_SCHEDULER_ASK_FOR_HELP
+ );
+ T_eq_int(
+ ctx->scheduler_log.events[ 2 ].operation,
+ T_SCHEDULER_ASK_FOR_HELP
+ );
+ } else {
+ T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_REMOVE_PROCESSOR
+ );
+ }
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Post_Removed_Nop: {
+ /*
+ * No processor shall be removed from a scheduler by the
+ * rtems_scheduler_remove_processor() call.
+ */
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ break;
+ }
+
+ case RtemsSchedulerReqRemoveProcessor_Post_Removed_NA:
+ break;
+ }
+}
+
+static void RtemsSchedulerReqRemoveProcessor_Setup(
+ RtemsSchedulerReqRemoveProcessor_Context *ctx
+)
+{
+ #if defined(RTEMS_SMP)
+ rtems_status_code sc;
+ rtems_task_priority priority;
+
+ ctx->runner_id = rtems_task_self();
+ ctx->mutex_id = CreateMutex();
+
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'S', 'T', 'K', 'Y' ),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
+ PRIO_NORMAL,
+ &ctx->sticky_id
+ );
+ T_rsc_success( sc );
+
+ sc = rtems_semaphore_set_priority(
+ ctx->sticky_id,
+ SCHEDULER_B_ID,
+ PRIO_NORMAL,
+ &priority
+ );
+ T_rsc_success( sc );
+
+ if ( rtems_scheduler_get_processor_maximum() >= 3 ) {
+ sc = rtems_semaphore_set_priority(
+ ctx->sticky_id,
+ SCHEDULER_C_ID,
+ PRIO_LOW,
+ &priority
+ );
+ T_rsc_success( sc );
+
+ ctx->worker_id[ WORKER_C ] = CreateTask( "WRKC", PRIO_NORMAL );
+ SetScheduler( ctx->worker_id[ WORKER_C ], SCHEDULER_C_ID, PRIO_NORMAL );
+ StartTask( ctx->worker_id[ WORKER_C ], WorkerC, ctx );
+
+ if ( rtems_scheduler_get_processor_maximum() >= 4 ) {
+ RemoveProcessor( SCHEDULER_C_ID, 3 );
+ }
+ }
+
+ SetSelfPriority( PRIO_NORMAL );
+ SetSelfAffinityOne( 0 );
+
+ ctx->worker_id[ WORKER_A ] = CreateTask( "WRKA", PRIO_HIGH );
+ StartTask( ctx->worker_id[ WORKER_A ], WorkerA, ctx );
+
+ ctx->worker_id[ WORKER_B ] = CreateTask( "WRKB", PRIO_HIGH );
+ StartTask( ctx->worker_id[ WORKER_B ], WorkerB, ctx );
+
+ WrapThreadQueueInitialize( &ctx->wrap_tq_ctx, RequestISR, ctx );
+ #endif
+}
+
+static void RtemsSchedulerReqRemoveProcessor_Setup_Wrap( void *arg )
+{
+ RtemsSchedulerReqRemoveProcessor_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSchedulerReqRemoveProcessor_Setup( ctx );
+}
+
+static void RtemsSchedulerReqRemoveProcessor_Teardown(
+ RtemsSchedulerReqRemoveProcessor_Context *ctx
+)
+{
+ #if defined(RTEMS_SMP)
+ DeleteTask( ctx->worker_id[ WORKER_A ] );
+ DeleteTask( ctx->worker_id[ WORKER_B ] );
+ DeleteTask( ctx->worker_id[ WORKER_C ] );
+ DeleteMutex( ctx->mutex_id );
+ DeleteMutex( ctx->sticky_id );
+ WrapThreadQueueDestroy( &ctx->wrap_tq_ctx );
+
+ if ( rtems_scheduler_get_processor_maximum() >= 4 ) {
+ AddProcessor( SCHEDULER_C_ID, 3 );
+ }
+
+ RestoreRunnerPriority();
+ SetSelfAffinityAll();
+ #endif
+}
+
+static void RtemsSchedulerReqRemoveProcessor_Teardown_Wrap( void *arg )
+{
+ RtemsSchedulerReqRemoveProcessor_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSchedulerReqRemoveProcessor_Teardown( ctx );
+}
+
+static void RtemsSchedulerReqRemoveProcessor_Prepare(
+ RtemsSchedulerReqRemoveProcessor_Context *ctx
+)
+{
+ ctx->status = RTEMS_NOT_IMPLEMENTED;
+}
+
+static void RtemsSchedulerReqRemoveProcessor_Action(
+ RtemsSchedulerReqRemoveProcessor_Context *ctx
+)
+{
+ if (
+ ctx->id == INVALID_ID ||
+ ctx->cpu_index == rtems_configuration_get_maximum_processors() ||
+ ( ctx->owned && ctx->last && ctx->home && ctx->required_by_affinity &&
+ ( ctx->task || ctx->idle ) )
+ ) {
+ DoRemoveProcessor( ctx );
+ } else {
+ #if defined(RTEMS_SMP)
+ if ( ctx->owned && !ctx->home && ctx->helping ) {
+ RemoveWithHelpingOnly( ctx );
+ } else {
+ if ( ctx->owned ) {
+ rtems_id worker_a;
+ rtems_id worker_b;
+
+ worker_a = ctx->worker_id[ WORKER_A ];
+ worker_b = ctx->worker_id[ WORKER_B ];
+
+ ctx->cpu_index = 1;
+
+ if ( ctx->last ) {
+ ctx->id = SCHEDULER_B_ID;
+ } else {
+ RemoveProcessor( SCHEDULER_B_ID, 1 );
+ AddProcessor( SCHEDULER_A_ID, 1 );
+ }
+
+ if ( ctx->home ) {
+ SetScheduler( worker_a, ctx->id, PRIO_LOW );
+
+ if ( ctx->required_by_affinity ) {
+ SetAffinityOne( worker_a, 1 );
+ } else {
+ SetAffinityAll( worker_a );
+ }
+ }
+
+ if ( ctx->idle ) {
+ if ( ctx->task ) {
+ SendAndSync( ctx, WORKER_A, EVENT_STICKY_OBTAIN );
+ SuspendTask( worker_a );
+ }
+ } else if ( ctx->task ) {
+ MakeBusy( ctx, WORKER_A );
+ } else if ( ctx->helping ) {
+ T_true( ctx->home );
+
+ if ( ctx->last ) {
+ SendEvents( worker_b, EVENT_OBTAIN );
+ SetPriority( worker_b, PRIO_LOW );
+ } else {
+ SetScheduler( worker_b, SCHEDULER_C_ID, PRIO_LOW );
+ SendAndSync( ctx, WORKER_B, EVENT_OBTAIN );
+ MakeBusyAndSync( ctx, WORKER_C );
+ }
+
+ SendAndSync( ctx, WORKER_A, EVENT_OBTAIN );
+ MakeBusy( ctx, WORKER_B );
+ WaitForBusy( ctx, WORKER_B );
+ }
+
+ DoRemoveProcessor( ctx );
+
+ if ( ctx->idle ) {
+ if ( ctx->task ) {
+ ResumeTask( worker_a );
+ SendAndSync( ctx, WORKER_A, EVENT_STICKY_RELEASE );
+ }
+ } else if ( ctx->task ) {
+ StopBusyAndWait( ctx, WORKER_A );
+ } else if ( ctx->helping ) {
+ StopBusy( ctx, WORKER_B );
+
+ if ( ctx->last ) {
+ SetPriority( worker_b, PRIO_HIGH );
+ SendEvents( worker_b, EVENT_RELEASE );
+ } else {
+ StopBusyAndWait( ctx, WORKER_C );
+ SendAndSync( ctx, WORKER_B, EVENT_RELEASE );
+ SetScheduler( worker_b, SCHEDULER_A_ID, PRIO_HIGH );
+ }
+
+ WaitForExecutionStop( worker_b );
+ SendAndSync( ctx, WORKER_A, EVENT_RELEASE );
+ }
+
+ SetAffinityAll( worker_a );
+ SetScheduler( worker_a, SCHEDULER_A_ID, PRIO_HIGH );
+
+ if ( !ctx->last ) {
+ RemoveProcessor( SCHEDULER_A_ID, 1 );
+ AddProcessor( SCHEDULER_B_ID, 1 );
+ }
+ } else {
+ ctx->id = SCHEDULER_B_ID;
+ DoRemoveProcessor( ctx );
+ }
+ }
+ #else
+ T_unreachable();
+ #endif
+ }
+}
+
+static const RtemsSchedulerReqRemoveProcessor_Entry
+RtemsSchedulerReqRemoveProcessor_Entries[] = {
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, RtemsSchedulerReqRemoveProcessor_Post_Status_NA,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_NA },
+#else
+ { 0, 0, 0, 1, 1, 1, 1, 1, RtemsSchedulerReqRemoveProcessor_Post_Status_InvId,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_Nop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, RtemsSchedulerReqRemoveProcessor_Post_Status_NA,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_NA },
+#else
+ { 0, 0, 0, 1, 1, 1, 1, 1,
+ RtemsSchedulerReqRemoveProcessor_Post_Status_InvNum,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_Nop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, RtemsSchedulerReqRemoveProcessor_Post_Status_NA,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_NA },
+#else
+ { 0, 0, 0, 0, 1, 1, 1, 1,
+ RtemsSchedulerReqRemoveProcessor_Post_Status_InvNum,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_Nop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, RtemsSchedulerReqRemoveProcessor_Post_Status_NA,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, 1, 0, RtemsSchedulerReqRemoveProcessor_Post_Status_NA,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, RtemsSchedulerReqRemoveProcessor_Post_Status_NA,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsSchedulerReqRemoveProcessor_Post_Status_InUse,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_Nop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, RtemsSchedulerReqRemoveProcessor_Post_Status_NA,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 1, 0, RtemsSchedulerReqRemoveProcessor_Post_Status_Ok,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_Yes },
+#endif
+ { 0, 0, 0, 1, 1, 1, 1, 1, RtemsSchedulerReqRemoveProcessor_Post_Status_InvId,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_Nop },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, RtemsSchedulerReqRemoveProcessor_Post_Status_NA,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, RtemsSchedulerReqRemoveProcessor_Post_Status_NA,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, RtemsSchedulerReqRemoveProcessor_Post_Status_NA,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsSchedulerReqRemoveProcessor_Post_Status_Ok,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_Yes },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsSchedulerReqRemoveProcessor_Post_Status_InUse,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_Nop },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, RtemsSchedulerReqRemoveProcessor_Post_Status_NA,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 1, 0, RtemsSchedulerReqRemoveProcessor_Post_Status_InUse,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_Nop },
+#endif
+ { 0, 0, 0, 1, 1, 1, 1, 1,
+ RtemsSchedulerReqRemoveProcessor_Post_Status_InvNum,
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_Nop }
+};
+
+static const uint8_t
+RtemsSchedulerReqRemoveProcessor_Map[] = {
+ 6, 6, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9,
+ 4, 4, 7, 7, 7, 7, 5, 3, 3, 10, 5, 3, 3, 10, 4, 4, 4, 4, 8, 8, 8, 8, 5, 3, 3,
+ 5, 5, 3, 3, 5, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 11, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+};
+
+static size_t RtemsSchedulerReqRemoveProcessor_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ RtemsSchedulerReqRemoveProcessor_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsSchedulerReqRemoveProcessor_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsSchedulerReqRemoveProcessor_Fixture = {
+ .setup = RtemsSchedulerReqRemoveProcessor_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsSchedulerReqRemoveProcessor_Teardown_Wrap,
+ .scope = RtemsSchedulerReqRemoveProcessor_Scope,
+ .initial_context = &RtemsSchedulerReqRemoveProcessor_Instance
+};
+
+static const uint8_t RtemsSchedulerReqRemoveProcessor_Weights[] = {
+ 128, 64, 32, 16, 8, 4, 1
+};
+
+static void RtemsSchedulerReqRemoveProcessor_Skip(
+ RtemsSchedulerReqRemoveProcessor_Context *ctx,
+ size_t index
+)
+{
+ switch ( index + 1 ) {
+ case 1:
+ ctx->Map.pci[ 1 ] = RtemsSchedulerReqRemoveProcessor_Pre_CPUIndex_NA - 1;
+ /* Fall through */
+ case 2:
+ ctx->Map.pci[ 2 ] = RtemsSchedulerReqRemoveProcessor_Pre_Owned_NA - 1;
+ /* Fall through */
+ case 3:
+ ctx->Map.pci[ 3 ] = RtemsSchedulerReqRemoveProcessor_Pre_Last_NA - 1;
+ /* Fall through */
+ case 4:
+ ctx->Map.pci[ 4 ] = RtemsSchedulerReqRemoveProcessor_Pre_Home_NA - 1;
+ /* Fall through */
+ case 5:
+ ctx->Map.pci[ 5 ] = RtemsSchedulerReqRemoveProcessor_Pre_RequiredByAffinity_NA - 1;
+ /* Fall through */
+ case 6:
+ ctx->Map.pci[ 6 ] = RtemsSchedulerReqRemoveProcessor_Pre_UsedBy_NA - 1;
+ break;
+ }
+}
+
+static inline RtemsSchedulerReqRemoveProcessor_Entry
+RtemsSchedulerReqRemoveProcessor_PopEntry(
+ RtemsSchedulerReqRemoveProcessor_Context *ctx
+)
+{
+ size_t index;
+
+ if ( ctx->Map.skip ) {
+ size_t i;
+
+ ctx->Map.skip = false;
+ index = 0;
+
+ for ( i = 0; i < 7; ++i ) {
+ index += RtemsSchedulerReqRemoveProcessor_Weights[ i ] * ctx->Map.pci[ i ];
+ }
+ } else {
+ index = ctx->Map.index;
+ }
+
+ ctx->Map.index = index + 1;
+
+ return RtemsSchedulerReqRemoveProcessor_Entries[
+ RtemsSchedulerReqRemoveProcessor_Map[ index ]
+ ];
+}
+
+static void RtemsSchedulerReqRemoveProcessor_SetPreConditionStates(
+ RtemsSchedulerReqRemoveProcessor_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+
+ if ( ctx->Map.entry.Pre_Owned_NA ) {
+ ctx->Map.pcs[ 2 ] = RtemsSchedulerReqRemoveProcessor_Pre_Owned_NA;
+ } else {
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Last_NA ) {
+ ctx->Map.pcs[ 3 ] = RtemsSchedulerReqRemoveProcessor_Pre_Last_NA;
+ } else {
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Home_NA ) {
+ ctx->Map.pcs[ 4 ] = RtemsSchedulerReqRemoveProcessor_Pre_Home_NA;
+ } else {
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+ }
+
+ if ( ctx->Map.entry.Pre_RequiredByAffinity_NA ) {
+ ctx->Map.pcs[ 5 ] = RtemsSchedulerReqRemoveProcessor_Pre_RequiredByAffinity_NA;
+ } else {
+ ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
+ }
+
+ if ( ctx->Map.entry.Pre_UsedBy_NA ) {
+ ctx->Map.pcs[ 6 ] = RtemsSchedulerReqRemoveProcessor_Pre_UsedBy_NA;
+ } else {
+ ctx->Map.pcs[ 6 ] = ctx->Map.pci[ 6 ];
+ }
+}
+
+static void RtemsSchedulerReqRemoveProcessor_TestVariant(
+ RtemsSchedulerReqRemoveProcessor_Context *ctx
+)
+{
+ RtemsSchedulerReqRemoveProcessor_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsSchedulerReqRemoveProcessor_Pre_CPUIndex_Prepare(
+ ctx,
+ ctx->Map.pcs[ 1 ]
+ );
+ RtemsSchedulerReqRemoveProcessor_Pre_Owned_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsSchedulerReqRemoveProcessor_Pre_Last_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsSchedulerReqRemoveProcessor_Pre_Home_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsSchedulerReqRemoveProcessor_Pre_RequiredByAffinity_Prepare(
+ ctx,
+ ctx->Map.pcs[ 5 ]
+ );
+ RtemsSchedulerReqRemoveProcessor_Pre_UsedBy_Prepare(
+ ctx,
+ ctx->Map.pcs[ 6 ]
+ );
+
+ if ( ctx->Map.skip ) {
+ RtemsSchedulerReqRemoveProcessor_Skip( ctx, 6 );
+ return;
+ }
+
+ RtemsSchedulerReqRemoveProcessor_Action( ctx );
+ RtemsSchedulerReqRemoveProcessor_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ RtemsSchedulerReqRemoveProcessor_Post_Removed_Check(
+ ctx,
+ ctx->Map.entry.Post_Removed
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsSchedulerReqRemoveProcessor( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsSchedulerReqRemoveProcessor,
+ &RtemsSchedulerReqRemoveProcessor_Fixture
+)
+{
+ RtemsSchedulerReqRemoveProcessor_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+ ctx->Map.skip = false;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsSchedulerReqRemoveProcessor_Pre_Id_Invalid;
+ ctx->Map.pci[ 0 ] < RtemsSchedulerReqRemoveProcessor_Pre_Id_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsSchedulerReqRemoveProcessor_Pre_CPUIndex_Valid;
+ ctx->Map.pci[ 1 ] < RtemsSchedulerReqRemoveProcessor_Pre_CPUIndex_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsSchedulerReqRemoveProcessor_Pre_Owned_Yes;
+ ctx->Map.pci[ 2 ] < RtemsSchedulerReqRemoveProcessor_Pre_Owned_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = RtemsSchedulerReqRemoveProcessor_Pre_Last_Yes;
+ ctx->Map.pci[ 3 ] < RtemsSchedulerReqRemoveProcessor_Pre_Last_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ for (
+ ctx->Map.pci[ 4 ] = RtemsSchedulerReqRemoveProcessor_Pre_Home_Yes;
+ ctx->Map.pci[ 4 ] < RtemsSchedulerReqRemoveProcessor_Pre_Home_NA;
+ ++ctx->Map.pci[ 4 ]
+ ) {
+ for (
+ ctx->Map.pci[ 5 ] = RtemsSchedulerReqRemoveProcessor_Pre_RequiredByAffinity_Yes;
+ ctx->Map.pci[ 5 ] < RtemsSchedulerReqRemoveProcessor_Pre_RequiredByAffinity_NA;
+ ++ctx->Map.pci[ 5 ]
+ ) {
+ for (
+ ctx->Map.pci[ 6 ] = RtemsSchedulerReqRemoveProcessor_Pre_UsedBy_Idle;
+ ctx->Map.pci[ 6 ] < RtemsSchedulerReqRemoveProcessor_Pre_UsedBy_NA;
+ ++ctx->Map.pci[ 6 ]
+ ) {
+ ctx->Map.entry = RtemsSchedulerReqRemoveProcessor_PopEntry(
+ ctx
+ );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsSchedulerReqRemoveProcessor_SetPreConditionStates( ctx );
+ RtemsSchedulerReqRemoveProcessor_Prepare( ctx );
+ RtemsSchedulerReqRemoveProcessor_TestVariant( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-scheduler-smp-only.c b/testsuites/validation/tc-scheduler-smp-only.c
new file mode 100644
index 0000000000..0455567aee
--- /dev/null
+++ b/testsuites/validation/tc-scheduler-smp-only.c
@@ -0,0 +1,255 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSchedulerValSmpOnly
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <rtems.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSchedulerValSmpOnly spec:/rtems/scheduler/val/smp-only
+ *
+ * @ingroup TestsuitesValidationSmpOnly0
+ *
+ * @brief This test case collection provides validation test cases for SMP-only
+ * requirements of the @ref RTEMSAPIClassicScheduler.
+ *
+ * This test case performs the following actions:
+ *
+ * - Call rtems_scheduler_get_processor() on all online processors and check
+ * the returned value.
+ *
+ * - Call rtems_scheduler_get_processor_maximum() and check the returned value.
+ *
+ * - Check that the returned value is greater than or equal to one.
+ *
+ * - Check that the returned value is less than or equal to
+ * rtems_configuration_get_maximum_processors().
+ *
+ * - Call rtems_scheduler_ident() for each configured scheduler.
+ *
+ * - Check that the object index of scheduler A has the expected value.
+ *
+ * - Check that the object index of scheduler B has the expected value.
+ *
+ * - Check that the object index of scheduler C has the expected value.
+ *
+ * - Check that the object index of scheduler D has the expected value.
+ *
+ * - Check that processor 0 has scheduler A assigned.
+ *
+ * - Check that processor 1 has scheduler B assigned.
+ *
+ * - Check that scheduler B has the maximum priority of the EDF SMP
+ * scheduler.
+ *
+ * - Check that processor 2 has scheduler C assigned if it is present.
+ *
+ * - Check that processor 3 has scheduler C assigned if it is present.
+ *
+ * @{
+ */
+
+/**
+ * @brief Call rtems_scheduler_get_processor() on all online processors and
+ * check the returned value.
+ */
+static void RtemsSchedulerValSmpOnly_Action_0( void )
+{
+ rtems_id scheduler_id;
+ rtems_task_priority priority;
+ uint32_t cpu_index;
+ uint32_t cpu_max;
+
+ scheduler_id = GetSelfScheduler();
+ priority = GetSelfPriority();
+ cpu_max = rtems_scheduler_get_processor_maximum();
+ T_step_ge_u32( 0, cpu_max, 1 );
+
+ for ( cpu_index = 0; cpu_index < cpu_max; ++cpu_index ) {
+ rtems_status_code sc;
+ rtems_id id;
+
+ sc = rtems_scheduler_ident_by_processor( cpu_index, &id );
+ T_quiet_rsc_success( sc );
+
+ SetSelfScheduler( id, priority );
+ SetSelfAffinityOne( cpu_index );
+
+ T_quiet_eq_u32( rtems_scheduler_get_processor(), cpu_index );
+
+ SetSelfAffinityAll();
+ }
+
+ SetSelfScheduler( scheduler_id, priority );
+}
+
+/**
+ * @brief Call rtems_scheduler_get_processor_maximum() and check the returned
+ * value.
+ */
+static void RtemsSchedulerValSmpOnly_Action_1( void )
+{
+ uint32_t cpu_max;
+
+ cpu_max = rtems_scheduler_get_processor_maximum();
+
+ /*
+ * Check that the returned value is greater than or equal to one.
+ */
+ T_step_ge_u32( 1, cpu_max, 1 );
+
+ /*
+ * Check that the returned value is less than or equal to
+ * rtems_configuration_get_maximum_processors().
+ */
+ T_step_le_u32(
+ 2,
+ cpu_max,
+ rtems_configuration_get_maximum_processors()
+ );
+}
+
+/**
+ * @brief Call rtems_scheduler_ident() for each configured scheduler.
+ */
+static void RtemsSchedulerValSmpOnly_Action_2( void )
+{
+ rtems_status_code sc;
+ rtems_id id[ 4 ];
+ rtems_id id_by_cpu;
+ rtems_task_priority priority;
+
+ sc = rtems_scheduler_ident( TEST_SCHEDULER_A_NAME, &id[ 0 ]);
+ T_step_rsc_success( 3, sc );
+
+ sc = rtems_scheduler_ident( TEST_SCHEDULER_B_NAME, &id[ 1 ]);
+ T_step_rsc_success( 4, sc );
+
+ sc = rtems_scheduler_ident( TEST_SCHEDULER_C_NAME, &id[ 2 ]);
+ T_step_rsc_success( 5, sc );
+
+ sc = rtems_scheduler_ident( TEST_SCHEDULER_D_NAME, &id[ 3 ]);
+ T_step_rsc_success( 6, sc );
+
+ /*
+ * Check that the object index of scheduler A has the expected value.
+ */
+ T_step_eq_u16( 7, rtems_object_id_get_index( id[ 0 ] ), 1 );
+
+ /*
+ * Check that the object index of scheduler B has the expected value.
+ */
+ T_step_eq_u16( 8, rtems_object_id_get_index( id[ 1 ] ), 2 );
+
+ /*
+ * Check that the object index of scheduler C has the expected value.
+ */
+ T_step_eq_u16( 9, rtems_object_id_get_index( id[ 2 ] ), 3 );
+
+ /*
+ * Check that the object index of scheduler D has the expected value.
+ */
+ T_step_eq_u16( 10, rtems_object_id_get_index( id[ 3 ] ), 4 );
+
+ /*
+ * Check that processor 0 has scheduler A assigned.
+ */
+ sc = rtems_scheduler_ident_by_processor( 0, &id_by_cpu );
+ T_step_rsc_success( 11, sc );
+ T_step_eq_u32( 12, id[ 0 ], id_by_cpu );
+
+ /*
+ * Check that processor 1 has scheduler B assigned.
+ */
+ sc = rtems_scheduler_ident_by_processor( 1, &id_by_cpu );
+ T_step_rsc_success( 13, sc );
+ T_step_eq_u32( 14, id[ 1 ], id_by_cpu );
+
+ /*
+ * Check that scheduler B has the maximum priority of the EDF SMP scheduler.
+ */
+ sc = rtems_scheduler_get_maximum_priority( id_by_cpu, &priority );
+ T_step_rsc_success( 15, sc );
+ T_step_eq_u32( 16, priority, (uint32_t) INT_MAX );
+
+ /*
+ * Check that processor 2 has scheduler C assigned if it is present.
+ */
+ sc = rtems_scheduler_ident_by_processor( 2, &id_by_cpu );
+ T_step_true( 17, sc == RTEMS_INVALID_NAME || id[ 2 ] == id_by_cpu );
+
+ /*
+ * Check that processor 3 has scheduler C assigned if it is present.
+ */
+ sc = rtems_scheduler_ident_by_processor( 3, &id_by_cpu );
+ T_step_true( 18, sc == RTEMS_INVALID_NAME || id[ 2 ] == id_by_cpu );
+}
+
+/**
+ * @fn void T_case_body_RtemsSchedulerValSmpOnly( void )
+ */
+T_TEST_CASE( RtemsSchedulerValSmpOnly )
+{
+ T_plan( 19 );
+
+ RtemsSchedulerValSmpOnly_Action_0();
+ RtemsSchedulerValSmpOnly_Action_1();
+ RtemsSchedulerValSmpOnly_Action_2();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-scheduler.c b/testsuites/validation/tc-scheduler.c
new file mode 100644
index 0000000000..2f5b70fc1a
--- /dev/null
+++ b/testsuites/validation/tc-scheduler.c
@@ -0,0 +1,156 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSchedulerValScheduler
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSchedulerValScheduler spec:/rtems/scheduler/val/scheduler
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief This test case collection provides validation test cases for general
+ * requirements of the @ref RTEMSAPIClassicScheduler.
+ *
+ * This test case performs the following actions:
+ *
+ * - Validate rtems_scheduler_get_processor().
+ *
+ * - Check that the values returned by rtems_scheduler_get_processor() and
+ * rtems_scheduler_get_processor() are equal.
+ *
+ * - Validate rtems_scheduler_get_processor_maximum().
+ *
+ * - Check that the values returned by
+ * rtems_scheduler_get_processor_maximum() and
+ * rtems_scheduler_get_processor_maximum() are equal.
+ *
+ * @{
+ */
+
+static uint32_t GetProcessorMaximumMacro( void )
+{
+ return rtems_scheduler_get_processor_maximum();
+}
+
+#undef rtems_scheduler_get_processor_maximum
+
+static uint32_t GetProcessorMaximum( void )
+{
+ return rtems_scheduler_get_processor_maximum();
+}
+
+static uint32_t GetProcessorMacro( void )
+{
+ return rtems_scheduler_get_processor();
+}
+
+#undef rtems_scheduler_get_processor
+
+static uint32_t GetProcessor( void )
+{
+ return rtems_scheduler_get_processor();
+}
+
+/**
+ * @brief Validate rtems_scheduler_get_processor().
+ */
+static void RtemsSchedulerValScheduler_Action_0( void )
+{
+ uint32_t cpu_index;
+ uint32_t cpu_index_macro;
+
+ cpu_index = GetProcessor();
+ cpu_index_macro = GetProcessorMacro();
+
+ /*
+ * Check that the values returned by rtems_scheduler_get_processor() and
+ * rtems_scheduler_get_processor() are equal.
+ */
+ T_step_eq_u32( 0, cpu_index, cpu_index_macro );
+}
+
+/**
+ * @brief Validate rtems_scheduler_get_processor_maximum().
+ */
+static void RtemsSchedulerValScheduler_Action_1( void )
+{
+ uint32_t cpu_max;
+ uint32_t cpu_max_macro;
+
+ cpu_max = GetProcessorMaximum();
+ cpu_max_macro = GetProcessorMaximumMacro();
+
+ /*
+ * Check that the values returned by rtems_scheduler_get_processor_maximum()
+ * and rtems_scheduler_get_processor_maximum() are equal.
+ */
+ T_step_eq_u32( 1, cpu_max, cpu_max_macro );
+}
+
+/**
+ * @fn void T_case_body_RtemsSchedulerValScheduler( void )
+ */
+T_TEST_CASE( RtemsSchedulerValScheduler )
+{
+ T_plan( 2 );
+
+ RtemsSchedulerValScheduler_Action_0();
+ RtemsSchedulerValScheduler_Action_1();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-score-fatal.c b/testsuites/validation/tc-score-fatal.c
new file mode 100644
index 0000000000..b0a55f4664
--- /dev/null
+++ b/testsuites/validation/tc-score-fatal.c
@@ -0,0 +1,462 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreValFatal
+ */
+
+/*
+ * Copyright (C) 2021, 2024 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <setjmp.h>
+#include <string.h>
+#include <rtems/score/atomic.h>
+#include <rtems/score/isrlevel.h>
+#include <rtems/score/threaddispatch.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreValFatal spec:/score/val/fatal
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ * @ingroup TestsuitesValidationOneCpu0
+ *
+ * @brief Tests some fatal errors.
+ *
+ * This test case performs the following actions:
+ *
+ * - Construct a task with a task body which returns. Check that the right
+ * fatal error occurred.
+ *
+ * - Construct a task which performs a direct thread dispatch with maskable
+ * interrupts disabled. Where robust thread dispatching is required, check
+ * that the right fatal error occurred, otherwise check that no fatal error
+ * occurred.
+ *
+ * - Construct a task which performs an on demand thread dispatch with maskable
+ * interrupts disabled. Where robust thread dispatching is required, check
+ * that the right fatal error occurred, otherwise check that no fatal error
+ * occurred.
+ *
+ * - Construct a task which performs a direct thread dispatch with a thread
+ * dispatch level not equal to one. Check that the right fatal error
+ * occurred.
+ *
+ * - Create a mutex and construct a task which produces a deadlock which
+ * involves the allocator mutex.
+ *
+ * - Check that rtems_fatal() terminates the system. Since SetFatalHandler()
+ * requires an initial extension this validates CONFIGURE_INITIAL_EXTENSIONS.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/score/val/fatal test case.
+ */
+typedef struct {
+ /**
+ * @brief This member is a fatal extension invocation counter.
+ */
+ Atomic_Uint counter;
+
+ /**
+ * @brief This member contains the last fatal source.
+ */
+ rtems_fatal_source source;
+
+ /**
+ * @brief This member contains the last fatal code.
+ */
+ rtems_fatal_code code;
+} ScoreValFatal_Context;
+
+static ScoreValFatal_Context
+ ScoreValFatal_Instance;
+
+typedef ScoreValFatal_Context Context;
+
+static unsigned int GetFatalCounter( const Context *ctx )
+{
+ return _Atomic_Load_uint( &ctx->counter, ATOMIC_ORDER_RELAXED );
+}
+
+static unsigned int ResetFatalInfo( Context *ctx )
+{
+ ctx->source = RTEMS_FATAL_SOURCE_APPLICATION;
+ ctx->code = INTERNAL_ERROR_NO_MPCI;
+
+ return GetFatalCounter( ctx );
+}
+
+static void Fatal(
+ rtems_fatal_source source,
+ rtems_fatal_code code,
+ Context *ctx
+)
+{
+ ctx->source = source;
+ ctx->code = code;
+ _Atomic_Fetch_add_uint( &ctx->counter, 1, ATOMIC_ORDER_RELAXED );
+}
+
+static void FatalTaskExit(
+ rtems_fatal_source source,
+ rtems_fatal_code code,
+ void *arg
+)
+{
+ Fatal( source, code, arg );
+ rtems_task_exit();
+}
+
+static void ExitTask( rtems_task_argument arg )
+{
+ (void) arg;
+}
+
+static void FatalBadThreadDispatchEnvironment(
+ rtems_fatal_source source,
+ rtems_fatal_code code,
+ void *arg
+)
+{
+ Fatal( source, code, arg );
+ _ISR_Set_level( 0 );
+ _Thread_Dispatch_unnest( _Per_CPU_Get() );
+ rtems_task_exit();
+}
+
+static void ISRDisabledDirectThreadDispatchTask( rtems_task_argument arg )
+{
+ rtems_interrupt_level level;
+
+ (void) arg;
+ rtems_interrupt_local_disable( level );
+ (void) level;
+ rtems_task_exit();
+}
+
+static void ISRDisabledOnDemandThreadDispatchTask( rtems_task_argument arg )
+{
+ rtems_interrupt_level level;
+
+ (void) arg;
+ rtems_interrupt_local_disable( level );
+ (void) level;
+ SetSelfPriority( PRIO_VERY_HIGH );
+}
+
+static void FatalBadThreadDispatchDisableLevel(
+ rtems_fatal_source source,
+ rtems_fatal_code code,
+ void *arg
+)
+{
+ Per_CPU_Control *cpu_self;
+
+ Fatal( source, code, arg );
+ cpu_self = _Per_CPU_Get();
+ _Thread_Dispatch_unnest( cpu_self );
+ _Thread_Dispatch_direct_no_return( cpu_self );
+}
+
+static void BadLevelThreadDispatchTask( rtems_task_argument arg )
+{
+ (void) arg;
+ _Thread_Dispatch_disable();
+ rtems_task_exit();
+}
+
+static jmp_buf before_fatal;
+
+static rtems_id deadlock_mutex;
+
+static bool ThreadCreateDeadlock( rtems_tcb *executing, rtems_tcb *created )
+{
+ (void) executing;
+ (void) created;
+
+ ObtainMutex( deadlock_mutex );
+ ReleaseMutex( deadlock_mutex );
+
+ return true;
+}
+
+static void FatalJumpBack(
+ rtems_fatal_source source,
+ rtems_fatal_code code,
+ void *arg
+)
+{
+ SetFatalHandler( NULL, NULL );
+ Fatal( source, code, arg );
+ longjmp( before_fatal, 1 );
+}
+
+static void ThreadQueueDeadlockTask( rtems_task_argument arg )
+{
+ rtems_id id;
+
+ (void) arg;
+ id = CreateTask( "DORM", PRIO_NORMAL );
+ DeleteTask( id );
+
+ rtems_task_exit();
+}
+
+static T_fixture ScoreValFatal_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &ScoreValFatal_Instance
+};
+
+/**
+ * @brief Construct a task with a task body which returns. Check that the
+ * right fatal error occurred.
+ */
+static void ScoreValFatal_Action_0( ScoreValFatal_Context *ctx )
+{
+ rtems_id id;
+ unsigned int counter;
+
+ SetFatalHandler( FatalTaskExit, ctx );
+ SetSelfPriority( PRIO_NORMAL );
+ counter = ResetFatalInfo( ctx );
+ id = CreateTask( "EXIT", PRIO_HIGH );
+ StartTask( id, ExitTask, NULL );
+ T_eq_uint( GetFatalCounter( ctx ), counter + 1 );
+ T_eq_int( ctx->source, INTERNAL_ERROR_CORE );
+ T_eq_ulong( ctx->code, INTERNAL_ERROR_THREAD_EXITTED );
+ RestoreRunnerPriority();
+ SetFatalHandler( NULL, NULL );
+}
+
+/**
+ * @brief Construct a task which performs a direct thread dispatch with
+ * maskable interrupts disabled. Where robust thread dispatching is
+ * required, check that the right fatal error occurred, otherwise check that
+ * no fatal error occurred.
+ */
+static void ScoreValFatal_Action_1( ScoreValFatal_Context *ctx )
+{
+ rtems_id id;
+ unsigned int counter;
+
+ SetFatalHandler( FatalBadThreadDispatchEnvironment, ctx );
+ SetSelfPriority( PRIO_NORMAL );
+ counter = ResetFatalInfo( ctx );
+ id = CreateTask( "BENV", PRIO_HIGH );
+ StartTask( id, ISRDisabledDirectThreadDispatchTask, NULL );
+
+ #if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE
+ if ( rtems_configuration_get_maximum_processors() > 1 ) {
+ #endif
+ T_eq_uint( GetFatalCounter( ctx ), counter + 1 );
+ T_eq_int( ctx->source, INTERNAL_ERROR_CORE );
+ T_eq_ulong( ctx->code, INTERNAL_ERROR_BAD_THREAD_DISPATCH_ENVIRONMENT );
+ #if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE
+ } else {
+ T_eq_uint( GetFatalCounter( ctx ), counter );
+ }
+ #endif
+
+ RestoreRunnerPriority();
+ SetFatalHandler( NULL, NULL );
+}
+
+/**
+ * @brief Construct a task which performs an on demand thread dispatch with
+ * maskable interrupts disabled. Where robust thread dispatching is
+ * required, check that the right fatal error occurred, otherwise check that
+ * no fatal error occurred.
+ */
+static void ScoreValFatal_Action_2( ScoreValFatal_Context *ctx )
+{
+ rtems_id id;
+ unsigned int counter;
+
+ SetFatalHandler( FatalBadThreadDispatchEnvironment, ctx );
+ SetSelfPriority( PRIO_NORMAL );
+ counter = ResetFatalInfo( ctx );
+ id = CreateTask( "BENV", PRIO_HIGH );
+ StartTask( id, ISRDisabledOnDemandThreadDispatchTask, NULL );
+
+ #if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE
+ if ( rtems_configuration_get_maximum_processors() > 1 ) {
+ #endif
+ T_eq_uint( GetFatalCounter( ctx ), counter + 1 );
+ T_eq_int( ctx->source, INTERNAL_ERROR_CORE );
+ T_eq_ulong( ctx->code, INTERNAL_ERROR_BAD_THREAD_DISPATCH_ENVIRONMENT );
+ #if CPU_ENABLE_ROBUST_THREAD_DISPATCH == FALSE
+ } else {
+ T_eq_uint( GetFatalCounter( ctx ), counter );
+ }
+ #endif
+
+ RestoreRunnerPriority();
+ SetFatalHandler( NULL, NULL );
+}
+
+/**
+ * @brief Construct a task which performs a direct thread dispatch with a
+ * thread dispatch level not equal to one. Check that the right fatal error
+ * occurred.
+ */
+static void ScoreValFatal_Action_3( ScoreValFatal_Context *ctx )
+{
+ rtems_id id;
+ unsigned int counter;
+
+ SetFatalHandler( FatalBadThreadDispatchDisableLevel, ctx );
+ SetSelfPriority( PRIO_NORMAL );
+ counter = ResetFatalInfo( ctx );
+ id = CreateTask( "BLVL", PRIO_HIGH );
+ StartTask( id, BadLevelThreadDispatchTask, NULL );
+ T_eq_uint( GetFatalCounter( ctx ), counter + 1 );
+ T_eq_int( ctx->source, INTERNAL_ERROR_CORE );
+ T_eq_ulong( ctx->code, INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL );
+ RestoreRunnerPriority();
+ SetFatalHandler( NULL, NULL );
+}
+
+/**
+ * @brief Create a mutex and construct a task which produces a deadlock which
+ * involves the allocator mutex.
+ */
+static void ScoreValFatal_Action_4( ScoreValFatal_Context *ctx )
+{
+ rtems_extensions_table extensions;
+ rtems_status_code sc;
+ rtems_id extension_id;
+ rtems_id task_id;
+ unsigned int counter;
+
+ memset( &extensions, 0, sizeof( extensions ) );
+ extensions.thread_create = ThreadCreateDeadlock;
+
+ sc = rtems_extension_create(
+ rtems_build_name( 'T', 'E', 'X', 'T' ),
+ &extensions,
+ &extension_id
+ );
+ T_rsc_success( sc );
+
+ deadlock_mutex = CreateMutex();
+
+ SetFatalHandler( FatalJumpBack, ctx );
+ SetSelfPriority( PRIO_NORMAL );
+ counter = ResetFatalInfo( ctx );
+
+ ObtainMutex( deadlock_mutex );
+
+ task_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( task_id, ThreadQueueDeadlockTask, NULL );
+
+ if ( setjmp( before_fatal ) == 0 ) {
+ (void) CreateTask( "DLCK", PRIO_NORMAL );
+ }
+
+ ReleaseMutex( deadlock_mutex );
+
+ T_eq_uint( GetFatalCounter( ctx ), counter + 1 );
+ T_eq_int( ctx->source, INTERNAL_ERROR_CORE );
+ T_eq_ulong( ctx->code, INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK );
+
+ RestoreRunnerPriority();
+
+ sc = rtems_extension_delete( extension_id );
+ T_rsc_success( sc );
+
+ DeleteMutex( deadlock_mutex );
+}
+
+/**
+ * @brief Check that rtems_fatal() terminates the system. Since
+ * SetFatalHandler() requires an initial extension this validates
+ * CONFIGURE_INITIAL_EXTENSIONS.
+ */
+static void ScoreValFatal_Action_5( ScoreValFatal_Context *ctx )
+{
+ unsigned int counter;
+
+ SetFatalHandler( FatalJumpBack, ctx );
+ counter = ResetFatalInfo( ctx );
+
+ if ( setjmp( before_fatal ) == 0 ) {
+ rtems_fatal( 123, 4567890 );
+ }
+
+ T_eq_uint( GetFatalCounter( ctx ), counter + 1 );
+ T_eq_int( ctx->source, 123 );
+ T_eq_ulong( ctx->code, 4567890 );
+}
+
+/**
+ * @fn void T_case_body_ScoreValFatal( void )
+ */
+T_TEST_CASE_FIXTURE( ScoreValFatal, &ScoreValFatal_Fixture )
+{
+ ScoreValFatal_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ ScoreValFatal_Action_0( ctx );
+ ScoreValFatal_Action_1( ctx );
+ ScoreValFatal_Action_2( ctx );
+ ScoreValFatal_Action_3( ctx );
+ ScoreValFatal_Action_4( ctx );
+ ScoreValFatal_Action_5( ctx );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-score-isr.c b/testsuites/validation/tc-score-isr.c
new file mode 100644
index 0000000000..b178541e72
--- /dev/null
+++ b/testsuites/validation/tc-score-isr.c
@@ -0,0 +1,285 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreIsrValIsr
+ */
+
+/*
+ * Copyright (C) 2023 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/sysinit.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/thread.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreIsrValIsr spec:/score/isr/val/isr
+ *
+ * @ingroup TestsuitesValidationIntr
+ *
+ * @brief Tests general interrupt support behaviour.
+ *
+ * This test case performs the following actions:
+ *
+ * - Submit an ISR request during system initialization. Check the stack of
+ * the interrupted context while the ISR request is serviced. Store the
+ * result of the check in interrupted_stack_at_multitasking_start_is_valid.
+ *
+ * - Check that stack of the interrupted context was valid when an interrupt
+ * was serviced during the multitasking start.
+ *
+ * @{
+ */
+
+static uintptr_t interrupted_stack_at_multitasking_start;
+
+static bool interrupted_stack_at_multitasking_start_is_valid;
+
+#if defined(__aarch64__)
+void __real_bsp_interrupt_dispatch( void );
+
+void __wrap_bsp_interrupt_dispatch( void );
+
+void __wrap_bsp_interrupt_dispatch( void )
+{
+ if ( interrupted_stack_at_multitasking_start == 0 ) {
+ uintptr_t sp;
+ rtems_interrupt_level level;
+
+ rtems_interrupt_local_disable( level );
+ __asm__ volatile (
+ "msr spsel, #1\n"
+ "mov %0, sp\n"
+ "msr spsel, #0"
+ : "=r" ( sp )
+ );
+ rtems_interrupt_local_enable( level );
+
+ interrupted_stack_at_multitasking_start = sp;
+ }
+
+ __real_bsp_interrupt_dispatch();
+}
+#endif
+
+#if defined(ARM_MULTILIB_ARCH_V4)
+void __real_bsp_interrupt_dispatch( void );
+
+void __wrap_bsp_interrupt_dispatch( void );
+
+void __wrap_bsp_interrupt_dispatch( void )
+{
+ register uintptr_t sp __asm__( "9" );
+
+ if ( interrupted_stack_at_multitasking_start == 0 ) {
+ interrupted_stack_at_multitasking_start = sp;
+ }
+
+ __real_bsp_interrupt_dispatch();
+}
+#endif
+
+#if defined(__microblaze__)
+void __real_bsp_interrupt_dispatch( uint32_t source );
+
+void __wrap_bsp_interrupt_dispatch( uint32_t source );
+
+void __wrap_bsp_interrupt_dispatch( uint32_t source )
+{
+ register uintptr_t sp __asm__( "1" );
+
+ if ( interrupted_stack_at_multitasking_start == 0 ) {
+ interrupted_stack_at_multitasking_start = sp;
+ }
+
+ __real_bsp_interrupt_dispatch( source );
+}
+#endif
+
+#if defined(__PPC__) || defined(__powerpc64__)
+void __real_bsp_interrupt_dispatch( void );
+
+void __wrap_bsp_interrupt_dispatch( void );
+
+void __wrap_bsp_interrupt_dispatch( void )
+{
+ register uintptr_t sp __asm__( "14" );
+
+ if ( interrupted_stack_at_multitasking_start == 0 ) {
+ interrupted_stack_at_multitasking_start = sp;
+ }
+
+ __real_bsp_interrupt_dispatch();
+}
+#endif
+
+#if defined(__riscv)
+void __real__RISCV_Interrupt_dispatch(
+ uintptr_t mcause,
+ Per_CPU_Control *cpu_self
+);
+
+void __wrap__RISCV_Interrupt_dispatch(
+ uintptr_t mcause,
+ Per_CPU_Control *cpu_self
+);
+
+void __wrap__RISCV_Interrupt_dispatch(
+ uintptr_t mcause,
+ Per_CPU_Control *cpu_self
+)
+{
+ register uintptr_t sp __asm__( "s1" );
+
+ if ( interrupted_stack_at_multitasking_start == 0 ) {
+ interrupted_stack_at_multitasking_start = sp;
+ }
+
+ __real__RISCV_Interrupt_dispatch( mcause, cpu_self );
+}
+#endif
+
+#if defined(__sparc__)
+void __real__SPARC_Interrupt_dispatch( uint32_t irq );
+
+static RTEMS_USED void InterruptDispatch( uint32_t irq, uintptr_t sp )
+{
+ if ( interrupted_stack_at_multitasking_start == 0 ) {
+ interrupted_stack_at_multitasking_start = sp;
+ }
+
+ __real__SPARC_Interrupt_dispatch( irq );
+}
+
+__asm__ (
+ "\t.section\t\".text\"\n"
+ "\t.align\t4\n"
+ "\t.globl\t__wrap__SPARC_Interrupt_dispatch\n"
+ "\t.type\t__wrap__SPARC_Interrupt_dispatch, #function\n"
+ "__wrap__SPARC_Interrupt_dispatch:\n"
+ "\tmov\t%fp, %o1\n"
+ "\tor\t%o7, %g0, %g1\n"
+ "\tcall\tInterruptDispatch, 0\n"
+ "\t or\t%g1, %g0, %o7\n"
+ "\t.previous\n"
+);
+#endif
+
+static void ISRHandler( void *arg )
+{
+ uintptr_t begin;
+ uintptr_t end;
+
+ (void) arg;
+
+#if defined(RTEMS_SMP) && !(defined(__PPC__) || (__powerpc64__))
+ Per_CPU_Control *cpu_self;
+
+ cpu_self = _Per_CPU_Get();
+ begin = (uintptr_t) &cpu_self->Interrupt_frame;
+ end = begin + sizeof( cpu_self->Interrupt_frame );
+#else
+ Thread_Control *executing;
+
+ executing = GetExecuting();
+ begin = (uintptr_t) executing->Start.Initial_stack.area;
+ end = begin + executing->Start.Initial_stack.size;
+#endif
+
+ interrupted_stack_at_multitasking_start_is_valid =
+ ( begin <= interrupted_stack_at_multitasking_start &&
+ interrupted_stack_at_multitasking_start < end );
+}
+
+static CallWithinISRRequest isr_request = {
+ .handler = ISRHandler
+};
+
+static void SubmitISRRequest( void )
+{
+ CallWithinISRSubmit( &isr_request );
+}
+
+RTEMS_SYSINIT_ITEM(
+ SubmitISRRequest,
+ RTEMS_SYSINIT_DEVICE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_LAST
+);
+
+/**
+ * @brief Submit an ISR request during system initialization. Check the stack
+ * of the interrupted context while the ISR request is serviced. Store the
+ * result of the check in interrupted_stack_at_multitasking_start_is_valid.
+ */
+static void ScoreIsrValIsr_Action_0( void )
+{
+ /*
+ * The actions are performed during system initialization and the
+ * multitasking start.
+ */
+
+ /*
+ * Check that stack of the interrupted context was valid when an interrupt
+ * was serviced during the multitasking start.
+ */
+ T_true( interrupted_stack_at_multitasking_start_is_valid );
+}
+
+/**
+ * @fn void T_case_body_ScoreIsrValIsr( void )
+ */
+T_TEST_CASE( ScoreIsrValIsr )
+{
+ ScoreIsrValIsr_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-score-smp-per-cpu-jobs.c b/testsuites/validation/tc-score-smp-per-cpu-jobs.c
new file mode 100644
index 0000000000..62812279cb
--- /dev/null
+++ b/testsuites/validation/tc-score-smp-per-cpu-jobs.c
@@ -0,0 +1,151 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSmpValPerCpuJobs
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/score/atomic.h>
+#include <rtems/score/percpu.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreSmpValPerCpuJobs spec:/score/smp/val/per-cpu-jobs
+ *
+ * @ingroup TestsuitesValidationSmpOnly0
+ *
+ * @brief Tests the processing order of per-processor jobs.
+ *
+ * This test case performs the following actions:
+ *
+ * - Issue two jobs on the current processor with interrupts disabled. Wait
+ * for completion of the second job.
+ *
+ * - Check that the first job was processed firstly.
+ *
+ * - Check that the second job was processed secondly.
+ *
+ * @{
+ */
+
+static Atomic_Uint job_counter;
+
+static void Increment( void *arg )
+{
+ unsigned int *value;
+
+ value = (unsigned int *) arg;
+ *value =
+ _Atomic_Fetch_add_uint( &job_counter, 1, ATOMIC_ORDER_RELAXED ) + 1;
+}
+
+static unsigned int counter_0;
+
+static const Per_CPU_Job_context job_context_0 = {
+ .handler = Increment,
+ .arg = &counter_0
+};
+
+Per_CPU_Job job_0 = {
+ .context = &job_context_0
+};
+
+static unsigned int counter_1;
+
+static const Per_CPU_Job_context job_context_1 = {
+ .handler = Increment,
+ .arg = &counter_1
+};
+
+Per_CPU_Job job_1 = {
+ .context = &job_context_1,
+};
+
+/**
+ * @brief Issue two jobs on the current processor with interrupts disabled.
+ * Wait for completion of the second job.
+ */
+static void ScoreSmpValPerCpuJobs_Action_0( void )
+{
+ rtems_interrupt_level level;
+ Per_CPU_Control *cpu;
+
+ rtems_interrupt_local_disable(level);
+ cpu = _Per_CPU_Get();
+ _Per_CPU_Add_job( cpu, &job_0 );
+ _Per_CPU_Submit_job( cpu, &job_1 );
+ rtems_interrupt_local_enable(level);
+
+ _Per_CPU_Wait_for_job( cpu, &job_1 );
+
+ /*
+ * Check that the first job was processed firstly.
+ */
+ T_step_eq_int( 0, counter_0, 1 );
+
+ /*
+ * Check that the second job was processed secondly.
+ */
+ T_step_eq_int( 1, counter_1, 2 );
+}
+
+/**
+ * @fn void T_case_body_ScoreSmpValPerCpuJobs( void )
+ */
+T_TEST_CASE( ScoreSmpValPerCpuJobs )
+{
+ T_plan( 2 );
+
+ ScoreSmpValPerCpuJobs_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-score-smp-thread.c b/testsuites/validation/tc-score-smp-thread.c
new file mode 100644
index 0000000000..38d2b26e29
--- /dev/null
+++ b/testsuites/validation/tc-score-smp-thread.c
@@ -0,0 +1,554 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreThreadValSmp
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/test-scheduler.h>
+#include <rtems/score/smpbarrier.h>
+#include <rtems/score/threadimpl.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreThreadValSmp spec:/score/thread/val/smp
+ *
+ * @ingroup TestsuitesValidationSmpOnly0
+ *
+ * @brief Tests SMP-specific thread behaviour.
+ *
+ * This test case performs the following actions:
+ *
+ * - Create three worker threads and a mutex. Use the mutex and the worker to
+ * move to a helping scheduler.
+ *
+ * - Pin the runner thread while it executes on a processor owned by a
+ * helping scheduler.
+ *
+ * - Pin and unpin the runner thread. This is a nested operation.
+ *
+ * - Preempt the pinned runner thread. Worker B and C execute at the same
+ * time on processor 0 and 1 respectively for some point in time. This
+ * shows that the pinning of the runner thread is maintained.
+ *
+ * - Unpin the runner thread. The runner moves back to its home scheduler.
+ *
+ * - Release the mutex.
+ *
+ * - Pin the runner thread. Unpin the runner thread while it is suspended.
+ *
+ * - Make sure the worker released the mutex.
+ *
+ * - Clean up all used resources.
+ *
+ * - Create three worker threads and a mutex. Use the mutex and the worker to
+ * check that a suspended thread does not reconsider help requests.
+ *
+ * - Let worker B help worker A through the mutex. Preempt worker A. Delay
+ * the thread switch to worker A.
+ *
+ * - Suspend worker A and let it wait on its thread state lock. Check that
+ * worker A did not reconsider help requests.
+ *
+ * - Resume worker A. Check that worker A did reconsider help requests after
+ * the thread dispatch.
+ *
+ * - Clean up all used resources.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/score/thread/val/smp test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the worker A identifier.
+ */
+ rtems_id worker_a_id;
+
+ /**
+ * @brief This member contains the worker B identifier.
+ */
+ rtems_id worker_b_id;
+
+ /**
+ * @brief This member contains the worker C identifier.
+ */
+ rtems_id worker_c_id;
+
+ /**
+ * @brief This member contains the mutex identifier.
+ */
+ rtems_id mutex_id;
+
+ /**
+ * @brief If this member is true, then the worker shall busy wait.
+ */
+ volatile bool busy;
+
+ /**
+ * @brief This member contains a counter for EVENT_COUNT.
+ */
+ volatile uint32_t counter;
+
+ /**
+ * @brief This member contains the barrier to synchronize the runner and the
+ * workers.
+ */
+ SMP_barrier_Control barrier;
+
+ /**
+ * @brief This member contains the barrier state for the runner processor.
+ */
+ SMP_barrier_State barrier_state;
+} ScoreThreadValSmp_Context;
+
+static ScoreThreadValSmp_Context
+ ScoreThreadValSmp_Instance;
+
+#define EVENT_OBTAIN RTEMS_EVENT_0
+
+#define EVENT_RELEASE RTEMS_EVENT_1
+
+#define EVENT_COUNT_EARLY RTEMS_EVENT_2
+
+#define EVENT_BUSY RTEMS_EVENT_3
+
+#define EVENT_COUNT RTEMS_EVENT_4
+
+#define EVENT_LET_WORKER_C_COUNT RTEMS_EVENT_5
+
+#define EVENT_SET_TASK_SWITCH_EXTENSION RTEMS_EVENT_6
+
+typedef ScoreThreadValSmp_Context Context;
+
+static void TaskSwitchExtension( rtems_tcb *executing, rtems_tcb *heir )
+{
+ Context *ctx;
+ Thread_Control *thread;
+
+ (void) executing;
+ (void) heir;
+
+ ctx = T_fixture_context();
+ thread = GetThread( ctx->worker_a_id );
+
+ if ( thread == heir ) {
+ SMP_barrier_State state;
+
+ _SMP_barrier_State_initialize( &state );
+
+ /* B0 */
+ _SMP_barrier_Wait( &ctx->barrier, &state, 2 );
+
+ /* B1 */
+ _SMP_barrier_Wait( &ctx->barrier, &state, 2 );
+ }
+}
+
+static void WorkerTask( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ while ( true ) {
+ rtems_event_set events;
+
+ events = ReceiveAnyEvents();
+
+ if ( ( events & EVENT_OBTAIN ) != 0 ) {
+ ObtainMutex( ctx->mutex_id );
+ }
+
+ if ( ( events & EVENT_RELEASE ) != 0 ) {
+ ReleaseMutex( ctx->mutex_id );
+ }
+
+ if ( ( events & EVENT_COUNT_EARLY ) != 0 ) {
+ ++ctx->counter;
+ }
+
+ if ( ( events & EVENT_BUSY ) != 0 ) {
+ while ( ctx->busy ) {
+ /* Do nothing */
+ }
+ }
+
+ if ( ( events & EVENT_COUNT ) != 0 ) {
+ ++ctx->counter;
+ }
+
+ if ( ( events & EVENT_LET_WORKER_C_COUNT ) != 0 ) {
+ uint32_t counter;
+
+ counter = ctx->counter;
+ SendEvents( ctx->worker_c_id, EVENT_COUNT );
+
+ while ( ctx->counter == counter ) {
+ /* Wait */
+ }
+ }
+
+ if ( ( events & EVENT_SET_TASK_SWITCH_EXTENSION ) != 0 ) {
+ SetTaskSwitchExtension( TaskSwitchExtension );
+ }
+ }
+}
+
+static void SchedulerBlock(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ if (
+ when == T_SCHEDULER_BEFORE &&
+ event->operation == T_SCHEDULER_BLOCK
+ ) {
+ Thread_Control *thread;
+
+ T_scheduler_set_event_handler( NULL, NULL );
+
+ /* B1 */
+ _SMP_barrier_Wait( &ctx->barrier, &ctx->barrier_state, 2 );
+
+ thread = GetThread( ctx->worker_a_id );
+ TicketLockWaitForOthers( &thread->Join_queue.Queue.Lock, 1 );
+ }
+}
+
+static void Suspend( void *arg )
+{
+ Thread_Control *thread;
+
+ thread = arg;
+ SuspendTask( thread->Object.id );
+}
+
+static void Resume( void *arg )
+{
+ Thread_Control *thread;
+
+ thread = arg;
+ ResumeTask( thread->Object.id );
+}
+
+static void WaitForCounter( const Context *ctx, uint32_t expected )
+{
+ while ( ctx->counter != expected ) {
+ /* Wait */
+ }
+}
+
+static void ScoreThreadValSmp_Setup( ScoreThreadValSmp_Context *ctx )
+{
+ SetSelfPriority( PRIO_NORMAL );
+}
+
+static void ScoreThreadValSmp_Setup_Wrap( void *arg )
+{
+ ScoreThreadValSmp_Context *ctx;
+
+ ctx = arg;
+ ScoreThreadValSmp_Setup( ctx );
+}
+
+static void ScoreThreadValSmp_Teardown( ScoreThreadValSmp_Context *ctx )
+{
+ RestoreRunnerPriority();
+}
+
+static void ScoreThreadValSmp_Teardown_Wrap( void *arg )
+{
+ ScoreThreadValSmp_Context *ctx;
+
+ ctx = arg;
+ ScoreThreadValSmp_Teardown( ctx );
+}
+
+static T_fixture ScoreThreadValSmp_Fixture = {
+ .setup = ScoreThreadValSmp_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreThreadValSmp_Teardown_Wrap,
+ .scope = NULL,
+ .initial_context = &ScoreThreadValSmp_Instance
+};
+
+/**
+ * @brief Create three worker threads and a mutex. Use the mutex and the
+ * worker to move to a helping scheduler.
+ */
+static void ScoreThreadValSmp_Action_0( ScoreThreadValSmp_Context *ctx )
+{
+ Per_CPU_Control*cpu_self;
+ Thread_Control *executing;
+
+ executing = _Thread_Get_executing();
+ ctx->counter = 0;
+
+ ctx->mutex_id = CreateMutex();
+
+ ctx->worker_a_id = CreateTask( "WRKA", PRIO_NORMAL );
+ SetScheduler( ctx->worker_a_id, SCHEDULER_B_ID, PRIO_NORMAL );
+ StartTask( ctx->worker_a_id, WorkerTask, ctx );
+
+ ctx->worker_b_id = CreateTask( "WRKB", PRIO_HIGH );
+ StartTask( ctx->worker_b_id, WorkerTask, ctx );
+
+ ctx->worker_c_id = CreateTask( "WRKC", PRIO_LOW );
+ StartTask( ctx->worker_c_id, WorkerTask, ctx );
+
+ ObtainMutex( ctx->mutex_id );
+ SendEvents( ctx->worker_a_id, EVENT_OBTAIN | EVENT_RELEASE );
+
+ ctx->busy = true;
+ SendEvents( ctx->worker_b_id, EVENT_BUSY );
+
+ /*
+ * Pin the runner thread while it executes on a processor owned by a helping
+ * scheduler.
+ */
+ T_eq_u32( rtems_scheduler_get_processor(), 1 );
+ _Thread_Pin( executing );
+
+ /*
+ * Pin and unpin the runner thread. This is a nested operation.
+ */
+ T_eq_u32( rtems_scheduler_get_processor(), 1 );
+ _Thread_Pin( executing );
+ _Thread_Unpin( executing, _Per_CPU_Get_snapshot() );
+
+ /*
+ * Preempt the pinned runner thread. Worker B and C execute at the same time
+ * on processor 0 and 1 respectively for some point in time. This shows that
+ * the pinning of the runner thread is maintained.
+ */
+ ctx->busy = false;
+ SetScheduler( ctx->worker_b_id, SCHEDULER_B_ID, PRIO_HIGH );
+ SendEvents( ctx->worker_b_id, EVENT_LET_WORKER_C_COUNT );
+
+ T_eq_u32( rtems_scheduler_get_processor(), 1 );
+ T_eq_u32( ctx->counter, 1 );
+
+ /*
+ * Unpin the runner thread. The runner moves back to its home scheduler.
+ */
+ cpu_self = _Thread_Dispatch_disable();
+ _Thread_Unpin( executing, cpu_self );
+ _Thread_Dispatch_direct( cpu_self );
+
+ T_eq_u32( rtems_scheduler_get_processor(), 0 );
+
+ /*
+ * Release the mutex.
+ */
+ ReleaseMutex( ctx->mutex_id);
+ T_eq_u32( rtems_scheduler_get_processor(), 0 );
+
+ /*
+ * Pin the runner thread. Unpin the runner thread while it is suspended.
+ */
+ _Thread_Pin( executing );
+
+ /* We have to preempt the runner to end up in _Thread_Do_unpin() */
+ SetPriority( ctx->worker_c_id, PRIO_HIGH );
+ SendEvents( ctx->worker_c_id, EVENT_COUNT );
+ T_eq_u32( ctx->counter, 2 );
+
+ cpu_self = _Thread_Dispatch_disable();
+ CallWithinISR( Suspend, executing );
+ _Thread_Unpin( executing, cpu_self );
+ CallWithinISR( Resume, executing );
+ _Thread_Dispatch_direct( cpu_self );
+
+ /*
+ * Make sure the worker released the mutex.
+ */
+ SetSelfScheduler( SCHEDULER_B_ID, PRIO_LOW );
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_NORMAL );
+
+ /*
+ * Clean up all used resources.
+ */
+ DeleteTask( ctx->worker_a_id );
+ DeleteTask( ctx->worker_b_id );
+ DeleteTask( ctx->worker_c_id );
+ DeleteMutex( ctx->mutex_id );
+}
+
+/**
+ * @brief Create three worker threads and a mutex. Use the mutex and the
+ * worker to check that a suspended thread does not reconsider help requests.
+ */
+static void ScoreThreadValSmp_Action_1( ScoreThreadValSmp_Context *ctx )
+{
+ T_scheduler_log_10 scheduler_log;
+ size_t index;
+ const T_scheduler_event *event;
+
+ _SMP_barrier_Control_initialize( &ctx->barrier );
+ _SMP_barrier_State_initialize( &ctx->barrier_state );
+
+ ctx->counter = 0;
+ ctx->mutex_id = CreateMutex();
+
+ ctx->worker_a_id = CreateTask( "WRKA", PRIO_NORMAL );
+ SetScheduler( ctx->worker_a_id, SCHEDULER_B_ID, PRIO_NORMAL );
+ StartTask( ctx->worker_a_id, WorkerTask, ctx );
+
+ ctx->worker_b_id = CreateTask( "WRKB", PRIO_HIGH );
+ StartTask( ctx->worker_b_id, WorkerTask, ctx );
+
+ ctx->worker_c_id = CreateTask( "WRKC", PRIO_NORMAL );
+ SetScheduler( ctx->worker_c_id, SCHEDULER_B_ID, PRIO_HIGH );
+ StartTask( ctx->worker_c_id, WorkerTask, ctx );
+
+ /*
+ * Let worker B help worker A through the mutex. Preempt worker A. Delay
+ * the thread switch to worker A.
+ */
+ ctx->busy = true;
+ SendEvents(
+ ctx->worker_a_id,
+ EVENT_OBTAIN | EVENT_COUNT_EARLY | EVENT_BUSY | EVENT_COUNT
+ );
+ WaitForCounter( ctx, 1 );
+
+ SendEvents( ctx->worker_b_id, EVENT_OBTAIN );
+ SetPriority( ctx->worker_b_id, PRIO_LOW );
+ SendEvents( ctx->worker_c_id, EVENT_SET_TASK_SWITCH_EXTENSION );
+
+ /* B0 */
+ _SMP_barrier_Wait( &ctx->barrier, &ctx->barrier_state, 2 );
+
+ /*
+ * Suspend worker A and let it wait on its thread state lock. Check that
+ * worker A did not reconsider help requests.
+ */
+ T_scheduler_record_10( &scheduler_log );
+ T_scheduler_set_event_handler( SchedulerBlock, ctx );
+ SuspendTask( ctx->worker_a_id );
+ WaitForExecutionStop( ctx->worker_a_id );
+ T_scheduler_record( NULL );
+ T_eq_sz( scheduler_log.header.recorded, 2 );
+ index = 0;
+ event = T_scheduler_next_any( &scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_BLOCK );
+ event = T_scheduler_next_any( &scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_WITHDRAW_NODE );
+ event = T_scheduler_next_any( &scheduler_log.header, &index );
+ T_eq_ptr( event, &T_scheduler_event_null );
+ SetTaskSwitchExtension( NULL );
+
+ /*
+ * Resume worker A. Check that worker A did reconsider help requests after
+ * the thread dispatch.
+ */
+ T_scheduler_record_10( &scheduler_log );
+ ResumeTask( ctx->worker_a_id );
+ ctx->busy = false;
+ WaitForCounter( ctx, 2 );
+ WaitForExecutionStop( ctx->worker_a_id );
+ T_scheduler_record( NULL );
+ T_eq_sz( scheduler_log.header.recorded, 5 );
+ index = 0;
+ event = T_scheduler_next_any( &scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_UNBLOCK );
+ event = T_scheduler_next_any( &scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_RECONSIDER_HELP_REQUEST );
+ event = T_scheduler_next_any( &scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_RECONSIDER_HELP_REQUEST );
+ event = T_scheduler_next_any( &scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_BLOCK );
+ event = T_scheduler_next_any( &scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_WITHDRAW_NODE );
+ event = T_scheduler_next_any( &scheduler_log.header, &index );
+ T_eq_ptr( event, &T_scheduler_event_null );
+
+ /*
+ * Clean up all used resources.
+ */
+ SendEvents( ctx->worker_a_id, EVENT_RELEASE | EVENT_COUNT );
+ WaitForCounter( ctx, 3 );
+
+ SetPriority( ctx->worker_b_id, PRIO_HIGH );
+ SendEvents( ctx->worker_b_id, EVENT_RELEASE );
+
+ DeleteTask( ctx->worker_a_id );
+ DeleteTask( ctx->worker_b_id );
+ DeleteTask( ctx->worker_c_id );
+ DeleteMutex( ctx->mutex_id );
+}
+
+/**
+ * @fn void T_case_body_ScoreThreadValSmp( void )
+ */
+T_TEST_CASE_FIXTURE( ScoreThreadValSmp, &ScoreThreadValSmp_Fixture )
+{
+ ScoreThreadValSmp_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ ScoreThreadValSmp_Action_0( ctx );
+ ScoreThreadValSmp_Action_1( ctx );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-score-thread-smp-one-cpu.c b/testsuites/validation/tc-score-thread-smp-one-cpu.c
new file mode 100644
index 0000000000..b3564d574e
--- /dev/null
+++ b/testsuites/validation/tc-score-thread-smp-one-cpu.c
@@ -0,0 +1,183 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreThreadValSmpOneCpu
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/threadimpl.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreThreadValSmpOneCpu spec:/score/thread/val/smp-one-cpu
+ *
+ * @ingroup TestsuitesValidationSmpOneCpu0
+ *
+ * @brief Tests SMP-specific thread behaviour using only one processor and a
+ * uniprocessor scheduler.
+ *
+ * This test case performs the following actions:
+ *
+ * - Create one worker thread to validate the thread pinning on only one
+ * processor using a uniprocessor scheduler.
+ *
+ * - Pin the runner thread. Preempt the runner thread. Unpin the runner
+ * thread.
+ *
+ * - Clean up all used resources.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/score/thread/val/smp-one-cpu test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the worker thread identifier.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member contains a counter for EVENT_COUNT.
+ */
+ volatile uint32_t counter;
+} ScoreThreadValSmpOneCpu_Context;
+
+static ScoreThreadValSmpOneCpu_Context
+ ScoreThreadValSmpOneCpu_Instance;
+
+#define EVENT_COUNT RTEMS_EVENT_0
+
+typedef ScoreThreadValSmpOneCpu_Context Context;
+
+static void WorkerTask( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ while ( true ) {
+ rtems_event_set events;
+
+ events = ReceiveAnyEvents();
+
+ if ( ( events & EVENT_COUNT ) != 0 ) {
+ ++ctx->counter;
+ }
+ }
+}
+
+static T_fixture ScoreThreadValSmpOneCpu_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &ScoreThreadValSmpOneCpu_Instance
+};
+
+/**
+ * @brief Create one worker thread to validate the thread pinning on only one
+ * processor using a uniprocessor scheduler.
+ */
+static void ScoreThreadValSmpOneCpu_Action_0(
+ ScoreThreadValSmpOneCpu_Context *ctx
+)
+{
+ Per_CPU_Control *cpu_self;
+ Thread_Control *executing;
+
+ executing = _Thread_Get_executing();
+ SetSelfPriority( PRIO_NORMAL );
+ ctx->counter = 0;
+
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, WorkerTask, ctx );
+
+ /*
+ * Pin the runner thread. Preempt the runner thread. Unpin the runner
+ * thread.
+ */
+ _Thread_Pin( executing );
+
+ /* We have to preempt the runner to end up in _Thread_Do_unpin() */
+ SendEvents( ctx->worker_id, EVENT_COUNT );
+ T_eq_u32( ctx->counter, 1 );
+
+ cpu_self = _Thread_Dispatch_disable();
+ _Thread_Unpin( executing, cpu_self );
+ _Thread_Dispatch_direct( cpu_self );
+
+ /*
+ * Clean up all used resources.
+ */
+ DeleteTask( ctx->worker_id );
+ RestoreRunnerPriority();
+}
+
+/**
+ * @fn void T_case_body_ScoreThreadValSmpOneCpu( void )
+ */
+T_TEST_CASE_FIXTURE(
+ ScoreThreadValSmpOneCpu,
+ &ScoreThreadValSmpOneCpu_Fixture
+)
+{
+ ScoreThreadValSmpOneCpu_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ ScoreThreadValSmpOneCpu_Action_0( ctx );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-score-thread-tls-max-zero.c b/testsuites/validation/tc-score-thread-tls-max-zero.c
new file mode 100644
index 0000000000..6205147865
--- /dev/null
+++ b/testsuites/validation/tc-score-thread-tls-max-zero.c
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreThreadValTlsMaxZero
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/thread.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreThreadValTlsMaxZero spec:/score/thread/val/tls-max-zero
+ *
+ * @ingroup TestsuitesValidationTls1
+ *
+ * @brief Tests properties of thread-local objects.
+ *
+ * This test case performs the following actions:
+ *
+ * - The test action is carried out by the thread-local objects definition and
+ * the application configuration.
+ *
+ * - Check that the CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE application
+ * configuration option resulted in the expected system setting. Since at
+ * least one thread-local objects is available, the referenced requirement
+ * is validated.
+ *
+ * @{
+ */
+
+static _Thread_local int volatile tls_object;
+
+/**
+ * @brief The test action is carried out by the thread-local objects definition
+ * and the application configuration.
+ */
+static void ScoreThreadValTlsMaxZero_Action_0( void )
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE application
+ * configuration option resulted in the expected system setting. Since at
+ * least one thread-local objects is available, the referenced requirement is
+ * validated.
+ */
+ T_step_eq_int( 0, tls_object, 0 );
+ T_step_eq_sz( 1, _Thread_Maximum_TLS_size, 0 );
+}
+
+/**
+ * @fn void T_case_body_ScoreThreadValTlsMaxZero( void )
+ */
+T_TEST_CASE( ScoreThreadValTlsMaxZero )
+{
+ T_plan( 2 );
+
+ ScoreThreadValTlsMaxZero_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-score-thread-tls.c b/testsuites/validation/tc-score-thread-tls.c
new file mode 100644
index 0000000000..54d930d111
--- /dev/null
+++ b/testsuites/validation/tc-score-thread-tls.c
@@ -0,0 +1,135 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreThreadValTls
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreThreadValTls spec:/score/thread/val/tls
+ *
+ * @ingroup TestsuitesValidationTls0
+ * @ingroup TestsuitesValidationTls1
+ *
+ * @brief Tests properties of thread-local objects.
+ *
+ * This test case performs the following actions:
+ *
+ * - The test action is carried out by the thread-local objects definition.
+ *
+ * - Check that the initial value of the zero initialized thread-local object
+ * has the expected value.
+ *
+ * - Check that the alignment of the zero initialized thread-local object has
+ * the expected value.
+ *
+ * - Check that the initial value of the non-zero initialized thread-local
+ * object has the expected value.
+ *
+ * - Check that the alignment of the non-zero initialized thread-local object
+ * has the expected value.
+ *
+ * @{
+ */
+
+static RTEMS_ALIGNED( 256 ) _Thread_local int volatile tls_object_0;
+
+static RTEMS_ALIGNED( 256 ) _Thread_local int volatile tls_object_1 = 123;
+
+/**
+ * @brief The test action is carried out by the thread-local objects
+ * definition.
+ */
+static void ScoreThreadValTls_Action_0( void )
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the initial value of the zero initialized thread-local object
+ * has the expected value.
+ */
+ T_step_eq_int( 0, tls_object_0, 0 );
+
+ /*
+ * Check that the alignment of the zero initialized thread-local object has
+ * the expected value.
+ */
+ T_step_eq_uptr( 1, ( (uintptr_t) &tls_object_0 ) % 256, 0 );
+
+ /*
+ * Check that the initial value of the non-zero initialized thread-local
+ * object has the expected value.
+ */
+ T_step_eq_int( 2, tls_object_1, 123 );
+
+ /*
+ * Check that the alignment of the non-zero initialized thread-local object
+ * has the expected value.
+ */
+ T_step_eq_uptr( 3, ( (uintptr_t) &tls_object_1 ) % 256, 0 );
+}
+
+/**
+ * @fn void T_case_body_ScoreThreadValTls( void )
+ */
+T_TEST_CASE( ScoreThreadValTls )
+{
+ T_plan( 4 );
+
+ ScoreThreadValTls_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-score-thread.c b/testsuites/validation/tc-score-thread.c
new file mode 100644
index 0000000000..e065905641
--- /dev/null
+++ b/testsuites/validation/tc-score-thread.c
@@ -0,0 +1,446 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreThreadValThread
+ */
+
+/*
+ * Copyright (C) 2021, 2023 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/score/statesimpl.h>
+#include <rtems/score/threadimpl.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreThreadValThread spec:/score/thread/val/thread
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests general thread behaviour.
+ *
+ * This test case performs the following actions:
+ *
+ * - Create an extension set with a thread terminate extension which deletes
+ * the killer task if it is invoked for the worker task. Create and start
+ * the worker task. Create and start the killer task. The killer task
+ * deletes the worker task.
+ *
+ * - Check that the killer task was deleted.
+ *
+ * - Check that the worker task still exists.
+ *
+ * - Check that the life of the worker task is protected and terminating.
+ *
+ * - Check that the worker task is waiting for a joining thread.
+ *
+ * - Delete the worker task using brute force.
+ *
+ * - Clean up all used resources.
+ *
+ * - Delete a thread which least recently used the floating point coprocessor.
+ *
+ * - Start the worker thread. Let it use the floating point coprocessor.
+ *
+ * - Delete the worker thread and free the thread resources.
+ *
+ * - Clean up all used resources.
+ *
+ * - Validate the global construction. Mark that the test case executed.
+ *
+ * - Check that the global constructor was called exactly once.
+ *
+ * - Check that the global construction was done by the Classic API user
+ * initialization task.
+ *
+ * - Check that the global constructor was called before the task entry.
+ *
+ * - Validate that thread dispatching does not recurse. Issue a couple of
+ * thread context switches during a thread dispatch. Record the stack
+ * pointers of the heir threads.
+ *
+ * - Check that the thread dispatching did not recurse through the recorded
+ * stack pointers.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/score/thread/val/thread test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the worker task identifier.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member contains the killer task identifier.
+ */
+ rtems_id killer_id;
+
+ /**
+ * @brief This member contains a floating-point object.
+ */
+ volatile double fp_obj;
+
+ /**
+ * @brief This member indicates the thread switch state.
+ */
+ int thread_switch_state;
+
+ /**
+ * @brief This member contain the runner stack pointer at the context switch.
+ */
+ uintptr_t runner_stack[ 2 ];
+
+ /**
+ * @brief This member contain the worker stack pointer at the context switch.
+ */
+ uintptr_t worker_stack[ 2 ];
+} ScoreThreadValThread_Context;
+
+static ScoreThreadValThread_Context
+ ScoreThreadValThread_Instance;
+
+typedef ScoreThreadValThread_Context Context;
+
+static bool test_case_executed;
+
+static bool constructor_test_case_executed;
+
+static uint32_t constructor_calls;
+
+static rtems_id constructor_id;
+
+static __attribute__(( __constructor__ )) void Constructor( void )
+{
+ constructor_test_case_executed = test_case_executed;
+ ++constructor_calls;
+ constructor_id = rtems_task_self();
+}
+
+static void TaskTerminate( rtems_tcb *executing )
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+
+ if ( ctx->worker_id == executing->Object.id ) {
+ DeleteTask( ctx->killer_id );
+ }
+}
+
+static void WorkerTask( rtems_task_argument arg )
+{
+ (void) arg;
+ SuspendSelf();
+}
+
+static void GoBackToRunner( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ SetPriority( ctx->worker_id, PRIO_LOW );
+}
+
+static void FloatingPointTask( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+ ctx->fp_obj *= 1.23;
+
+ /*
+ * We use an interrupt to go back to the runner since on some
+ * architectures, the floating-point context is only saved during interrupt
+ * processing and not for synchronous thread switches.
+ */
+ CallWithinISR( GoBackToRunner, ctx );
+}
+
+static void KillerTask( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+ DeleteTask( ctx->worker_id );
+}
+
+static void TaskSwitch( rtems_tcb *executing, rtems_tcb *heir )
+{
+ Context *ctx;
+ rtems_id worker_id;
+ int state;
+ uintptr_t heir_stack;
+
+ ctx = T_fixture_context();
+ worker_id = ctx->worker_id;
+ state = ctx->thread_switch_state;
+ ctx->thread_switch_state = state + 1;
+ heir_stack = _CPU_Context_Get_SP( &heir->Registers );
+
+ switch ( state ) {
+ case 0:
+ T_eq_u32( heir->Object.id, worker_id );
+ SuspendTask( worker_id );
+ ctx->worker_stack[ 0 ] = heir_stack;
+ break;
+ case 1:
+ T_eq_u32( executing->Object.id, worker_id );
+ ResumeTask( worker_id );
+ ctx->runner_stack[ 0 ] = heir_stack;
+ break;
+ case 2:
+ T_eq_u32( heir->Object.id, worker_id );
+ SuspendTask( worker_id );
+ ctx->worker_stack[ 1 ] = heir_stack;
+ break;
+ case 3:
+ T_eq_u32( executing->Object.id, worker_id );
+ ctx->runner_stack[ 1 ] = heir_stack;
+ break;
+ default:
+ T_unreachable();
+ }
+}
+
+static T_fixture ScoreThreadValThread_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &ScoreThreadValThread_Instance
+};
+
+/**
+ * @brief Create an extension set with a thread terminate extension which
+ * deletes the killer task if it is invoked for the worker task. Create and
+ * start the worker task. Create and start the killer task. The killer task
+ * deletes the worker task.
+ */
+static void ScoreThreadValThread_Action_0( ScoreThreadValThread_Context *ctx )
+{
+ rtems_extensions_table table = {
+ .thread_terminate = TaskTerminate
+ };
+ rtems_status_code sc;
+ rtems_id id;
+ rtems_tcb *worker_tcb;
+
+ sc = rtems_extension_create(
+ rtems_build_name( 'T', 'E', 'S', 'T' ),
+ &table,
+ &id
+ );
+ T_rsc_success( sc );
+
+ SetSelfPriority( PRIO_NORMAL );
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ worker_tcb = GetThread( ctx->worker_id );
+ StartTask( ctx->worker_id, WorkerTask, NULL );
+ ctx->killer_id = CreateTask( "KILL", PRIO_HIGH );
+ StartTask( ctx->killer_id, KillerTask, ctx );
+
+ /*
+ * Check that the killer task was deleted.
+ */
+ sc = rtems_event_send( ctx->killer_id, RTEMS_EVENT_0 );
+ T_rsc( sc, RTEMS_INVALID_ID );
+
+ /*
+ * Check that the worker task still exists.
+ */
+ sc = rtems_event_send( ctx->worker_id, RTEMS_EVENT_0 );
+ T_rsc_success( sc );
+
+ /*
+ * Check that the life of the worker task is protected and terminating.
+ */
+ T_eq_int(
+ worker_tcb->Life.state,
+ THREAD_LIFE_PROTECTED | THREAD_LIFE_TERMINATING
+ );
+
+ /*
+ * Check that the worker task is waiting for a joining thread.
+ */
+ T_eq_u32(
+ worker_tcb->current_state,
+ STATES_WAITING_FOR_JOIN_AT_EXIT
+ );
+
+ /*
+ * Delete the worker task using brute force.
+ */
+ worker_tcb->Life.state = THREAD_LIFE_DETACHED |
+ THREAD_LIFE_PROTECTED | THREAD_LIFE_TERMINATING;
+ _Thread_Clear_state( worker_tcb, STATES_WAITING_FOR_JOIN_AT_EXIT );
+
+ /*
+ * Clean up all used resources.
+ */
+ KillZombies();
+ RestoreRunnerPriority();
+
+ sc = rtems_extension_delete( id );
+ T_rsc_success( sc );
+}
+
+/**
+ * @brief Delete a thread which least recently used the floating point
+ * coprocessor.
+ */
+static void ScoreThreadValThread_Action_1( ScoreThreadValThread_Context *ctx )
+{
+ rtems_status_code sc;
+
+ SetSelfPriority( PRIO_NORMAL );
+ sc = rtems_task_create(
+ rtems_build_name( 'W', 'O', 'R', 'K'),
+ PRIO_HIGH,
+ TEST_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_FLOATING_POINT,
+ &ctx->worker_id
+ );
+ T_rsc_success( sc );
+
+ /*
+ * Start the worker thread. Let it use the floating point coprocessor.
+ */
+ StartTask( ctx->worker_id, FloatingPointTask, ctx );
+
+ /*
+ * Delete the worker thread and free the thread resources.
+ */
+ DeleteTask( ctx->worker_id );
+ KillZombies();
+
+ /*
+ * Clean up all used resources.
+ */
+ RestoreRunnerPriority();
+}
+
+/**
+ * @brief Validate the global construction. Mark that the test case executed.
+ */
+static void ScoreThreadValThread_Action_2( ScoreThreadValThread_Context *ctx )
+{
+ test_case_executed = true;
+
+ /*
+ * Check that the global constructor was called exactly once.
+ */
+ T_eq_u32( constructor_calls, 1 );
+
+ /*
+ * Check that the global construction was done by the Classic API user
+ * initialization task.
+ */
+ T_eq_u32( constructor_id, rtems_task_self() );
+
+ /*
+ * Check that the global constructor was called before the task entry.
+ */
+ T_false( constructor_test_case_executed );
+}
+
+/**
+ * @brief Validate that thread dispatching does not recurse. Issue a couple of
+ * thread context switches during a thread dispatch. Record the stack
+ * pointers of the heir threads.
+ */
+static void ScoreThreadValThread_Action_3( ScoreThreadValThread_Context *ctx )
+{
+ SetSelfPriority( PRIO_NORMAL );
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, WorkerTask, NULL );
+
+ ctx->thread_switch_state = 0;
+ ctx->runner_stack[ 0 ] = 0;
+ ctx->runner_stack[ 1 ] = 1;
+ ctx->worker_stack[ 0 ] = 0;
+ ctx->worker_stack[ 1 ] = 1;
+ SetTaskSwitchExtension( TaskSwitch );
+ ResumeTask( ctx->worker_id );
+
+ SetTaskSwitchExtension( NULL );
+ DeleteTask( ctx->worker_id );
+ RestoreRunnerPriority();
+
+ /*
+ * Check that the thread dispatching did not recurse through the recorded
+ * stack pointers.
+ */
+ T_eq_uptr( ctx->runner_stack[ 0 ], ctx->runner_stack[ 1 ] );
+ T_eq_uptr( ctx->worker_stack[ 0 ], ctx->worker_stack[ 1 ] );
+}
+
+/**
+ * @fn void T_case_body_ScoreThreadValThread( void )
+ */
+T_TEST_CASE_FIXTURE( ScoreThreadValThread, &ScoreThreadValThread_Fixture )
+{
+ ScoreThreadValThread_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ ScoreThreadValThread_Action_0( ctx );
+ ScoreThreadValThread_Action_1( ctx );
+ ScoreThreadValThread_Action_2( ctx );
+ ScoreThreadValThread_Action_3( ctx );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-score-tq-smp.c b/testsuites/validation/tc-score-tq-smp.c
new file mode 100644
index 0000000000..624ad0e7b6
--- /dev/null
+++ b/testsuites/validation/tc-score-tq-smp.c
@@ -0,0 +1,571 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqValSmp
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/smpbarrier.h>
+#include <rtems/score/threadimpl.h>
+#include <rtems/score/threadqimpl.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTqValSmp spec:/score/tq/val/smp
+ *
+ * @ingroup TestsuitesValidationSmpOnly0
+ *
+ * @brief Tests SMP-specific thread queue behaviour.
+ *
+ * This test case performs the following actions:
+ *
+ * - Create two or three worker threads and a mutex. Use the mutex and the
+ * worker to do a thread priority change in parallel with a thread queue
+ * extraction.
+ *
+ * - Create a mutex and let the runner obtain it.
+ *
+ * - Create and start worker A on a second processor. mutex. Let it wait on
+ * the barrier.
+ *
+ * - If there are more than two processors, then create and start also worker
+ * C. Let it wait on the barrier.
+ *
+ * - Create and start worker B. Let it try to obtain the mutex which is
+ * owned by the runner. Delete worker B to extract it from the thread
+ * queue. Wrap the thread queue extract operation to do a parallel thread
+ * priority change carried out by worker A (and maybe C).
+ *
+ * - Clean up all used resources.
+ *
+ * - Build a cyclic dependency graph using several worker threads and mutexes.
+ * Use the mutexes and the worker to construct a thread queue deadlock which
+ * is detected on one processor while it uses thread queue links inserted by
+ * another processor. The runner thread controls the test scenario via the
+ * two thread queue locks. This is an important test scenario which shows
+ * why the thread queue implementation is a bit more complicated in SMP
+ * configurations.
+ *
+ * - Let worker D wait for mutex A. Let worker C wait for mutex D. Let
+ * worker B wait for mutex C.
+ *
+ * - Let worker A attempt to obtain mutex B. Let worker A wait on the lock
+ * of mutex C. Worker A will insert two thread queue links.
+ *
+ * - Let worker E try to obtain mutex D. Worker E will add a thread queue
+ * link which is later used by worker A to detect the deadlock.
+ *
+ * - Let worker A continue the obtain sequence. It will detect a deadlock.
+ *
+ * - Clean up all used resources.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/score/tq/val/smp test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the runner identifier.
+ */
+ rtems_id runner_id;
+
+ /**
+ * @brief This member contains the worker A identifier.
+ */
+ rtems_id worker_a_id;
+
+ /**
+ * @brief This member contains the worker B identifier.
+ */
+ rtems_id worker_b_id;
+
+ /**
+ * @brief This member contains the worker C identifier.
+ */
+ rtems_id worker_c_id;
+
+ /**
+ * @brief This member contains the worker D identifier.
+ */
+ rtems_id worker_d_id;
+
+ /**
+ * @brief This member contains the worker E identifier.
+ */
+ rtems_id worker_e_id;
+
+ /**
+ * @brief This member contains the mutex A identifier.
+ */
+ rtems_id mutex_a_id;
+
+ /**
+ * @brief This member contains the mutex B identifier.
+ */
+ rtems_id mutex_b_id;
+
+ /**
+ * @brief This member contains the mutex C identifier.
+ */
+ rtems_id mutex_c_id;
+
+ /**
+ * @brief This member contains the mutex D identifier.
+ */
+ rtems_id mutex_d_id;
+
+ /**
+ * @brief This member contains the count of processors used by the test.
+ */
+ uint32_t used_cpus;
+
+ /**
+ * @brief This member contains the thread queue of the mutex.
+ */
+ Thread_queue_Queue *thread_queue;
+
+ /**
+ * @brief This member contains the context to wrap the thread queue extract.
+ */
+ WrapThreadQueueContext wrap;
+
+ /**
+ * @brief This member contains the barrier to synchronize the runner and the
+ * workers.
+ */
+ SMP_barrier_Control barrier;
+
+ /**
+ * @brief This member contains the barrier state for the runner processor.
+ */
+ SMP_barrier_State barrier_state;
+} ScoreTqValSmp_Context;
+
+static ScoreTqValSmp_Context
+ ScoreTqValSmp_Instance;
+
+typedef ScoreTqValSmp_Context Context;
+
+static void Extract( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ /* PC0 */
+ _SMP_barrier_Wait( &ctx->barrier, &ctx->barrier_state, ctx->used_cpus );
+
+ /*
+ * Ensure that worker A (and maybe C) acquired the thread wait lock of
+ * worker B.
+ */
+ TicketLockWaitForOthers( &ctx->thread_queue->Lock, ctx->used_cpus - 1 );
+
+ /*
+ * Continue with the thread queue extraction. The thread wait lock of
+ * worker B will be changed back to the default thread wait lock. This
+ * will cause worker A (and maybe C) to release the thread queue lock and
+ * acquire the default thread wait lock of worker B instead to carry out
+ * the priority change.
+ *
+ * See also _Thread_Wait_acquire_critical().
+ */
+}
+
+static void PriorityChangeWorker( rtems_task_argument arg )
+{
+ Context *ctx;
+ SMP_barrier_State state;
+
+ ctx = (Context *) arg;
+ _SMP_barrier_State_initialize( &state );
+
+ /* PC0 */
+ _SMP_barrier_Wait( &ctx->barrier, &state, ctx->used_cpus );
+
+ SetPriority( ctx->worker_b_id, PRIO_VERY_HIGH );
+
+ /* PC1 */
+ _SMP_barrier_Wait( &ctx->barrier, &state, ctx->used_cpus );
+
+ (void) ReceiveAnyEvents();
+}
+
+static void MutexObtainWorker( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ ObtainMutex( ctx->mutex_a_id );
+}
+
+static void DeadlockWorkerA( rtems_task_argument arg )
+{
+ Context *ctx;
+ SMP_barrier_State state;
+
+ ctx = (Context *) arg;
+ _SMP_barrier_State_initialize( &state );
+
+ ObtainMutex( ctx->mutex_a_id );
+
+ /* D0 */
+ _SMP_barrier_Wait( &ctx->barrier, &state, 2 );
+
+ /* D1 */
+ _SMP_barrier_Wait( &ctx->barrier, &state, 2 );
+
+ ObtainMutexDeadlock( ctx->mutex_b_id );
+
+ ReleaseMutex( ctx->mutex_a_id );
+ SendEvents( ctx->runner_id, RTEMS_EVENT_0 );
+ (void) ReceiveAnyEvents();
+}
+
+static void DeadlockWorkerB( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ ObtainMutex( ctx->mutex_b_id );
+ SendEvents( ctx->runner_id, RTEMS_EVENT_5 );
+ ObtainMutex( ctx->mutex_c_id );
+ ReleaseMutex( ctx->mutex_c_id );
+ ReleaseMutex( ctx->mutex_b_id );
+ SendEvents( ctx->runner_id, RTEMS_EVENT_1 );
+ (void) ReceiveAnyEvents();
+}
+
+static void DeadlockWorkerC( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ ObtainMutex( ctx->mutex_c_id );
+ ObtainMutex( ctx->mutex_d_id );
+ ReleaseMutex( ctx->mutex_d_id );
+ ReleaseMutex( ctx->mutex_c_id );
+ SendEvents( ctx->runner_id, RTEMS_EVENT_2 );
+ (void) ReceiveAnyEvents();
+}
+
+static void DeadlockWorkerD( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ ObtainMutex( ctx->mutex_d_id );
+ ObtainMutex( ctx->mutex_a_id );
+ ReleaseMutex( ctx->mutex_a_id );
+ ReleaseMutex( ctx->mutex_d_id );
+ SendEvents( ctx->runner_id, RTEMS_EVENT_3 );
+ (void) ReceiveAnyEvents();
+}
+
+static void DeadlockWorkerE( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ ObtainMutex( ctx->mutex_d_id );
+ ReleaseMutex( ctx->mutex_d_id );
+ SendEvents( ctx->runner_id, RTEMS_EVENT_4 );
+ (void) ReceiveAnyEvents();
+}
+
+static void ScoreTqValSmp_Setup( ScoreTqValSmp_Context *ctx )
+{
+ SetSelfPriority( PRIO_NORMAL );
+}
+
+static void ScoreTqValSmp_Setup_Wrap( void *arg )
+{
+ ScoreTqValSmp_Context *ctx;
+
+ ctx = arg;
+ ScoreTqValSmp_Setup( ctx );
+}
+
+static void ScoreTqValSmp_Teardown( ScoreTqValSmp_Context *ctx )
+{
+ RestoreRunnerPriority();
+}
+
+static void ScoreTqValSmp_Teardown_Wrap( void *arg )
+{
+ ScoreTqValSmp_Context *ctx;
+
+ ctx = arg;
+ ScoreTqValSmp_Teardown( ctx );
+}
+
+static T_fixture ScoreTqValSmp_Fixture = {
+ .setup = ScoreTqValSmp_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreTqValSmp_Teardown_Wrap,
+ .scope = NULL,
+ .initial_context = &ScoreTqValSmp_Instance
+};
+
+/**
+ * @brief Create two or three worker threads and a mutex. Use the mutex and
+ * the worker to do a thread priority change in parallel with a thread queue
+ * extraction.
+ */
+static void ScoreTqValSmp_Action_0( ScoreTqValSmp_Context *ctx )
+{
+ _SMP_barrier_Control_initialize( &ctx->barrier );
+ _SMP_barrier_State_initialize( &ctx->barrier_state );
+ WrapThreadQueueInitialize( &ctx->wrap, Extract, ctx );
+
+ if ( rtems_scheduler_get_processor_maximum() > 2 ) {
+ ctx->used_cpus = 3;
+ } else {
+ ctx->used_cpus = 2;
+ }
+
+ /*
+ * Create a mutex and let the runner obtain it.
+ */
+ ctx->mutex_a_id = CreateMutexNoProtocol();
+ ctx->thread_queue = GetMutexThreadQueue( ctx->mutex_a_id );
+ ObtainMutex( ctx->mutex_a_id );
+
+ /*
+ * Create and start worker A on a second processor. mutex. Let it wait on
+ * the barrier.
+ */
+ ctx->worker_a_id = CreateTask( "WRKA", PRIO_NORMAL );
+ SetScheduler( ctx->worker_a_id, SCHEDULER_B_ID, PRIO_NORMAL );
+ StartTask( ctx->worker_a_id, PriorityChangeWorker, ctx );
+
+ /*
+ * If there are more than two processors, then create and start also worker
+ * C. Let it wait on the barrier.
+ */
+ if ( ctx->used_cpus > 2 ) {
+ ctx->worker_c_id = CreateTask( "WRKC", PRIO_NORMAL );
+ SetScheduler( ctx->worker_c_id, SCHEDULER_C_ID, PRIO_NORMAL );
+ StartTask( ctx->worker_c_id, PriorityChangeWorker, ctx );
+ }
+
+ /*
+ * Create and start worker B. Let it try to obtain the mutex which is owned
+ * by the runner. Delete worker B to extract it from the thread queue. Wrap
+ * the thread queue extract operation to do a parallel thread priority change
+ * carried out by worker A (and maybe C).
+ */
+ ctx->worker_b_id = CreateTask( "WRKB", PRIO_HIGH );
+ StartTask( ctx->worker_b_id, MutexObtainWorker, ctx );
+ WrapThreadQueueExtractDirect( &ctx->wrap, GetThread( ctx->worker_b_id ) );
+ DeleteTask( ctx->worker_b_id );
+
+ /*
+ * Clean up all used resources.
+ */
+ /* PC1 */
+ _SMP_barrier_Wait( &ctx->barrier, &ctx->barrier_state, ctx->used_cpus );
+
+ WaitForExecutionStop( ctx->worker_a_id );
+ DeleteTask( ctx->worker_a_id );
+
+ if ( ctx->used_cpus > 2 ) {
+ WaitForExecutionStop( ctx->worker_c_id );
+ DeleteTask( ctx->worker_c_id );
+ }
+
+ ReleaseMutex( ctx->mutex_a_id );
+ DeleteMutex( ctx->mutex_a_id );
+ WrapThreadQueueDestroy( &ctx->wrap );
+}
+
+/**
+ * @brief Build a cyclic dependency graph using several worker threads and
+ * mutexes. Use the mutexes and the worker to construct a thread queue
+ * deadlock which is detected on one processor while it uses thread queue
+ * links inserted by another processor. The runner thread controls the test
+ * scenario via the two thread queue locks. This is an important test
+ * scenario which shows why the thread queue implementation is a bit more
+ * complicated in SMP configurations.
+ */
+static void ScoreTqValSmp_Action_1( ScoreTqValSmp_Context *ctx )
+{
+ Thread_queue_Queue *queue_b;
+ Thread_queue_Queue *queue_c;
+ ISR_lock_Context lock_context;
+ SMP_barrier_State state;
+
+ if ( rtems_scheduler_get_processor_maximum() <= 2 ) {
+ /*
+ * We can only run this validation test on systems with three or more
+ * processors. The sequence under test can happen on systems with only two
+ * processors, however, we need a third processor to control the other two
+ * processors via ISR locks to get a deterministic test scenario.
+ */
+ return;
+ }
+
+ ctx->runner_id = rtems_task_self();
+
+ _SMP_barrier_Control_initialize( &ctx->barrier );
+ _SMP_barrier_State_initialize( &state );
+
+ ctx->mutex_a_id = CreateMutexNoProtocol();
+ ctx->mutex_b_id = CreateMutexNoProtocol();
+ ctx->mutex_c_id = CreateMutexNoProtocol();
+ ctx->mutex_d_id = CreateMutexNoProtocol();
+
+ queue_b = GetMutexThreadQueue( ctx->mutex_b_id );
+ queue_c = GetMutexThreadQueue( ctx->mutex_c_id );
+
+ ctx->worker_a_id = CreateTask( "WRKA", PRIO_NORMAL );
+ ctx->worker_b_id = CreateTask( "WRKB", PRIO_NORMAL );
+ ctx->worker_c_id = CreateTask( "WRKC", PRIO_NORMAL );
+ ctx->worker_d_id = CreateTask( "WRKD", PRIO_NORMAL );
+ ctx->worker_e_id = CreateTask( "WRKE", PRIO_NORMAL );
+
+ SetScheduler( ctx->worker_a_id, SCHEDULER_B_ID, PRIO_NORMAL );
+ SetScheduler( ctx->worker_b_id, SCHEDULER_B_ID, PRIO_HIGH );
+ SetScheduler( ctx->worker_c_id, SCHEDULER_B_ID, PRIO_HIGH );
+ SetScheduler( ctx->worker_d_id, SCHEDULER_B_ID, PRIO_HIGH );
+ SetScheduler( ctx->worker_e_id, SCHEDULER_C_ID, PRIO_NORMAL );
+
+ /*
+ * Let worker D wait for mutex A. Let worker C wait for mutex D. Let worker
+ * B wait for mutex C.
+ */
+ StartTask( ctx->worker_a_id, DeadlockWorkerA, ctx );
+
+ /* D0 */
+ _SMP_barrier_Wait( &ctx->barrier, &state, 2 );
+
+ StartTask( ctx->worker_d_id, DeadlockWorkerD, ctx );
+ StartTask( ctx->worker_c_id, DeadlockWorkerC, ctx );
+ StartTask( ctx->worker_b_id, DeadlockWorkerB, ctx );
+ ReceiveAllEvents( RTEMS_EVENT_5 );
+ WaitForExecutionStop( ctx->worker_b_id );
+
+ /*
+ * Let worker A attempt to obtain mutex B. Let worker A wait on the lock of
+ * mutex C. Worker A will insert two thread queue links.
+ */
+ _ISR_lock_ISR_disable( &lock_context );
+ _Thread_queue_Queue_acquire_critical(
+ queue_c,
+ &_Thread_Executing->Potpourri_stats,
+ &lock_context
+ );
+ _ISR_lock_ISR_enable( &lock_context );
+
+ /* D1 */
+ _SMP_barrier_Wait( &ctx->barrier, &state, 2 );
+
+ TicketLockWaitForOthers( &queue_c->Lock, 1 );
+
+ /*
+ * Let worker E try to obtain mutex D. Worker E will add a thread queue link
+ * which is later used by worker A to detect the deadlock.
+ */
+ StartTask( ctx->worker_e_id, DeadlockWorkerE, ctx );
+ TicketLockWaitForOthers( &queue_b->Lock, 1 );
+
+ /*
+ * Let worker A continue the obtain sequence. It will detect a deadlock.
+ */
+ _ISR_lock_ISR_disable( &lock_context );
+ _Thread_queue_Queue_release( queue_c, &lock_context );
+
+ /*
+ * Clean up all used resources.
+ */
+ ReceiveAllEvents(
+ RTEMS_EVENT_0 | RTEMS_EVENT_1 | RTEMS_EVENT_2 | RTEMS_EVENT_3 |
+ RTEMS_EVENT_4
+ );
+ WaitForExecutionStop( ctx->worker_a_id );
+ WaitForExecutionStop( ctx->worker_b_id );
+ WaitForExecutionStop( ctx->worker_c_id );
+ WaitForExecutionStop( ctx->worker_d_id );
+ WaitForExecutionStop( ctx->worker_e_id );
+ DeleteTask( ctx->worker_a_id );
+ DeleteTask( ctx->worker_b_id );
+ DeleteTask( ctx->worker_c_id );
+ DeleteTask( ctx->worker_d_id );
+ DeleteTask( ctx->worker_e_id );
+ DeleteMutex( ctx->mutex_a_id );
+ DeleteMutex( ctx->mutex_b_id );
+ DeleteMutex( ctx->mutex_c_id );
+ DeleteMutex( ctx->mutex_d_id );
+}
+
+/**
+ * @fn void T_case_body_ScoreTqValSmp( void )
+ */
+T_TEST_CASE_FIXTURE( ScoreTqValSmp, &ScoreTqValSmp_Fixture )
+{
+ ScoreTqValSmp_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ ScoreTqValSmp_Action_0( ctx );
+ ScoreTqValSmp_Action_1( ctx );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-score-tq.c b/testsuites/validation/tc-score-tq.c
new file mode 100644
index 0000000000..5439d910f5
--- /dev/null
+++ b/testsuites/validation/tc-score-tq.c
@@ -0,0 +1,190 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqValTq
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tx-support.h"
+#include "tx-thread-queue.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTqValTq spec:/score/tq/val/tq
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests special thread queue behaviour.
+ *
+ * This test case performs the following actions:
+ *
+ * - Use two worker threads to provoke a deadlock detection involving a thread
+ * queue with no owner.
+ *
+ * - Let blocker A obtain mutex A.
+ *
+ * - Let blocker A block on a counting semaphore.
+ *
+ * - Let blocker B block on mutex A. The deadlock detection will stop since
+ * blocker A blocks on the counting semaphore which has no owner.
+ *
+ * - Clean up all used resources.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/score/tq/val/tq test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the thread queue test context.
+ */
+ TQContext tq_ctx;
+} ScoreTqValTq_Context;
+
+static ScoreTqValTq_Context
+ ScoreTqValTq_Instance;
+
+static void ScoreTqValTq_Setup( ScoreTqValTq_Context *ctx )
+{
+ rtems_status_code sc;
+
+ SetSelfPriority( PRIO_NORMAL );
+ TQInitialize( &ctx->tq_ctx );
+
+ /* Replace mutex D with a counting semaphore */
+ DeleteMutex( ctx->tq_ctx.mutex_id[ TQ_MUTEX_D ] );
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'C', 'S', 'E', 'M' ),
+ 0,
+ RTEMS_COUNTING_SEMAPHORE | RTEMS_PRIORITY,
+ 0,
+ &ctx->tq_ctx.mutex_id[ TQ_MUTEX_D ]
+ );
+ T_rsc_success( sc );
+}
+
+static void ScoreTqValTq_Setup_Wrap( void *arg )
+{
+ ScoreTqValTq_Context *ctx;
+
+ ctx = arg;
+ ScoreTqValTq_Setup( ctx );
+}
+
+static void ScoreTqValTq_Teardown( ScoreTqValTq_Context *ctx )
+{
+ TQDestroy( &ctx->tq_ctx );
+ RestoreRunnerPriority();
+}
+
+static void ScoreTqValTq_Teardown_Wrap( void *arg )
+{
+ ScoreTqValTq_Context *ctx;
+
+ ctx = arg;
+ ScoreTqValTq_Teardown( ctx );
+}
+
+static T_fixture ScoreTqValTq_Fixture = {
+ .setup = ScoreTqValTq_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreTqValTq_Teardown_Wrap,
+ .scope = NULL,
+ .initial_context = &ScoreTqValTq_Instance
+};
+
+/**
+ * @brief Use two worker threads to provoke a deadlock detection involving a
+ * thread queue with no owner.
+ */
+static void ScoreTqValTq_Action_0( ScoreTqValTq_Context *ctx )
+{
+ TQReset( &ctx->tq_ctx );
+
+ /*
+ * Let blocker A obtain mutex A.
+ */
+ TQSend( &ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_MUTEX_A_OBTAIN );
+
+ /*
+ * Let blocker A block on a counting semaphore.
+ */
+ TQSend( &ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_MUTEX_D_OBTAIN );
+
+ /*
+ * Let blocker B block on mutex A. The deadlock detection will stop since
+ * blocker A blocks on the counting semaphore which has no owner.
+ */
+ TQSend( &ctx->tq_ctx, TQ_BLOCKER_B, TQ_EVENT_MUTEX_A_OBTAIN );
+
+ /*
+ * Clean up all used resources.
+ */
+ TQMutexRelease( &ctx->tq_ctx, TQ_MUTEX_D );
+ TQSend( &ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_MUTEX_A_RELEASE );
+ TQSend( &ctx->tq_ctx, TQ_BLOCKER_B, TQ_EVENT_MUTEX_A_RELEASE );
+}
+
+/**
+ * @fn void T_case_body_ScoreTqValTq( void )
+ */
+T_TEST_CASE_FIXTURE( ScoreTqValTq, &ScoreTqValTq_Fixture )
+{
+ ScoreTqValTq_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ ScoreTqValTq_Action_0( ctx );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-sem-create.c b/testsuites/validation/tc-sem-create.c
new file mode 100644
index 0000000000..9975cb0778
--- /dev/null
+++ b/testsuites/validation/tc-sem-create.c
@@ -0,0 +1,1559 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSemReqCreate
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <rtems.h>
+#include <string.h>
+#include <rtems/rtems/semimpl.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSemReqCreate spec:/rtems/sem/req/create
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsSemReqCreate_Pre_Name_Valid,
+ RtemsSemReqCreate_Pre_Name_Invalid,
+ RtemsSemReqCreate_Pre_Name_NA
+} RtemsSemReqCreate_Pre_Name;
+
+typedef enum {
+ RtemsSemReqCreate_Pre_Id_Valid,
+ RtemsSemReqCreate_Pre_Id_Null,
+ RtemsSemReqCreate_Pre_Id_NA
+} RtemsSemReqCreate_Pre_Id;
+
+typedef enum {
+ RtemsSemReqCreate_Pre_Count_Zero,
+ RtemsSemReqCreate_Pre_Count_One,
+ RtemsSemReqCreate_Pre_Count_GtOne,
+ RtemsSemReqCreate_Pre_Count_NA
+} RtemsSemReqCreate_Pre_Count;
+
+typedef enum {
+ RtemsSemReqCreate_Pre_Binary_Yes,
+ RtemsSemReqCreate_Pre_Binary_No,
+ RtemsSemReqCreate_Pre_Binary_NA
+} RtemsSemReqCreate_Pre_Binary;
+
+typedef enum {
+ RtemsSemReqCreate_Pre_Simple_Yes,
+ RtemsSemReqCreate_Pre_Simple_No,
+ RtemsSemReqCreate_Pre_Simple_NA
+} RtemsSemReqCreate_Pre_Simple;
+
+typedef enum {
+ RtemsSemReqCreate_Pre_Inherit_Yes,
+ RtemsSemReqCreate_Pre_Inherit_No,
+ RtemsSemReqCreate_Pre_Inherit_NA
+} RtemsSemReqCreate_Pre_Inherit;
+
+typedef enum {
+ RtemsSemReqCreate_Pre_Ceiling_Yes,
+ RtemsSemReqCreate_Pre_Ceiling_No,
+ RtemsSemReqCreate_Pre_Ceiling_NA
+} RtemsSemReqCreate_Pre_Ceiling;
+
+typedef enum {
+ RtemsSemReqCreate_Pre_MrsP_Yes,
+ RtemsSemReqCreate_Pre_MrsP_No,
+ RtemsSemReqCreate_Pre_MrsP_NA
+} RtemsSemReqCreate_Pre_MrsP;
+
+typedef enum {
+ RtemsSemReqCreate_Pre_Disc_FIFO,
+ RtemsSemReqCreate_Pre_Disc_Prio,
+ RtemsSemReqCreate_Pre_Disc_NA
+} RtemsSemReqCreate_Pre_Disc;
+
+typedef enum {
+ RtemsSemReqCreate_Pre_Prio_LeCur,
+ RtemsSemReqCreate_Pre_Prio_GtCur,
+ RtemsSemReqCreate_Pre_Prio_Invalid,
+ RtemsSemReqCreate_Pre_Prio_NA
+} RtemsSemReqCreate_Pre_Prio;
+
+typedef enum {
+ RtemsSemReqCreate_Pre_Free_Yes,
+ RtemsSemReqCreate_Pre_Free_No,
+ RtemsSemReqCreate_Pre_Free_NA
+} RtemsSemReqCreate_Pre_Free;
+
+typedef enum {
+ RtemsSemReqCreate_Post_Status_Ok,
+ RtemsSemReqCreate_Post_Status_InvName,
+ RtemsSemReqCreate_Post_Status_InvAddr,
+ RtemsSemReqCreate_Post_Status_InvNum,
+ RtemsSemReqCreate_Post_Status_InvPrio,
+ RtemsSemReqCreate_Post_Status_NotDef,
+ RtemsSemReqCreate_Post_Status_TooMany,
+ RtemsSemReqCreate_Post_Status_NA
+} RtemsSemReqCreate_Post_Status;
+
+typedef enum {
+ RtemsSemReqCreate_Post_Name_Valid,
+ RtemsSemReqCreate_Post_Name_Invalid,
+ RtemsSemReqCreate_Post_Name_NA
+} RtemsSemReqCreate_Post_Name;
+
+typedef enum {
+ RtemsSemReqCreate_Post_IdVar_Set,
+ RtemsSemReqCreate_Post_IdVar_Nop,
+ RtemsSemReqCreate_Post_IdVar_NA
+} RtemsSemReqCreate_Post_IdVar;
+
+typedef enum {
+ RtemsSemReqCreate_Post_Variant_Cnt,
+ RtemsSemReqCreate_Post_Variant_Bin,
+ RtemsSemReqCreate_Post_Variant_PI,
+ RtemsSemReqCreate_Post_Variant_PC,
+ RtemsSemReqCreate_Post_Variant_SB,
+ RtemsSemReqCreate_Post_Variant_MrsP,
+ RtemsSemReqCreate_Post_Variant_NA
+} RtemsSemReqCreate_Post_Variant;
+
+typedef enum {
+ RtemsSemReqCreate_Post_Disc_FIFO,
+ RtemsSemReqCreate_Post_Disc_Prio,
+ RtemsSemReqCreate_Post_Disc_NA
+} RtemsSemReqCreate_Post_Disc;
+
+typedef enum {
+ RtemsSemReqCreate_Post_Count_Initial,
+ RtemsSemReqCreate_Post_Count_NA
+} RtemsSemReqCreate_Post_Count;
+
+typedef enum {
+ RtemsSemReqCreate_Post_Owner_Caller,
+ RtemsSemReqCreate_Post_Owner_No,
+ RtemsSemReqCreate_Post_Owner_NA
+} RtemsSemReqCreate_Post_Owner;
+
+typedef enum {
+ RtemsSemReqCreate_Post_Prio_Ceiling,
+ RtemsSemReqCreate_Post_Prio_Nop,
+ RtemsSemReqCreate_Post_Prio_NA
+} RtemsSemReqCreate_Post_Prio;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_Name_NA : 1;
+ uint32_t Pre_Id_NA : 1;
+ uint32_t Pre_Count_NA : 1;
+ uint32_t Pre_Binary_NA : 1;
+ uint32_t Pre_Simple_NA : 1;
+ uint32_t Pre_Inherit_NA : 1;
+ uint32_t Pre_Ceiling_NA : 1;
+ uint32_t Pre_MrsP_NA : 1;
+ uint32_t Pre_Disc_NA : 1;
+ uint32_t Pre_Prio_NA : 1;
+ uint32_t Pre_Free_NA : 1;
+ uint32_t Post_Status : 3;
+ uint32_t Post_Name : 2;
+ uint32_t Post_IdVar : 2;
+ uint32_t Post_Variant : 3;
+ uint32_t Post_Disc : 2;
+ uint32_t Post_Count : 1;
+ uint32_t Post_Owner : 2;
+ uint32_t Post_Prio : 2;
+} RtemsSemReqCreate_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/sem/req/create test case.
+ */
+typedef struct {
+ void *seized_objects;
+
+ rtems_status_code status;
+
+ Semaphore_Variant variant;
+
+ Semaphore_Discipline discipline;
+
+ uint32_t sem_count;
+
+ Thread_Control *executing;
+
+ Thread_Control *owner;
+
+ rtems_name name;
+
+ uint32_t count;
+
+ rtems_attribute attribute_set;
+
+ rtems_task_priority priority_ceiling;
+
+ rtems_id *id;
+
+ rtems_id id_value;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 11 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsSemReqCreate_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsSemReqCreate_Context;
+
+static RtemsSemReqCreate_Context
+ RtemsSemReqCreate_Instance;
+
+static const char * const RtemsSemReqCreate_PreDesc_Name[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsSemReqCreate_PreDesc_Id[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsSemReqCreate_PreDesc_Count[] = {
+ "Zero",
+ "One",
+ "GtOne",
+ "NA"
+};
+
+static const char * const RtemsSemReqCreate_PreDesc_Binary[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsSemReqCreate_PreDesc_Simple[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsSemReqCreate_PreDesc_Inherit[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsSemReqCreate_PreDesc_Ceiling[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsSemReqCreate_PreDesc_MrsP[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsSemReqCreate_PreDesc_Disc[] = {
+ "FIFO",
+ "Prio",
+ "NA"
+};
+
+static const char * const RtemsSemReqCreate_PreDesc_Prio[] = {
+ "LeCur",
+ "GtCur",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsSemReqCreate_PreDesc_Free[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsSemReqCreate_PreDesc[] = {
+ RtemsSemReqCreate_PreDesc_Name,
+ RtemsSemReqCreate_PreDesc_Id,
+ RtemsSemReqCreate_PreDesc_Count,
+ RtemsSemReqCreate_PreDesc_Binary,
+ RtemsSemReqCreate_PreDesc_Simple,
+ RtemsSemReqCreate_PreDesc_Inherit,
+ RtemsSemReqCreate_PreDesc_Ceiling,
+ RtemsSemReqCreate_PreDesc_MrsP,
+ RtemsSemReqCreate_PreDesc_Disc,
+ RtemsSemReqCreate_PreDesc_Prio,
+ RtemsSemReqCreate_PreDesc_Free,
+ NULL
+};
+
+#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+typedef RtemsSemReqCreate_Context Context;
+
+static rtems_status_code Create( void *arg, uint32_t *id )
+{
+ (void) arg;
+
+ return rtems_semaphore_create(
+ rtems_build_name( 'S', 'I', 'Z', 'E' ),
+ 1,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ 0,
+ id
+ );
+}
+
+static void GetSemAttributes( Context *ctx )
+{
+ if ( ctx->id_value != INVALID_ID ) {
+ Semaphore_Control *semaphore;
+ Thread_queue_Context queue_context;
+ uintptr_t flags;
+
+ semaphore = _Semaphore_Get( ctx->id_value, &queue_context );
+ T_assert_not_null( semaphore );
+ ctx->sem_count = semaphore->Core_control.Semaphore.count;
+ ctx->owner = semaphore->Core_control.Wait_queue.Queue.owner;
+ flags = _Semaphore_Get_flags( semaphore );
+ _ISR_lock_ISR_enable( &queue_context.Lock_context.Lock_context );
+ ctx->variant = _Semaphore_Get_variant( flags );
+ ctx->discipline = _Semaphore_Get_discipline( flags );
+ } else {
+ ctx->sem_count = 123;
+ ctx->owner = (void *)(uintptr_t) 1;
+ ctx->variant = INT_MAX;
+ ctx->discipline = INT_MAX;
+ }
+}
+
+static void RtemsSemReqCreate_Pre_Name_Prepare(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Pre_Name state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqCreate_Pre_Name_Valid: {
+ /*
+ * While the ``name`` parameter is valid.
+ */
+ ctx->name = NAME;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Name_Invalid: {
+ /*
+ * While the ``name`` parameter is invalid.
+ */
+ ctx->name = 0;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Name_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Pre_Id_Prepare(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqCreate_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter references an object of type rtems_id.
+ */
+ ctx->id = &ctx->id_value;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Id_Null: {
+ /*
+ * While the ``id`` parameter is NULL.
+ */
+ ctx->id = NULL;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Pre_Count_Prepare(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Pre_Count state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqCreate_Pre_Count_Zero: {
+ /*
+ * While the ``count`` parameter is zero.
+ */
+ ctx->count = 0;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Count_One: {
+ /*
+ * While the ``count`` parameter is one.
+ */
+ ctx->count = 1;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Count_GtOne: {
+ /*
+ * While the ``count`` parameter is greater than one.
+ */
+ ctx->count = UINT32_MAX;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Count_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Pre_Binary_Prepare(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Pre_Binary state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqCreate_Pre_Binary_Yes: {
+ /*
+ * While the ``attribute_set`` parameter specifies the binary semaphore
+ * class.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Binary_No: {
+ /*
+ * While the ``attribute_set`` parameter does not specify the binary
+ * semaphore class.
+ */
+ /* Use default */
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Binary_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Pre_Simple_Prepare(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Pre_Simple state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqCreate_Pre_Simple_Yes: {
+ /*
+ * While the ``attribute_set`` parameter specifies the simple binary
+ * semaphore class.
+ */
+ ctx->attribute_set |= RTEMS_SIMPLE_BINARY_SEMAPHORE;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Simple_No: {
+ /*
+ * While the ``attribute_set`` parameter does not specify the simple
+ * binary semaphore class.
+ */
+ /* Use default */
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Simple_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Pre_Inherit_Prepare(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Pre_Inherit state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqCreate_Pre_Inherit_Yes: {
+ /*
+ * While the ``attribute_set`` parameter specifies the priority
+ * inheritance locking protocol.
+ */
+ ctx->attribute_set |= RTEMS_INHERIT_PRIORITY;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Inherit_No: {
+ /*
+ * While the ``attribute_set`` parameter does not specify the priority
+ * inheritance locking protocol.
+ */
+ ctx->attribute_set |= RTEMS_NO_INHERIT_PRIORITY;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Inherit_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Pre_Ceiling_Prepare(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Pre_Ceiling state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqCreate_Pre_Ceiling_Yes: {
+ /*
+ * While the ``attribute_set`` parameter specifies the priority ceiling
+ * locking protocol.
+ */
+ ctx->attribute_set |= RTEMS_PRIORITY_CEILING;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Ceiling_No: {
+ /*
+ * While the ``attribute_set`` parameter does not specify the priority
+ * ceiling locking protocol.
+ */
+ ctx->attribute_set |= RTEMS_NO_PRIORITY_CEILING;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Ceiling_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Pre_MrsP_Prepare(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Pre_MrsP state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqCreate_Pre_MrsP_Yes: {
+ /*
+ * While the ``attribute_set`` parameter specifies the MrsP locking
+ * protocol.
+ */
+ ctx->attribute_set |= RTEMS_MULTIPROCESSOR_RESOURCE_SHARING;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_MrsP_No: {
+ /*
+ * While the ``attribute_set`` parameter does not specify the MrsP
+ * locking protocol.
+ */
+ ctx->attribute_set |= RTEMS_NO_MULTIPROCESSOR_RESOURCE_SHARING;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_MrsP_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Pre_Disc_Prepare(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Pre_Disc state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqCreate_Pre_Disc_FIFO: {
+ /*
+ * While the ``attribute_set`` parameter specifies the FIFO task wait
+ * queue discipline or the default task wait queue discipline.
+ */
+ RTEMS_STATIC_ASSERT( RTEMS_DEFAULT_ATTRIBUTES == RTEMS_FIFO, RTEMS_FIFO );
+ ctx->attribute_set |= RTEMS_FIFO;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Disc_Prio: {
+ /*
+ * While the ``attribute_set`` parameter specifies the priority task wait
+ * queue discipline.
+ */
+ ctx->attribute_set |= RTEMS_PRIORITY;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Disc_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Pre_Prio_Prepare(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Pre_Prio state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqCreate_Pre_Prio_LeCur: {
+ /*
+ * While the ``priority_ceiling`` parameter is a valid task priority less
+ * than or equal to the current priority of the calling task with respect
+ * to the scheduler of the calling task at some point during the
+ * directive call.
+ */
+ ctx->priority_ceiling = 0;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Prio_GtCur: {
+ /*
+ * While the ``priority_ceiling`` parameter is a valid task priority
+ * greater than the current priority of the calling task with respect to
+ * the scheduler of the calling task at some point during the directive
+ * call.
+ */
+ ctx->priority_ceiling = 2;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Prio_Invalid: {
+ /*
+ * The ``priority_ceiling`` parameter shall not be a valid task priority
+ * with respect to the scheduler of the calling task at some point during
+ * the directive call.
+ */
+ ctx->priority_ceiling = UINT32_MAX;
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Prio_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Pre_Free_Prepare(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Pre_Free state
+)
+{
+ size_t i;
+
+ switch ( state ) {
+ case RtemsSemReqCreate_Pre_Free_Yes: {
+ /*
+ * While the system has at least one inactive semaphore object available.
+ */
+ /* Nothing to do */
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Free_No: {
+ /*
+ * While the system has no inactive semaphore object available.
+ */
+ i = 0;
+ ctx->seized_objects = T_seize_objects( Create, &i );
+ break;
+ }
+
+ case RtemsSemReqCreate_Pre_Free_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Post_Status_Check(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqCreate_Post_Status_Ok: {
+ /*
+ * The return status of rtems_semaphore_create() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Status_InvName: {
+ /*
+ * The return status of rtems_semaphore_create() shall be
+ * RTEMS_INVALID_NAME.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_semaphore_create() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Status_InvNum: {
+ /*
+ * The return status of rtems_semaphore_create() shall be
+ * RTEMS_INVALID_NUMBER.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NUMBER );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Status_InvPrio: {
+ /*
+ * The return status of rtems_semaphore_create() shall be
+ * RTEMS_INVALID_PRIORITY.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_PRIORITY );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Status_NotDef: {
+ /*
+ * The return status of rtems_semaphore_create() shall be
+ * RTEMS_NOT_DEFINED.
+ */
+ T_rsc( ctx->status, RTEMS_NOT_DEFINED );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Status_TooMany: {
+ /*
+ * The return status of rtems_semaphore_create() shall be RTEMS_TOO_MANY.
+ */
+ T_rsc( ctx->status, RTEMS_TOO_MANY );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Post_Name_Check(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Post_Name state
+)
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ switch ( state ) {
+ case RtemsSemReqCreate_Post_Name_Valid: {
+ /*
+ * The unique object name shall identify the semaphore created by the
+ * rtems_semaphore_create() call.
+ */
+ id = 0;
+ sc = rtems_semaphore_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc_success( sc );
+ T_eq_u32( id, ctx->id_value );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Name_Invalid: {
+ /*
+ * The unique object name shall not identify a semaphore.
+ */
+ sc = rtems_semaphore_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc( sc, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Name_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Post_IdVar_Check(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Post_IdVar state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqCreate_Post_IdVar_Set: {
+ /*
+ * The value of the object referenced by the ``id`` parameter shall be
+ * set to the object identifier of the created semaphore after the return
+ * of the rtems_semaphore_create() call.
+ */
+ T_eq_ptr( ctx->id, &ctx->id_value );
+ T_ne_u32( ctx->id_value, INVALID_ID );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_IdVar_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past calls to
+ * rtems_semaphore_create() shall not be accessed by the
+ * rtems_semaphore_create() call.
+ */
+ T_eq_u32( ctx->id_value, INVALID_ID );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_IdVar_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Post_Variant_Check(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Post_Variant state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqCreate_Post_Variant_Cnt: {
+ /*
+ * The semaphore created by the rtems_semaphore_create() call shall be a
+ * counting semaphore.
+ */
+ T_eq_int( ctx->variant, SEMAPHORE_VARIANT_COUNTING );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Variant_Bin: {
+ /*
+ * The semaphore created by the rtems_semaphore_create() call shall be a
+ * binary semaphore not using a locking protocol.
+ */
+ T_eq_int( ctx->variant, SEMAPHORE_VARIANT_MUTEX_NO_PROTOCOL );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Variant_PI: {
+ /*
+ * The semaphore created by the rtems_semaphore_create() call shall be a
+ * binary semaphore using the priority inheritance locking protocol.
+ */
+ T_eq_int( ctx->variant, SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Variant_PC: {
+ /*
+ * The semaphore created by the rtems_semaphore_create() call shall be a
+ * binary semaphore using the priority ceiling locking protocol.
+ */
+ T_eq_int( ctx->variant, SEMAPHORE_VARIANT_MUTEX_PRIORITY_CEILING );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Variant_SB: {
+ /*
+ * The semaphore created by the rtems_semaphore_create() call shall be a
+ * simple binary semaphore.
+ */
+ T_eq_int( ctx->variant, SEMAPHORE_VARIANT_SIMPLE_BINARY );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Variant_MrsP: {
+ /*
+ * The semaphore created by the rtems_semaphore_create() call shall be a
+ * binary semaphore using the MrsP locking protocol.
+ */
+ #if defined(RTEMS_SMP)
+ T_eq_int( ctx->variant, SEMAPHORE_VARIANT_MRSP );
+ #else
+ T_true( false );
+ #endif
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Variant_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Post_Disc_Check(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Post_Disc state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqCreate_Post_Disc_FIFO: {
+ /*
+ * The semaphore created by the rtems_semaphore_create() call shall use
+ * the FIFO task wait queue discipline.
+ */
+ T_eq_int( ctx->discipline, SEMAPHORE_DISCIPLINE_FIFO );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Disc_Prio: {
+ /*
+ * The semaphore created by the rtems_semaphore_create() call shall use
+ * the priority task wait queue discipline.
+ */
+ T_eq_int( ctx->discipline, SEMAPHORE_DISCIPLINE_PRIORITY );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Disc_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Post_Count_Check(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Post_Count state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqCreate_Post_Count_Initial: {
+ /*
+ * The semaphore created by the rtems_semaphore_create() call shall have
+ * an initial count equal to the value of the ``count`` parameter.
+ */
+ T_eq_u32( ctx->sem_count, ctx->count );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Count_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Post_Owner_Check(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Post_Owner state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqCreate_Post_Owner_Caller: {
+ /*
+ * The semaphore created by the rtems_semaphore_create() call shall be
+ * initially owned by the calling task.
+ */
+ T_eq_ptr( ctx->owner, ctx->executing );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Owner_No: {
+ /*
+ * The semaphore created by the rtems_semaphore_create() call shall not
+ * initially have an owner.
+ */
+ T_null( ctx->owner );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Owner_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Post_Prio_Check(
+ RtemsSemReqCreate_Context *ctx,
+ RtemsSemReqCreate_Post_Prio state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqCreate_Post_Prio_Ceiling: {
+ /*
+ * The current priority of the task which called rtems_semaphore_create()
+ * shall be equal to the value of the ``priority_ceiling`` parameter.
+ */
+ T_eq_u32( GetSelfPriority(), ctx->priority_ceiling );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Prio_Nop: {
+ /*
+ * The current priority of the task which called rtems_semaphore_create()
+ * shall not be modified by the rtems_semaphore_create() call.
+ */
+ T_eq_u32( GetSelfPriority(), 1 );
+ break;
+ }
+
+ case RtemsSemReqCreate_Post_Prio_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqCreate_Setup( RtemsSemReqCreate_Context *ctx )
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->executing = _Thread_Get_executing();
+}
+
+static void RtemsSemReqCreate_Setup_Wrap( void *arg )
+{
+ RtemsSemReqCreate_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSemReqCreate_Setup( ctx );
+}
+
+static void RtemsSemReqCreate_Prepare( RtemsSemReqCreate_Context *ctx )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ ctx->id_value = INVALID_ID;
+ ctx->attribute_set = RTEMS_DEFAULT_ATTRIBUTES;
+
+ id = INVALID_ID;
+ sc = rtems_semaphore_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc( sc, RTEMS_INVALID_NAME );
+ T_eq_u32( id, INVALID_ID );
+}
+
+static void RtemsSemReqCreate_Action( RtemsSemReqCreate_Context *ctx )
+{
+ ctx->status = rtems_semaphore_create(
+ ctx->name,
+ ctx->count,
+ ctx->attribute_set,
+ ctx->priority_ceiling,
+ ctx->id
+ );
+
+ GetSemAttributes( ctx );
+}
+
+static void RtemsSemReqCreate_Cleanup( RtemsSemReqCreate_Context *ctx )
+{
+ rtems_status_code sc;
+
+ if ( ctx->id_value != INVALID_ID ) {
+ if ( ctx->count == 0 ) {
+ sc = rtems_semaphore_release( ctx->id_value );
+ T_rsc_success( sc );
+ }
+
+ sc = rtems_semaphore_delete( ctx->id_value );
+ T_rsc_success( sc );
+ }
+
+ T_surrender_objects( &ctx->seized_objects, rtems_semaphore_delete );
+}
+
+static const RtemsSemReqCreate_Entry
+RtemsSemReqCreate_Entries[] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_InvName,
+ RtemsSemReqCreate_Post_Name_Invalid, RtemsSemReqCreate_Post_IdVar_Nop,
+ RtemsSemReqCreate_Post_Variant_NA, RtemsSemReqCreate_Post_Disc_NA,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_NA,
+ RtemsSemReqCreate_Post_Prio_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_InvAddr,
+ RtemsSemReqCreate_Post_Name_Invalid, RtemsSemReqCreate_Post_IdVar_Nop,
+ RtemsSemReqCreate_Post_Variant_NA, RtemsSemReqCreate_Post_Disc_NA,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_NA,
+ RtemsSemReqCreate_Post_Prio_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_NotDef,
+ RtemsSemReqCreate_Post_Name_Invalid, RtemsSemReqCreate_Post_IdVar_Nop,
+ RtemsSemReqCreate_Post_Variant_NA, RtemsSemReqCreate_Post_Disc_NA,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_NA,
+ RtemsSemReqCreate_Post_Prio_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_TooMany,
+ RtemsSemReqCreate_Post_Name_Invalid, RtemsSemReqCreate_Post_IdVar_Nop,
+ RtemsSemReqCreate_Post_Variant_NA, RtemsSemReqCreate_Post_Disc_NA,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_NA,
+ RtemsSemReqCreate_Post_Prio_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_InvNum,
+ RtemsSemReqCreate_Post_Name_Invalid, RtemsSemReqCreate_Post_IdVar_Nop,
+ RtemsSemReqCreate_Post_Variant_NA, RtemsSemReqCreate_Post_Disc_NA,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_NA,
+ RtemsSemReqCreate_Post_Prio_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_Ok,
+ RtemsSemReqCreate_Post_Name_Valid, RtemsSemReqCreate_Post_IdVar_Set,
+ RtemsSemReqCreate_Post_Variant_Cnt, RtemsSemReqCreate_Post_Disc_FIFO,
+ RtemsSemReqCreate_Post_Count_Initial, RtemsSemReqCreate_Post_Owner_No,
+ RtemsSemReqCreate_Post_Prio_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_Ok,
+ RtemsSemReqCreate_Post_Name_Valid, RtemsSemReqCreate_Post_IdVar_Set,
+ RtemsSemReqCreate_Post_Variant_Cnt, RtemsSemReqCreate_Post_Disc_Prio,
+ RtemsSemReqCreate_Post_Count_Initial, RtemsSemReqCreate_Post_Owner_No,
+ RtemsSemReqCreate_Post_Prio_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_InvPrio,
+ RtemsSemReqCreate_Post_Name_Invalid, RtemsSemReqCreate_Post_IdVar_Nop,
+ RtemsSemReqCreate_Post_Variant_NA, RtemsSemReqCreate_Post_Disc_NA,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_NA,
+ RtemsSemReqCreate_Post_Prio_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_Ok,
+ RtemsSemReqCreate_Post_Name_Valid, RtemsSemReqCreate_Post_IdVar_Set,
+ RtemsSemReqCreate_Post_Variant_SB, RtemsSemReqCreate_Post_Disc_FIFO,
+ RtemsSemReqCreate_Post_Count_Initial, RtemsSemReqCreate_Post_Owner_No,
+ RtemsSemReqCreate_Post_Prio_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_Ok,
+ RtemsSemReqCreate_Post_Name_Valid, RtemsSemReqCreate_Post_IdVar_Set,
+ RtemsSemReqCreate_Post_Variant_SB, RtemsSemReqCreate_Post_Disc_Prio,
+ RtemsSemReqCreate_Post_Count_Initial, RtemsSemReqCreate_Post_Owner_No,
+ RtemsSemReqCreate_Post_Prio_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_Ok,
+ RtemsSemReqCreate_Post_Name_Valid, RtemsSemReqCreate_Post_IdVar_Set,
+ RtemsSemReqCreate_Post_Variant_PI, RtemsSemReqCreate_Post_Disc_Prio,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_Caller,
+ RtemsSemReqCreate_Post_Prio_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_Ok,
+ RtemsSemReqCreate_Post_Name_Valid, RtemsSemReqCreate_Post_IdVar_Set,
+ RtemsSemReqCreate_Post_Variant_Bin, RtemsSemReqCreate_Post_Disc_FIFO,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_Caller,
+ RtemsSemReqCreate_Post_Prio_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_Ok,
+ RtemsSemReqCreate_Post_Name_Valid, RtemsSemReqCreate_Post_IdVar_Set,
+ RtemsSemReqCreate_Post_Variant_Bin, RtemsSemReqCreate_Post_Disc_Prio,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_Caller,
+ RtemsSemReqCreate_Post_Prio_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_Ok,
+ RtemsSemReqCreate_Post_Name_Valid, RtemsSemReqCreate_Post_IdVar_Set,
+ RtemsSemReqCreate_Post_Variant_PI, RtemsSemReqCreate_Post_Disc_Prio,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_No,
+ RtemsSemReqCreate_Post_Prio_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_Ok,
+ RtemsSemReqCreate_Post_Name_Valid, RtemsSemReqCreate_Post_IdVar_Set,
+ RtemsSemReqCreate_Post_Variant_Bin, RtemsSemReqCreate_Post_Disc_FIFO,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_No,
+ RtemsSemReqCreate_Post_Prio_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_Ok,
+ RtemsSemReqCreate_Post_Name_Valid, RtemsSemReqCreate_Post_IdVar_Set,
+ RtemsSemReqCreate_Post_Variant_Bin, RtemsSemReqCreate_Post_Disc_Prio,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_No,
+ RtemsSemReqCreate_Post_Prio_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_Ok,
+ RtemsSemReqCreate_Post_Name_Valid, RtemsSemReqCreate_Post_IdVar_Set,
+ RtemsSemReqCreate_Post_Variant_PC, RtemsSemReqCreate_Post_Disc_Prio,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_No,
+ RtemsSemReqCreate_Post_Prio_Nop },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_Ok,
+ RtemsSemReqCreate_Post_Name_Valid, RtemsSemReqCreate_Post_IdVar_Set,
+ RtemsSemReqCreate_Post_Variant_MrsP, RtemsSemReqCreate_Post_Disc_Prio,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_No,
+ RtemsSemReqCreate_Post_Prio_Nop },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_Ok,
+ RtemsSemReqCreate_Post_Name_Valid, RtemsSemReqCreate_Post_IdVar_Set,
+ RtemsSemReqCreate_Post_Variant_PC, RtemsSemReqCreate_Post_Disc_Prio,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_No,
+ RtemsSemReqCreate_Post_Prio_Nop },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_Ok,
+ RtemsSemReqCreate_Post_Name_Valid, RtemsSemReqCreate_Post_IdVar_Set,
+ RtemsSemReqCreate_Post_Variant_PC, RtemsSemReqCreate_Post_Disc_Prio,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_Caller,
+ RtemsSemReqCreate_Post_Prio_Ceiling },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_Ok,
+ RtemsSemReqCreate_Post_Name_Valid, RtemsSemReqCreate_Post_IdVar_Set,
+ RtemsSemReqCreate_Post_Variant_MrsP, RtemsSemReqCreate_Post_Disc_Prio,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_Caller,
+ RtemsSemReqCreate_Post_Prio_Ceiling }
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsSemReqCreate_Post_Status_Ok,
+ RtemsSemReqCreate_Post_Name_Valid, RtemsSemReqCreate_Post_IdVar_Set,
+ RtemsSemReqCreate_Post_Variant_PC, RtemsSemReqCreate_Post_Disc_Prio,
+ RtemsSemReqCreate_Post_Count_NA, RtemsSemReqCreate_Post_Owner_Caller,
+ RtemsSemReqCreate_Post_Prio_Ceiling }
+#endif
+};
+
+static const uint8_t
+RtemsSemReqCreate_Map[] = {
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 10, 3, 10, 3, 10, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 18, 3, 7, 3, 7, 3, 2, 2, 2, 2, 2, 2, 19, 3, 7, 3, 7, 3,
+ 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 8, 3, 8, 3, 8, 3,
+ 9, 3, 9, 3, 9, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 13, 3, 13, 3, 13, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 16, 3, 16, 3, 7, 3, 2, 2, 2, 2, 2, 2, 17, 3, 17, 3, 7, 3, 14,
+ 3, 14, 3, 14, 3, 15, 3, 15, 3, 15, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 8, 3, 8, 3, 8, 3, 9,
+ 3, 9, 3, 9, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 6, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static size_t RtemsSemReqCreate_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsSemReqCreate_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsSemReqCreate_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsSemReqCreate_Fixture = {
+ .setup = RtemsSemReqCreate_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsSemReqCreate_Scope,
+ .initial_context = &RtemsSemReqCreate_Instance
+};
+
+static inline RtemsSemReqCreate_Entry RtemsSemReqCreate_PopEntry(
+ RtemsSemReqCreate_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsSemReqCreate_Entries[
+ RtemsSemReqCreate_Map[ index ]
+ ];
+}
+
+static void RtemsSemReqCreate_TestVariant( RtemsSemReqCreate_Context *ctx )
+{
+ RtemsSemReqCreate_Pre_Name_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsSemReqCreate_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsSemReqCreate_Pre_Count_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsSemReqCreate_Pre_Binary_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsSemReqCreate_Pre_Simple_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsSemReqCreate_Pre_Inherit_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsSemReqCreate_Pre_Ceiling_Prepare( ctx, ctx->Map.pcs[ 6 ] );
+ RtemsSemReqCreate_Pre_MrsP_Prepare( ctx, ctx->Map.pcs[ 7 ] );
+ RtemsSemReqCreate_Pre_Disc_Prepare( ctx, ctx->Map.pcs[ 8 ] );
+ RtemsSemReqCreate_Pre_Prio_Prepare( ctx, ctx->Map.pcs[ 9 ] );
+ RtemsSemReqCreate_Pre_Free_Prepare( ctx, ctx->Map.pcs[ 10 ] );
+ RtemsSemReqCreate_Action( ctx );
+ RtemsSemReqCreate_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsSemReqCreate_Post_Name_Check( ctx, ctx->Map.entry.Post_Name );
+ RtemsSemReqCreate_Post_IdVar_Check( ctx, ctx->Map.entry.Post_IdVar );
+ RtemsSemReqCreate_Post_Variant_Check( ctx, ctx->Map.entry.Post_Variant );
+ RtemsSemReqCreate_Post_Disc_Check( ctx, ctx->Map.entry.Post_Disc );
+ RtemsSemReqCreate_Post_Count_Check( ctx, ctx->Map.entry.Post_Count );
+ RtemsSemReqCreate_Post_Owner_Check( ctx, ctx->Map.entry.Post_Owner );
+ RtemsSemReqCreate_Post_Prio_Check( ctx, ctx->Map.entry.Post_Prio );
+}
+
+/**
+ * @fn void T_case_body_RtemsSemReqCreate( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsSemReqCreate, &RtemsSemReqCreate_Fixture )
+{
+ RtemsSemReqCreate_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsSemReqCreate_Pre_Name_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsSemReqCreate_Pre_Name_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsSemReqCreate_Pre_Id_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsSemReqCreate_Pre_Id_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsSemReqCreate_Pre_Count_Zero;
+ ctx->Map.pcs[ 2 ] < RtemsSemReqCreate_Pre_Count_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsSemReqCreate_Pre_Binary_Yes;
+ ctx->Map.pcs[ 3 ] < RtemsSemReqCreate_Pre_Binary_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = RtemsSemReqCreate_Pre_Simple_Yes;
+ ctx->Map.pcs[ 4 ] < RtemsSemReqCreate_Pre_Simple_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 5 ] = RtemsSemReqCreate_Pre_Inherit_Yes;
+ ctx->Map.pcs[ 5 ] < RtemsSemReqCreate_Pre_Inherit_NA;
+ ++ctx->Map.pcs[ 5 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 6 ] = RtemsSemReqCreate_Pre_Ceiling_Yes;
+ ctx->Map.pcs[ 6 ] < RtemsSemReqCreate_Pre_Ceiling_NA;
+ ++ctx->Map.pcs[ 6 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 7 ] = RtemsSemReqCreate_Pre_MrsP_Yes;
+ ctx->Map.pcs[ 7 ] < RtemsSemReqCreate_Pre_MrsP_NA;
+ ++ctx->Map.pcs[ 7 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 8 ] = RtemsSemReqCreate_Pre_Disc_FIFO;
+ ctx->Map.pcs[ 8 ] < RtemsSemReqCreate_Pre_Disc_NA;
+ ++ctx->Map.pcs[ 8 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 9 ] = RtemsSemReqCreate_Pre_Prio_LeCur;
+ ctx->Map.pcs[ 9 ] < RtemsSemReqCreate_Pre_Prio_NA;
+ ++ctx->Map.pcs[ 9 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 10 ] = RtemsSemReqCreate_Pre_Free_Yes;
+ ctx->Map.pcs[ 10 ] < RtemsSemReqCreate_Pre_Free_NA;
+ ++ctx->Map.pcs[ 10 ]
+ ) {
+ ctx->Map.entry = RtemsSemReqCreate_PopEntry( ctx );
+ RtemsSemReqCreate_Prepare( ctx );
+ RtemsSemReqCreate_TestVariant( ctx );
+ RtemsSemReqCreate_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-sem-delete.c b/testsuites/validation/tc-sem-delete.c
new file mode 100644
index 0000000000..188b532870
--- /dev/null
+++ b/testsuites/validation/tc-sem-delete.c
@@ -0,0 +1,759 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSemReqDelete
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSemReqDelete spec:/rtems/sem/req/delete
+ *
+ * @ingroup TestsuitesValidationOneCpu0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsSemReqDelete_Pre_Id_NoObj,
+ RtemsSemReqDelete_Pre_Id_Counting,
+ RtemsSemReqDelete_Pre_Id_Simple,
+ RtemsSemReqDelete_Pre_Id_Binary,
+ RtemsSemReqDelete_Pre_Id_PrioCeiling,
+ RtemsSemReqDelete_Pre_Id_PrioInherit,
+ RtemsSemReqDelete_Pre_Id_MrsP,
+ RtemsSemReqDelete_Pre_Id_NA
+} RtemsSemReqDelete_Pre_Id;
+
+typedef enum {
+ RtemsSemReqDelete_Pre_Discipline_FIFO,
+ RtemsSemReqDelete_Pre_Discipline_Priority,
+ RtemsSemReqDelete_Pre_Discipline_NA
+} RtemsSemReqDelete_Pre_Discipline;
+
+typedef enum {
+ RtemsSemReqDelete_Pre_State_GtZeroOrNoOwner,
+ RtemsSemReqDelete_Pre_State_Zero,
+ RtemsSemReqDelete_Pre_State_Blocked,
+ RtemsSemReqDelete_Pre_State_NA
+} RtemsSemReqDelete_Pre_State;
+
+typedef enum {
+ RtemsSemReqDelete_Post_Status_Ok,
+ RtemsSemReqDelete_Post_Status_InvId,
+ RtemsSemReqDelete_Post_Status_InUse,
+ RtemsSemReqDelete_Post_Status_NA
+} RtemsSemReqDelete_Post_Status;
+
+typedef enum {
+ RtemsSemReqDelete_Post_Name_Valid,
+ RtemsSemReqDelete_Post_Name_Invalid,
+ RtemsSemReqDelete_Post_Name_NA
+} RtemsSemReqDelete_Post_Name;
+
+typedef enum {
+ RtemsSemReqDelete_Post_Flush_FIFO,
+ RtemsSemReqDelete_Post_Flush_Priority,
+ RtemsSemReqDelete_Post_Flush_No,
+ RtemsSemReqDelete_Post_Flush_NA
+} RtemsSemReqDelete_Post_Flush;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_Discipline_NA : 1;
+ uint16_t Pre_State_NA : 1;
+ uint16_t Post_Status : 2;
+ uint16_t Post_Name : 2;
+ uint16_t Post_Flush : 2;
+} RtemsSemReqDelete_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/sem/req/delete test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the worker task identifiers.
+ */
+ rtems_id worker_id[ 2 ];
+
+ /**
+ * @brief This member contains the worker activity counter.
+ */
+ uint32_t counter;
+
+ /**
+ * @brief This member contains the worker activity counter of a specific
+ * worker.
+ */
+ uint32_t worker_counter[ 2 ];
+
+ /**
+ * @brief This member specifies the expected rtems_semaphore_obtain() status.
+ */
+ rtems_status_code obtain_status;
+
+ /**
+ * @brief This member specifies if the initial count of the semaphore.
+ */
+ uint32_t count;
+
+ /**
+ * @brief This member specifies if the attribute set of the semaphore.
+ */
+ rtems_attribute attribute_set;
+
+ /**
+ * @brief This member contains the semaphore identifier.
+ */
+ rtems_id semaphore_id;
+
+ /**
+ * @brief If this member is true, then the ``name`` parameter shall be valid,
+ * otherwise it should be NULL.
+ */
+ bool valid_id;
+
+ /**
+ * @brief If this member is true, then tasks shall be blocked on the
+ * semaphore, otherwise no tasks shall be blocked on the semaphore.
+ */
+ bool blocked;
+
+ /**
+ * @brief This member specifies the ``name`` parameter for the
+ * rtems_semaphore_delete() call.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member specifies the expected rtems_semaphore_delete() status.
+ */
+ rtems_status_code delete_status;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsSemReqDelete_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsSemReqDelete_Context;
+
+static RtemsSemReqDelete_Context
+ RtemsSemReqDelete_Instance;
+
+static const char * const RtemsSemReqDelete_PreDesc_Id[] = {
+ "NoObj",
+ "Counting",
+ "Simple",
+ "Binary",
+ "PrioCeiling",
+ "PrioInherit",
+ "MrsP",
+ "NA"
+};
+
+static const char * const RtemsSemReqDelete_PreDesc_Discipline[] = {
+ "FIFO",
+ "Priority",
+ "NA"
+};
+
+static const char * const RtemsSemReqDelete_PreDesc_State[] = {
+ "GtZeroOrNoOwner",
+ "Zero",
+ "Blocked",
+ "NA"
+};
+
+static const char * const * const RtemsSemReqDelete_PreDesc[] = {
+ RtemsSemReqDelete_PreDesc_Id,
+ RtemsSemReqDelete_PreDesc_Discipline,
+ RtemsSemReqDelete_PreDesc_State,
+ NULL
+};
+
+#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+#define EVENT_OBTAIN RTEMS_EVENT_0
+
+typedef RtemsSemReqDelete_Context Context;
+
+static void WakeUp( Context *ctx, size_t index )
+{
+ SendEvents( ctx->worker_id[ index ], RTEMS_EVENT_0 );
+}
+
+static void Worker( rtems_task_argument arg, size_t index )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ /*
+ * In order to test the flush in FIFO order, we have to use the no-preempt
+ * mode.
+ */
+ SetMode( RTEMS_NO_PREEMPT, RTEMS_PREEMPT_MASK );
+
+ while ( true ) {
+ rtems_status_code sc;
+ rtems_event_set events;
+ uint32_t counter;
+
+ events = ReceiveAnyEvents();
+ T_eq_u32( events, RTEMS_EVENT_0 );
+
+ sc = rtems_semaphore_obtain(
+ ctx->semaphore_id,
+ RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+ T_rsc( sc, ctx->obtain_status );
+
+ counter = ctx->counter;
+ ++counter;
+ ctx->counter = counter;
+ ctx->worker_counter[ index ] = counter;
+
+ if ( sc == RTEMS_SUCCESSFUL ) {
+ sc = rtems_semaphore_release( ctx->semaphore_id );
+ T_rsc_success( sc );
+ }
+ }
+}
+
+static void WorkerZero( rtems_task_argument arg )
+{
+ Worker( arg, 0 );
+}
+
+static void WorkerOne( rtems_task_argument arg )
+{
+ Worker( arg, 1 );
+}
+
+static void RtemsSemReqDelete_Pre_Id_Prepare(
+ RtemsSemReqDelete_Context *ctx,
+ RtemsSemReqDelete_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqDelete_Pre_Id_NoObj: {
+ /*
+ * While the ``id`` parameter is not associated with a semaphore.
+ */
+ ctx->valid_id = false;
+ break;
+ }
+
+ case RtemsSemReqDelete_Pre_Id_Counting: {
+ /*
+ * While the ``id`` parameter is associated with a counting semaphore.
+ */
+ ctx->attribute_set |= RTEMS_COUNTING_SEMAPHORE;
+ ctx->obtain_status = RTEMS_OBJECT_WAS_DELETED;
+ break;
+ }
+
+ case RtemsSemReqDelete_Pre_Id_Simple: {
+ /*
+ * While the ``id`` parameter is associated with a simple binary
+ * semaphore.
+ */
+ ctx->attribute_set |= RTEMS_SIMPLE_BINARY_SEMAPHORE;
+ ctx->obtain_status = RTEMS_OBJECT_WAS_DELETED;
+ break;
+ }
+
+ case RtemsSemReqDelete_Pre_Id_Binary: {
+ /*
+ * While the ``id`` parameter is associated with a binary semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE;
+ break;
+ }
+
+ case RtemsSemReqDelete_Pre_Id_PrioCeiling: {
+ /*
+ * While the ``id`` parameter is associated with a priority ceiling
+ * semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY_CEILING;
+ break;
+ }
+
+ case RtemsSemReqDelete_Pre_Id_PrioInherit: {
+ /*
+ * While the ``id`` parameter is associated with a priority inheritance
+ * semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY;
+ break;
+ }
+
+ case RtemsSemReqDelete_Pre_Id_MrsP: {
+ /*
+ * While the ``id`` parameter is associated with a MrsP semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING;
+ break;
+ }
+
+ case RtemsSemReqDelete_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqDelete_Pre_Discipline_Prepare(
+ RtemsSemReqDelete_Context *ctx,
+ RtemsSemReqDelete_Pre_Discipline state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqDelete_Pre_Discipline_FIFO: {
+ /*
+ * While the semaphore uses the FIFO task wait queue discipline.
+ */
+ ctx->attribute_set |= RTEMS_FIFO;
+ break;
+ }
+
+ case RtemsSemReqDelete_Pre_Discipline_Priority: {
+ /*
+ * While the semaphore uses the priority task wait queue discipline.
+ */
+ ctx->attribute_set |= RTEMS_PRIORITY;
+ break;
+ }
+
+ case RtemsSemReqDelete_Pre_Discipline_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqDelete_Pre_State_Prepare(
+ RtemsSemReqDelete_Context *ctx,
+ RtemsSemReqDelete_Pre_State state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqDelete_Pre_State_GtZeroOrNoOwner: {
+ /*
+ * While the semaphore has a count greater than zero or no owner.
+ */
+ ctx->blocked = false;
+ ctx->count = 1;
+ break;
+ }
+
+ case RtemsSemReqDelete_Pre_State_Zero: {
+ /*
+ * While the semaphore has a count of zero or an owner.
+ */
+ ctx->blocked = false;
+ ctx->count = 0;
+ break;
+ }
+
+ case RtemsSemReqDelete_Pre_State_Blocked: {
+ /*
+ * While the semaphore has tasks blocked on the semaphore.
+ */
+ ctx->blocked = true;
+ ctx->count = 0;
+ break;
+ }
+
+ case RtemsSemReqDelete_Pre_State_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqDelete_Post_Status_Check(
+ RtemsSemReqDelete_Context *ctx,
+ RtemsSemReqDelete_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqDelete_Post_Status_Ok: {
+ /*
+ * The return status of rtems_semaphore_delete() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ ctx->semaphore_id = 0;
+ T_rsc_success( ctx->delete_status );
+ break;
+ }
+
+ case RtemsSemReqDelete_Post_Status_InvId: {
+ /*
+ * The return status of rtems_semaphore_delete() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->delete_status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsSemReqDelete_Post_Status_InUse: {
+ /*
+ * The return status of rtems_semaphore_delete() shall be
+ * RTEMS_RESOURCE_IN_USE.
+ */
+ T_rsc( ctx->delete_status, RTEMS_RESOURCE_IN_USE );
+ break;
+ }
+
+ case RtemsSemReqDelete_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqDelete_Post_Name_Check(
+ RtemsSemReqDelete_Context *ctx,
+ RtemsSemReqDelete_Post_Name state
+)
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ switch ( state ) {
+ case RtemsSemReqDelete_Post_Name_Valid: {
+ /*
+ * The unique object name shall identify a semaphore.
+ */
+ id = 0;
+ sc = rtems_semaphore_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc_success( sc );
+ T_eq_u32( id, ctx->semaphore_id );
+ break;
+ }
+
+ case RtemsSemReqDelete_Post_Name_Invalid: {
+ /*
+ * The unique object name shall not identify a semaphore.
+ */
+ sc = rtems_semaphore_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc( sc, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsSemReqDelete_Post_Name_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqDelete_Post_Flush_Check(
+ RtemsSemReqDelete_Context *ctx,
+ RtemsSemReqDelete_Post_Flush state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqDelete_Post_Flush_FIFO: {
+ /*
+ * Tasks waiting at the semaphore shall be unblocked in FIFO order.
+ */
+ T_eq_u32( ctx->worker_counter[ 0 ], 1 );
+ T_eq_u32( ctx->worker_counter[ 1 ], 2 );
+ break;
+ }
+
+ case RtemsSemReqDelete_Post_Flush_Priority: {
+ /*
+ * Tasks waiting at the semaphore shall be unblocked in priority order.
+ */
+ T_eq_u32( ctx->worker_counter[ 0 ], 2 );
+ T_eq_u32( ctx->worker_counter[ 1 ], 1 );
+ break;
+ }
+
+ case RtemsSemReqDelete_Post_Flush_No: {
+ /*
+ * Tasks waiting at the semaphore shall remain blocked.
+ */
+ T_eq_u32( ctx->worker_counter[ 0 ], 0 );
+ T_eq_u32( ctx->worker_counter[ 1 ], 0 );
+ break;
+ }
+
+ case RtemsSemReqDelete_Post_Flush_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqDelete_Setup( RtemsSemReqDelete_Context *ctx )
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+ SetSelfPriority( PRIO_NORMAL );
+ ctx->worker_id[ 0 ] = CreateTask( "WRK0", PRIO_HIGH );
+ StartTask( ctx->worker_id[ 0 ], WorkerZero, ctx );
+ ctx->worker_id[ 1 ] = CreateTask( "WRK1", PRIO_VERY_HIGH );
+ StartTask( ctx->worker_id[ 1 ], WorkerOne, ctx );
+}
+
+static void RtemsSemReqDelete_Setup_Wrap( void *arg )
+{
+ RtemsSemReqDelete_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSemReqDelete_Setup( ctx );
+}
+
+static void RtemsSemReqDelete_Teardown( RtemsSemReqDelete_Context *ctx )
+{
+ size_t i;
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->worker_id ); ++i ) {
+ DeleteTask( ctx->worker_id[ i ] );
+ }
+
+ RestoreRunnerPriority();
+}
+
+static void RtemsSemReqDelete_Teardown_Wrap( void *arg )
+{
+ RtemsSemReqDelete_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSemReqDelete_Teardown( ctx );
+}
+
+static void RtemsSemReqDelete_Prepare( RtemsSemReqDelete_Context *ctx )
+{
+ ctx->counter = 0;
+ ctx->worker_counter[ 0 ] = 0;
+ ctx->worker_counter[ 1 ] = 0;
+ ctx->attribute_set = RTEMS_DEFAULT_ATTRIBUTES;
+ ctx->valid_id = true;
+ ctx->obtain_status = RTEMS_SUCCESSFUL;
+}
+
+static void RtemsSemReqDelete_Action( RtemsSemReqDelete_Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_create(
+ NAME,
+ ctx->count,
+ ctx->attribute_set,
+ PRIO_ULTRA_HIGH,
+ &ctx->semaphore_id
+ );
+ T_rsc_success( sc );
+
+ if ( ctx->blocked ) {
+ WakeUp( ctx, 0 );
+ WakeUp( ctx, 1 );
+ }
+
+ if ( ctx->valid_id ) {
+ ctx->id = ctx->semaphore_id;
+ } else {
+ ctx->id = 0;
+ }
+
+ ctx->delete_status = rtems_semaphore_delete( ctx->id );
+}
+
+static void RtemsSemReqDelete_Cleanup( RtemsSemReqDelete_Context *ctx )
+{
+ if ( ctx->semaphore_id != 0 ) {
+ rtems_status_code sc;
+
+ if ( ctx->count == 0 ) {
+ sc = rtems_semaphore_release( ctx->semaphore_id );
+ T_rsc_success( sc );
+ }
+
+ sc = rtems_semaphore_delete( ctx->semaphore_id );
+ T_rsc_success( sc );
+
+ ctx->semaphore_id = 0;
+ }
+}
+
+static const RtemsSemReqDelete_Entry
+RtemsSemReqDelete_Entries[] = {
+ { 0, 0, 0, 0, RtemsSemReqDelete_Post_Status_Ok,
+ RtemsSemReqDelete_Post_Name_Invalid, RtemsSemReqDelete_Post_Flush_No },
+ { 0, 0, 0, 0, RtemsSemReqDelete_Post_Status_InUse,
+ RtemsSemReqDelete_Post_Name_Valid, RtemsSemReqDelete_Post_Flush_No },
+ { 1, 0, 0, 0, RtemsSemReqDelete_Post_Status_NA,
+ RtemsSemReqDelete_Post_Name_NA, RtemsSemReqDelete_Post_Flush_NA },
+ { 0, 0, 0, 0, RtemsSemReqDelete_Post_Status_InvId,
+ RtemsSemReqDelete_Post_Name_Valid, RtemsSemReqDelete_Post_Flush_No },
+ { 0, 0, 0, 0, RtemsSemReqDelete_Post_Status_Ok,
+ RtemsSemReqDelete_Post_Name_Invalid, RtemsSemReqDelete_Post_Flush_FIFO },
+ { 0, 0, 0, 0, RtemsSemReqDelete_Post_Status_Ok,
+ RtemsSemReqDelete_Post_Name_Invalid, RtemsSemReqDelete_Post_Flush_Priority }
+};
+
+static const uint8_t
+RtemsSemReqDelete_Map[] = {
+ 3, 3, 3, 3, 3, 3, 0, 0, 4, 0, 0, 5, 0, 0, 4, 0, 0, 5, 0, 1, 1, 0, 1, 1, 2, 2,
+ 2, 0, 1, 1, 2, 2, 2, 0, 1, 1, 2, 2, 2, 0, 1, 1
+};
+
+static size_t RtemsSemReqDelete_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsSemReqDelete_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsSemReqDelete_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsSemReqDelete_Fixture = {
+ .setup = RtemsSemReqDelete_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsSemReqDelete_Teardown_Wrap,
+ .scope = RtemsSemReqDelete_Scope,
+ .initial_context = &RtemsSemReqDelete_Instance
+};
+
+static inline RtemsSemReqDelete_Entry RtemsSemReqDelete_PopEntry(
+ RtemsSemReqDelete_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsSemReqDelete_Entries[
+ RtemsSemReqDelete_Map[ index ]
+ ];
+}
+
+static void RtemsSemReqDelete_TestVariant( RtemsSemReqDelete_Context *ctx )
+{
+ RtemsSemReqDelete_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsSemReqDelete_Pre_Discipline_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsSemReqDelete_Pre_State_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsSemReqDelete_Action( ctx );
+ RtemsSemReqDelete_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsSemReqDelete_Post_Name_Check( ctx, ctx->Map.entry.Post_Name );
+ RtemsSemReqDelete_Post_Flush_Check( ctx, ctx->Map.entry.Post_Flush );
+}
+
+/**
+ * @fn void T_case_body_RtemsSemReqDelete( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsSemReqDelete, &RtemsSemReqDelete_Fixture )
+{
+ RtemsSemReqDelete_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsSemReqDelete_Pre_Id_NoObj;
+ ctx->Map.pcs[ 0 ] < RtemsSemReqDelete_Pre_Id_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsSemReqDelete_Pre_Discipline_FIFO;
+ ctx->Map.pcs[ 1 ] < RtemsSemReqDelete_Pre_Discipline_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsSemReqDelete_Pre_State_GtZeroOrNoOwner;
+ ctx->Map.pcs[ 2 ] < RtemsSemReqDelete_Pre_State_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ ctx->Map.entry = RtemsSemReqDelete_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsSemReqDelete_Prepare( ctx );
+ RtemsSemReqDelete_TestVariant( ctx );
+ RtemsSemReqDelete_Cleanup( ctx );
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-sem-flush.c b/testsuites/validation/tc-sem-flush.c
new file mode 100644
index 0000000000..4fb2027354
--- /dev/null
+++ b/testsuites/validation/tc-sem-flush.c
@@ -0,0 +1,629 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSemReqFlush
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+
+#include "tr-tq-flush-fifo.h"
+#include "tr-tq-flush-priority-inherit.h"
+#include "tr-tq-flush-priority.h"
+#include "tx-support.h"
+#include "tx-thread-queue.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSemReqFlush spec:/rtems/sem/req/flush
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsSemReqFlush_Pre_Class_Counting,
+ RtemsSemReqFlush_Pre_Class_Simple,
+ RtemsSemReqFlush_Pre_Class_Binary,
+ RtemsSemReqFlush_Pre_Class_PrioCeiling,
+ RtemsSemReqFlush_Pre_Class_PrioInherit,
+ RtemsSemReqFlush_Pre_Class_MrsP,
+ RtemsSemReqFlush_Pre_Class_NA
+} RtemsSemReqFlush_Pre_Class;
+
+typedef enum {
+ RtemsSemReqFlush_Pre_Discipline_FIFO,
+ RtemsSemReqFlush_Pre_Discipline_Priority,
+ RtemsSemReqFlush_Pre_Discipline_NA
+} RtemsSemReqFlush_Pre_Discipline;
+
+typedef enum {
+ RtemsSemReqFlush_Pre_Id_Valid,
+ RtemsSemReqFlush_Pre_Id_Invalid,
+ RtemsSemReqFlush_Pre_Id_NA
+} RtemsSemReqFlush_Pre_Id;
+
+typedef enum {
+ RtemsSemReqFlush_Post_Action_InvId,
+ RtemsSemReqFlush_Post_Action_NotDef,
+ RtemsSemReqFlush_Post_Action_FlushFIFO,
+ RtemsSemReqFlush_Post_Action_FlushPriority,
+ RtemsSemReqFlush_Post_Action_FlushPriorityCeiling,
+ RtemsSemReqFlush_Post_Action_FlushPriorityInherit,
+ RtemsSemReqFlush_Post_Action_NA
+} RtemsSemReqFlush_Post_Action;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Class_NA : 1;
+ uint8_t Pre_Discipline_NA : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Post_Action : 3;
+} RtemsSemReqFlush_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/sem/req/flush test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the thread queue test context.
+ */
+ TQContext tq_ctx;
+
+ /**
+ * @brief This member specifies if the attribute set of the semaphore.
+ */
+ rtems_attribute attribute_set;
+
+ /**
+ * @brief This member specifies if the initial count of the semaphore.
+ */
+ uint32_t initial_count;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 3 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsSemReqFlush_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsSemReqFlush_Context;
+
+static RtemsSemReqFlush_Context
+ RtemsSemReqFlush_Instance;
+
+static const char * const RtemsSemReqFlush_PreDesc_Class[] = {
+ "Counting",
+ "Simple",
+ "Binary",
+ "PrioCeiling",
+ "PrioInherit",
+ "MrsP",
+ "NA"
+};
+
+static const char * const RtemsSemReqFlush_PreDesc_Discipline[] = {
+ "FIFO",
+ "Priority",
+ "NA"
+};
+
+static const char * const RtemsSemReqFlush_PreDesc_Id[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const * const RtemsSemReqFlush_PreDesc[] = {
+ RtemsSemReqFlush_PreDesc_Class,
+ RtemsSemReqFlush_PreDesc_Discipline,
+ RtemsSemReqFlush_PreDesc_Id,
+ NULL
+};
+
+#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+typedef RtemsSemReqFlush_Context Context;
+
+static void EnqueuePrepare( TQContext *tq_ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_obtain(
+ tq_ctx->thread_queue_id,
+ RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+ T_rsc_success( sc );
+}
+
+static Status_Control Enqueue( TQContext *tq_ctx, TQWait wait )
+{
+ rtems_status_code sc;
+
+ (void) wait;
+ sc = rtems_semaphore_obtain(
+ tq_ctx->thread_queue_id,
+ RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+ T_rsc( sc, RTEMS_UNSATISFIED );
+
+ return STATUS_BUILD( STATUS_SUCCESSFUL, 0 );
+}
+
+static uint32_t Flush( TQContext *tq_ctx, uint32_t thread_count, bool all )
+{
+ rtems_status_code sc;
+
+ (void) all;
+
+ sc = rtems_semaphore_flush( tq_ctx->thread_queue_id );
+ T_rsc_success( sc );
+
+ return thread_count;
+}
+
+static void RtemsSemReqFlush_Pre_Class_Prepare(
+ RtemsSemReqFlush_Context *ctx,
+ RtemsSemReqFlush_Pre_Class state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqFlush_Pre_Class_Counting: {
+ /*
+ * While the semaphore object is a counting semaphore.
+ */
+ ctx->attribute_set |= RTEMS_COUNTING_SEMAPHORE;
+ ctx->initial_count = 0;
+ ctx->tq_ctx.enqueue_prepare = TQDoNothing;
+ ctx->tq_ctx.enqueue_done = TQDoNothing;
+ break;
+ }
+
+ case RtemsSemReqFlush_Pre_Class_Simple: {
+ /*
+ * While the semaphore object is a simple binary semaphore.
+ */
+ ctx->attribute_set |= RTEMS_SIMPLE_BINARY_SEMAPHORE;
+ ctx->initial_count = 0;
+ ctx->tq_ctx.enqueue_prepare = TQDoNothing;
+ ctx->tq_ctx.enqueue_done = TQDoNothing;
+ break;
+ }
+
+ case RtemsSemReqFlush_Pre_Class_Binary: {
+ /*
+ * While the semaphore object is a binary semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE;
+ ctx->initial_count = 1;
+ ctx->tq_ctx.enqueue_prepare = EnqueuePrepare;
+ ctx->tq_ctx.enqueue_done = TQEnqueueDoneDefault;
+ break;
+ }
+
+ case RtemsSemReqFlush_Pre_Class_PrioCeiling: {
+ /*
+ * While the semaphore object is a priority ceiling semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY_CEILING;
+ ctx->initial_count = 1;
+ ctx->tq_ctx.enqueue_prepare = EnqueuePrepare;
+ ctx->tq_ctx.enqueue_done = TQEnqueueDoneDefault;
+ break;
+ }
+
+ case RtemsSemReqFlush_Pre_Class_PrioInherit: {
+ /*
+ * While the semaphore object is a priority inheritance semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY;
+ ctx->initial_count = 1;
+ ctx->tq_ctx.enqueue_prepare = EnqueuePrepare;
+ ctx->tq_ctx.enqueue_done = TQEnqueueDoneDefault;
+ break;
+ }
+
+ case RtemsSemReqFlush_Pre_Class_MrsP: {
+ /*
+ * While the semaphore object is a MrsP semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING;
+ ctx->initial_count = 1;
+ ctx->tq_ctx.enqueue_prepare = EnqueuePrepare;
+ ctx->tq_ctx.enqueue_done = TQEnqueueDoneDefault;
+ break;
+ }
+
+ case RtemsSemReqFlush_Pre_Class_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqFlush_Pre_Discipline_Prepare(
+ RtemsSemReqFlush_Context *ctx,
+ RtemsSemReqFlush_Pre_Discipline state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqFlush_Pre_Discipline_FIFO: {
+ /*
+ * While the semaphore uses the FIFO task wait queue discipline.
+ */
+ ctx->attribute_set |= RTEMS_FIFO;
+ ctx->tq_ctx.discipline = TQ_FIFO;
+ break;
+ }
+
+ case RtemsSemReqFlush_Pre_Discipline_Priority: {
+ /*
+ * While the semaphore uses the priority task wait queue discipline.
+ */
+ ctx->attribute_set |= RTEMS_PRIORITY;
+ ctx->tq_ctx.discipline = TQ_PRIORITY;
+ break;
+ }
+
+ case RtemsSemReqFlush_Pre_Discipline_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqFlush_Pre_Id_Prepare(
+ RtemsSemReqFlush_Context *ctx,
+ RtemsSemReqFlush_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqFlush_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter is associated with the semaphore.
+ */
+ /* Nothing to prepare */
+ break;
+ }
+
+ case RtemsSemReqFlush_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a semaphore.
+ */
+ /* Nothing to prepare */
+ break;
+ }
+
+ case RtemsSemReqFlush_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqFlush_Post_Action_Check(
+ RtemsSemReqFlush_Context *ctx,
+ RtemsSemReqFlush_Post_Action state
+)
+{
+ rtems_status_code sc;
+
+ switch ( state ) {
+ case RtemsSemReqFlush_Post_Action_InvId: {
+ /*
+ * The return status of rtems_semaphore_flush() shall be
+ * RTEMS_INVALID_ID.
+ */
+ sc = rtems_semaphore_flush( 0xffffffff );
+ T_rsc( sc, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsSemReqFlush_Post_Action_NotDef: {
+ /*
+ * The return status of rtems_semaphore_flush() shall be
+ * RTEMS_NOT_DEFINED.
+ */
+ sc = rtems_semaphore_flush( ctx->tq_ctx.thread_queue_id );
+ T_rsc( sc, RTEMS_NOT_DEFINED );
+ break;
+ }
+
+ case RtemsSemReqFlush_Post_Action_FlushFIFO: {
+ /*
+ * The calling task shall flush the semaphore as specified by
+ * spec:/score/tq/req/flush-fifo.
+ */
+ ScoreTqReqFlushFifo_Run( &ctx->tq_ctx, false );
+ break;
+ }
+
+ case RtemsSemReqFlush_Post_Action_FlushPriority: {
+ /*
+ * The calling task shall flush the semaphore as specified by
+ * spec:/score/tq/req/flush-priority.
+ */
+ ScoreTqReqFlushPriority_Run( &ctx->tq_ctx, true );
+ break;
+ }
+
+ case RtemsSemReqFlush_Post_Action_FlushPriorityCeiling: {
+ /*
+ * The calling task shall flush the semaphore as specified by
+ * spec:/score/tq/req/flush-priority.
+ */
+ ScoreTqReqFlushPriority_Run( &ctx->tq_ctx, false );
+ break;
+ }
+
+ case RtemsSemReqFlush_Post_Action_FlushPriorityInherit: {
+ /*
+ * The calling task shall flush the semaphore as specified by
+ * spec:/score/tq/req/flush-priority-inherit.
+ */
+ ScoreTqReqFlushPriorityInherit_Run( &ctx->tq_ctx );
+ break;
+ }
+
+ case RtemsSemReqFlush_Post_Action_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqFlush_Setup( RtemsSemReqFlush_Context *ctx )
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->tq_ctx.enqueue = Enqueue;
+ ctx->tq_ctx.flush = Flush;
+ ctx->tq_ctx.surrender = TQSurrenderClassicSem;
+ ctx->tq_ctx.convert_status = TQConvertStatusClassic;
+ TQInitialize( &ctx->tq_ctx );
+}
+
+static void RtemsSemReqFlush_Setup_Wrap( void *arg )
+{
+ RtemsSemReqFlush_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSemReqFlush_Setup( ctx );
+}
+
+static void RtemsSemReqFlush_Teardown( RtemsSemReqFlush_Context *ctx )
+{
+ TQDestroy( &ctx->tq_ctx );
+}
+
+static void RtemsSemReqFlush_Teardown_Wrap( void *arg )
+{
+ RtemsSemReqFlush_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSemReqFlush_Teardown( ctx );
+}
+
+static void RtemsSemReqFlush_Prepare( RtemsSemReqFlush_Context *ctx )
+{
+ ctx->attribute_set = RTEMS_DEFAULT_ATTRIBUTES;
+}
+
+static void RtemsSemReqFlush_Action( RtemsSemReqFlush_Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_create(
+ NAME,
+ ctx->initial_count,
+ ctx->attribute_set,
+ PRIO_ULTRA_HIGH,
+ &ctx->tq_ctx.thread_queue_id
+ );
+ T_rsc_success( sc );
+}
+
+static void RtemsSemReqFlush_Cleanup( RtemsSemReqFlush_Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_delete( ctx->tq_ctx.thread_queue_id );
+ T_rsc_success( sc );
+}
+
+static const RtemsSemReqFlush_Entry
+RtemsSemReqFlush_Entries[] = {
+ { 0, 1, 1, 0, RtemsSemReqFlush_Post_Action_InvId },
+ { 0, 0, 0, 0, RtemsSemReqFlush_Post_Action_FlushFIFO },
+ { 0, 0, 0, 0, RtemsSemReqFlush_Post_Action_FlushPriority },
+ { 1, 0, 0, 0, RtemsSemReqFlush_Post_Action_NA },
+ { 0, 0, 0, 0, RtemsSemReqFlush_Post_Action_FlushPriorityCeiling },
+ { 0, 0, 0, 0, RtemsSemReqFlush_Post_Action_FlushPriorityInherit },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, RtemsSemReqFlush_Post_Action_NotDef }
+#else
+ { 1, 0, 0, 0, RtemsSemReqFlush_Post_Action_NA }
+#endif
+};
+
+static const uint8_t
+RtemsSemReqFlush_Map[] = {
+ 1, 0, 2, 0, 1, 0, 2, 0, 1, 0, 2, 0, 3, 0, 4, 0, 3, 0, 5, 0, 3, 0, 6, 0
+};
+
+static size_t RtemsSemReqFlush_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsSemReqFlush_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsSemReqFlush_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsSemReqFlush_Fixture = {
+ .setup = RtemsSemReqFlush_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsSemReqFlush_Teardown_Wrap,
+ .scope = RtemsSemReqFlush_Scope,
+ .initial_context = &RtemsSemReqFlush_Instance
+};
+
+static inline RtemsSemReqFlush_Entry RtemsSemReqFlush_PopEntry(
+ RtemsSemReqFlush_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsSemReqFlush_Entries[
+ RtemsSemReqFlush_Map[ index ]
+ ];
+}
+
+static void RtemsSemReqFlush_SetPreConditionStates(
+ RtemsSemReqFlush_Context *ctx
+)
+{
+ if ( ctx->Map.entry.Pre_Class_NA ) {
+ ctx->Map.pcs[ 0 ] = RtemsSemReqFlush_Pre_Class_NA;
+ } else {
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Discipline_NA ) {
+ ctx->Map.pcs[ 1 ] = RtemsSemReqFlush_Pre_Discipline_NA;
+ } else {
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ }
+
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+}
+
+static void RtemsSemReqFlush_TestVariant( RtemsSemReqFlush_Context *ctx )
+{
+ RtemsSemReqFlush_Pre_Class_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsSemReqFlush_Pre_Discipline_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsSemReqFlush_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsSemReqFlush_Action( ctx );
+ RtemsSemReqFlush_Post_Action_Check( ctx, ctx->Map.entry.Post_Action );
+}
+
+/**
+ * @fn void T_case_body_RtemsSemReqFlush( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsSemReqFlush, &RtemsSemReqFlush_Fixture )
+{
+ RtemsSemReqFlush_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsSemReqFlush_Pre_Class_Counting;
+ ctx->Map.pci[ 0 ] < RtemsSemReqFlush_Pre_Class_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsSemReqFlush_Pre_Discipline_FIFO;
+ ctx->Map.pci[ 1 ] < RtemsSemReqFlush_Pre_Discipline_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsSemReqFlush_Pre_Id_Valid;
+ ctx->Map.pci[ 2 ] < RtemsSemReqFlush_Pre_Id_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ ctx->Map.entry = RtemsSemReqFlush_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsSemReqFlush_SetPreConditionStates( ctx );
+ RtemsSemReqFlush_Prepare( ctx );
+ RtemsSemReqFlush_TestVariant( ctx );
+ RtemsSemReqFlush_Cleanup( ctx );
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-sem-ident.c b/testsuites/validation/tc-sem-ident.c
new file mode 100644
index 0000000000..abeddfa5e2
--- /dev/null
+++ b/testsuites/validation/tc-sem-ident.c
@@ -0,0 +1,121 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSemValIdent
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-object-ident.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSemValIdent spec:/rtems/sem/val/ident
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Test the rtems_semaphore_ident() directive.
+ *
+ * This test case performs the following actions:
+ *
+ * - Run the generic object identification tests for Classic API semaphore
+ * class objects defined by spec:/rtems/req/ident.
+ *
+ * @{
+ */
+
+#define NAME_LOCAL_OBJECT rtems_build_name( 'S', 'E', 'M', 'A' )
+
+static rtems_status_code ClassicSemIdentAction(
+ rtems_name name,
+ uint32_t node,
+ rtems_id *id
+)
+{
+ return rtems_semaphore_ident( name, node, id );
+}
+
+/**
+ * @brief Run the generic object identification tests for Classic API semaphore
+ * class objects defined by spec:/rtems/req/ident.
+ */
+static void RtemsSemValIdent_Action_0( void )
+{
+ rtems_status_code sc;
+ rtems_id id_local_object;
+
+ sc = rtems_semaphore_create(
+ NAME_LOCAL_OBJECT,
+ 0,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ 0,
+ &id_local_object
+ );
+ T_assert_rsc_success( sc );
+
+ RtemsReqIdent_Run(
+ id_local_object,
+ NAME_LOCAL_OBJECT,
+ ClassicSemIdentAction
+ );
+
+ sc = rtems_semaphore_delete( id_local_object );
+ T_rsc_success( sc );
+}
+
+/**
+ * @fn void T_case_body_RtemsSemValIdent( void )
+ */
+T_TEST_CASE( RtemsSemValIdent )
+{
+ RtemsSemValIdent_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-sem-mrsp-obtain.c b/testsuites/validation/tc-sem-mrsp-obtain.c
new file mode 100644
index 0000000000..e7d50c34da
--- /dev/null
+++ b/testsuites/validation/tc-sem-mrsp-obtain.c
@@ -0,0 +1,1202 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSemReqMrspObtain
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/threadimpl.h>
+
+#include "tx-support.h"
+#include "tx-thread-queue.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSemReqMrspObtain spec:/rtems/sem/req/mrsp-obtain
+ *
+ * @ingroup TestsuitesValidationSmpOnly0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsSemReqMrspObtain_Pre_Home_Idle,
+ RtemsSemReqMrspObtain_Pre_Home_Task,
+ RtemsSemReqMrspObtain_Pre_Home_TaskIdle,
+ RtemsSemReqMrspObtain_Pre_Home_Second,
+ RtemsSemReqMrspObtain_Pre_Home_SecondIdle,
+ RtemsSemReqMrspObtain_Pre_Home_NA
+} RtemsSemReqMrspObtain_Pre_Home;
+
+typedef enum {
+ RtemsSemReqMrspObtain_Pre_Helping_Idle,
+ RtemsSemReqMrspObtain_Pre_Helping_Task,
+ RtemsSemReqMrspObtain_Pre_Helping_Helping,
+ RtemsSemReqMrspObtain_Pre_Helping_HelpingIdle,
+ RtemsSemReqMrspObtain_Pre_Helping_Third,
+ RtemsSemReqMrspObtain_Pre_Helping_ThirdIdle,
+ RtemsSemReqMrspObtain_Pre_Helping_NA
+} RtemsSemReqMrspObtain_Pre_Helping;
+
+typedef enum {
+ RtemsSemReqMrspObtain_Pre_PriorityHome_None,
+ RtemsSemReqMrspObtain_Pre_PriorityHome_NewHigh,
+ RtemsSemReqMrspObtain_Pre_PriorityHome_NewEqual,
+ RtemsSemReqMrspObtain_Pre_PriorityHome_SecondHigh,
+ RtemsSemReqMrspObtain_Pre_PriorityHome_SecondEqual,
+ RtemsSemReqMrspObtain_Pre_PriorityHome_SecondLow,
+ RtemsSemReqMrspObtain_Pre_PriorityHome_NA
+} RtemsSemReqMrspObtain_Pre_PriorityHome;
+
+typedef enum {
+ RtemsSemReqMrspObtain_Pre_PriorityHelping_None,
+ RtemsSemReqMrspObtain_Pre_PriorityHelping_Helping,
+ RtemsSemReqMrspObtain_Pre_PriorityHelping_ThirdHigh,
+ RtemsSemReqMrspObtain_Pre_PriorityHelping_ThirdEqual,
+ RtemsSemReqMrspObtain_Pre_PriorityHelping_ThirdLow,
+ RtemsSemReqMrspObtain_Pre_PriorityHelping_NA
+} RtemsSemReqMrspObtain_Pre_PriorityHelping;
+
+typedef enum {
+ RtemsSemReqMrspObtain_Post_Home_Task,
+ RtemsSemReqMrspObtain_Post_Home_TaskIdle,
+ RtemsSemReqMrspObtain_Post_Home_Second,
+ RtemsSemReqMrspObtain_Post_Home_SecondIdle,
+ RtemsSemReqMrspObtain_Post_Home_NA
+} RtemsSemReqMrspObtain_Post_Home;
+
+typedef enum {
+ RtemsSemReqMrspObtain_Post_Helping_Idle,
+ RtemsSemReqMrspObtain_Post_Helping_Task,
+ RtemsSemReqMrspObtain_Post_Helping_TaskIdle,
+ RtemsSemReqMrspObtain_Post_Helping_Helping,
+ RtemsSemReqMrspObtain_Post_Helping_HelpingIdle,
+ RtemsSemReqMrspObtain_Post_Helping_Third,
+ RtemsSemReqMrspObtain_Post_Helping_ThirdIdle,
+ RtemsSemReqMrspObtain_Post_Helping_NA
+} RtemsSemReqMrspObtain_Post_Helping;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Home_NA : 1;
+ uint16_t Pre_Helping_NA : 1;
+ uint16_t Pre_PriorityHome_NA : 1;
+ uint16_t Pre_PriorityHelping_NA : 1;
+ uint16_t Post_Home : 3;
+ uint16_t Post_Helping : 3;
+} RtemsSemReqMrspObtain_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/sem/req/mrsp-obtain test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the thread queue test context.
+ */
+ TQContext tq_ctx;
+
+ /**
+ * @brief This member contains the MrsP semaphore to obtain.
+ */
+ rtems_id sema_id;
+
+ /**
+ * @brief This member specifies the scheduler on which the task executes.
+ */
+ rtems_id task_scheduler;
+
+ /**
+ * @brief If this member is true, then the task shall already own a MrsP
+ * semaphore.
+ */
+ bool task_owns_mrsp_semaphore;
+
+ /**
+ * @brief If this member is true, then an idle task shall execute on
+ * scheduler A.
+ */
+ bool scheduler_a_idle;
+
+ /**
+ * @brief If this member is true, then an idle task shall execute on
+ * scheduler B.
+ */
+ bool scheduler_b_idle;
+
+ /**
+ * @brief If this member is true, then the second task shall be active.
+ */
+ bool second_active;
+
+ /**
+ * @brief This member specifies the priority of the second task.
+ */
+ rtems_task_priority second_priority;
+
+ /**
+ * @brief If this member is true, then the third task shall be active.
+ */
+ bool third_active;
+
+ /**
+ * @brief This member specifies the priority of the third task.
+ */
+ rtems_task_priority third_priority;
+
+ /**
+ * @brief If this member is true, then the helping task shall be active.
+ */
+ bool helping_active;
+
+ /**
+ * @brief This member specifies the priority of the MrsP semaphore with
+ * respect to scheduler A.
+ */
+ rtems_task_priority sema_priority_scheduler_a;
+
+ /**
+ * @brief This member specifies the priority of the MrsP semaphore with
+ * respect to scheduler B.
+ */
+ rtems_task_priority sema_priority_scheduler_b;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 4 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsSemReqMrspObtain_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsSemReqMrspObtain_Context;
+
+static RtemsSemReqMrspObtain_Context
+ RtemsSemReqMrspObtain_Instance;
+
+static const char * const RtemsSemReqMrspObtain_PreDesc_Home[] = {
+ "Idle",
+ "Task",
+ "TaskIdle",
+ "Second",
+ "SecondIdle",
+ "NA"
+};
+
+static const char * const RtemsSemReqMrspObtain_PreDesc_Helping[] = {
+ "Idle",
+ "Task",
+ "Helping",
+ "HelpingIdle",
+ "Third",
+ "ThirdIdle",
+ "NA"
+};
+
+static const char * const RtemsSemReqMrspObtain_PreDesc_PriorityHome[] = {
+ "None",
+ "NewHigh",
+ "NewEqual",
+ "SecondHigh",
+ "SecondEqual",
+ "SecondLow",
+ "NA"
+};
+
+static const char * const RtemsSemReqMrspObtain_PreDesc_PriorityHelping[] = {
+ "None",
+ "Helping",
+ "ThirdHigh",
+ "ThirdEqual",
+ "ThirdLow",
+ "NA"
+};
+
+static const char * const * const RtemsSemReqMrspObtain_PreDesc[] = {
+ RtemsSemReqMrspObtain_PreDesc_Home,
+ RtemsSemReqMrspObtain_PreDesc_Helping,
+ RtemsSemReqMrspObtain_PreDesc_PriorityHome,
+ RtemsSemReqMrspObtain_PreDesc_PriorityHelping,
+ NULL
+};
+
+#define HELPING TQ_BLOCKER_A
+
+#define SECOND TQ_BLOCKER_B
+
+#define THIRD TQ_BLOCKER_C
+
+#define ASSISTANT TQ_BLOCKER_D
+
+#define MOVER TQ_BLOCKER_E
+
+typedef RtemsSemReqMrspObtain_Context Context;
+
+static void SetSemaphorePriority(
+ rtems_id id,
+ rtems_task_priority priority_a,
+ rtems_task_priority priority_b
+)
+{
+ rtems_status_code sc;
+ rtems_task_priority priority;
+
+ sc = rtems_semaphore_set_priority(
+ id,
+ SCHEDULER_A_ID,
+ priority_a,
+ &priority
+ );
+ T_rsc_success( sc );
+
+ sc = rtems_semaphore_set_priority(
+ id,
+ SCHEDULER_B_ID,
+ priority_b,
+ &priority
+ );
+ T_rsc_success( sc );
+}
+
+static void MoveToScheduler( Context *ctx, rtems_id scheduler_id )
+{
+ rtems_id other_scheduler_id;
+ uint32_t cpu;
+
+ if ( scheduler_id == SCHEDULER_A_ID ) {
+ other_scheduler_id = SCHEDULER_B_ID;
+ cpu = 0;
+ } else {
+ other_scheduler_id = SCHEDULER_A_ID;
+ cpu = 1;
+ }
+
+ TQSetScheduler( &ctx->tq_ctx, MOVER, other_scheduler_id, PRIO_VERY_HIGH );
+ ctx->tq_ctx.busy_wait[ MOVER ] = true;
+ TQSend( &ctx->tq_ctx, MOVER, TQ_EVENT_BUSY_WAIT );
+ TQWaitForEventsReceived( &ctx->tq_ctx, MOVER );
+ T_eq_u32( rtems_scheduler_get_processor(), cpu );
+ ctx->tq_ctx.busy_wait[ MOVER ] = false;
+ TQWaitForExecutionStop( &ctx->tq_ctx, MOVER );
+}
+
+static void RtemsSemReqMrspObtain_Pre_Home_Prepare(
+ RtemsSemReqMrspObtain_Context *ctx,
+ RtemsSemReqMrspObtain_Pre_Home state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqMrspObtain_Pre_Home_Idle: {
+ /*
+ * While an idle task executes on the processor owned by the home
+ * scheduler of the obtaining task.
+ */
+ ctx->scheduler_a_idle = true;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_Home_Task: {
+ /*
+ * While the obtaining task executes on the processor owned by the home
+ * scheduler of the obtaining task.
+ */
+ ctx->task_scheduler = SCHEDULER_A_ID;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_Home_TaskIdle: {
+ /*
+ * While an idle task on behalf of the obtaining task executes on the
+ * processor owned by the home scheduler of the obtaining task.
+ */
+ ctx->scheduler_a_idle = true;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_Home_Second: {
+ /*
+ * While the second task executes on the processor owned by the home
+ * scheduler of the obtaining task.
+ */
+ ctx->second_active = true;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_Home_SecondIdle: {
+ /*
+ * While an idle task on behalf of the second task executes on the
+ * processor owned by the home scheduler of the obtaining task.
+ */
+ ctx->second_active = true;
+ ctx->scheduler_a_idle = true;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_Home_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqMrspObtain_Pre_Helping_Prepare(
+ RtemsSemReqMrspObtain_Context *ctx,
+ RtemsSemReqMrspObtain_Pre_Helping state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqMrspObtain_Pre_Helping_Idle: {
+ /*
+ * While an idle task executes on the processor owned by the helping
+ * scheduler of the obtaining task.
+ */
+ ctx->scheduler_b_idle = true;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_Helping_Task: {
+ /*
+ * While the obtaining task executes on the processor owned by the
+ * helping scheduler of the obtaining task.
+ */
+ ctx->task_scheduler = SCHEDULER_B_ID;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_Helping_Helping: {
+ /*
+ * While a helping task of the obtaining task executes on the processor
+ * owned by the helping scheduler of the obtaining task.
+ */
+ ctx->task_owns_mrsp_semaphore = true;
+ ctx->helping_active = true;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_Helping_HelpingIdle: {
+ /*
+ * While an idle task on behalf of a helping task of the obtaining task
+ * executes on the processor owned by the helping scheduler of the
+ * obtaining task.
+ */
+ ctx->task_owns_mrsp_semaphore = true;
+ ctx->helping_active = true;
+ ctx->scheduler_b_idle = true;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_Helping_Third: {
+ /*
+ * While the third task executes on the processor owned by the helping
+ * scheduler of the obtaining task.
+ */
+ ctx->third_active = true;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_Helping_ThirdIdle: {
+ /*
+ * While an idle task on behalf of the third task executes on the
+ * processor owned by the helping scheduler of the obtaining task.
+ */
+ ctx->third_active = true;
+ ctx->scheduler_b_idle = true;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_Helping_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqMrspObtain_Pre_PriorityHome_Prepare(
+ RtemsSemReqMrspObtain_Context *ctx,
+ RtemsSemReqMrspObtain_Pre_PriorityHome state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqMrspObtain_Pre_PriorityHome_None: {
+ /*
+ * While no ceiling priority with respect to the home scheduler of the
+ * obtaining task is already available to the task.
+ */
+ ctx->second_priority = PRIO_HIGH;
+ ctx->sema_priority_scheduler_a = PRIO_NORMAL;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_PriorityHome_NewHigh: {
+ /*
+ * While the ceiling priority of the semaphore with respect to the home
+ * scheduler of the obtaining task is higher than the ceiling priorities
+ * already available to the task.
+ */
+ ctx->task_owns_mrsp_semaphore = true;
+ ctx->sema_priority_scheduler_a = PRIO_HIGH;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_PriorityHome_NewEqual: {
+ /*
+ * While the ceiling priority of the semaphore with respect to the home
+ * scheduler of the obtaining task is equal to the ceiling priorities
+ * already available to the task.
+ */
+ ctx->task_owns_mrsp_semaphore = true;
+ ctx->sema_priority_scheduler_a = PRIO_NORMAL;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_PriorityHome_SecondHigh: {
+ /*
+ * While the ceiling priority of the semaphore with respect to the home
+ * scheduler of the obtaining task is higher than the priority of the
+ * second task.
+ */
+ ctx->second_priority = PRIO_HIGH;
+ ctx->sema_priority_scheduler_a = PRIO_VERY_HIGH;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_PriorityHome_SecondEqual: {
+ /*
+ * While the ceiling priority of the semaphore with respect to the home
+ * scheduler of the obtaining task is equal to the priority of the second
+ * task.
+ */
+ ctx->second_priority = PRIO_HIGH;
+ ctx->sema_priority_scheduler_a = PRIO_HIGH;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_PriorityHome_SecondLow: {
+ /*
+ * While the ceiling priority of the semaphore with respect to the home
+ * scheduler of the obtaining task is lower than the priority of the
+ * second task.
+ */
+ ctx->second_priority = PRIO_HIGH;
+ ctx->sema_priority_scheduler_a = PRIO_NORMAL;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_PriorityHome_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqMrspObtain_Pre_PriorityHelping_Prepare(
+ RtemsSemReqMrspObtain_Context *ctx,
+ RtemsSemReqMrspObtain_Pre_PriorityHelping state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqMrspObtain_Pre_PriorityHelping_None: {
+ /*
+ * While no ceiling priority with respect to the helping scheduler of the
+ * obtaining task is already available to the task.
+ */
+ ctx->sema_priority_scheduler_b = PRIO_NORMAL;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_PriorityHelping_Helping: {
+ /*
+ * While ceiling priorities with respect to the helping scheduler of the
+ * obtaining task are already available to the task.
+ */
+ ctx->helping_active = true;
+ ctx->task_owns_mrsp_semaphore = true;
+ ctx->sema_priority_scheduler_b = PRIO_NORMAL;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_PriorityHelping_ThirdHigh: {
+ /*
+ * While the ceiling priority of the semaphore with respect to the
+ * helping scheduler of the obtaining task is higher than the priority of
+ * the third task.
+ */
+ ctx->third_priority = PRIO_LOW;
+ ctx->sema_priority_scheduler_b = PRIO_NORMAL;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_PriorityHelping_ThirdEqual: {
+ /*
+ * While the ceiling priority of the semaphore with respect to the
+ * helping scheduler of the obtaining task is equal to the priority of
+ * the third task.
+ */
+ ctx->third_priority = PRIO_NORMAL;
+ ctx->sema_priority_scheduler_b = PRIO_NORMAL;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_PriorityHelping_ThirdLow: {
+ /*
+ * While the ceiling priority of the semaphore with respect to the
+ * helping scheduler of the obtaining task is lower than the priority of
+ * the third task.
+ */
+ ctx->third_priority = PRIO_HIGH;
+ ctx->sema_priority_scheduler_b = PRIO_NORMAL;
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Pre_PriorityHelping_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqMrspObtain_Post_Home_Check(
+ RtemsSemReqMrspObtain_Context *ctx,
+ RtemsSemReqMrspObtain_Post_Home state
+)
+{
+ const Per_CPU_Control *cpu;
+ const Thread_Control *scheduled;
+ const Scheduler_Node *scheduler_node;
+ uint32_t task_cpu_index;
+
+ cpu = _Per_CPU_Get_by_index( 0 );
+ scheduled = cpu->heir;
+ task_cpu_index = rtems_scheduler_get_processor();
+
+ switch ( state ) {
+ case RtemsSemReqMrspObtain_Post_Home_Task: {
+ /*
+ * The obtaining task shall execute on the processor owned by the home
+ * scheduler of the obtaining task.
+ */
+ T_eq_u32( task_cpu_index, 0 );
+ T_eq_ptr( scheduled, ctx->tq_ctx.runner_tcb );
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Post_Home_TaskIdle: {
+ /*
+ * An idle task on behalf of the obtaining task shall execute on the
+ * processor owned by the home scheduler of the obtaining task.
+ */
+ T_eq_u32( task_cpu_index, 1 );
+ T_true( scheduled->is_idle );
+ scheduler_node = _Thread_Scheduler_get_node_by_index(
+ ctx->tq_ctx.runner_tcb,
+ 0
+ );
+ T_eq_ptr( scheduler_node->user, scheduled );
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Post_Home_Second: {
+ /*
+ * The second task shall execute on the processor owned by the home
+ * scheduler of the obtaining task.
+ */
+ T_eq_u32( task_cpu_index, 1 );
+ T_eq_ptr( scheduled, ctx->tq_ctx.worker_tcb[ SECOND ] );
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Post_Home_SecondIdle: {
+ /*
+ * An idle task on behalf of the second task shall execute on the
+ * processor owned by the home scheduler of the obtaining task.
+ */
+ T_eq_u32( task_cpu_index, 1 );
+ T_true( scheduled->is_idle );
+ scheduler_node = _Thread_Scheduler_get_node_by_index(
+ ctx->tq_ctx.worker_tcb[ SECOND ],
+ 0
+ );
+ T_eq_ptr( scheduler_node->user, scheduled );
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Post_Home_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqMrspObtain_Post_Helping_Check(
+ RtemsSemReqMrspObtain_Context *ctx,
+ RtemsSemReqMrspObtain_Post_Helping state
+)
+{
+ const Per_CPU_Control *cpu;
+ const Thread_Control *scheduled;
+ const Scheduler_Node *scheduler_node;
+ uint32_t task_cpu_index;
+
+ cpu = _Per_CPU_Get_by_index( 1 );
+ scheduled = cpu->heir;
+ task_cpu_index = rtems_scheduler_get_processor();
+
+ switch ( state ) {
+ case RtemsSemReqMrspObtain_Post_Helping_Idle: {
+ /*
+ * An idle task shall execute on the processor owned by the helping
+ * scheduler of the obtaining task.
+ */
+ T_eq_u32( task_cpu_index, 0 );
+ T_true( scheduled->is_idle );
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Post_Helping_Task: {
+ /*
+ * The obtaining task shall execute on the processor owned by the helping
+ * scheduler of the obtaining task.
+ */
+ T_eq_u32( task_cpu_index, 1 );
+ T_eq_ptr( scheduled, ctx->tq_ctx.runner_tcb );
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Post_Helping_TaskIdle: {
+ /*
+ * An idle task on behalf of the obtaining task shall execute on the
+ * processor owned by the helping scheduler of the obtaining task.
+ */
+ T_eq_u32( task_cpu_index, 0 );
+ T_true( scheduled->is_idle );
+ scheduler_node = _Thread_Scheduler_get_node_by_index(
+ ctx->tq_ctx.runner_tcb,
+ 1
+ );
+ T_eq_ptr( scheduler_node->user, ctx->tq_ctx.runner_tcb );
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Post_Helping_Helping: {
+ /*
+ * The helping task shall execute on the processor owned by the helping
+ * scheduler of the obtaining task.
+ */
+ T_eq_u32( task_cpu_index, 0 );
+ T_eq_ptr( scheduled, ctx->tq_ctx.worker_tcb[ HELPING ] );
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Post_Helping_HelpingIdle: {
+ /*
+ * An idle task on behalf of the helping task shall execute on the
+ * processor owned by the helping scheduler of the obtaining task.
+ */
+ T_eq_u32( task_cpu_index, 0 );
+ T_true( scheduled->is_idle );
+ scheduler_node = _Thread_Scheduler_get_node_by_index(
+ ctx->tq_ctx.worker_tcb[ HELPING ],
+ 1
+ );
+ T_eq_ptr( scheduler_node->user, scheduled );
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Post_Helping_Third: {
+ /*
+ * The third task shall execute on the processor owned by the helping
+ * scheduler of the obtaining task.
+ */
+ T_eq_u32( task_cpu_index, 0 );
+ T_eq_ptr( scheduled, ctx->tq_ctx.worker_tcb[ THIRD ] );
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Post_Helping_ThirdIdle: {
+ /*
+ * An idle task on behalf of the third task shall execute on the
+ * processor owned by the helping scheduler of the obtaining task.
+ */
+ T_eq_u32( task_cpu_index, 0 );
+ scheduler_node = _Thread_Scheduler_get_node_by_index(
+ ctx->tq_ctx.worker_tcb[ THIRD ],
+ 1
+ );
+ T_eq_ptr( scheduler_node->user, scheduled );
+ break;
+ }
+
+ case RtemsSemReqMrspObtain_Post_Helping_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqMrspObtain_Setup( RtemsSemReqMrspObtain_Context *ctx )
+{
+ rtems_status_code sc;
+ rtems_id mutex_b;
+ rtems_id mutex_c;
+
+ memset( ctx, 0, sizeof( *ctx ) );
+
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'S', 'E', 'M', 'A' ),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
+ PRIO_NORMAL,
+ &ctx->sema_id
+ );
+ T_rsc_success( sc );
+
+ ctx->tq_ctx.deadlock = TQ_DEADLOCK_STATUS;
+ ctx->tq_ctx.enqueue_prepare = TQEnqueuePrepareDefault;
+ ctx->tq_ctx.enqueue_done = TQEnqueueDoneDefault;
+ ctx->tq_ctx.enqueue = TQEnqueueClassicSem;
+ ctx->tq_ctx.surrender = TQSurrenderClassicSem;
+ ctx->tq_ctx.get_owner = TQGetOwnerClassicSem;
+ ctx->tq_ctx.convert_status = TQConvertStatusClassic;
+ TQInitialize( &ctx->tq_ctx );
+
+ DeleteMutex( ctx->tq_ctx.mutex_id[ TQ_MUTEX_B ] );
+ DeleteMutex( ctx->tq_ctx.mutex_id[ TQ_MUTEX_C ] );
+
+ mutex_b = 0;
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'M', 'T', 'X', 'B' ),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
+ PRIO_NORMAL,
+ &mutex_b
+ );
+ T_rsc_success( sc );
+
+ mutex_c = 0;
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'M', 'T', 'X', 'C' ),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
+ PRIO_NORMAL,
+ &mutex_c
+ );
+ T_rsc_success( sc );
+
+ ctx->tq_ctx.mutex_id[ TQ_MUTEX_B ] = mutex_b;
+ ctx->tq_ctx.mutex_id[ TQ_MUTEX_C ] = mutex_c;
+
+ TQSetScheduler( &ctx->tq_ctx, HELPING, SCHEDULER_B_ID, PRIO_VERY_LOW );
+ TQSetScheduler( &ctx->tq_ctx, THIRD, SCHEDULER_B_ID, PRIO_NORMAL );
+
+ TQMutexObtain( &ctx->tq_ctx, TQ_MUTEX_A );
+ TQSetScheduler( &ctx->tq_ctx, ASSISTANT, SCHEDULER_B_ID, PRIO_VERY_LOW );
+ TQSendAndWaitForExecutionStop(
+ &ctx->tq_ctx,
+ ASSISTANT,
+ TQ_EVENT_MUTEX_A_OBTAIN
+ );
+
+ SetSemaphorePriority(
+ ctx->tq_ctx.mutex_id[ TQ_MUTEX_B ],
+ PRIO_NORMAL,
+ PRIO_VERY_LOW
+ );
+}
+
+static void RtemsSemReqMrspObtain_Setup_Wrap( void *arg )
+{
+ RtemsSemReqMrspObtain_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSemReqMrspObtain_Setup( ctx );
+}
+
+static void RtemsSemReqMrspObtain_Teardown(
+ RtemsSemReqMrspObtain_Context *ctx
+)
+{
+ TQMutexRelease( &ctx->tq_ctx, TQ_MUTEX_A );
+ TQSendAndWaitForExecutionStop(
+ &ctx->tq_ctx,
+ ASSISTANT,
+ TQ_EVENT_MUTEX_A_RELEASE
+ );
+ TQDestroy( &ctx->tq_ctx );
+ DeleteMutex( ctx->sema_id );
+}
+
+static void RtemsSemReqMrspObtain_Teardown_Wrap( void *arg )
+{
+ RtemsSemReqMrspObtain_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSemReqMrspObtain_Teardown( ctx );
+}
+
+static void RtemsSemReqMrspObtain_Prepare( RtemsSemReqMrspObtain_Context *ctx )
+{
+ ctx->task_scheduler = INVALID_ID;
+ ctx->task_owns_mrsp_semaphore = false;
+ ctx->scheduler_a_idle = false;
+ ctx->scheduler_b_idle = false;
+ ctx->helping_active = false;
+ ctx->second_active = false;
+ ctx->third_active = false;
+}
+
+static void RtemsSemReqMrspObtain_Action( RtemsSemReqMrspObtain_Context *ctx )
+{
+ if ( ctx->task_owns_mrsp_semaphore ) {
+ TQMutexObtain( &ctx->tq_ctx, TQ_MUTEX_B );
+ }
+
+ if ( ctx->helping_active ) {
+ T_true( ctx->task_owns_mrsp_semaphore );
+
+ TQSendAndWaitForIntendToBlock(
+ &ctx->tq_ctx,
+ HELPING,
+ TQ_EVENT_MUTEX_B_OBTAIN
+ );
+
+ if ( ctx->scheduler_b_idle ) {
+ SuspendTask( ctx->tq_ctx.worker_id[ HELPING ] );
+ }
+ }
+
+ if ( ctx->scheduler_a_idle || ctx->second_active ) {
+ MoveToScheduler( ctx, SCHEDULER_B_ID );
+ }
+
+ if ( ctx->second_active ) {
+ T_false( ctx->third_active );
+
+ TQSetPriority( &ctx->tq_ctx, SECOND, ctx->second_priority );
+
+ if ( ctx->scheduler_a_idle ) {
+ SetSemaphorePriority(
+ ctx->tq_ctx.mutex_id[ TQ_MUTEX_C ],
+ ctx->second_priority,
+ ctx->second_priority
+ );
+ TQSendAndWaitForExecutionStop(
+ &ctx->tq_ctx,
+ SECOND,
+ TQ_EVENT_MUTEX_C_OBTAIN
+ );
+ } else {
+ ctx->tq_ctx.busy_wait[ SECOND ] = true;
+ TQSend( &ctx->tq_ctx, SECOND, TQ_EVENT_BUSY_WAIT );
+ TQWaitForEventsReceived( &ctx->tq_ctx, SECOND );
+ }
+ }
+
+ if ( ctx->third_active ) {
+ T_false( ctx->second_active );
+
+ TQSetPriority( &ctx->tq_ctx, THIRD, ctx->third_priority );
+
+ if ( ctx->scheduler_b_idle ) {
+ SetSemaphorePriority(
+ ctx->tq_ctx.mutex_id[ TQ_MUTEX_C ],
+ ctx->third_priority,
+ ctx->third_priority
+ );
+ TQSendAndWaitForExecutionStop(
+ &ctx->tq_ctx,
+ THIRD,
+ TQ_EVENT_MUTEX_C_OBTAIN
+ );
+ } else {
+ ctx->tq_ctx.busy_wait[ THIRD ] = true;
+ TQSend( &ctx->tq_ctx, THIRD, TQ_EVENT_BUSY_WAIT );
+ TQWaitForEventsReceived( &ctx->tq_ctx, THIRD );
+ }
+ }
+
+ SetSemaphorePriority(
+ ctx->sema_id,
+ ctx->sema_priority_scheduler_a,
+ ctx->sema_priority_scheduler_b
+ );
+ ObtainMutex( ctx->sema_id );
+}
+
+static void RtemsSemReqMrspObtain_Cleanup( RtemsSemReqMrspObtain_Context *ctx )
+{
+ ReleaseMutex( ctx->sema_id );
+
+ if ( ctx->task_owns_mrsp_semaphore ) {
+ TQMutexRelease( &ctx->tq_ctx, TQ_MUTEX_B );
+ }
+
+ if ( ctx->second_active ) {
+ MoveToScheduler( ctx, SCHEDULER_B_ID );
+
+ if ( ctx->scheduler_a_idle ) {
+ TQSendAndWaitForExecutionStop(
+ &ctx->tq_ctx,
+ SECOND,
+ TQ_EVENT_MUTEX_C_RELEASE
+ );
+ } else {
+ ctx->tq_ctx.busy_wait[ SECOND ] = false;
+ TQWaitForExecutionStop( &ctx->tq_ctx, SECOND );
+ }
+ }
+
+ if ( ctx->third_active ) {
+ MoveToScheduler( ctx, SCHEDULER_A_ID );
+
+ if ( ctx->scheduler_b_idle ) {
+ TQSendAndWaitForExecutionStop(
+ &ctx->tq_ctx,
+ THIRD,
+ TQ_EVENT_MUTEX_C_RELEASE
+ );
+ } else {
+ ctx->tq_ctx.busy_wait[ THIRD ] = false;
+ TQWaitForExecutionStop( &ctx->tq_ctx, THIRD );
+ }
+ }
+
+ if ( ctx->helping_active ) {
+ MoveToScheduler( ctx, SCHEDULER_A_ID );
+
+ if ( ctx->scheduler_b_idle ) {
+ ResumeTask( ctx->tq_ctx.worker_id[ HELPING ] );
+ }
+
+ TQSendAndWaitForExecutionStop(
+ &ctx->tq_ctx,
+ HELPING,
+ TQ_EVENT_MUTEX_B_RELEASE
+ );
+ }
+
+ MoveToScheduler( ctx, SCHEDULER_A_ID );
+}
+
+static const RtemsSemReqMrspObtain_Entry
+RtemsSemReqMrspObtain_Entries[] = {
+ { 1, 0, 0, 0, 0, RtemsSemReqMrspObtain_Post_Home_NA,
+ RtemsSemReqMrspObtain_Post_Helping_NA },
+ { 1, 0, 0, 0, 0, RtemsSemReqMrspObtain_Post_Home_NA,
+ RtemsSemReqMrspObtain_Post_Helping_NA },
+ { 1, 0, 0, 0, 0, RtemsSemReqMrspObtain_Post_Home_NA,
+ RtemsSemReqMrspObtain_Post_Helping_NA },
+ { 1, 0, 0, 0, 0, RtemsSemReqMrspObtain_Post_Home_NA,
+ RtemsSemReqMrspObtain_Post_Helping_NA },
+ { 0, 0, 0, 0, 0, RtemsSemReqMrspObtain_Post_Home_Task,
+ RtemsSemReqMrspObtain_Post_Helping_Third },
+ { 0, 0, 0, 0, 0, RtemsSemReqMrspObtain_Post_Home_Task,
+ RtemsSemReqMrspObtain_Post_Helping_ThirdIdle },
+ { 0, 0, 0, 0, 0, RtemsSemReqMrspObtain_Post_Home_TaskIdle,
+ RtemsSemReqMrspObtain_Post_Helping_Task },
+ { 0, 0, 0, 0, 0, RtemsSemReqMrspObtain_Post_Home_Second,
+ RtemsSemReqMrspObtain_Post_Helping_Task },
+ { 0, 0, 0, 0, 0, RtemsSemReqMrspObtain_Post_Home_SecondIdle,
+ RtemsSemReqMrspObtain_Post_Helping_Task },
+ { 0, 0, 0, 0, 0, RtemsSemReqMrspObtain_Post_Home_Task,
+ RtemsSemReqMrspObtain_Post_Helping_Helping },
+ { 0, 0, 0, 0, 0, RtemsSemReqMrspObtain_Post_Home_Task,
+ RtemsSemReqMrspObtain_Post_Helping_HelpingIdle },
+ { 0, 0, 0, 0, 0, RtemsSemReqMrspObtain_Post_Home_Task,
+ RtemsSemReqMrspObtain_Post_Helping_Idle }
+};
+
+static const uint8_t
+RtemsSemReqMrspObtain_Map[] = {
+ 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 1, 1, 3, 0, 1, 1, 1, 3,
+ 0, 1, 1, 1, 6, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 1, 1, 1, 3, 3,
+ 1, 1, 1, 3, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 1,
+ 1, 1, 3, 3, 1, 1, 1, 3, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 1, 1, 1, 0, 3, 1, 1, 1, 0, 3, 1, 1, 1, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 0, 2, 2, 2, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 11,
+ 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 1, 1, 3, 0, 1, 1, 1, 3, 0,
+ 1, 1, 1, 2, 0, 1, 1, 1, 0, 2, 1, 1, 1, 0, 2, 1, 1, 1, 3, 3, 1, 1, 1, 3, 3, 1,
+ 1, 1, 3, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 9, 1, 1, 1, 0, 9, 1, 1, 1, 3, 3, 1, 1,
+ 1, 3, 3, 1, 1, 1, 3, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 10, 1, 1, 1, 0, 10, 1, 1,
+ 1, 0, 3, 1, 1, 1, 0, 3, 1, 1, 1, 0, 3, 1, 1, 1, 4, 0, 4, 4, 4, 0, 4, 4, 4, 4,
+ 0, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 5, 0, 5, 5, 5, 0,
+ 5, 5, 5, 5, 0, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1,
+ 1, 1, 0, 0, 0, 0, 0, 0, 6, 1, 1, 1, 0, 6, 1, 1, 1, 0, 3, 1, 1, 1, 0, 3, 1, 1,
+ 1, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 0, 2, 1, 1, 1, 0, 3, 1, 1, 1,
+ 0, 3, 1, 1, 1, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 0, 2, 1, 1, 1, 0,
+ 3, 1, 1, 1, 0, 3, 1, 1, 1, 0, 3, 1, 1, 1, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 2,
+ 2, 2, 2, 0, 3, 3, 3, 3, 0, 3, 3, 3, 3, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 2, 2,
+ 2, 2, 0, 2, 2, 2, 2, 0, 3, 3, 3, 3, 0, 3, 3, 3, 3, 0, 3, 3, 3, 3, 2, 0, 1, 1,
+ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 1, 1, 2, 0, 1, 1, 1, 2, 0, 1, 1, 1,
+ 7, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 1, 1, 1, 7, 7, 1, 1, 1, 7,
+ 7, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 2, 2,
+ 1, 1, 1, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1,
+ 1, 1, 0, 2, 1, 1, 1, 0, 2, 1, 1, 1, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 1, 1, 2, 0, 1, 1, 1, 2, 0, 1, 1, 1, 8, 0,
+ 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 1, 1, 1, 8, 8, 1, 1, 1, 8, 8, 1,
+ 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 1, 1, 1, 2, 2, 1, 1,
+ 1, 2, 2, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1,
+ 0, 2, 1, 1, 1, 0, 2, 1, 1, 1, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
+};
+
+static size_t RtemsSemReqMrspObtain_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsSemReqMrspObtain_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsSemReqMrspObtain_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsSemReqMrspObtain_Fixture = {
+ .setup = RtemsSemReqMrspObtain_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsSemReqMrspObtain_Teardown_Wrap,
+ .scope = RtemsSemReqMrspObtain_Scope,
+ .initial_context = &RtemsSemReqMrspObtain_Instance
+};
+
+static inline RtemsSemReqMrspObtain_Entry RtemsSemReqMrspObtain_PopEntry(
+ RtemsSemReqMrspObtain_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsSemReqMrspObtain_Entries[
+ RtemsSemReqMrspObtain_Map[ index ]
+ ];
+}
+
+static void RtemsSemReqMrspObtain_TestVariant(
+ RtemsSemReqMrspObtain_Context *ctx
+)
+{
+ RtemsSemReqMrspObtain_Pre_Home_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsSemReqMrspObtain_Pre_Helping_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsSemReqMrspObtain_Pre_PriorityHome_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsSemReqMrspObtain_Pre_PriorityHelping_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsSemReqMrspObtain_Action( ctx );
+ RtemsSemReqMrspObtain_Post_Home_Check( ctx, ctx->Map.entry.Post_Home );
+ RtemsSemReqMrspObtain_Post_Helping_Check( ctx, ctx->Map.entry.Post_Helping );
+}
+
+/**
+ * @fn void T_case_body_RtemsSemReqMrspObtain( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsSemReqMrspObtain, &RtemsSemReqMrspObtain_Fixture )
+{
+ RtemsSemReqMrspObtain_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsSemReqMrspObtain_Pre_Home_Idle;
+ ctx->Map.pcs[ 0 ] < RtemsSemReqMrspObtain_Pre_Home_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsSemReqMrspObtain_Pre_Helping_Idle;
+ ctx->Map.pcs[ 1 ] < RtemsSemReqMrspObtain_Pre_Helping_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsSemReqMrspObtain_Pre_PriorityHome_None;
+ ctx->Map.pcs[ 2 ] < RtemsSemReqMrspObtain_Pre_PriorityHome_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsSemReqMrspObtain_Pre_PriorityHelping_None;
+ ctx->Map.pcs[ 3 ] < RtemsSemReqMrspObtain_Pre_PriorityHelping_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ ctx->Map.entry = RtemsSemReqMrspObtain_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsSemReqMrspObtain_Prepare( ctx );
+ RtemsSemReqMrspObtain_TestVariant( ctx );
+ RtemsSemReqMrspObtain_Cleanup( ctx );
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-sem-obtain.c b/testsuites/validation/tc-sem-obtain.c
new file mode 100644
index 0000000000..10c4475d8c
--- /dev/null
+++ b/testsuites/validation/tc-sem-obtain.c
@@ -0,0 +1,733 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSemReqObtain
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+
+#include "tr-mtx-seize-try.h"
+#include "tr-mtx-seize-wait.h"
+#include "tr-sem-seize-try.h"
+#include "tr-sem-seize-wait.h"
+#include "tx-support.h"
+#include "tx-thread-queue.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSemReqObtain spec:/rtems/sem/req/obtain
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsSemReqObtain_Pre_Class_Counting,
+ RtemsSemReqObtain_Pre_Class_Simple,
+ RtemsSemReqObtain_Pre_Class_Binary,
+ RtemsSemReqObtain_Pre_Class_PrioCeiling,
+ RtemsSemReqObtain_Pre_Class_PrioInherit,
+ RtemsSemReqObtain_Pre_Class_MrsP,
+ RtemsSemReqObtain_Pre_Class_NA
+} RtemsSemReqObtain_Pre_Class;
+
+typedef enum {
+ RtemsSemReqObtain_Pre_Discipline_FIFO,
+ RtemsSemReqObtain_Pre_Discipline_Priority,
+ RtemsSemReqObtain_Pre_Discipline_NA
+} RtemsSemReqObtain_Pre_Discipline;
+
+typedef enum {
+ RtemsSemReqObtain_Pre_Id_Valid,
+ RtemsSemReqObtain_Pre_Id_Invalid,
+ RtemsSemReqObtain_Pre_Id_NA
+} RtemsSemReqObtain_Pre_Id;
+
+typedef enum {
+ RtemsSemReqObtain_Pre_Wait_No,
+ RtemsSemReqObtain_Pre_Wait_Timeout,
+ RtemsSemReqObtain_Pre_Wait_Forever,
+ RtemsSemReqObtain_Pre_Wait_NA
+} RtemsSemReqObtain_Pre_Wait;
+
+typedef enum {
+ RtemsSemReqObtain_Post_Action_InvId,
+ RtemsSemReqObtain_Post_Action_SemSeizeTry,
+ RtemsSemReqObtain_Post_Action_SemSeizeWait,
+ RtemsSemReqObtain_Post_Action_MtxSeizeTry,
+ RtemsSemReqObtain_Post_Action_MtxSeizeWait,
+ RtemsSemReqObtain_Post_Action_InheritMtxSeizeTry,
+ RtemsSemReqObtain_Post_Action_InheritMtxSeizeWait,
+ RtemsSemReqObtain_Post_Action_CeilingMtxSeizeTry,
+ RtemsSemReqObtain_Post_Action_CeilingMtxSeizeWait,
+ RtemsSemReqObtain_Post_Action_MrsPMtxSeizeTry,
+ RtemsSemReqObtain_Post_Action_MrsPMtxSeizeWait,
+ RtemsSemReqObtain_Post_Action_NA
+} RtemsSemReqObtain_Post_Action;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Class_NA : 1;
+ uint16_t Pre_Discipline_NA : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_Wait_NA : 1;
+ uint16_t Post_Action : 4;
+} RtemsSemReqObtain_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/sem/req/obtain test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the thread queue test context.
+ */
+ union {
+ TQContext tq_ctx;
+ TQMtxContext tq_mtx_ctx;
+ TQSemContext tq_sem_ctx;
+ };
+
+ /**
+ * @brief This member specifies if the attribute set of the semaphore.
+ */
+ rtems_attribute attribute_set;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 4 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsSemReqObtain_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsSemReqObtain_Context;
+
+static RtemsSemReqObtain_Context
+ RtemsSemReqObtain_Instance;
+
+static const char * const RtemsSemReqObtain_PreDesc_Class[] = {
+ "Counting",
+ "Simple",
+ "Binary",
+ "PrioCeiling",
+ "PrioInherit",
+ "MrsP",
+ "NA"
+};
+
+static const char * const RtemsSemReqObtain_PreDesc_Discipline[] = {
+ "FIFO",
+ "Priority",
+ "NA"
+};
+
+static const char * const RtemsSemReqObtain_PreDesc_Id[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsSemReqObtain_PreDesc_Wait[] = {
+ "No",
+ "Timeout",
+ "Forever",
+ "NA"
+};
+
+static const char * const * const RtemsSemReqObtain_PreDesc[] = {
+ RtemsSemReqObtain_PreDesc_Class,
+ RtemsSemReqObtain_PreDesc_Discipline,
+ RtemsSemReqObtain_PreDesc_Id,
+ RtemsSemReqObtain_PreDesc_Wait,
+ NULL
+};
+
+#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+typedef RtemsSemReqObtain_Context Context;
+
+static void RtemsSemReqObtain_Pre_Class_Prepare(
+ RtemsSemReqObtain_Context *ctx,
+ RtemsSemReqObtain_Pre_Class state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqObtain_Pre_Class_Counting: {
+ /*
+ * While the semaphore object is a counting semaphore.
+ */
+ ctx->attribute_set |= RTEMS_COUNTING_SEMAPHORE;
+ break;
+ }
+
+ case RtemsSemReqObtain_Pre_Class_Simple: {
+ /*
+ * While the semaphore object is a simple binary semaphore.
+ */
+ ctx->attribute_set |= RTEMS_SIMPLE_BINARY_SEMAPHORE;
+ break;
+ }
+
+ case RtemsSemReqObtain_Pre_Class_Binary: {
+ /*
+ * While the semaphore object is a binary semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE;
+ break;
+ }
+
+ case RtemsSemReqObtain_Pre_Class_PrioCeiling: {
+ /*
+ * While the semaphore object is a priority ceiling semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY_CEILING;
+ break;
+ }
+
+ case RtemsSemReqObtain_Pre_Class_PrioInherit: {
+ /*
+ * While the semaphore object is a priority inheritance semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY;
+ break;
+ }
+
+ case RtemsSemReqObtain_Pre_Class_MrsP: {
+ /*
+ * While the semaphore object is a MrsP semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING;
+ break;
+ }
+
+ case RtemsSemReqObtain_Pre_Class_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqObtain_Pre_Discipline_Prepare(
+ RtemsSemReqObtain_Context *ctx,
+ RtemsSemReqObtain_Pre_Discipline state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqObtain_Pre_Discipline_FIFO: {
+ /*
+ * While the semaphore uses the FIFO task wait queue discipline.
+ */
+ ctx->attribute_set |= RTEMS_FIFO;
+ ctx->tq_ctx.discipline = TQ_FIFO;
+ break;
+ }
+
+ case RtemsSemReqObtain_Pre_Discipline_Priority: {
+ /*
+ * While the semaphore uses the priority task wait queue discipline.
+ */
+ ctx->attribute_set |= RTEMS_PRIORITY;
+ ctx->tq_ctx.discipline = TQ_PRIORITY;
+ break;
+ }
+
+ case RtemsSemReqObtain_Pre_Discipline_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqObtain_Pre_Id_Prepare(
+ RtemsSemReqObtain_Context *ctx,
+ RtemsSemReqObtain_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqObtain_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter is associated with the semaphore.
+ */
+ /* Nothing to prepare */
+ break;
+ }
+
+ case RtemsSemReqObtain_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a semaphore.
+ */
+ /* Nothing to prepare */
+ break;
+ }
+
+ case RtemsSemReqObtain_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqObtain_Pre_Wait_Prepare(
+ RtemsSemReqObtain_Context *ctx,
+ RtemsSemReqObtain_Pre_Wait state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqObtain_Pre_Wait_No: {
+ /*
+ * While the ``option_set`` parameter indicates the RTEMS_NO_WAIT option.
+ */
+ ctx->tq_ctx.wait = TQ_NO_WAIT;
+ break;
+ }
+
+ case RtemsSemReqObtain_Pre_Wait_Timeout: {
+ /*
+ * While the ``option_set`` parameter indicates the RTEMS_WAIT option,
+ * while the ``timeout`` parameter is not equal to RTEMS_NO_TIMEOUT.
+ */
+ ctx->tq_ctx.wait = TQ_WAIT_TIMED;
+ break;
+ }
+
+ case RtemsSemReqObtain_Pre_Wait_Forever: {
+ /*
+ * While the ``option_set`` parameter indicates the RTEMS_WAIT option,
+ * while the ``timeout`` parameter is equal to RTEMS_NO_TIMEOUT.
+ */
+ ctx->tq_ctx.wait = TQ_WAIT_FOREVER;
+ break;
+ }
+
+ case RtemsSemReqObtain_Pre_Wait_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqObtain_Post_Action_Check(
+ RtemsSemReqObtain_Context *ctx,
+ RtemsSemReqObtain_Post_Action state
+)
+{
+ rtems_status_code sc;
+
+ switch ( state ) {
+ case RtemsSemReqObtain_Post_Action_InvId: {
+ /*
+ * The return status of rtems_semaphore_obtain() shall be
+ * RTEMS_INVALID_ID.
+ */
+ sc = rtems_semaphore_obtain( 0xffffffff, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
+ T_rsc( sc, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsSemReqObtain_Post_Action_SemSeizeTry: {
+ /*
+ * The calling task shall try to seize the semaphore as specified by
+ * spec:/score/sem/req/seize-try.
+ */
+ ctx->tq_sem_ctx.get_count = TQSemGetCountClassic;
+ ctx->tq_sem_ctx.set_count = TQSemSetCountClassic;
+ ScoreSemReqSeizeTry_Run( &ctx->tq_sem_ctx );
+ break;
+ }
+
+ case RtemsSemReqObtain_Post_Action_SemSeizeWait: {
+ /*
+ * The calling task shall wait to seize the semaphore as specified by
+ * spec:/score/sem/req/seize-wait.
+ */
+ ctx->tq_sem_ctx.get_count = TQSemGetCountClassic;
+ ctx->tq_sem_ctx.set_count = TQSemSetCountClassic;
+ ScoreSemReqSeizeWait_Run( &ctx->tq_sem_ctx );
+ break;
+ }
+
+ case RtemsSemReqObtain_Post_Action_MtxSeizeTry: {
+ /*
+ * The calling task shall try to seize the mutex as specified by
+ * spec:/score/mtx/req/seize-try where an enqueue blocks, a recursive
+ * seize is allowed, and no locking protocol is used.
+ */
+ ctx->tq_mtx_ctx.base.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ ctx->tq_mtx_ctx.protocol = TQ_MTX_NO_PROTOCOL;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
+ ctx->tq_mtx_ctx.priority_ceiling = PRIO_INVALID;
+ ScoreMtxReqSeizeTry_Run( &ctx->tq_mtx_ctx );
+ break;
+ }
+
+ case RtemsSemReqObtain_Post_Action_MtxSeizeWait: {
+ /*
+ * The calling task shall wait to seize the mutex as specified by
+ * spec:/score/mtx/req/seize-wait where an enqueue blocks, a recursive
+ * seize is allowed, and no locking protocol is used.
+ */
+ ctx->tq_mtx_ctx.base.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ ctx->tq_mtx_ctx.protocol = TQ_MTX_NO_PROTOCOL;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
+ ctx->tq_mtx_ctx.priority_ceiling = PRIO_INVALID;
+ ScoreMtxReqSeizeWait_Run( &ctx->tq_mtx_ctx );
+ break;
+ }
+
+ case RtemsSemReqObtain_Post_Action_InheritMtxSeizeTry: {
+ /*
+ * The calling task shall try to seize the mutex as specified by
+ * spec:/score/mtx/req/seize-try where an enqueue blocks, a recursive
+ * seize is allowed, and a priority inheritance protocol is used.
+ */
+ ctx->tq_mtx_ctx.base.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ ctx->tq_mtx_ctx.protocol = TQ_MTX_NO_PROTOCOL;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
+ ctx->tq_mtx_ctx.priority_ceiling = PRIO_INVALID;
+ ScoreMtxReqSeizeTry_Run( &ctx->tq_mtx_ctx );
+ break;
+ }
+
+ case RtemsSemReqObtain_Post_Action_InheritMtxSeizeWait: {
+ /*
+ * The calling task shall wait to seize the mutex as specified by
+ * spec:/score/mtx/req/seize-wait where an enqueue blocks, a recursive
+ * seize is allowed, and a priority inheritance protocol is used.
+ */
+ ctx->tq_mtx_ctx.base.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ ctx->tq_mtx_ctx.protocol = TQ_MTX_NO_PROTOCOL;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
+ ctx->tq_mtx_ctx.priority_ceiling = PRIO_INVALID;
+ ScoreMtxReqSeizeWait_Run( &ctx->tq_mtx_ctx );
+ break;
+ }
+
+ case RtemsSemReqObtain_Post_Action_CeilingMtxSeizeTry: {
+ /*
+ * The calling task shall try to seize the mutex as specified by
+ * spec:/score/mtx/req/seize-try where an enqueue blocks, a recursive
+ * seize is allowed, and a priority ceiling is used.
+ */
+ ctx->tq_mtx_ctx.base.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ ctx->tq_mtx_ctx.protocol = TQ_MTX_PRIORITY_CEILING;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
+ ctx->tq_mtx_ctx.priority_ceiling = PRIO_VERY_HIGH;
+ ScoreMtxReqSeizeTry_Run( &ctx->tq_mtx_ctx );
+ break;
+ }
+
+ case RtemsSemReqObtain_Post_Action_CeilingMtxSeizeWait: {
+ /*
+ * The calling task shall wait to seize the mutex as specified by
+ * spec:/score/mtx/req/seize-wait where an enqueue blocks, a recursive
+ * seize is allowed, and a priority ceiling is used.
+ */
+ ctx->tq_mtx_ctx.base.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ ctx->tq_mtx_ctx.protocol = TQ_MTX_PRIORITY_CEILING;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
+ ctx->tq_mtx_ctx.priority_ceiling = PRIO_VERY_HIGH;
+ ScoreMtxReqSeizeWait_Run( &ctx->tq_mtx_ctx );
+ break;
+ }
+
+ case RtemsSemReqObtain_Post_Action_MrsPMtxSeizeTry: {
+ /*
+ * The calling task shall try to seize the mutex as specified by
+ * spec:/score/mtx/req/seize-try where an enqueue is sticky, a recursive
+ * seize returns an error status, and a priority ceiling is used.
+ */
+ #if defined(RTEMS_SMP)
+ ctx->tq_mtx_ctx.base.enqueue_variant = TQ_ENQUEUE_STICKY;
+ ctx->tq_mtx_ctx.protocol = TQ_MTX_MRSP;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_DEADLOCK;
+ ctx->tq_mtx_ctx.priority_ceiling = PRIO_VERY_HIGH;
+ ScoreMtxReqSeizeTry_Run( &ctx->tq_mtx_ctx );
+ #else
+ T_unreachable();
+ #endif
+ break;
+ }
+
+ case RtemsSemReqObtain_Post_Action_MrsPMtxSeizeWait: {
+ /*
+ * The calling task shall wait to seize the mutex as specified by
+ * spec:/score/mtx/req/seize-wait where an enqueue is sticky, a recursive
+ * seize returns an error status, and a priority ceiling is used.
+ */
+ #if defined(RTEMS_SMP)
+ ctx->tq_mtx_ctx.base.enqueue_variant = TQ_ENQUEUE_STICKY;
+ ctx->tq_mtx_ctx.protocol = TQ_MTX_MRSP;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_DEADLOCK;
+ ctx->tq_mtx_ctx.priority_ceiling = PRIO_VERY_HIGH;
+ ScoreMtxReqSeizeWait_Run( &ctx->tq_mtx_ctx );
+ #else
+ T_unreachable();
+ #endif
+ break;
+ }
+
+ case RtemsSemReqObtain_Post_Action_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqObtain_Setup( RtemsSemReqObtain_Context *ctx )
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->tq_ctx.deadlock = TQ_DEADLOCK_STATUS;
+ ctx->tq_ctx.enqueue_prepare = TQEnqueuePrepareDefault;
+ ctx->tq_ctx.enqueue_done = TQEnqueueDoneDefault;
+ ctx->tq_ctx.enqueue = TQEnqueueClassicSem;
+ ctx->tq_ctx.surrender = TQSurrenderClassicSem;
+ ctx->tq_ctx.get_owner = TQGetOwnerClassicSem;
+ ctx->tq_ctx.convert_status = TQConvertStatusClassic;
+ TQInitialize( &ctx->tq_ctx );
+}
+
+static void RtemsSemReqObtain_Setup_Wrap( void *arg )
+{
+ RtemsSemReqObtain_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSemReqObtain_Setup( ctx );
+}
+
+static void RtemsSemReqObtain_Teardown( RtemsSemReqObtain_Context *ctx )
+{
+ TQDestroy( &ctx->tq_ctx );
+}
+
+static void RtemsSemReqObtain_Teardown_Wrap( void *arg )
+{
+ RtemsSemReqObtain_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSemReqObtain_Teardown( ctx );
+}
+
+static void RtemsSemReqObtain_Prepare( RtemsSemReqObtain_Context *ctx )
+{
+ ctx->attribute_set = RTEMS_DEFAULT_ATTRIBUTES;
+}
+
+static void RtemsSemReqObtain_Action( RtemsSemReqObtain_Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_create(
+ NAME,
+ 1,
+ ctx->attribute_set,
+ PRIO_VERY_HIGH,
+ &ctx->tq_ctx.thread_queue_id
+ );
+ T_rsc_success( sc );
+
+ #if defined(RTEMS_SMP)
+ if ( ( ctx->attribute_set & RTEMS_MULTIPROCESSOR_RESOURCE_SHARING ) != 0 ) {
+ rtems_task_priority prio;
+
+ sc = rtems_semaphore_set_priority(
+ ctx->tq_ctx.thread_queue_id,
+ SCHEDULER_B_ID,
+ PRIO_VERY_HIGH,
+ &prio
+ );
+ T_rsc_success( sc );
+ }
+ #endif
+}
+
+static void RtemsSemReqObtain_Cleanup( RtemsSemReqObtain_Context *ctx )
+{
+ rtems_status_code sc;
+ sc = rtems_semaphore_delete( ctx->tq_ctx.thread_queue_id ); T_rsc_success( sc );
+}
+
+static const RtemsSemReqObtain_Entry
+RtemsSemReqObtain_Entries[] = {
+ { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_InvId },
+ { 1, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_NA },
+ { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_SemSeizeWait },
+ { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_SemSeizeTry },
+ { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_MtxSeizeWait },
+ { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_MtxSeizeTry },
+ { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_CeilingMtxSeizeWait },
+ { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_InheritMtxSeizeWait },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_MrsPMtxSeizeWait },
+#else
+ { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_CeilingMtxSeizeWait },
+#endif
+ { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_CeilingMtxSeizeTry },
+ { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_InheritMtxSeizeTry },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_MrsPMtxSeizeTry }
+#else
+ { 0, 0, 0, 0, 0, RtemsSemReqObtain_Post_Action_CeilingMtxSeizeTry }
+#endif
+};
+
+static const uint8_t
+RtemsSemReqObtain_Map[] = {
+ 3, 2, 2, 0, 0, 0, 3, 2, 2, 0, 0, 0, 3, 2, 2, 0, 0, 0, 3, 2, 2, 0, 0, 0, 5, 4,
+ 4, 0, 0, 0, 5, 4, 4, 0, 0, 0, 1, 1, 1, 1, 1, 1, 9, 6, 6, 0, 0, 0, 1, 1, 1, 1,
+ 1, 1, 10, 7, 7, 0, 0, 0, 1, 1, 1, 1, 1, 1, 11, 8, 8, 0, 0, 0
+};
+
+static size_t RtemsSemReqObtain_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsSemReqObtain_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsSemReqObtain_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsSemReqObtain_Fixture = {
+ .setup = RtemsSemReqObtain_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsSemReqObtain_Teardown_Wrap,
+ .scope = RtemsSemReqObtain_Scope,
+ .initial_context = &RtemsSemReqObtain_Instance
+};
+
+static inline RtemsSemReqObtain_Entry RtemsSemReqObtain_PopEntry(
+ RtemsSemReqObtain_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsSemReqObtain_Entries[
+ RtemsSemReqObtain_Map[ index ]
+ ];
+}
+
+static void RtemsSemReqObtain_TestVariant( RtemsSemReqObtain_Context *ctx )
+{
+ RtemsSemReqObtain_Pre_Class_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsSemReqObtain_Pre_Discipline_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsSemReqObtain_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsSemReqObtain_Pre_Wait_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsSemReqObtain_Action( ctx );
+ RtemsSemReqObtain_Post_Action_Check( ctx, ctx->Map.entry.Post_Action );
+}
+
+/**
+ * @fn void T_case_body_RtemsSemReqObtain( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsSemReqObtain, &RtemsSemReqObtain_Fixture )
+{
+ RtemsSemReqObtain_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsSemReqObtain_Pre_Class_Counting;
+ ctx->Map.pcs[ 0 ] < RtemsSemReqObtain_Pre_Class_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsSemReqObtain_Pre_Discipline_FIFO;
+ ctx->Map.pcs[ 1 ] < RtemsSemReqObtain_Pre_Discipline_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsSemReqObtain_Pre_Id_Valid;
+ ctx->Map.pcs[ 2 ] < RtemsSemReqObtain_Pre_Id_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsSemReqObtain_Pre_Wait_No;
+ ctx->Map.pcs[ 3 ] < RtemsSemReqObtain_Pre_Wait_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ ctx->Map.entry = RtemsSemReqObtain_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsSemReqObtain_Prepare( ctx );
+ RtemsSemReqObtain_TestVariant( ctx );
+ RtemsSemReqObtain_Cleanup( ctx );
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-sem-performance.c b/testsuites/validation/tc-sem-performance.c
new file mode 100644
index 0000000000..5861e3ee8e
--- /dev/null
+++ b/testsuites/validation/tc-sem-performance.c
@@ -0,0 +1,968 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSemValPerf
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSemValPerf spec:/rtems/sem/val/perf
+ *
+ * @ingroup TestsuitesPerformanceNoClock0
+ *
+ * @brief This test case provides a context to run @ref RTEMSAPIClassicSem
+ * performance tests.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/rtems/sem/val/perf test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides a mutex identifier.
+ */
+ rtems_id mutex_id;
+
+ /**
+ * @brief This member provides a worker identifier.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member provides a status code.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member references the measure runtime context.
+ */
+ T_measure_runtime_context *context;
+
+ /**
+ * @brief This member provides the measure runtime request.
+ */
+ T_measure_runtime_request request;
+
+ /**
+ * @brief This member provides an optional measurement begin time point.
+ */
+ T_ticks begin;
+
+ /**
+ * @brief This member provides an optional measurement end time point.
+ */
+ T_ticks end;
+} RtemsSemValPerf_Context;
+
+static RtemsSemValPerf_Context
+ RtemsSemValPerf_Instance;
+
+#define EVENT_END RTEMS_EVENT_0
+
+#define EVENT_OBTAIN RTEMS_EVENT_1
+
+#define EVENT_OBTAIN_END RTEMS_EVENT_2
+
+#define EVENT_RELEASE RTEMS_EVENT_3
+
+#define EVENT_RELEASE_END RTEMS_EVENT_4
+
+typedef RtemsSemValPerf_Context Context;
+
+static void Send( const Context *ctx, rtems_event_set events )
+{
+ SendEvents( ctx->worker_id, events );
+}
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ while ( true ) {
+ rtems_event_set events;
+ rtems_status_code sc;
+ T_ticks ticks;
+
+ sc = rtems_event_receive(
+ RTEMS_ALL_EVENTS,
+ RTEMS_EVENT_ANY | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &events
+ );
+ ticks = T_tick();
+ T_quiet_rsc_success( sc );
+
+ if ( ( events & EVENT_END ) != 0 ) {
+ ctx->end = ticks;
+ }
+
+ if ( ( events & EVENT_OBTAIN ) != 0 ) {
+ sc = rtems_semaphore_obtain(
+ ctx->mutex_id,
+ RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+ ticks = T_tick();
+ T_quiet_rsc_success( sc );
+
+ if ( ( events & EVENT_OBTAIN_END ) != 0 ) {
+ ctx->end = ticks;
+ }
+ }
+
+ if ( ( events & EVENT_RELEASE ) != 0 ) {
+ sc = rtems_semaphore_release( ctx->mutex_id );
+ ticks = T_tick();
+ T_quiet_rsc_success( sc );
+
+ if ( ( events & EVENT_RELEASE_END ) != 0 ) {
+ ctx->end = ticks;
+ }
+ }
+ }
+}
+
+static void RtemsSemValPerf_Setup_Context( RtemsSemValPerf_Context *ctx )
+{
+ T_measure_runtime_config config;
+
+ memset( &config, 0, sizeof( config ) );
+ config.sample_count = 100;
+ ctx->request.arg = ctx;
+ ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES;
+ ctx->context = T_measure_runtime_create( &config );
+ T_assert_not_null( ctx->context );
+}
+
+/**
+ * @brief Create a mutex and a worker task.
+ */
+static void RtemsSemValPerf_Setup( RtemsSemValPerf_Context *ctx )
+{
+ SetSelfPriority( PRIO_NORMAL );
+ ctx->mutex_id = CreateMutex();
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+static void RtemsSemValPerf_Setup_Wrap( void *arg )
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsSemValPerf_Setup_Context( ctx );
+ RtemsSemValPerf_Setup( ctx );
+}
+
+/**
+ * @brief Delete the worker task and the mutex.
+ */
+static void RtemsSemValPerf_Teardown( RtemsSemValPerf_Context *ctx )
+{
+ DeleteTask( ctx->worker_id );
+ DeleteMutex( ctx->mutex_id );
+ RestoreRunnerPriority();
+}
+
+static void RtemsSemValPerf_Teardown_Wrap( void *arg )
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsSemValPerf_Teardown( ctx );
+}
+
+static T_fixture RtemsSemValPerf_Fixture = {
+ .setup = RtemsSemValPerf_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsSemValPerf_Teardown_Wrap,
+ .scope = NULL,
+ .initial_context = &RtemsSemValPerf_Instance
+};
+
+/**
+ * @defgroup RtemsSemReqPerfMtxPiObtain spec:/rtems/sem/req/perf-mtx-pi-obtain
+ *
+ * @{
+ */
+
+/**
+ * @brief Obtain the available mutex.
+ */
+static void RtemsSemReqPerfMtxPiObtain_Body( RtemsSemValPerf_Context *ctx )
+{
+ ctx->status = rtems_semaphore_obtain(
+ ctx->mutex_id,
+ RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+}
+
+static void RtemsSemReqPerfMtxPiObtain_Body_Wrap( void *arg )
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsSemReqPerfMtxPiObtain_Body( ctx );
+}
+
+/**
+ * @brief Release the mutex. Discard samples interrupted by a clock tick.
+ */
+static bool RtemsSemReqPerfMtxPiObtain_Teardown(
+ RtemsSemValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ ReleaseMutex( ctx->mutex_id );
+
+ return tic == toc;
+}
+
+static bool RtemsSemReqPerfMtxPiObtain_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsSemReqPerfMtxPiObtain_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/** @} */
+
+/**
+ * @defgroup RtemsSemReqPerfMtxPiRelease \
+ * spec:/rtems/sem/req/perf-mtx-pi-release
+ *
+ * @{
+ */
+
+/**
+ * @brief Obtain the mutex.
+ */
+static void RtemsSemReqPerfMtxPiRelease_Setup( RtemsSemValPerf_Context *ctx )
+{
+ ObtainMutex( ctx->mutex_id );
+}
+
+static void RtemsSemReqPerfMtxPiRelease_Setup_Wrap( void *arg )
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsSemReqPerfMtxPiRelease_Setup( ctx );
+}
+
+/**
+ * @brief Release the mutex.
+ */
+static void RtemsSemReqPerfMtxPiRelease_Body( RtemsSemValPerf_Context *ctx )
+{
+ ctx->status = rtems_semaphore_release( ctx->mutex_id );
+}
+
+static void RtemsSemReqPerfMtxPiRelease_Body_Wrap( void *arg )
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsSemReqPerfMtxPiRelease_Body( ctx );
+}
+
+/**
+ * @brief Discard samples interrupted by a clock tick.
+ */
+static bool RtemsSemReqPerfMtxPiRelease_Teardown(
+ RtemsSemValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ return tic == toc;
+}
+
+static bool RtemsSemReqPerfMtxPiRelease_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsSemReqPerfMtxPiRelease_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/** @} */
+
+/**
+ * @defgroup RtemsSemReqPerfMtxPiReleaseOne \
+ * spec:/rtems/sem/req/perf-mtx-pi-release-one
+ *
+ * @{
+ */
+
+/**
+ * @brief Let one task wait on the mutex.
+ */
+static void RtemsSemReqPerfMtxPiReleaseOne_Setup(
+ RtemsSemValPerf_Context *ctx
+)
+{
+ SetSelfPriority( PRIO_HIGH );
+ ObtainMutex( ctx->mutex_id );
+ Send( ctx, EVENT_OBTAIN );
+ Yield();
+ Send( ctx, EVENT_RELEASE );
+}
+
+static void RtemsSemReqPerfMtxPiReleaseOne_Setup_Wrap( void *arg )
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsSemReqPerfMtxPiReleaseOne_Setup( ctx );
+}
+
+/**
+ * @brief Release the mutex.
+ */
+static void RtemsSemReqPerfMtxPiReleaseOne_Body( RtemsSemValPerf_Context *ctx )
+{
+ /*
+ * The release will unblock the worker task which has our priority. The
+ * scheduler ensures FIFO ordering for ready threads of the same priority, so
+ * the release will not preempt us.
+ */
+ ctx->status = rtems_semaphore_release( ctx->mutex_id );
+}
+
+static void RtemsSemReqPerfMtxPiReleaseOne_Body_Wrap( void *arg )
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsSemReqPerfMtxPiReleaseOne_Body( ctx );
+}
+
+/**
+ * @brief Restore the worker priority. Discard samples interrupted by a clock
+ * tick.
+ */
+static bool RtemsSemReqPerfMtxPiReleaseOne_Teardown(
+ RtemsSemValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc( ctx->status, RTEMS_SUCCESSFUL );
+
+ SetSelfPriority( PRIO_NORMAL );
+
+ return tic == toc;
+}
+
+static bool RtemsSemReqPerfMtxPiReleaseOne_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsSemReqPerfMtxPiReleaseOne_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/** @} */
+
+#if defined(RTEMS_SMP)
+/**
+ * @defgroup RtemsSemReqPerfMtxPiReleaseOtherCpu \
+ * spec:/rtems/sem/req/perf-mtx-pi-release-other-cpu
+ *
+ * @{
+ */
+
+/**
+ * @brief Move worker to scheduler B.
+ */
+static void RtemsSemReqPerfMtxPiReleaseOtherCpu_Prepare(
+ RtemsSemValPerf_Context *ctx
+)
+{
+ SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+}
+
+/**
+ * @brief Let one task wait on the mutex.
+ */
+static void RtemsSemReqPerfMtxPiReleaseOtherCpu_Setup(
+ RtemsSemValPerf_Context *ctx
+)
+{
+ ObtainMutex( ctx->mutex_id );
+ Send( ctx, EVENT_OBTAIN | EVENT_OBTAIN_END | EVENT_RELEASE );
+ WaitForNextTask( 1, ctx->worker_id );
+}
+
+static void RtemsSemReqPerfMtxPiReleaseOtherCpu_Setup_Wrap( void *arg )
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsSemReqPerfMtxPiReleaseOtherCpu_Setup( ctx );
+}
+
+/**
+ * @brief Release the mutex.
+ */
+static void RtemsSemReqPerfMtxPiReleaseOtherCpu_Body(
+ RtemsSemValPerf_Context *ctx
+)
+{
+ ctx->begin = T_tick();
+ ctx->status = rtems_semaphore_release( ctx->mutex_id );
+}
+
+static void RtemsSemReqPerfMtxPiReleaseOtherCpu_Body_Wrap( void *arg )
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsSemReqPerfMtxPiReleaseOtherCpu_Body( ctx );
+}
+
+/**
+ * @brief Make sure the worker waits for the next event. Set the measured
+ * runtime. Discard samples interrupted by a clock tick.
+ */
+static bool RtemsSemReqPerfMtxPiReleaseOtherCpu_Teardown(
+ RtemsSemValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc( ctx->status, RTEMS_SUCCESSFUL );
+
+ WaitForNextTask( 1, ctx->worker_id );
+ *delta = ctx->end - ctx->begin;
+
+ return tic == toc;
+}
+
+static bool RtemsSemReqPerfMtxPiReleaseOtherCpu_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsSemReqPerfMtxPiReleaseOtherCpu_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/**
+ * @brief Move worker to scheduler A.
+ */
+static void RtemsSemReqPerfMtxPiReleaseOtherCpu_Cleanup(
+ RtemsSemValPerf_Context *ctx
+)
+{
+ SetScheduler( ctx->worker_id, SCHEDULER_A_ID, PRIO_HIGH );
+}
+
+/** @} */
+#endif
+
+/**
+ * @defgroup RtemsSemReqPerfMtxPiReleasePreempt \
+ * spec:/rtems/sem/req/perf-mtx-pi-release-preempt
+ *
+ * @{
+ */
+
+/**
+ * @brief Let one task wait on the mutex.
+ */
+static void RtemsSemReqPerfMtxPiReleasePreempt_Setup(
+ RtemsSemValPerf_Context *ctx
+)
+{
+ ObtainMutex( ctx->mutex_id );
+ Send( ctx, EVENT_OBTAIN | EVENT_OBTAIN_END | EVENT_RELEASE );
+}
+
+static void RtemsSemReqPerfMtxPiReleasePreempt_Setup_Wrap( void *arg )
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsSemReqPerfMtxPiReleasePreempt_Setup( ctx );
+}
+
+/**
+ * @brief Release the mutex.
+ */
+static void RtemsSemReqPerfMtxPiReleasePreempt_Body(
+ RtemsSemValPerf_Context *ctx
+)
+{
+ ctx->begin = T_tick();
+ ctx->status = rtems_semaphore_release( ctx->mutex_id );
+}
+
+static void RtemsSemReqPerfMtxPiReleasePreempt_Body_Wrap( void *arg )
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsSemReqPerfMtxPiReleasePreempt_Body( ctx );
+}
+
+/**
+ * @brief Set the measured runtime. Discard samples interrupted by a clock
+ * tick.
+ */
+static bool RtemsSemReqPerfMtxPiReleasePreempt_Teardown(
+ RtemsSemValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc( ctx->status, RTEMS_SUCCESSFUL );
+
+ *delta = ctx->end - ctx->begin;
+
+ return tic == toc;
+}
+
+static bool RtemsSemReqPerfMtxPiReleasePreempt_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsSemReqPerfMtxPiReleasePreempt_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/** @} */
+
+/**
+ * @defgroup RtemsSemReqPerfMtxPiTry spec:/rtems/sem/req/perf-mtx-pi-try
+ *
+ * @{
+ */
+
+/**
+ * @brief Make the mutex unavailable.
+ */
+static void RtemsSemReqPerfMtxPiTry_Prepare( RtemsSemValPerf_Context *ctx )
+{
+ Send( ctx, EVENT_OBTAIN );
+}
+
+/**
+ * @brief Try to obtain the unavailable mutex.
+ */
+static void RtemsSemReqPerfMtxPiTry_Body( RtemsSemValPerf_Context *ctx )
+{
+ ctx->status = rtems_semaphore_obtain( ctx->mutex_id, RTEMS_NO_WAIT, 0 );
+}
+
+static void RtemsSemReqPerfMtxPiTry_Body_Wrap( void *arg )
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsSemReqPerfMtxPiTry_Body( ctx );
+}
+
+/**
+ * @brief Discard samples interrupted by a clock tick.
+ */
+static bool RtemsSemReqPerfMtxPiTry_Teardown(
+ RtemsSemValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc( ctx->status, RTEMS_UNSATISFIED );
+
+ return tic == toc;
+}
+
+static bool RtemsSemReqPerfMtxPiTry_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsSemReqPerfMtxPiTry_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/**
+ * @brief Make the mutex available.
+ */
+static void RtemsSemReqPerfMtxPiTry_Cleanup( RtemsSemValPerf_Context *ctx )
+{
+ Send( ctx, EVENT_RELEASE );
+}
+
+/** @} */
+
+/**
+ * @defgroup RtemsSemReqPerfMtxPiWaitForever \
+ * spec:/rtems/sem/req/perf-mtx-pi-wait-forever
+ *
+ * @{
+ */
+
+/**
+ * @brief Make the mutex unavailable.
+ */
+static void RtemsSemReqPerfMtxPiWaitForever_Setup(
+ RtemsSemValPerf_Context *ctx
+)
+{
+ Send( ctx, EVENT_OBTAIN );
+ SetSelfPriority( PRIO_VERY_HIGH );
+ Send( ctx, EVENT_END | EVENT_RELEASE );
+}
+
+static void RtemsSemReqPerfMtxPiWaitForever_Setup_Wrap( void *arg )
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsSemReqPerfMtxPiWaitForever_Setup( ctx );
+}
+
+/**
+ * @brief Obtain the unavailable mutex and wait forever.
+ */
+static void RtemsSemReqPerfMtxPiWaitForever_Body(
+ RtemsSemValPerf_Context *ctx
+)
+{
+ ctx->begin = T_tick();
+ ctx->status = rtems_semaphore_obtain(
+ ctx->mutex_id,
+ RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+}
+
+static void RtemsSemReqPerfMtxPiWaitForever_Body_Wrap( void *arg )
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsSemReqPerfMtxPiWaitForever_Body( ctx );
+}
+
+/**
+ * @brief Set the measured runtime. Restore the worker priority. Release the
+ * mutex. Discard samples interrupted by a clock tick.
+ */
+static bool RtemsSemReqPerfMtxPiWaitForever_Teardown(
+ RtemsSemValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc( ctx->status, RTEMS_SUCCESSFUL );
+
+ *delta = ctx->end - ctx->begin;
+ ReleaseMutex( ctx->mutex_id );
+ SetSelfPriority( PRIO_NORMAL );
+
+ return tic == toc;
+}
+
+static bool RtemsSemReqPerfMtxPiWaitForever_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsSemReqPerfMtxPiWaitForever_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/** @} */
+
+/**
+ * @defgroup RtemsSemReqPerfMtxPiWaitTimed \
+ * spec:/rtems/sem/req/perf-mtx-pi-wait-timed
+ *
+ * @{
+ */
+
+/**
+ * @brief Make the mutex unavailable.
+ */
+static void RtemsSemReqPerfMtxPiWaitTimed_Setup( RtemsSemValPerf_Context *ctx )
+{
+ Send( ctx, EVENT_OBTAIN );
+ SetSelfPriority( PRIO_VERY_HIGH );
+ Send( ctx, EVENT_END | EVENT_RELEASE );
+}
+
+static void RtemsSemReqPerfMtxPiWaitTimed_Setup_Wrap( void *arg )
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsSemReqPerfMtxPiWaitTimed_Setup( ctx );
+}
+
+/**
+ * @brief Obtain the unavailable mutex and wait forever.
+ */
+static void RtemsSemReqPerfMtxPiWaitTimed_Body( RtemsSemValPerf_Context *ctx )
+{
+ ctx->begin = T_tick();
+ ctx->status = rtems_semaphore_obtain(
+ ctx->mutex_id,
+ RTEMS_WAIT,
+ UINT32_MAX
+ );
+}
+
+static void RtemsSemReqPerfMtxPiWaitTimed_Body_Wrap( void *arg )
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsSemReqPerfMtxPiWaitTimed_Body( ctx );
+}
+
+/**
+ * @brief Set the measured runtime. Restore the worker priority. Release the
+ * mutex. Discard samples interrupted by a clock tick.
+ */
+static bool RtemsSemReqPerfMtxPiWaitTimed_Teardown(
+ RtemsSemValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc( ctx->status, RTEMS_SUCCESSFUL );
+
+ *delta = ctx->end - ctx->begin;
+ ReleaseMutex( ctx->mutex_id );
+ SetSelfPriority( PRIO_NORMAL );
+
+ return tic == toc;
+}
+
+static bool RtemsSemReqPerfMtxPiWaitTimed_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsSemReqPerfMtxPiWaitTimed_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/** @} */
+
+/**
+ * @fn void T_case_body_RtemsSemValPerf( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsSemValPerf, &RtemsSemValPerf_Fixture )
+{
+ RtemsSemValPerf_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ ctx->request.name = "RtemsSemReqPerfMtxPiObtain";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsSemReqPerfMtxPiObtain_Body_Wrap;
+ ctx->request.teardown = RtemsSemReqPerfMtxPiObtain_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ ctx->request.name = "RtemsSemReqPerfMtxPiRelease";
+ ctx->request.setup = RtemsSemReqPerfMtxPiRelease_Setup_Wrap;
+ ctx->request.body = RtemsSemReqPerfMtxPiRelease_Body_Wrap;
+ ctx->request.teardown = RtemsSemReqPerfMtxPiRelease_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ ctx->request.name = "RtemsSemReqPerfMtxPiReleaseOne";
+ ctx->request.setup = RtemsSemReqPerfMtxPiReleaseOne_Setup_Wrap;
+ ctx->request.body = RtemsSemReqPerfMtxPiReleaseOne_Body_Wrap;
+ ctx->request.teardown = RtemsSemReqPerfMtxPiReleaseOne_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ #if defined(RTEMS_SMP)
+ RtemsSemReqPerfMtxPiReleaseOtherCpu_Prepare( ctx );
+ ctx->request.name = "RtemsSemReqPerfMtxPiReleaseOtherCpu";
+ ctx->request.setup = RtemsSemReqPerfMtxPiReleaseOtherCpu_Setup_Wrap;
+ ctx->request.body = RtemsSemReqPerfMtxPiReleaseOtherCpu_Body_Wrap;
+ ctx->request.teardown = RtemsSemReqPerfMtxPiReleaseOtherCpu_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsSemReqPerfMtxPiReleaseOtherCpu_Cleanup( ctx );
+ #endif
+
+ ctx->request.name = "RtemsSemReqPerfMtxPiReleasePreempt";
+ ctx->request.setup = RtemsSemReqPerfMtxPiReleasePreempt_Setup_Wrap;
+ ctx->request.body = RtemsSemReqPerfMtxPiReleasePreempt_Body_Wrap;
+ ctx->request.teardown = RtemsSemReqPerfMtxPiReleasePreempt_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ RtemsSemReqPerfMtxPiTry_Prepare( ctx );
+ ctx->request.name = "RtemsSemReqPerfMtxPiTry";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsSemReqPerfMtxPiTry_Body_Wrap;
+ ctx->request.teardown = RtemsSemReqPerfMtxPiTry_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsSemReqPerfMtxPiTry_Cleanup( ctx );
+
+ ctx->request.name = "RtemsSemReqPerfMtxPiWaitForever";
+ ctx->request.setup = RtemsSemReqPerfMtxPiWaitForever_Setup_Wrap;
+ ctx->request.body = RtemsSemReqPerfMtxPiWaitForever_Body_Wrap;
+ ctx->request.teardown = RtemsSemReqPerfMtxPiWaitForever_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ ctx->request.name = "RtemsSemReqPerfMtxPiWaitTimed";
+ ctx->request.setup = RtemsSemReqPerfMtxPiWaitTimed_Setup_Wrap;
+ ctx->request.body = RtemsSemReqPerfMtxPiWaitTimed_Body_Wrap;
+ ctx->request.teardown = RtemsSemReqPerfMtxPiWaitTimed_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-sem-release.c b/testsuites/validation/tc-sem-release.c
new file mode 100644
index 0000000000..1e9c2091c0
--- /dev/null
+++ b/testsuites/validation/tc-sem-release.c
@@ -0,0 +1,615 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSemReqRelease
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+
+#include "tr-mtx-surrender.h"
+#include "tr-sem-surrender.h"
+#include "tx-support.h"
+#include "tx-thread-queue.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSemReqRelease spec:/rtems/sem/req/release
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsSemReqRelease_Pre_Class_Counting,
+ RtemsSemReqRelease_Pre_Class_Simple,
+ RtemsSemReqRelease_Pre_Class_Binary,
+ RtemsSemReqRelease_Pre_Class_PrioCeiling,
+ RtemsSemReqRelease_Pre_Class_PrioInherit,
+ RtemsSemReqRelease_Pre_Class_MrsP,
+ RtemsSemReqRelease_Pre_Class_NA
+} RtemsSemReqRelease_Pre_Class;
+
+typedef enum {
+ RtemsSemReqRelease_Pre_Discipline_FIFO,
+ RtemsSemReqRelease_Pre_Discipline_Priority,
+ RtemsSemReqRelease_Pre_Discipline_NA
+} RtemsSemReqRelease_Pre_Discipline;
+
+typedef enum {
+ RtemsSemReqRelease_Pre_Id_Valid,
+ RtemsSemReqRelease_Pre_Id_Invalid,
+ RtemsSemReqRelease_Pre_Id_NA
+} RtemsSemReqRelease_Pre_Id;
+
+typedef enum {
+ RtemsSemReqRelease_Post_Action_InvId,
+ RtemsSemReqRelease_Post_Action_BinarySurrender,
+ RtemsSemReqRelease_Post_Action_CountingSurrender,
+ RtemsSemReqRelease_Post_Action_MtxSurrender,
+ RtemsSemReqRelease_Post_Action_InheritMtxSurrender,
+ RtemsSemReqRelease_Post_Action_CeilingMtxSurrender,
+ RtemsSemReqRelease_Post_Action_MrsPMtxSurrender,
+ RtemsSemReqRelease_Post_Action_NA
+} RtemsSemReqRelease_Post_Action;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Class_NA : 1;
+ uint8_t Pre_Discipline_NA : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Post_Action : 3;
+} RtemsSemReqRelease_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/sem/req/release test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the thread queue test context.
+ */
+ union {
+ TQContext tq_ctx;
+ TQMtxContext tq_mtx_ctx;
+ TQSemContext tq_sem_ctx;
+ };
+
+ /**
+ * @brief This member specifies if the attribute set of the semaphore.
+ */
+ rtems_attribute attribute_set;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsSemReqRelease_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsSemReqRelease_Context;
+
+static RtemsSemReqRelease_Context
+ RtemsSemReqRelease_Instance;
+
+static const char * const RtemsSemReqRelease_PreDesc_Class[] = {
+ "Counting",
+ "Simple",
+ "Binary",
+ "PrioCeiling",
+ "PrioInherit",
+ "MrsP",
+ "NA"
+};
+
+static const char * const RtemsSemReqRelease_PreDesc_Discipline[] = {
+ "FIFO",
+ "Priority",
+ "NA"
+};
+
+static const char * const RtemsSemReqRelease_PreDesc_Id[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const * const RtemsSemReqRelease_PreDesc[] = {
+ RtemsSemReqRelease_PreDesc_Class,
+ RtemsSemReqRelease_PreDesc_Discipline,
+ RtemsSemReqRelease_PreDesc_Id,
+ NULL
+};
+
+#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+typedef RtemsSemReqRelease_Context Context;
+
+static void RtemsSemReqRelease_Pre_Class_Prepare(
+ RtemsSemReqRelease_Context *ctx,
+ RtemsSemReqRelease_Pre_Class state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqRelease_Pre_Class_Counting: {
+ /*
+ * While the semaphore object is a counting semaphore.
+ */
+ ctx->attribute_set |= RTEMS_COUNTING_SEMAPHORE;
+ break;
+ }
+
+ case RtemsSemReqRelease_Pre_Class_Simple: {
+ /*
+ * While the semaphore object is a simple binary semaphore.
+ */
+ ctx->attribute_set |= RTEMS_SIMPLE_BINARY_SEMAPHORE;
+ break;
+ }
+
+ case RtemsSemReqRelease_Pre_Class_Binary: {
+ /*
+ * While the semaphore object is a binary semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE;
+ break;
+ }
+
+ case RtemsSemReqRelease_Pre_Class_PrioCeiling: {
+ /*
+ * While the semaphore object is a priority ceiling semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY_CEILING;
+ break;
+ }
+
+ case RtemsSemReqRelease_Pre_Class_PrioInherit: {
+ /*
+ * While the semaphore object is a priority inheritance semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY;
+ break;
+ }
+
+ case RtemsSemReqRelease_Pre_Class_MrsP: {
+ /*
+ * While the semaphore object is a MrsP semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING;
+ break;
+ }
+
+ case RtemsSemReqRelease_Pre_Class_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqRelease_Pre_Discipline_Prepare(
+ RtemsSemReqRelease_Context *ctx,
+ RtemsSemReqRelease_Pre_Discipline state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqRelease_Pre_Discipline_FIFO: {
+ /*
+ * While the semaphore uses the FIFO task wait queue discipline.
+ */
+ ctx->attribute_set |= RTEMS_FIFO;
+ ctx->tq_ctx.discipline = TQ_FIFO;
+ break;
+ }
+
+ case RtemsSemReqRelease_Pre_Discipline_Priority: {
+ /*
+ * While the semaphore uses the priority task wait queue discipline.
+ */
+ ctx->attribute_set |= RTEMS_PRIORITY;
+ ctx->tq_ctx.discipline = TQ_PRIORITY;
+ break;
+ }
+
+ case RtemsSemReqRelease_Pre_Discipline_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqRelease_Pre_Id_Prepare(
+ RtemsSemReqRelease_Context *ctx,
+ RtemsSemReqRelease_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqRelease_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter is associated with the semaphore.
+ */
+ /* Nothing to prepare */
+ break;
+ }
+
+ case RtemsSemReqRelease_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a semaphore.
+ */
+ /* Nothing to prepare */
+ break;
+ }
+
+ case RtemsSemReqRelease_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqRelease_Post_Action_Check(
+ RtemsSemReqRelease_Context *ctx,
+ RtemsSemReqRelease_Post_Action state
+)
+{
+ rtems_status_code sc;
+
+ switch ( state ) {
+ case RtemsSemReqRelease_Post_Action_InvId: {
+ /*
+ * The return status of rtems_semaphore_release() shall be
+ * RTEMS_INVALID_ID.
+ */
+ sc = rtems_semaphore_release( 0xffffffff );
+ T_rsc( sc, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsSemReqRelease_Post_Action_BinarySurrender: {
+ /*
+ * The calling task shall surrender the binary semaphore as specified by
+ * spec:/score/sem/req/surrender.
+ */
+ ctx->tq_ctx.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ ctx->tq_ctx.get_owner = NULL;
+ ctx->tq_sem_ctx.variant = TQ_SEM_BINARY;
+ ctx->tq_sem_ctx.get_count = TQSemGetCountClassic;
+ ctx->tq_sem_ctx.set_count = TQSemSetCountClassic;
+ ScoreSemReqSurrender_Run( &ctx->tq_sem_ctx );
+ break;
+ }
+
+ case RtemsSemReqRelease_Post_Action_CountingSurrender: {
+ /*
+ * The calling task shall surrender the counting semaphore as specified
+ * by spec:/score/sem/req/surrender.
+ */
+ ctx->tq_ctx.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ ctx->tq_ctx.get_owner = NULL;
+ ctx->tq_sem_ctx.variant = TQ_SEM_COUNTING;
+ ctx->tq_sem_ctx.get_count = TQSemGetCountClassic;
+ ctx->tq_sem_ctx.set_count = TQSemSetCountClassic;
+ ScoreSemReqSurrender_Run( &ctx->tq_sem_ctx );
+ break;
+ }
+
+ case RtemsSemReqRelease_Post_Action_MtxSurrender: {
+ /*
+ * The calling task shall surrender the mutex as specified by
+ * spec:/score/mtx/req/surrender where an enqueue blocks, a recursive
+ * seize is allowed, the owner is checked, and no locking protocol is
+ * used.
+ */
+ ctx->tq_ctx.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ ctx->tq_ctx.get_owner = TQGetOwnerClassicSem;
+ ctx->tq_mtx_ctx.protocol = TQ_MTX_NO_PROTOCOL;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
+ ctx->tq_mtx_ctx.owner_check = TQ_MTX_CHECKS_OWNER;
+ ctx->tq_mtx_ctx.priority_ceiling = PRIO_INVALID;
+ ScoreMtxReqSurrender_Run( &ctx->tq_mtx_ctx );
+ break;
+ }
+
+ case RtemsSemReqRelease_Post_Action_InheritMtxSurrender: {
+ /*
+ * The calling task shall surrender the mutex as specified by
+ * spec:/score/mtx/req/surrender where an enqueue blocks, a recursive
+ * seize is allowed, the owner is checked, and a priority inheritance
+ * protocol is used.
+ */
+ ctx->tq_ctx.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ ctx->tq_ctx.get_owner = TQGetOwnerClassicSem;
+ ctx->tq_mtx_ctx.protocol = TQ_MTX_PRIORITY_INHERIT;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
+ ctx->tq_mtx_ctx.owner_check = TQ_MTX_CHECKS_OWNER;
+ ctx->tq_mtx_ctx.priority_ceiling = PRIO_INVALID;
+ ScoreMtxReqSurrender_Run( &ctx->tq_mtx_ctx );
+ break;
+ }
+
+ case RtemsSemReqRelease_Post_Action_CeilingMtxSurrender: {
+ /*
+ * The calling task shall surrender the mutex as specified by
+ * spec:/score/mtx/req/surrender where an enqueue blocks, a recursive
+ * seize is allowed, the owner is checked, and a priority ceiling is
+ * used.
+ */
+ ctx->tq_ctx.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ ctx->tq_ctx.get_owner = TQGetOwnerClassicSem;
+ ctx->tq_mtx_ctx.protocol = TQ_MTX_PRIORITY_CEILING;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
+ ctx->tq_mtx_ctx.owner_check = TQ_MTX_CHECKS_OWNER;
+ ctx->tq_mtx_ctx.priority_ceiling = PRIO_VERY_HIGH;
+ ScoreMtxReqSurrender_Run( &ctx->tq_mtx_ctx );
+ break;
+ }
+
+ case RtemsSemReqRelease_Post_Action_MrsPMtxSurrender: {
+ /*
+ * The calling task shall surrender the mutex as specified by
+ * spec:/score/mtx/req/surrender where an enqueue is sticky, a recursive
+ * seize returns an error status, the owner is checked, and a priority
+ * ceiling is used.
+ */
+ ctx->tq_ctx.enqueue_variant = TQ_ENQUEUE_STICKY;
+ ctx->tq_ctx.get_owner = TQGetOwnerClassicSem;
+ ctx->tq_mtx_ctx.protocol = TQ_MTX_MRSP;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_DEADLOCK;
+ ctx->tq_mtx_ctx.owner_check = TQ_MTX_CHECKS_OWNER;
+ ctx->tq_mtx_ctx.priority_ceiling = PRIO_VERY_HIGH;
+ ScoreMtxReqSurrender_Run( &ctx->tq_mtx_ctx );
+ break;
+ }
+
+ case RtemsSemReqRelease_Post_Action_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqRelease_Setup( RtemsSemReqRelease_Context *ctx )
+{
+ SetSelfPriority( PRIO_NORMAL );
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->tq_ctx.deadlock = TQ_DEADLOCK_STATUS;
+ ctx->tq_ctx.enqueue_prepare = TQEnqueuePrepareDefault;
+ ctx->tq_ctx.enqueue_done = TQEnqueueDoneDefault;
+ ctx->tq_ctx.enqueue = TQEnqueueClassicSem;
+ ctx->tq_ctx.surrender = TQSurrenderClassicSem;
+ ctx->tq_ctx.convert_status = TQConvertStatusClassic;
+ TQInitialize( &ctx->tq_ctx );
+}
+
+static void RtemsSemReqRelease_Setup_Wrap( void *arg )
+{
+ RtemsSemReqRelease_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSemReqRelease_Setup( ctx );
+}
+
+static void RtemsSemReqRelease_Teardown( RtemsSemReqRelease_Context *ctx )
+{
+ TQDestroy( &ctx->tq_ctx );
+ RestoreRunnerPriority();
+}
+
+static void RtemsSemReqRelease_Teardown_Wrap( void *arg )
+{
+ RtemsSemReqRelease_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSemReqRelease_Teardown( ctx );
+}
+
+static void RtemsSemReqRelease_Prepare( RtemsSemReqRelease_Context *ctx )
+{
+ ctx->attribute_set = RTEMS_DEFAULT_ATTRIBUTES;
+}
+
+static void RtemsSemReqRelease_Action( RtemsSemReqRelease_Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_create(
+ NAME,
+ 1,
+ ctx->attribute_set,
+ PRIO_VERY_HIGH,
+ &ctx->tq_ctx.thread_queue_id
+ );
+ T_rsc_success( sc );
+
+ if ( ( ctx->attribute_set & RTEMS_MULTIPROCESSOR_RESOURCE_SHARING ) != 0 ) {
+ rtems_task_priority prio;
+
+ sc = rtems_semaphore_set_priority(
+ ctx->tq_ctx.thread_queue_id,
+ SCHEDULER_B_ID,
+ PRIO_VERY_HIGH,
+ &prio
+ );
+ T_rsc_success( sc );
+ }
+}
+
+static void RtemsSemReqRelease_Cleanup( RtemsSemReqRelease_Context *ctx )
+{
+ rtems_status_code sc;
+ sc = rtems_semaphore_delete( ctx->tq_ctx.thread_queue_id ); T_rsc_success( sc );
+}
+
+static const RtemsSemReqRelease_Entry
+RtemsSemReqRelease_Entries[] = {
+ { 0, 0, 0, 0, RtemsSemReqRelease_Post_Action_InvId },
+ { 1, 0, 0, 0, RtemsSemReqRelease_Post_Action_NA },
+ { 0, 0, 0, 0, RtemsSemReqRelease_Post_Action_CountingSurrender },
+ { 0, 0, 0, 0, RtemsSemReqRelease_Post_Action_BinarySurrender },
+ { 0, 0, 0, 0, RtemsSemReqRelease_Post_Action_MtxSurrender },
+ { 0, 0, 0, 0, RtemsSemReqRelease_Post_Action_CeilingMtxSurrender },
+ { 0, 0, 0, 0, RtemsSemReqRelease_Post_Action_InheritMtxSurrender },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, RtemsSemReqRelease_Post_Action_MrsPMtxSurrender },
+#else
+ { 1, 0, 0, 0, RtemsSemReqRelease_Post_Action_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, RtemsSemReqRelease_Post_Action_InvId }
+#else
+ { 1, 0, 0, 0, RtemsSemReqRelease_Post_Action_NA }
+#endif
+};
+
+static const uint8_t
+RtemsSemReqRelease_Map[] = {
+ 2, 0, 2, 0, 3, 0, 3, 0, 4, 0, 4, 0, 1, 1, 5, 0, 1, 1, 6, 0, 1, 1, 7, 8
+};
+
+static size_t RtemsSemReqRelease_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsSemReqRelease_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsSemReqRelease_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsSemReqRelease_Fixture = {
+ .setup = RtemsSemReqRelease_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsSemReqRelease_Teardown_Wrap,
+ .scope = RtemsSemReqRelease_Scope,
+ .initial_context = &RtemsSemReqRelease_Instance
+};
+
+static inline RtemsSemReqRelease_Entry RtemsSemReqRelease_PopEntry(
+ RtemsSemReqRelease_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsSemReqRelease_Entries[
+ RtemsSemReqRelease_Map[ index ]
+ ];
+}
+
+static void RtemsSemReqRelease_TestVariant( RtemsSemReqRelease_Context *ctx )
+{
+ RtemsSemReqRelease_Pre_Class_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsSemReqRelease_Pre_Discipline_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsSemReqRelease_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsSemReqRelease_Action( ctx );
+ RtemsSemReqRelease_Post_Action_Check( ctx, ctx->Map.entry.Post_Action );
+}
+
+/**
+ * @fn void T_case_body_RtemsSemReqRelease( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsSemReqRelease, &RtemsSemReqRelease_Fixture )
+{
+ RtemsSemReqRelease_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsSemReqRelease_Pre_Class_Counting;
+ ctx->Map.pcs[ 0 ] < RtemsSemReqRelease_Pre_Class_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsSemReqRelease_Pre_Discipline_FIFO;
+ ctx->Map.pcs[ 1 ] < RtemsSemReqRelease_Pre_Discipline_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsSemReqRelease_Pre_Id_Valid;
+ ctx->Map.pcs[ 2 ] < RtemsSemReqRelease_Pre_Id_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ ctx->Map.entry = RtemsSemReqRelease_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsSemReqRelease_Prepare( ctx );
+ RtemsSemReqRelease_TestVariant( ctx );
+ RtemsSemReqRelease_Cleanup( ctx );
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-sem-set-priority.c b/testsuites/validation/tc-sem-set-priority.c
new file mode 100644
index 0000000000..fc4501b6fa
--- /dev/null
+++ b/testsuites/validation/tc-sem-set-priority.c
@@ -0,0 +1,1136 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSemReqSetPriority
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSemReqSetPriority spec:/rtems/sem/req/set-priority
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsSemReqSetPriority_Pre_Class_Counting,
+ RtemsSemReqSetPriority_Pre_Class_Simple,
+ RtemsSemReqSetPriority_Pre_Class_Binary,
+ RtemsSemReqSetPriority_Pre_Class_PrioCeilingNoOwner,
+ RtemsSemReqSetPriority_Pre_Class_PrioCeilingOwner,
+ RtemsSemReqSetPriority_Pre_Class_PrioInherit,
+ RtemsSemReqSetPriority_Pre_Class_MrsP,
+ RtemsSemReqSetPriority_Pre_Class_NA
+} RtemsSemReqSetPriority_Pre_Class;
+
+typedef enum {
+ RtemsSemReqSetPriority_Pre_SemId_Valid,
+ RtemsSemReqSetPriority_Pre_SemId_Invalid,
+ RtemsSemReqSetPriority_Pre_SemId_NA
+} RtemsSemReqSetPriority_Pre_SemId;
+
+typedef enum {
+ RtemsSemReqSetPriority_Pre_SchedId_Invalid,
+ RtemsSemReqSetPriority_Pre_SchedId_Create,
+ RtemsSemReqSetPriority_Pre_SchedId_Other,
+ RtemsSemReqSetPriority_Pre_SchedId_NA
+} RtemsSemReqSetPriority_Pre_SchedId;
+
+typedef enum {
+ RtemsSemReqSetPriority_Pre_NewPrio_Current,
+ RtemsSemReqSetPriority_Pre_NewPrio_Valid,
+ RtemsSemReqSetPriority_Pre_NewPrio_Invalid,
+ RtemsSemReqSetPriority_Pre_NewPrio_NA
+} RtemsSemReqSetPriority_Pre_NewPrio;
+
+typedef enum {
+ RtemsSemReqSetPriority_Pre_OldPrio_Valid,
+ RtemsSemReqSetPriority_Pre_OldPrio_Null,
+ RtemsSemReqSetPriority_Pre_OldPrio_NA
+} RtemsSemReqSetPriority_Pre_OldPrio;
+
+typedef enum {
+ RtemsSemReqSetPriority_Post_Status_Ok,
+ RtemsSemReqSetPriority_Post_Status_InvAddr,
+ RtemsSemReqSetPriority_Post_Status_InvId,
+ RtemsSemReqSetPriority_Post_Status_InvPrio,
+ RtemsSemReqSetPriority_Post_Status_NotDef,
+ RtemsSemReqSetPriority_Post_Status_NA
+} RtemsSemReqSetPriority_Post_Status;
+
+typedef enum {
+ RtemsSemReqSetPriority_Post_OwnerPrio_Nop,
+ RtemsSemReqSetPriority_Post_OwnerPrio_New,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA
+} RtemsSemReqSetPriority_Post_OwnerPrio;
+
+typedef enum {
+ RtemsSemReqSetPriority_Post_SemPrio_Set,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_SemPrio_NA
+} RtemsSemReqSetPriority_Post_SemPrio;
+
+typedef enum {
+ RtemsSemReqSetPriority_Post_OldPrioVar_Set,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_NA
+} RtemsSemReqSetPriority_Post_OldPrioVar;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Class_NA : 1;
+ uint16_t Pre_SemId_NA : 1;
+ uint16_t Pre_SchedId_NA : 1;
+ uint16_t Pre_NewPrio_NA : 1;
+ uint16_t Pre_OldPrio_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_OwnerPrio : 2;
+ uint16_t Post_SemPrio : 2;
+ uint16_t Post_OldPrioVar : 2;
+} RtemsSemReqSetPriority_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/sem/req/set-priority test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the scheduler identifier of the runner task.
+ */
+ rtems_id runner_scheduler_id;
+
+ /**
+ * @brief This member contains the scheduler identifier of a scheduler not
+ * used by the runner task.
+ */
+ rtems_id other_scheduler_id;
+
+ /**
+ * @brief This member specifies the initial count of the semaphore.
+ */
+ uint32_t count;
+
+ /**
+ * @brief This member specifies the attribute set of the semaphore.
+ */
+ rtems_attribute attribute_set;
+
+ /**
+ * @brief This member contains the semaphore identifier.
+ */
+ rtems_id the_semaphore_id;
+
+ /**
+ * @brief If this member is true, then the ``semaphore_id`` parameter value
+ * shall be associated with the semaphore, otherwise it shall be not
+ * associated with a semaphore.
+ */
+ bool valid_id;
+
+ /**
+ * @brief This member may contain the task priority returned by
+ * rtems_semaphore_set_priority().
+ */
+ rtems_task_priority old_priority_value;
+
+ /**
+ * @brief This member specifies the ``semaphore_id`` parameter for the
+ * rtems_semaphore_set_priority() call.
+ */
+ rtems_id semaphore_id;
+
+ /**
+ * @brief This member specifies the ``scheduler_id`` parameter for the
+ * rtems_semaphore_set_priority() call.
+ */
+ rtems_id scheduler_id;
+
+ /**
+ * @brief This member specifies the ``new_priority`` parameter for the
+ * rtems_semaphore_set_priority() call.
+ */
+ rtems_task_priority new_priority;
+
+ /**
+ * @brief This member specifies the ``old_priority`` parameter for the
+ * rtems_semaphore_set_priority() call.
+ */
+ rtems_task_priority *old_priority;
+
+ /**
+ * @brief This member contains the status of the
+ * rtems_semaphore_set_priority() call.
+ */
+ rtems_status_code status;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 5 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsSemReqSetPriority_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsSemReqSetPriority_Context;
+
+static RtemsSemReqSetPriority_Context
+ RtemsSemReqSetPriority_Instance;
+
+static const char * const RtemsSemReqSetPriority_PreDesc_Class[] = {
+ "Counting",
+ "Simple",
+ "Binary",
+ "PrioCeilingNoOwner",
+ "PrioCeilingOwner",
+ "PrioInherit",
+ "MrsP",
+ "NA"
+};
+
+static const char * const RtemsSemReqSetPriority_PreDesc_SemId[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsSemReqSetPriority_PreDesc_SchedId[] = {
+ "Invalid",
+ "Create",
+ "Other",
+ "NA"
+};
+
+static const char * const RtemsSemReqSetPriority_PreDesc_NewPrio[] = {
+ "Current",
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsSemReqSetPriority_PreDesc_OldPrio[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsSemReqSetPriority_PreDesc[] = {
+ RtemsSemReqSetPriority_PreDesc_Class,
+ RtemsSemReqSetPriority_PreDesc_SemId,
+ RtemsSemReqSetPriority_PreDesc_SchedId,
+ RtemsSemReqSetPriority_PreDesc_NewPrio,
+ RtemsSemReqSetPriority_PreDesc_OldPrio,
+ NULL
+};
+
+#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+typedef RtemsSemReqSetPriority_Context Context;
+
+static void ReleaseSemaphore( const Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_release( ctx->the_semaphore_id );
+ T_rsc_success( sc );
+}
+
+static void ChangeScheduler( rtems_id scheduler_id )
+{
+#if defined(RTEMS_SMP)
+ rtems_status_code sc;
+
+ sc = rtems_task_set_scheduler( RTEMS_SELF, scheduler_id, PRIO_NORMAL );
+ T_rsc_success( sc );
+#else
+ (void) scheduler_id;
+#endif
+}
+
+static void CheckPriority(
+ const Context *ctx,
+ rtems_id scheduler_id,
+ rtems_task_priority priority
+)
+{
+ rtems_status_code sc;
+
+ ChangeScheduler( scheduler_id );
+
+ sc = rtems_semaphore_obtain(
+ ctx->the_semaphore_id,
+ RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+ T_rsc_success( sc );
+
+ T_eq_u32( GetSelfPriority(), priority );
+
+ ReleaseSemaphore( ctx );
+ ChangeScheduler( ctx->runner_scheduler_id );
+}
+
+static void CheckNotDefined(
+ const Context *ctx,
+ rtems_id scheduler_id
+)
+{
+#if defined(RTEMS_SMP)
+ rtems_status_code sc;
+
+ ChangeScheduler( scheduler_id );
+
+ sc = rtems_semaphore_obtain(
+ ctx->the_semaphore_id,
+ RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+ T_rsc( sc, RTEMS_NOT_DEFINED );
+
+ ChangeScheduler( ctx->runner_scheduler_id );
+#else
+ (void) ctx;
+ (void) scheduler_id;
+#endif
+}
+
+static void RtemsSemReqSetPriority_Pre_Class_Prepare(
+ RtemsSemReqSetPriority_Context *ctx,
+ RtemsSemReqSetPriority_Pre_Class state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqSetPriority_Pre_Class_Counting: {
+ /*
+ * While the semaphore object is a counting semaphore.
+ */
+ ctx->attribute_set |= RTEMS_COUNTING_SEMAPHORE;
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Pre_Class_Simple: {
+ /*
+ * While the semaphore object is a simple binary semaphore.
+ */
+ ctx->attribute_set |= RTEMS_SIMPLE_BINARY_SEMAPHORE;
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Pre_Class_Binary: {
+ /*
+ * While the semaphore object is a binary semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE;
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Pre_Class_PrioCeilingNoOwner: {
+ /*
+ * While the semaphore object is a priority ceiling semaphore, while the
+ * semaphore has no owner.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY_CEILING;
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Pre_Class_PrioCeilingOwner: {
+ /*
+ * While the semaphore object is a priority ceiling semaphore, while the
+ * semaphore has an owner.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY_CEILING;
+ ctx->count = 0;
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Pre_Class_PrioInherit: {
+ /*
+ * While the semaphore object is a priority inheritance semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY;
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Pre_Class_MrsP: {
+ /*
+ * While the semaphore object is a MrsP semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING;
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Pre_Class_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqSetPriority_Pre_SemId_Prepare(
+ RtemsSemReqSetPriority_Context *ctx,
+ RtemsSemReqSetPriority_Pre_SemId state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqSetPriority_Pre_SemId_Valid: {
+ /*
+ * While the ``semaphore_id`` parameter is associated with the semaphore.
+ */
+ ctx->valid_id = true;
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Pre_SemId_Invalid: {
+ /*
+ * While the ``semaphore_id`` parameter is not associated with a
+ * semaphore.
+ */
+ ctx->valid_id = false;
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Pre_SemId_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqSetPriority_Pre_SchedId_Prepare(
+ RtemsSemReqSetPriority_Context *ctx,
+ RtemsSemReqSetPriority_Pre_SchedId state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqSetPriority_Pre_SchedId_Invalid: {
+ /*
+ * While the ``scheduler_id`` parameter is not associated with a
+ * scheduler.
+ */
+ ctx->scheduler_id = INVALID_ID;
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Pre_SchedId_Create: {
+ /*
+ * While the ``scheduler_id`` parameter is associated with the scheduler
+ * used to create the semaphore.
+ */
+ ctx->scheduler_id = ctx->runner_scheduler_id;
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Pre_SchedId_Other: {
+ /*
+ * While the ``scheduler_id`` parameter is associated with a scheduler
+ * other than the one used to create the semaphore.
+ */
+ ctx->scheduler_id = ctx->other_scheduler_id;
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Pre_SchedId_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqSetPriority_Pre_NewPrio_Prepare(
+ RtemsSemReqSetPriority_Context *ctx,
+ RtemsSemReqSetPriority_Pre_NewPrio state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqSetPriority_Pre_NewPrio_Current: {
+ /*
+ * While the ``new_priority`` parameter is equal to
+ * RTEMS_CURRENT_PRIORITY.
+ */
+ ctx->new_priority = RTEMS_CURRENT_PRIORITY;
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Pre_NewPrio_Valid: {
+ /*
+ * While the ``new_priority`` parameter is not equal to
+ * RTEMS_CURRENT_PRIORITY and valid with respect to the scheduler
+ * specified by the ``scheduler_id`` parameter.
+ */
+ ctx->new_priority = PRIO_VERY_HIGH;
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Pre_NewPrio_Invalid: {
+ /*
+ * While the ``new_priority`` parameter is invalid with respect to the
+ * scheduler specified by the ``scheduler_id`` parameter.
+ */
+ ctx->new_priority = PRIO_INVALID;
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Pre_NewPrio_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqSetPriority_Pre_OldPrio_Prepare(
+ RtemsSemReqSetPriority_Context *ctx,
+ RtemsSemReqSetPriority_Pre_OldPrio state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqSetPriority_Pre_OldPrio_Valid: {
+ /*
+ * While the ``old_priority`` parameter references an object of type
+ * rtems_task_priority.
+ */
+ ctx->old_priority = &ctx->old_priority_value;
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Pre_OldPrio_Null: {
+ /*
+ * While the ``old_priority`` parameter is NULL.
+ */
+ ctx->old_priority = NULL;
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Pre_OldPrio_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqSetPriority_Post_Status_Check(
+ RtemsSemReqSetPriority_Context *ctx,
+ RtemsSemReqSetPriority_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqSetPriority_Post_Status_Ok: {
+ /*
+ * The return status of rtems_semaphore_set_priority() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_semaphore_set_priority() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Post_Status_InvId: {
+ /*
+ * The return status of rtems_semaphore_set_priority() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Post_Status_InvPrio: {
+ /*
+ * The return status of rtems_semaphore_set_priority() shall be
+ * RTEMS_INVALID_PRIORITY.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_PRIORITY );
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Post_Status_NotDef: {
+ /*
+ * The return status of rtems_semaphore_set_priority() shall be
+ * RTEMS_NOT_DEFINED.
+ */
+ T_rsc( ctx->status, RTEMS_NOT_DEFINED );
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqSetPriority_Post_OwnerPrio_Check(
+ RtemsSemReqSetPriority_Context *ctx,
+ RtemsSemReqSetPriority_Post_OwnerPrio state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqSetPriority_Post_OwnerPrio_Nop: {
+ /*
+ * The current priority of the owner task of the semaphore for the
+ * scheduler specified by the ``scheduler_id`` parameter shall not be
+ * modified by the rtems_semaphore_set_priority() call.
+ */
+ T_eq_u32( GetSelfPriority(), PRIO_HIGH );
+ ReleaseSemaphore( ctx );
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Post_OwnerPrio_New: {
+ /*
+ * The current priority of the owner task of the semaphore for the
+ * scheduler specified by the ``scheduler_id`` parameter shall be less
+ * than or equal to the value of the ``new_priority`` parameter.
+ */
+ T_eq_u32( GetSelfPriority(), PRIO_VERY_HIGH );
+ ReleaseSemaphore( ctx );
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Post_OwnerPrio_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqSetPriority_Post_SemPrio_Check(
+ RtemsSemReqSetPriority_Context *ctx,
+ RtemsSemReqSetPriority_Post_SemPrio state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqSetPriority_Post_SemPrio_Set: {
+ /*
+ * The priority used for the scheduler specified by the ``scheduler_id``
+ * parameter of the semaphore associated with the identifier specified by
+ * the ``semaphore_id`` parameter shall be set to the prioriy specified
+ * by the ``new_priority`` parameter during the
+ * rtems_semaphore_set_priority() call.
+ */
+ if ( ( ctx->attribute_set & RTEMS_MULTIPROCESSOR_RESOURCE_SHARING ) != 0 ) {
+ if ( ctx->scheduler_id == ctx->other_scheduler_id ) {
+ CheckPriority( ctx, ctx->runner_scheduler_id, PRIO_HIGH );
+ CheckPriority( ctx, ctx->other_scheduler_id, PRIO_VERY_HIGH );
+ } else {
+ CheckPriority( ctx, ctx->runner_scheduler_id, PRIO_VERY_HIGH );
+ #if defined(RTEMS_SMP)
+ CheckPriority( ctx, ctx->other_scheduler_id, 0 );
+ #endif
+ }
+ } else if ( ( ctx->attribute_set & RTEMS_PRIORITY_CEILING ) != 0 ) {
+ CheckPriority( ctx, ctx->runner_scheduler_id, PRIO_VERY_HIGH );
+ CheckNotDefined( ctx, ctx->other_scheduler_id );
+ }
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Post_SemPrio_Nop: {
+ /*
+ * Priorities used by semaphores shall not be modified by the
+ * rtems_semaphore_set_priority() call.
+ */
+ if ( ( ctx->attribute_set & RTEMS_MULTIPROCESSOR_RESOURCE_SHARING ) != 0 ) {
+ CheckPriority( ctx, ctx->runner_scheduler_id, PRIO_HIGH );
+ #if defined(RTEMS_SMP)
+ CheckPriority( ctx, ctx->other_scheduler_id, 0 );
+ #endif
+ } else if ( ( ctx->attribute_set & RTEMS_PRIORITY_CEILING ) != 0 ) {
+ CheckPriority( ctx, ctx->runner_scheduler_id, PRIO_HIGH );
+ CheckNotDefined( ctx, ctx->other_scheduler_id );
+ }
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Post_SemPrio_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqSetPriority_Post_OldPrioVar_Check(
+ RtemsSemReqSetPriority_Context *ctx,
+ RtemsSemReqSetPriority_Post_OldPrioVar state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqSetPriority_Post_OldPrioVar_Set: {
+ /*
+ * The value of the object referenced by the ``old_priority`` parameter
+ * shall be set to the priority used for the scheduler specified by the
+ * ``scheduler_id`` parameter of the semaphore associated with the
+ * identifier specified by the ``semaphore_id`` parameter right before
+ * the priority is set by the rtems_semaphore_set_priority() call.
+ */
+ T_eq_ptr( ctx->old_priority, &ctx->old_priority_value );
+
+ if ( ctx->scheduler_id == ctx->other_scheduler_id ) {
+ T_eq_u32( ctx->old_priority_value, 0 );
+ } else {
+ T_eq_u32( ctx->old_priority_value, PRIO_HIGH );
+ }
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Post_OldPrioVar_Nop: {
+ /*
+ * Objects referenced by the ``old_priority`` parameter in past calls to
+ * rtems_semaphore_set_priority() shall not be accessed by the
+ * rtems_semaphore_set_priority() call.
+ */
+ T_eq_u32( ctx->old_priority_value, PRIO_INVALID );
+ break;
+ }
+
+ case RtemsSemReqSetPriority_Post_OldPrioVar_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqSetPriority_Setup( RtemsSemReqSetPriority_Context *ctx )
+{
+ rtems_status_code sc;
+
+ memset( ctx, 0, sizeof( *ctx ) );
+ SetSelfPriority( PRIO_NORMAL );
+
+ sc = rtems_task_get_scheduler( RTEMS_SELF, &ctx->runner_scheduler_id );
+ T_rsc_success( sc );
+
+ #if defined(RTEMS_SMP)
+ sc = rtems_scheduler_ident(
+ TEST_SCHEDULER_B_NAME,
+ &ctx->other_scheduler_id
+ );
+ T_rsc_success( sc );
+ #else
+ ctx->other_scheduler_id = INVALID_ID;
+ #endif
+}
+
+static void RtemsSemReqSetPriority_Setup_Wrap( void *arg )
+{
+ RtemsSemReqSetPriority_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSemReqSetPriority_Setup( ctx );
+}
+
+static void RtemsSemReqSetPriority_Teardown(
+ RtemsSemReqSetPriority_Context *ctx
+)
+{
+ RestoreRunnerPriority();
+}
+
+static void RtemsSemReqSetPriority_Teardown_Wrap( void *arg )
+{
+ RtemsSemReqSetPriority_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSemReqSetPriority_Teardown( ctx );
+}
+
+static void RtemsSemReqSetPriority_Prepare(
+ RtemsSemReqSetPriority_Context *ctx
+)
+{
+ ctx->old_priority_value = PRIO_INVALID;
+ ctx->count = 1;
+ ctx->attribute_set = RTEMS_PRIORITY;
+ ctx->valid_id = true;
+}
+
+static void RtemsSemReqSetPriority_Action(
+ RtemsSemReqSetPriority_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_create(
+ NAME,
+ ctx->count,
+ ctx->attribute_set,
+ PRIO_HIGH,
+ &ctx->the_semaphore_id
+ );
+ T_rsc_success( sc );
+
+ if ( ctx->valid_id ) {
+ ctx->semaphore_id = ctx->the_semaphore_id;
+ } else {
+ ctx->semaphore_id = INVALID_ID;
+ }
+
+ ctx->status = rtems_semaphore_set_priority(
+ ctx->semaphore_id,
+ ctx->scheduler_id,
+ ctx->new_priority,
+ ctx->old_priority
+ );
+}
+
+static void RtemsSemReqSetPriority_Cleanup(
+ RtemsSemReqSetPriority_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ T_eq_u32( GetSelfPriority(), PRIO_NORMAL );
+
+ sc = rtems_semaphore_delete( ctx->the_semaphore_id );
+ T_rsc_success( sc );
+}
+
+static const RtemsSemReqSetPriority_Entry
+RtemsSemReqSetPriority_Entries[] = {
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_InvAddr,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Nop },
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_InvId,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Nop },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_InvAddr,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Nop },
+#else
+ { 1, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_NA,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_NA,
+ RtemsSemReqSetPriority_Post_OldPrioVar_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_InvId,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Nop },
+#else
+ { 1, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_NA,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_NA,
+ RtemsSemReqSetPriority_Post_OldPrioVar_NA },
+#endif
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_InvAddr,
+ RtemsSemReqSetPriority_Post_OwnerPrio_Nop,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Nop },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_NotDef,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Nop },
+#else
+ { 1, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_NA,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_NA,
+ RtemsSemReqSetPriority_Post_OldPrioVar_NA },
+#endif
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_InvId,
+ RtemsSemReqSetPriority_Post_OwnerPrio_Nop,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Nop },
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_NotDef,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Nop },
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_InvPrio,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Nop },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_InvPrio,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Nop },
+#else
+ { 1, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_NA,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_NA,
+ RtemsSemReqSetPriority_Post_OldPrioVar_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_InvAddr,
+ RtemsSemReqSetPriority_Post_OwnerPrio_Nop,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Nop },
+#else
+ { 1, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_NA,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_NA,
+ RtemsSemReqSetPriority_Post_OldPrioVar_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_InvId,
+ RtemsSemReqSetPriority_Post_OwnerPrio_Nop,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Nop },
+#else
+ { 1, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_NA,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_NA,
+ RtemsSemReqSetPriority_Post_OldPrioVar_NA },
+#endif
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_Ok,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Set },
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_Ok,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_Set,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Set },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_NotDef,
+ RtemsSemReqSetPriority_Post_OwnerPrio_Nop,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Nop },
+#else
+ { 1, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_NA,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_NA,
+ RtemsSemReqSetPriority_Post_OldPrioVar_NA },
+#endif
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_Ok,
+ RtemsSemReqSetPriority_Post_OwnerPrio_Nop,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Set },
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_Ok,
+ RtemsSemReqSetPriority_Post_OwnerPrio_New,
+ RtemsSemReqSetPriority_Post_SemPrio_Set,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Set },
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_InvPrio,
+ RtemsSemReqSetPriority_Post_OwnerPrio_Nop,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Nop },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_InvPrio,
+ RtemsSemReqSetPriority_Post_OwnerPrio_Nop,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Nop },
+#else
+ { 1, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_NA,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_NA,
+ RtemsSemReqSetPriority_Post_OldPrioVar_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_Ok,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_Nop,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Set },
+#else
+ { 1, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_NA,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_NA,
+ RtemsSemReqSetPriority_Post_OldPrioVar_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_Ok,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_Set,
+ RtemsSemReqSetPriority_Post_OldPrioVar_Set }
+#else
+ { 1, 0, 0, 0, 0, 0, RtemsSemReqSetPriority_Post_Status_NA,
+ RtemsSemReqSetPriority_Post_OwnerPrio_NA,
+ RtemsSemReqSetPriority_Post_SemPrio_NA,
+ RtemsSemReqSetPriority_Post_OldPrioVar_NA }
+#endif
+};
+
+static const uint8_t
+RtemsSemReqSetPriority_Map[] = {
+ 1, 0, 1, 0, 1, 0, 7, 0, 7, 0, 8, 0, 5, 2, 5, 2, 9, 2, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 3, 2, 3, 2, 3, 2, 1, 0, 1, 0, 1, 0, 7, 0, 7, 0, 8, 0, 5, 2, 5, 2,
+ 9, 2, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 2, 3, 2, 3, 2, 1, 0, 1, 0, 1, 0,
+ 7, 0, 7, 0, 8, 0, 5, 2, 5, 2, 9, 2, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 2,
+ 3, 2, 3, 2, 1, 0, 1, 0, 1, 0, 12, 0, 13, 0, 8, 0, 5, 2, 5, 2, 9, 2, 1, 0, 1,
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 2, 3, 2, 3, 2, 6, 4, 6, 4, 6, 4, 15, 4, 16, 4,
+ 17, 4, 14, 10, 14, 10, 18, 10, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 11, 10,
+ 11, 10, 11, 10, 1, 0, 1, 0, 1, 0, 7, 0, 7, 0, 8, 0, 5, 2, 5, 2, 9, 2, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 2, 3, 2, 3, 2, 1, 0, 1, 0, 1, 0, 12, 0, 13,
+ 0, 8, 0, 19, 2, 20, 2, 9, 2, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 3, 2, 3, 2,
+ 3, 2
+};
+
+static size_t RtemsSemReqSetPriority_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsSemReqSetPriority_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsSemReqSetPriority_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsSemReqSetPriority_Fixture = {
+ .setup = RtemsSemReqSetPriority_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsSemReqSetPriority_Teardown_Wrap,
+ .scope = RtemsSemReqSetPriority_Scope,
+ .initial_context = &RtemsSemReqSetPriority_Instance
+};
+
+static inline RtemsSemReqSetPriority_Entry RtemsSemReqSetPriority_PopEntry(
+ RtemsSemReqSetPriority_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsSemReqSetPriority_Entries[
+ RtemsSemReqSetPriority_Map[ index ]
+ ];
+}
+
+static void RtemsSemReqSetPriority_TestVariant(
+ RtemsSemReqSetPriority_Context *ctx
+)
+{
+ RtemsSemReqSetPriority_Pre_Class_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsSemReqSetPriority_Pre_SemId_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsSemReqSetPriority_Pre_SchedId_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsSemReqSetPriority_Pre_NewPrio_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsSemReqSetPriority_Pre_OldPrio_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsSemReqSetPriority_Action( ctx );
+ RtemsSemReqSetPriority_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsSemReqSetPriority_Post_OwnerPrio_Check(
+ ctx,
+ ctx->Map.entry.Post_OwnerPrio
+ );
+ RtemsSemReqSetPriority_Post_SemPrio_Check(
+ ctx,
+ ctx->Map.entry.Post_SemPrio
+ );
+ RtemsSemReqSetPriority_Post_OldPrioVar_Check(
+ ctx,
+ ctx->Map.entry.Post_OldPrioVar
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsSemReqSetPriority( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsSemReqSetPriority, &RtemsSemReqSetPriority_Fixture )
+{
+ RtemsSemReqSetPriority_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsSemReqSetPriority_Pre_Class_Counting;
+ ctx->Map.pcs[ 0 ] < RtemsSemReqSetPriority_Pre_Class_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsSemReqSetPriority_Pre_SemId_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsSemReqSetPriority_Pre_SemId_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsSemReqSetPriority_Pre_SchedId_Invalid;
+ ctx->Map.pcs[ 2 ] < RtemsSemReqSetPriority_Pre_SchedId_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsSemReqSetPriority_Pre_NewPrio_Current;
+ ctx->Map.pcs[ 3 ] < RtemsSemReqSetPriority_Pre_NewPrio_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = RtemsSemReqSetPriority_Pre_OldPrio_Valid;
+ ctx->Map.pcs[ 4 ] < RtemsSemReqSetPriority_Pre_OldPrio_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ ctx->Map.entry = RtemsSemReqSetPriority_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsSemReqSetPriority_Prepare( ctx );
+ RtemsSemReqSetPriority_TestVariant( ctx );
+ RtemsSemReqSetPriority_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-sem-smp.c b/testsuites/validation/tc-sem-smp.c
new file mode 100644
index 0000000000..5dc3f437a1
--- /dev/null
+++ b/testsuites/validation/tc-sem-smp.c
@@ -0,0 +1,478 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSemValSmp
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/score/threaddispatch.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSemValSmp spec:/rtems/sem/val/smp
+ *
+ * @ingroup TestsuitesValidationSmpOnly0
+ *
+ * @brief Tests SMP-specific semaphore behaviour.
+ *
+ * This test case performs the following actions:
+ *
+ * - Create a worker thread and a MrsP mutex. Use the mutex and the worker to
+ * perform a bad sticky thread queue enqueue.
+ *
+ * - Create two worker threads, a MrsP mutex, and a priority inheritance mutex.
+ * Use the mutexes and the workers to raise the current priority to a higher
+ * priority than the ceiling priority of the mutex while one of the workers
+ * waits on the mutex.
+ *
+ * - Let the first worker try to obtain the MrsP mutex. Check that it
+ * acquired the ceiling priority.
+ *
+ * - Let the second worker try to obtain the priority inheritance mutex.
+ * Check that the first worker inherited the priority from the second
+ * worker.
+ *
+ * - Set the real priority of the first worker. Check that it defines the
+ * current priority.
+ *
+ * - Release the MrsP mutex so that the first worker can to obtain it. It
+ * will replace a temporary priority node which is the maximum priority
+ * node. This is the first scenario we want to test.
+ *
+ * - Obtain the MrsP mutex for the runner thread to start the second scenario
+ * we would like to test.
+ *
+ * - Let the first worker try to obtain the MrsP mutex. Check that it
+ * acquired the ceiling priority.
+ *
+ * - Let the second worker try to obtain the priority inheritance mutex.
+ * Check that the first worker inherited the priority from the second
+ * worker.
+ *
+ * - Lower the priority of the second worker. Check that the inherited
+ * priority of the first worker reflects this priority change.
+ *
+ * - Change the real priority of the first worker so that it defines its
+ * current priority.
+ *
+ * - Release the MrsP mutex so that the first worker can to obtain it. It
+ * will replace a temporary priority node which is between the minimum and
+ * maximum priority node. This is the second scenario we want to test.
+ *
+ * - Clean up all used resources.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/rtems/sem/val/smp test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the mutex identifier.
+ */
+ rtems_id mutex_id;
+
+ /**
+ * @brief This member contains the second mutex identifier.
+ */
+ rtems_id mutex_2_id;
+
+ /**
+ * @brief If this member is true, then the worker is done.
+ */
+ volatile bool done;
+
+ /**
+ * @brief If this member is true, then the second worker is done.
+ */
+ volatile bool done_2;
+} RtemsSemValSmp_Context;
+
+static RtemsSemValSmp_Context
+ RtemsSemValSmp_Instance;
+
+typedef RtemsSemValSmp_Context Context;
+
+static void BadEnqueueFatal(
+ rtems_fatal_source source,
+ rtems_fatal_code code,
+ void *arg
+)
+{
+ Per_CPU_Control *cpu_self;
+ Context *ctx;
+
+ T_eq_int( source, INTERNAL_ERROR_CORE );
+ T_eq_ulong(
+ code,
+ INTERNAL_ERROR_THREAD_QUEUE_ENQUEUE_STICKY_FROM_BAD_STATE
+ );
+
+ SetFatalHandler( NULL, NULL );
+
+ cpu_self = _Per_CPU_Get();
+ _Thread_Dispatch_unnest( cpu_self );
+ _Thread_Dispatch_unnest( cpu_self );
+
+ ctx = arg;
+ ctx->done = true;
+ SuspendSelf();
+}
+
+static void BadEnqueueTask( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+ (void) _Thread_Dispatch_disable();
+ ObtainMutex( ctx->mutex_id );
+}
+
+static void ObtainReleaseMrsPTask( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+ ObtainMutex( ctx->mutex_2_id );
+ ctx->done = true;
+ ObtainMutex( ctx->mutex_id );
+ ReleaseMutex( ctx->mutex_id );
+ ReleaseMutex( ctx->mutex_2_id );
+ ctx->done = true;
+ SuspendSelf();
+}
+
+static void ObtainRelease2Task( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+ ctx->done_2 = true;
+ ObtainMutex( ctx->mutex_2_id );
+ ReleaseMutex( ctx->mutex_2_id );
+ ctx->done_2 = true;
+ SuspendSelf();
+}
+
+static void RtemsSemValSmp_Setup( RtemsSemValSmp_Context *ctx )
+{
+ SetSelfPriority( PRIO_NORMAL );
+}
+
+static void RtemsSemValSmp_Setup_Wrap( void *arg )
+{
+ RtemsSemValSmp_Context *ctx;
+
+ ctx = arg;
+ RtemsSemValSmp_Setup( ctx );
+}
+
+static void RtemsSemValSmp_Teardown( RtemsSemValSmp_Context *ctx )
+{
+ RestoreRunnerPriority();
+}
+
+static void RtemsSemValSmp_Teardown_Wrap( void *arg )
+{
+ RtemsSemValSmp_Context *ctx;
+
+ ctx = arg;
+ RtemsSemValSmp_Teardown( ctx );
+}
+
+static T_fixture RtemsSemValSmp_Fixture = {
+ .setup = RtemsSemValSmp_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsSemValSmp_Teardown_Wrap,
+ .scope = NULL,
+ .initial_context = &RtemsSemValSmp_Instance
+};
+
+/**
+ * @brief Create a worker thread and a MrsP mutex. Use the mutex and the
+ * worker to perform a bad sticky thread queue enqueue.
+ */
+static void RtemsSemValSmp_Action_0( RtemsSemValSmp_Context *ctx )
+{
+ rtems_status_code sc;
+ rtems_id worker_id;
+ rtems_id scheduler_b_id;
+
+ ctx->done = false;
+
+ sc = rtems_scheduler_ident( TEST_SCHEDULER_B_NAME, &scheduler_b_id );
+ T_rsc_success( sc );
+
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'M', 'U', 'T', 'X' ),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
+ PRIO_HIGH,
+ &ctx->mutex_id
+ );
+ T_rsc_success( sc );
+
+ worker_id = CreateTask( "WORK", PRIO_NORMAL );
+ SetScheduler( worker_id, scheduler_b_id, PRIO_NORMAL );
+
+ ObtainMutex( ctx->mutex_id );
+ SetFatalHandler( BadEnqueueFatal, ctx );
+ StartTask( worker_id, BadEnqueueTask, ctx );
+
+ while ( !ctx->done ) {
+ /* Wait */
+ }
+
+ DeleteTask( worker_id );
+ ReleaseMutex( ctx->mutex_id );
+ DeleteMutex( ctx->mutex_id );
+}
+
+/**
+ * @brief Create two worker threads, a MrsP mutex, and a priority inheritance
+ * mutex. Use the mutexes and the workers to raise the current priority to a
+ * higher priority than the ceiling priority of the mutex while one of the
+ * workers waits on the mutex.
+ */
+static void RtemsSemValSmp_Action_1( RtemsSemValSmp_Context *ctx )
+{
+ rtems_status_code sc;
+ rtems_id worker_id;
+ rtems_id worker_2_id;
+ rtems_id scheduler_b_id;
+ rtems_task_priority prio;
+
+ sc = rtems_scheduler_ident( TEST_SCHEDULER_B_NAME, &scheduler_b_id );
+ T_rsc_success( sc );
+
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'M', 'U', 'T', 'X' ),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
+ PRIO_HIGH,
+ &ctx->mutex_id
+ );
+ T_rsc_success( sc );
+
+ sc = rtems_semaphore_set_priority(
+ ctx->mutex_id,
+ scheduler_b_id,
+ PRIO_HIGH,
+ &prio
+ );
+ T_rsc_success( sc );
+
+ ctx->mutex_2_id = CreateMutex();
+
+ worker_id = CreateTask( "WORK", PRIO_NORMAL );
+ SetScheduler( worker_id, scheduler_b_id, PRIO_NORMAL );
+
+ worker_2_id = CreateTask( "WRK2", PRIO_NORMAL );
+ SetScheduler( worker_2_id, scheduler_b_id, PRIO_VERY_HIGH );
+
+ /*
+ * Let the first worker try to obtain the MrsP mutex. Check that it acquired
+ * the ceiling priority.
+ */
+ ObtainMutex( ctx->mutex_id );
+ ctx->done = false;
+ StartTask( worker_id, ObtainReleaseMrsPTask, ctx );
+
+ while ( !ctx->done ) {
+ /* Wait */
+ }
+
+ ctx->done = false;
+ WaitForIntendToBlock( worker_id );
+ prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
+ T_eq_u32( prio, PRIO_HIGH );
+
+ /*
+ * Let the second worker try to obtain the priority inheritance mutex. Check
+ * that the first worker inherited the priority from the second worker.
+ */
+ ctx->done_2 = false;
+ StartTask( worker_2_id, ObtainRelease2Task, ctx );
+
+ while ( !ctx->done_2 ) {
+ /* Wait */
+ }
+
+ ctx->done_2 = false;
+ WaitForExecutionStop( worker_2_id );
+ prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
+ T_eq_u32( prio, PRIO_VERY_HIGH );
+
+ /*
+ * Set the real priority of the first worker. Check that it defines the
+ * current priority.
+ */
+ SetPriority( worker_id, PRIO_ULTRA_HIGH );
+
+ prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
+ T_eq_u32( prio, PRIO_ULTRA_HIGH );
+
+ /*
+ * Release the MrsP mutex so that the first worker can to obtain it. It will
+ * replace a temporary priority node which is the maximum priority node.
+ * This is the first scenario we want to test.
+ */
+ ReleaseMutex( ctx->mutex_id );
+
+ while ( !ctx->done || !ctx->done_2 ) {
+ /* Wait */
+ }
+
+ prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
+ T_eq_u32( prio, PRIO_ULTRA_HIGH );
+
+ /*
+ * Obtain the MrsP mutex for the runner thread to start the second scenario
+ * we would like to test.
+ */
+ ObtainMutex( ctx->mutex_id );
+
+ /*
+ * Let the first worker try to obtain the MrsP mutex. Check that it acquired
+ * the ceiling priority.
+ */
+ ctx->done = false;
+ sc = rtems_task_restart( worker_id, (rtems_task_argument) ctx );
+ T_rsc_success( sc );
+
+ while ( !ctx->done ) {
+ /* Wait */
+ }
+
+ ctx->done = false;
+ WaitForIntendToBlock( worker_id );
+ prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
+ T_eq_u32( prio, PRIO_HIGH );
+
+ /*
+ * Let the second worker try to obtain the priority inheritance mutex. Check
+ * that the first worker inherited the priority from the second worker.
+ */
+ ctx->done_2 = false;
+ sc = rtems_task_restart( worker_2_id, (rtems_task_argument) ctx );
+ T_rsc_success( sc );
+
+ while ( !ctx->done_2 ) {
+ /* Wait */
+ }
+
+ ctx->done_2 = false;
+ WaitForExecutionStop( worker_2_id );
+ prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
+ T_eq_u32( prio, PRIO_VERY_HIGH );
+
+ /*
+ * Lower the priority of the second worker. Check that the inherited
+ * priority of the first worker reflects this priority change.
+ */
+ SetPriority( worker_2_id, PRIO_LOW );
+
+ prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
+ T_eq_u32( prio, PRIO_HIGH );
+
+ /*
+ * Change the real priority of the first worker so that it defines its
+ * current priority.
+ */
+ SetPriority( worker_id, PRIO_ULTRA_HIGH );
+
+ prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
+ T_eq_u32( prio, PRIO_ULTRA_HIGH );
+
+ /*
+ * Release the MrsP mutex so that the first worker can to obtain it. It will
+ * replace a temporary priority node which is between the minimum and maximum
+ * priority node. This is the second scenario we want to test.
+ */
+ ReleaseMutex( ctx->mutex_id );
+
+ while ( !ctx->done || !ctx->done_2 ) {
+ /* Wait */
+ }
+
+ prio = GetPriorityByScheduler( worker_id, scheduler_b_id );
+ T_eq_u32( prio, PRIO_ULTRA_HIGH );
+
+ /*
+ * Clean up all used resources.
+ */
+ DeleteTask( worker_id );
+ DeleteTask( worker_2_id );
+ DeleteMutex( ctx->mutex_id );
+ DeleteMutex( ctx->mutex_2_id );
+}
+
+/**
+ * @fn void T_case_body_RtemsSemValSmp( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsSemValSmp, &RtemsSemValSmp_Fixture )
+{
+ RtemsSemValSmp_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ RtemsSemValSmp_Action_0( ctx );
+ RtemsSemValSmp_Action_1( ctx );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-sem-timeout.c b/testsuites/validation/tc-sem-timeout.c
new file mode 100644
index 0000000000..a150d067d2
--- /dev/null
+++ b/testsuites/validation/tc-sem-timeout.c
@@ -0,0 +1,476 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSemReqTimeout
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+
+#include "tr-tq-timeout-priority-inherit.h"
+#include "tr-tq-timeout.h"
+#include "tx-support.h"
+#include "tx-thread-queue.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSemReqTimeout spec:/rtems/sem/req/timeout
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsSemReqTimeout_Pre_Class_Counting,
+ RtemsSemReqTimeout_Pre_Class_Simple,
+ RtemsSemReqTimeout_Pre_Class_Binary,
+ RtemsSemReqTimeout_Pre_Class_PrioCeiling,
+ RtemsSemReqTimeout_Pre_Class_PrioInherit,
+ RtemsSemReqTimeout_Pre_Class_MrsP,
+ RtemsSemReqTimeout_Pre_Class_NA
+} RtemsSemReqTimeout_Pre_Class;
+
+typedef enum {
+ RtemsSemReqTimeout_Pre_Discipline_FIFO,
+ RtemsSemReqTimeout_Pre_Discipline_Priority,
+ RtemsSemReqTimeout_Pre_Discipline_NA
+} RtemsSemReqTimeout_Pre_Discipline;
+
+typedef enum {
+ RtemsSemReqTimeout_Post_Action_Timeout,
+ RtemsSemReqTimeout_Post_Action_TimeoutMrsP,
+ RtemsSemReqTimeout_Post_Action_TimeoutPriorityInherit,
+ RtemsSemReqTimeout_Post_Action_NA
+} RtemsSemReqTimeout_Post_Action;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Class_NA : 1;
+ uint8_t Pre_Discipline_NA : 1;
+ uint8_t Post_Action : 2;
+} RtemsSemReqTimeout_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/sem/req/timeout test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the thread queue test context.
+ */
+ TQContext tq_ctx;
+
+ /**
+ * @brief This member specifies if the attribute set of the semaphore.
+ */
+ rtems_attribute attribute_set;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsSemReqTimeout_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsSemReqTimeout_Context;
+
+static RtemsSemReqTimeout_Context
+ RtemsSemReqTimeout_Instance;
+
+static const char * const RtemsSemReqTimeout_PreDesc_Class[] = {
+ "Counting",
+ "Simple",
+ "Binary",
+ "PrioCeiling",
+ "PrioInherit",
+ "MrsP",
+ "NA"
+};
+
+static const char * const RtemsSemReqTimeout_PreDesc_Discipline[] = {
+ "FIFO",
+ "Priority",
+ "NA"
+};
+
+static const char * const * const RtemsSemReqTimeout_PreDesc[] = {
+ RtemsSemReqTimeout_PreDesc_Class,
+ RtemsSemReqTimeout_PreDesc_Discipline,
+ NULL
+};
+
+#if defined(RTEMS_SMP)
+#include "tr-tq-timeout-mrsp.h"
+#endif
+
+static void RtemsSemReqTimeout_Pre_Class_Prepare(
+ RtemsSemReqTimeout_Context *ctx,
+ RtemsSemReqTimeout_Pre_Class state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqTimeout_Pre_Class_Counting: {
+ /*
+ * While the semaphore object is a counting semaphore.
+ */
+ ctx->attribute_set |= RTEMS_COUNTING_SEMAPHORE;
+ ctx->tq_ctx.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ break;
+ }
+
+ case RtemsSemReqTimeout_Pre_Class_Simple: {
+ /*
+ * While the semaphore object is a simple binary semaphore.
+ */
+ ctx->attribute_set |= RTEMS_SIMPLE_BINARY_SEMAPHORE;
+ ctx->tq_ctx.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ break;
+ }
+
+ case RtemsSemReqTimeout_Pre_Class_Binary: {
+ /*
+ * While the semaphore object is a binary semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE;
+ ctx->tq_ctx.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ break;
+ }
+
+ case RtemsSemReqTimeout_Pre_Class_PrioCeiling: {
+ /*
+ * While the semaphore object is a priority ceiling semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY_CEILING;
+ ctx->tq_ctx.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ break;
+ }
+
+ case RtemsSemReqTimeout_Pre_Class_PrioInherit: {
+ /*
+ * While the semaphore object is a priority inheritance semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY;
+ ctx->tq_ctx.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ break;
+ }
+
+ case RtemsSemReqTimeout_Pre_Class_MrsP: {
+ /*
+ * While the semaphore object is a MrsP semaphore.
+ */
+ ctx->attribute_set |= RTEMS_BINARY_SEMAPHORE |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING;
+ #if defined(RTEMS_SMP)
+ ctx->tq_ctx.enqueue_variant = TQ_ENQUEUE_STICKY;
+ #else
+ ctx->tq_ctx.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ #endif
+ break;
+ }
+
+ case RtemsSemReqTimeout_Pre_Class_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqTimeout_Pre_Discipline_Prepare(
+ RtemsSemReqTimeout_Context *ctx,
+ RtemsSemReqTimeout_Pre_Discipline state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqTimeout_Pre_Discipline_FIFO: {
+ /*
+ * While the semaphore uses the FIFO task wait queue discipline.
+ */
+ ctx->attribute_set |= RTEMS_FIFO;
+ ctx->tq_ctx.discipline = TQ_FIFO;
+ break;
+ }
+
+ case RtemsSemReqTimeout_Pre_Discipline_Priority: {
+ /*
+ * While the semaphore uses the priority task wait queue discipline.
+ */
+ ctx->attribute_set |= RTEMS_PRIORITY;
+ ctx->tq_ctx.discipline = TQ_PRIORITY;
+ break;
+ }
+
+ case RtemsSemReqTimeout_Pre_Discipline_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqTimeout_Post_Action_Check(
+ RtemsSemReqTimeout_Context *ctx,
+ RtemsSemReqTimeout_Post_Action state
+)
+{
+ switch ( state ) {
+ case RtemsSemReqTimeout_Post_Action_Timeout: {
+ /*
+ * The semaphore obtain timeout actions shall be done as specified by
+ * spec:/score/tq/req/timeout.
+ */
+ ctx->tq_ctx.wait = TQ_WAIT_TIMED;
+ ScoreTqReqTimeout_Run( &ctx->tq_ctx );
+ break;
+ }
+
+ case RtemsSemReqTimeout_Post_Action_TimeoutMrsP: {
+ /*
+ * The semaphore obtain timeout actions shall be done as specified by
+ * spec:/score/tq/req/timeout-mrsp.
+ */
+ #if defined(RTEMS_SMP)
+ ctx->tq_ctx.wait = TQ_WAIT_TIMED;
+ ScoreTqReqTimeoutMrsp_Run( &ctx->tq_ctx );
+ #else
+ T_unreachable();
+ #endif
+ break;
+ }
+
+ case RtemsSemReqTimeout_Post_Action_TimeoutPriorityInherit: {
+ /*
+ * The semaphore obtain timeout actions shall be done as specified by
+ * spec:/score/tq/req/timeout-priority-inherit.
+ */
+ ctx->tq_ctx.wait = TQ_WAIT_FOREVER;
+ ScoreTqReqTimeoutPriorityInherit_Run( &ctx->tq_ctx );
+ break;
+ }
+
+ case RtemsSemReqTimeout_Post_Action_NA:
+ break;
+ }
+}
+
+static void RtemsSemReqTimeout_Setup( RtemsSemReqTimeout_Context *ctx )
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->tq_ctx.enqueue_prepare = TQEnqueuePrepareDefault;
+ ctx->tq_ctx.enqueue_done = TQEnqueueDoneDefault;
+ ctx->tq_ctx.enqueue = TQEnqueueClassicSem;
+ ctx->tq_ctx.surrender = TQSurrenderClassicSem;
+ ctx->tq_ctx.convert_status = TQConvertStatusClassic;
+ TQInitialize( &ctx->tq_ctx );
+}
+
+static void RtemsSemReqTimeout_Setup_Wrap( void *arg )
+{
+ RtemsSemReqTimeout_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSemReqTimeout_Setup( ctx );
+}
+
+static void RtemsSemReqTimeout_Teardown( RtemsSemReqTimeout_Context *ctx )
+{
+ TQDestroy( &ctx->tq_ctx );
+}
+
+static void RtemsSemReqTimeout_Teardown_Wrap( void *arg )
+{
+ RtemsSemReqTimeout_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsSemReqTimeout_Teardown( ctx );
+}
+
+static void RtemsSemReqTimeout_Prepare( RtemsSemReqTimeout_Context *ctx )
+{
+ ctx->attribute_set = RTEMS_DEFAULT_ATTRIBUTES;
+ ctx->tq_ctx.thread_queue_id = 0;
+}
+
+static void RtemsSemReqTimeout_Action( RtemsSemReqTimeout_Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_create(
+ OBJECT_NAME,
+ 1,
+ ctx->attribute_set,
+ PRIO_HIGH,
+ &ctx->tq_ctx.thread_queue_id
+ );
+ T_rsc_success( sc );
+}
+
+static void RtemsSemReqTimeout_Cleanup( RtemsSemReqTimeout_Context *ctx )
+{
+ if ( ctx->tq_ctx.thread_queue_id != 0 ) {
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_delete( ctx->tq_ctx.thread_queue_id );
+ T_rsc_success( sc );
+ }
+}
+
+static const RtemsSemReqTimeout_Entry
+RtemsSemReqTimeout_Entries[] = {
+ { 0, 0, 0, RtemsSemReqTimeout_Post_Action_Timeout },
+ { 1, 0, 0, RtemsSemReqTimeout_Post_Action_NA },
+ { 0, 0, 0, RtemsSemReqTimeout_Post_Action_TimeoutPriorityInherit },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, RtemsSemReqTimeout_Post_Action_TimeoutMrsP }
+#else
+ { 0, 0, 0, RtemsSemReqTimeout_Post_Action_Timeout }
+#endif
+};
+
+static const uint8_t
+RtemsSemReqTimeout_Map[] = {
+ 0, 0, 0, 0, 0, 0, 1, 0, 1, 2, 1, 3
+};
+
+static size_t RtemsSemReqTimeout_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsSemReqTimeout_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsSemReqTimeout_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsSemReqTimeout_Fixture = {
+ .setup = RtemsSemReqTimeout_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsSemReqTimeout_Teardown_Wrap,
+ .scope = RtemsSemReqTimeout_Scope,
+ .initial_context = &RtemsSemReqTimeout_Instance
+};
+
+static inline RtemsSemReqTimeout_Entry RtemsSemReqTimeout_PopEntry(
+ RtemsSemReqTimeout_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsSemReqTimeout_Entries[
+ RtemsSemReqTimeout_Map[ index ]
+ ];
+}
+
+static void RtemsSemReqTimeout_TestVariant( RtemsSemReqTimeout_Context *ctx )
+{
+ RtemsSemReqTimeout_Pre_Class_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsSemReqTimeout_Pre_Discipline_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsSemReqTimeout_Action( ctx );
+ RtemsSemReqTimeout_Post_Action_Check( ctx, ctx->Map.entry.Post_Action );
+}
+
+/**
+ * @fn void T_case_body_RtemsSemReqTimeout( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsSemReqTimeout, &RtemsSemReqTimeout_Fixture )
+{
+ RtemsSemReqTimeout_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsSemReqTimeout_Pre_Class_Counting;
+ ctx->Map.pcs[ 0 ] < RtemsSemReqTimeout_Pre_Class_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsSemReqTimeout_Pre_Discipline_FIFO;
+ ctx->Map.pcs[ 1 ] < RtemsSemReqTimeout_Pre_Discipline_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ ctx->Map.entry = RtemsSemReqTimeout_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsSemReqTimeout_Prepare( ctx );
+ RtemsSemReqTimeout_TestVariant( ctx );
+ RtemsSemReqTimeout_Cleanup( ctx );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-sem-uni.c b/testsuites/validation/tc-sem-uni.c
new file mode 100644
index 0000000000..04fec2009c
--- /dev/null
+++ b/testsuites/validation/tc-sem-uni.c
@@ -0,0 +1,226 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSemValUni
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSemValUni spec:/rtems/sem/val/uni
+ *
+ * @ingroup TestsuitesValidationOneCpu0
+ *
+ * @brief Tests uniprocessor-specific semaphore behaviour.
+ *
+ * This test case performs the following actions:
+ *
+ * - Create a worker thread and two MrsP mutexes. Obtain the Mrsp mutexes and
+ * check that a task yield works (owner is not sticky). We need two mutexes
+ * since the uniprocessor schedulers do not increment the stick level in the
+ * scheduler unblock operation.
+ *
+ * - Yield and let the worker obtain the MrsP mutexes.
+ *
+ * - Yield and let the worker release the MrsP mutexes.
+ *
+ * - Clean up all used resources.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/rtems/sem/val/uni test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the mutex identifier.
+ */
+ rtems_id mutex_id;
+
+ /**
+ * @brief This member contains the second mutex identifier.
+ */
+ rtems_id mutex_2_id;
+
+ /**
+ * @brief This member contains a progress counter.
+ */
+ uint32_t counter;
+} RtemsSemValUni_Context;
+
+static RtemsSemValUni_Context
+ RtemsSemValUni_Instance;
+
+typedef RtemsSemValUni_Context Context;
+
+static void ObtainReleaseMrsPTask( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+ ObtainMutex( ctx->mutex_id );
+ ObtainMutex( ctx->mutex_2_id );
+ ctx->counter = 1;
+ Yield();
+ ReleaseMutex( ctx->mutex_2_id );
+ ReleaseMutex( ctx->mutex_id );
+ ctx->counter = 2;
+ (void) ReceiveAnyEvents();
+}
+
+static void RtemsSemValUni_Setup( RtemsSemValUni_Context *ctx )
+{
+ SetSelfPriority( PRIO_NORMAL );
+}
+
+static void RtemsSemValUni_Setup_Wrap( void *arg )
+{
+ RtemsSemValUni_Context *ctx;
+
+ ctx = arg;
+ RtemsSemValUni_Setup( ctx );
+}
+
+static void RtemsSemValUni_Teardown( RtemsSemValUni_Context *ctx )
+{
+ RestoreRunnerPriority();
+}
+
+static void RtemsSemValUni_Teardown_Wrap( void *arg )
+{
+ RtemsSemValUni_Context *ctx;
+
+ ctx = arg;
+ RtemsSemValUni_Teardown( ctx );
+}
+
+static T_fixture RtemsSemValUni_Fixture = {
+ .setup = RtemsSemValUni_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsSemValUni_Teardown_Wrap,
+ .scope = NULL,
+ .initial_context = &RtemsSemValUni_Instance
+};
+
+/**
+ * @brief Create a worker thread and two MrsP mutexes. Obtain the Mrsp mutexes
+ * and check that a task yield works (owner is not sticky). We need two
+ * mutexes since the uniprocessor schedulers do not increment the stick level
+ * in the scheduler unblock operation.
+ */
+static void RtemsSemValUni_Action_0( RtemsSemValUni_Context *ctx )
+{
+ rtems_status_code sc;
+ rtems_id worker_id;
+
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'M', 'T', 'X', '1' ),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
+ PRIO_NORMAL,
+ &ctx->mutex_id
+ );
+ T_rsc_success( sc );
+
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'M', 'T', 'X', '2' ),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY |
+ RTEMS_MULTIPROCESSOR_RESOURCE_SHARING,
+ PRIO_NORMAL,
+ &ctx->mutex_2_id
+ );
+ T_rsc_success( sc );
+
+ ctx->counter = 0;
+
+ worker_id = CreateTask( "WORK", PRIO_NORMAL );
+ StartTask( worker_id, ObtainReleaseMrsPTask, ctx );
+
+ /*
+ * Yield and let the worker obtain the MrsP mutexes.
+ */
+ Yield();
+ T_eq_u32( ctx->counter, 1 );
+
+ /*
+ * Yield and let the worker release the MrsP mutexes.
+ */
+ Yield();
+ T_eq_u32( ctx->counter, 2 );
+
+ /*
+ * Clean up all used resources.
+ */
+ DeleteTask( worker_id );
+ DeleteMutex( ctx->mutex_2_id );
+ DeleteMutex( ctx->mutex_id );
+}
+
+/**
+ * @fn void T_case_body_RtemsSemValUni( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsSemValUni, &RtemsSemValUni_Fixture )
+{
+ RtemsSemValUni_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ RtemsSemValUni_Action_0( ctx );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-signal-catch.c b/testsuites/validation/tc-signal-catch.c
index 45482fc5a5..7a6439a60f 100644
--- a/testsuites/validation/tc-signal-catch.c
+++ b/testsuites/validation/tc-signal-catch.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsSignalReqCatch
+ * @ingroup RtemsSignalReqCatch
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -61,10 +61,10 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsSignalReqCatch spec:/rtems/signal/req/catch
+ * @defgroup RtemsSignalReqCatch spec:/rtems/signal/req/catch
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
- * @ingroup RTEMSTestSuiteTestsuitesValidation1
+ * @ingroup TestsuitesValidationNoClock0
+ * @ingroup TestsuitesValidationOneCpu0
*
* @{
*/
diff --git a/testsuites/validation/tc-signal-send.c b/testsuites/validation/tc-signal-send.c
index d884cdf230..aedcec5e47 100644
--- a/testsuites/validation/tc-signal-send.c
+++ b/testsuites/validation/tc-signal-send.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsSignalReqSend
+ * @ingroup RtemsSignalReqSend
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -59,10 +59,10 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsSignalReqSend spec:/rtems/signal/req/send
+ * @defgroup RtemsSignalReqSend spec:/rtems/signal/req/send
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
- * @ingroup RTEMSTestSuiteTestsuitesValidation1
+ * @ingroup TestsuitesValidationNoClock0
+ * @ingroup TestsuitesValidationOneCpu0
*
* @{
*/
@@ -154,9 +154,9 @@ typedef struct {
rtems_signal_set processed_signal_sets[ 2 ];
- uintptr_t stack_pointers[ 2 ];;
+ uintptr_t stack_pointers[ 2 ];
- rtems_mode mode;;
+ rtems_mode mode;
rtems_status_code status;
@@ -723,8 +723,10 @@ static void RtemsSignalReqSend_Action( RtemsSignalReqSend_Context *ctx )
if ( ctx->id == ctx->worker_id ) {
SendEventsToWorker( ctx, EVENT_START );
+ StartDelayThreadDispatch( 1 );
ctx->status = rtems_signal_send( ctx->id, ctx->signal_set );
ctx->calls_after_send = ctx->handler_calls;
+ StopDelayThreadDispatch( 1 );
SendEventsToWorker( ctx, EVENT_SEND_DONE );
ctx->calls_after_dispatch = ctx->handler_calls;
diff --git a/testsuites/validation/tc-signals.c b/testsuites/validation/tc-signals.c
new file mode 100644
index 0000000000..dc452ecbc0
--- /dev/null
+++ b/testsuites/validation/tc-signals.c
@@ -0,0 +1,134 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSignalValSignals
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tr-signal-constant.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSignalValSignals spec:/rtems/signal/val/signals
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief This test case collection provides validation test cases for the @ref
+ * RTEMSAPIClassicSignal.
+ *
+ * This test case performs the following actions:
+ *
+ * - Run the signal test for all 32 signal constants.
+ *
+ * @{
+ */
+
+static const rtems_signal_set signals[] = {
+ RTEMS_SIGNAL_0,
+ RTEMS_SIGNAL_1,
+ RTEMS_SIGNAL_2,
+ RTEMS_SIGNAL_3,
+ RTEMS_SIGNAL_4,
+ RTEMS_SIGNAL_5,
+ RTEMS_SIGNAL_6,
+ RTEMS_SIGNAL_7,
+ RTEMS_SIGNAL_8,
+ RTEMS_SIGNAL_9,
+ RTEMS_SIGNAL_10,
+ RTEMS_SIGNAL_11,
+ RTEMS_SIGNAL_12,
+ RTEMS_SIGNAL_13,
+ RTEMS_SIGNAL_14,
+ RTEMS_SIGNAL_15,
+ RTEMS_SIGNAL_16,
+ RTEMS_SIGNAL_17,
+ RTEMS_SIGNAL_18,
+ RTEMS_SIGNAL_19,
+ RTEMS_SIGNAL_20,
+ RTEMS_SIGNAL_21,
+ RTEMS_SIGNAL_22,
+ RTEMS_SIGNAL_23,
+ RTEMS_SIGNAL_24,
+ RTEMS_SIGNAL_25,
+ RTEMS_SIGNAL_26,
+ RTEMS_SIGNAL_27,
+ RTEMS_SIGNAL_28,
+ RTEMS_SIGNAL_29,
+ RTEMS_SIGNAL_30,
+ RTEMS_SIGNAL_31
+};
+
+/**
+ * @brief Run the signal test for all 32 signal constants.
+ */
+static void RtemsSignalValSignals_Action_0( void )
+{
+ unsigned int i;
+
+ for ( i = 0; i < 32; ++i ) {
+ RtemsSignalValSignalConstant_Run( signals[ i ], i );
+ T_step( i ); /* Accounts for 32 test plan steps */
+ }
+}
+
+/**
+ * @fn void T_case_body_RtemsSignalValSignals( void )
+ */
+T_TEST_CASE( RtemsSignalValSignals )
+{
+ T_plan( 32 );
+
+ RtemsSignalValSignals_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-start-of-optional-processor-failed.c b/testsuites/validation/tc-start-of-optional-processor-failed.c
new file mode 100644
index 0000000000..826ff3848d
--- /dev/null
+++ b/testsuites/validation/tc-start-of-optional-processor-failed.c
@@ -0,0 +1,116 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSmpValStartOfOptionalProcessorFailed
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/percpu.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreSmpValStartOfOptionalProcessorFailed \
+ * spec:/score/smp/val/start-of-optional-processor-failed
+ *
+ * @ingroup TestsuitesValidationSmpOnly2
+ *
+ * @brief Tests the state of an optional processor which failed to start.
+ *
+ * This test case performs the following actions:
+ *
+ * - The test action was carried by the system initialization. If we execute
+ * this test case, then the failed start of an optional processor did not
+ * abort the system initialization.
+ *
+ * - Check that the boot processor is online.
+ *
+ * - Check that the optional processor which failed to start is not online.
+ *
+ * @{
+ */
+
+/**
+ * @brief The test action was carried by the system initialization. If we
+ * execute this test case, then the failed start of an optional processor did
+ * not abort the system initialization.
+ */
+static void ScoreSmpValStartOfOptionalProcessorFailed_Action_0( void )
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the boot processor is online.
+ */
+ T_step_true(
+ 0,
+ _Per_CPU_Is_processor_online( _Per_CPU_Get_by_index( 0 ) )
+ );
+
+ /*
+ * Check that the optional processor which failed to start is not online.
+ */
+ T_step_false(
+ 1,
+ _Per_CPU_Is_processor_online( _Per_CPU_Get_by_index( 1 ) )
+ );
+}
+
+/**
+ * @fn void T_case_body_ScoreSmpValStartOfOptionalProcessorFailed( void )
+ */
+T_TEST_CASE( ScoreSmpValStartOfOptionalProcessorFailed )
+{
+ T_plan( 2 );
+
+ ScoreSmpValStartOfOptionalProcessorFailed_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-status-is-equal.c b/testsuites/validation/tc-status-is-equal.c
new file mode 100644
index 0000000000..6981ef84d1
--- /dev/null
+++ b/testsuites/validation/tc-status-is-equal.c
@@ -0,0 +1,286 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsStatusReqIsEqual
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsStatusReqIsEqual spec:/rtems/status/req/is-equal
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsStatusReqIsEqual_Pre_Status_Equal,
+ RtemsStatusReqIsEqual_Pre_Status_NotEqual,
+ RtemsStatusReqIsEqual_Pre_Status_NA
+} RtemsStatusReqIsEqual_Pre_Status;
+
+typedef enum {
+ RtemsStatusReqIsEqual_Post_Result_True,
+ RtemsStatusReqIsEqual_Post_Result_False,
+ RtemsStatusReqIsEqual_Post_Result_NA
+} RtemsStatusReqIsEqual_Post_Result;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Status_NA : 1;
+ uint8_t Post_Result : 2;
+} RtemsStatusReqIsEqual_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/status/req/is-equal test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the return value of the
+ * rtems_are_statuses_equal() call.
+ */
+ bool result;
+
+ /**
+ * @brief This member specifies if the ``left_status_code`` parameter value.
+ */
+ rtems_status_code status_0;
+
+ /**
+ * @brief This member specifies if the ``right_status_code`` parameter value.
+ */
+ rtems_status_code status_1;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsStatusReqIsEqual_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsStatusReqIsEqual_Context;
+
+static RtemsStatusReqIsEqual_Context
+ RtemsStatusReqIsEqual_Instance;
+
+static const char * const RtemsStatusReqIsEqual_PreDesc_Status[] = {
+ "Equal",
+ "NotEqual",
+ "NA"
+};
+
+static const char * const * const RtemsStatusReqIsEqual_PreDesc[] = {
+ RtemsStatusReqIsEqual_PreDesc_Status,
+ NULL
+};
+
+static void RtemsStatusReqIsEqual_Pre_Status_Prepare(
+ RtemsStatusReqIsEqual_Context *ctx,
+ RtemsStatusReqIsEqual_Pre_Status state
+)
+{
+ switch ( state ) {
+ case RtemsStatusReqIsEqual_Pre_Status_Equal: {
+ /*
+ * While the ``left_status_code`` parameter is equal to the
+ * ``right_status_code`` parameter.
+ */
+ ctx->status_0 = RTEMS_INVALID_NAME;
+ ctx->status_1 = RTEMS_INVALID_NAME;
+ break;
+ }
+
+ case RtemsStatusReqIsEqual_Pre_Status_NotEqual: {
+ /*
+ * While the ``left_status_code`` parameter is not equal to the
+ * ``right_status_code`` parameter.
+ */
+ ctx->status_0 = RTEMS_SUCCESSFUL;
+ ctx->status_1 = RTEMS_INVALID_ID;
+ break;
+ }
+
+ case RtemsStatusReqIsEqual_Pre_Status_NA:
+ break;
+ }
+}
+
+static void RtemsStatusReqIsEqual_Post_Result_Check(
+ RtemsStatusReqIsEqual_Context *ctx,
+ RtemsStatusReqIsEqual_Post_Result state
+)
+{
+ switch ( state ) {
+ case RtemsStatusReqIsEqual_Post_Result_True: {
+ /*
+ * The return value of rtems_are_statuses_equal() shall be true.
+ */
+ T_true( ctx->result );
+ break;
+ }
+
+ case RtemsStatusReqIsEqual_Post_Result_False: {
+ /*
+ * The return value of rtems_are_statuses_equal() shall be false.
+ */
+ T_false( ctx->result );
+ break;
+ }
+
+ case RtemsStatusReqIsEqual_Post_Result_NA:
+ break;
+ }
+}
+
+static void RtemsStatusReqIsEqual_Action( RtemsStatusReqIsEqual_Context *ctx )
+{
+ ctx->result = rtems_are_statuses_equal( ctx->status_0, ctx->status_1 );
+}
+
+static const RtemsStatusReqIsEqual_Entry
+RtemsStatusReqIsEqual_Entries[] = {
+ { 0, 0, RtemsStatusReqIsEqual_Post_Result_True },
+ { 0, 0, RtemsStatusReqIsEqual_Post_Result_False }
+};
+
+static const uint8_t
+RtemsStatusReqIsEqual_Map[] = {
+ 0, 1
+};
+
+static size_t RtemsStatusReqIsEqual_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsStatusReqIsEqual_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsStatusReqIsEqual_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsStatusReqIsEqual_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsStatusReqIsEqual_Scope,
+ .initial_context = &RtemsStatusReqIsEqual_Instance
+};
+
+static inline RtemsStatusReqIsEqual_Entry RtemsStatusReqIsEqual_PopEntry(
+ RtemsStatusReqIsEqual_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsStatusReqIsEqual_Entries[
+ RtemsStatusReqIsEqual_Map[ index ]
+ ];
+}
+
+static void RtemsStatusReqIsEqual_TestVariant(
+ RtemsStatusReqIsEqual_Context *ctx
+)
+{
+ RtemsStatusReqIsEqual_Pre_Status_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsStatusReqIsEqual_Action( ctx );
+ RtemsStatusReqIsEqual_Post_Result_Check( ctx, ctx->Map.entry.Post_Result );
+}
+
+/**
+ * @fn void T_case_body_RtemsStatusReqIsEqual( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsStatusReqIsEqual, &RtemsStatusReqIsEqual_Fixture )
+{
+ RtemsStatusReqIsEqual_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsStatusReqIsEqual_Pre_Status_Equal;
+ ctx->Map.pcs[ 0 ] < RtemsStatusReqIsEqual_Pre_Status_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = RtemsStatusReqIsEqual_PopEntry( ctx );
+ RtemsStatusReqIsEqual_TestVariant( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-status-is-successful.c b/testsuites/validation/tc-status-is-successful.c
new file mode 100644
index 0000000000..a04a9b4a7f
--- /dev/null
+++ b/testsuites/validation/tc-status-is-successful.c
@@ -0,0 +1,293 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsStatusReqIsSuccessful
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsStatusReqIsSuccessful spec:/rtems/status/req/is-successful
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsStatusReqIsSuccessful_Pre_Status_Successful,
+ RtemsStatusReqIsSuccessful_Pre_Status_Other,
+ RtemsStatusReqIsSuccessful_Pre_Status_NA
+} RtemsStatusReqIsSuccessful_Pre_Status;
+
+typedef enum {
+ RtemsStatusReqIsSuccessful_Post_Result_True,
+ RtemsStatusReqIsSuccessful_Post_Result_False,
+ RtemsStatusReqIsSuccessful_Post_Result_NA
+} RtemsStatusReqIsSuccessful_Post_Result;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Status_NA : 1;
+ uint8_t Post_Result : 2;
+} RtemsStatusReqIsSuccessful_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/status/req/is-successful test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the return value of the
+ * rtems_is_status_successful() call.
+ */
+ bool result;
+
+ /**
+ * @brief This member specifies if the ``status_code`` parameter value.
+ */
+ rtems_status_code status;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsStatusReqIsSuccessful_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsStatusReqIsSuccessful_Context;
+
+static RtemsStatusReqIsSuccessful_Context
+ RtemsStatusReqIsSuccessful_Instance;
+
+static const char * const RtemsStatusReqIsSuccessful_PreDesc_Status[] = {
+ "Successful",
+ "Other",
+ "NA"
+};
+
+static const char * const * const RtemsStatusReqIsSuccessful_PreDesc[] = {
+ RtemsStatusReqIsSuccessful_PreDesc_Status,
+ NULL
+};
+
+static void RtemsStatusReqIsSuccessful_Pre_Status_Prepare(
+ RtemsStatusReqIsSuccessful_Context *ctx,
+ RtemsStatusReqIsSuccessful_Pre_Status state
+)
+{
+ switch ( state ) {
+ case RtemsStatusReqIsSuccessful_Pre_Status_Successful: {
+ /*
+ * While the ``status_code`` parameter is equal to RTEMS_SUCCESSFUL.
+ */
+ ctx->status = RTEMS_SUCCESSFUL;
+ break;
+ }
+
+ case RtemsStatusReqIsSuccessful_Pre_Status_Other: {
+ /*
+ * While the ``status_code`` parameter is not equal to RTEMS_SUCCESSFUL.
+ */
+ ctx->status = RTEMS_INVALID_ID;
+ break;
+ }
+
+ case RtemsStatusReqIsSuccessful_Pre_Status_NA:
+ break;
+ }
+}
+
+static void RtemsStatusReqIsSuccessful_Post_Result_Check(
+ RtemsStatusReqIsSuccessful_Context *ctx,
+ RtemsStatusReqIsSuccessful_Post_Result state
+)
+{
+ switch ( state ) {
+ case RtemsStatusReqIsSuccessful_Post_Result_True: {
+ /*
+ * The return value of rtems_is_status_successful() shall be true.
+ */
+ T_true( ctx->result );
+ break;
+ }
+
+ case RtemsStatusReqIsSuccessful_Post_Result_False: {
+ /*
+ * The return value of rtems_is_status_successful() shall be false.
+ */
+ T_false( ctx->result );
+ break;
+ }
+
+ case RtemsStatusReqIsSuccessful_Post_Result_NA:
+ break;
+ }
+}
+
+static void RtemsStatusReqIsSuccessful_Action(
+ RtemsStatusReqIsSuccessful_Context *ctx
+)
+{
+ ctx->result = rtems_is_status_successful( ctx->status );
+}
+
+static const RtemsStatusReqIsSuccessful_Entry
+RtemsStatusReqIsSuccessful_Entries[] = {
+ { 0, 0, RtemsStatusReqIsSuccessful_Post_Result_True },
+ { 0, 0, RtemsStatusReqIsSuccessful_Post_Result_False }
+};
+
+static const uint8_t
+RtemsStatusReqIsSuccessful_Map[] = {
+ 0, 1
+};
+
+static size_t RtemsStatusReqIsSuccessful_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ RtemsStatusReqIsSuccessful_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsStatusReqIsSuccessful_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsStatusReqIsSuccessful_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsStatusReqIsSuccessful_Scope,
+ .initial_context = &RtemsStatusReqIsSuccessful_Instance
+};
+
+static inline RtemsStatusReqIsSuccessful_Entry
+RtemsStatusReqIsSuccessful_PopEntry( RtemsStatusReqIsSuccessful_Context *ctx )
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsStatusReqIsSuccessful_Entries[
+ RtemsStatusReqIsSuccessful_Map[ index ]
+ ];
+}
+
+static void RtemsStatusReqIsSuccessful_TestVariant(
+ RtemsStatusReqIsSuccessful_Context *ctx
+)
+{
+ RtemsStatusReqIsSuccessful_Pre_Status_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsStatusReqIsSuccessful_Action( ctx );
+ RtemsStatusReqIsSuccessful_Post_Result_Check(
+ ctx,
+ ctx->Map.entry.Post_Result
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsStatusReqIsSuccessful( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsStatusReqIsSuccessful,
+ &RtemsStatusReqIsSuccessful_Fixture
+)
+{
+ RtemsStatusReqIsSuccessful_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsStatusReqIsSuccessful_Pre_Status_Successful;
+ ctx->Map.pcs[ 0 ] < RtemsStatusReqIsSuccessful_Pre_Status_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = RtemsStatusReqIsSuccessful_PopEntry( ctx );
+ RtemsStatusReqIsSuccessful_TestVariant( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-status-text.c b/testsuites/validation/tc-status-text.c
new file mode 100644
index 0000000000..a877519dd2
--- /dev/null
+++ b/testsuites/validation/tc-status-text.c
@@ -0,0 +1,914 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsStatusReqText
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsStatusReqText spec:/rtems/status/req/text
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsStatusReqText_Pre_Code_AlreadySuspended,
+ RtemsStatusReqText_Pre_Code_CalledFromIsr,
+ RtemsStatusReqText_Pre_Code_IllegalOnRemoteObject,
+ RtemsStatusReqText_Pre_Code_IllegalOnSelf,
+ RtemsStatusReqText_Pre_Code_IncorrectState,
+ RtemsStatusReqText_Pre_Code_InternalError,
+ RtemsStatusReqText_Pre_Code_Interrupted,
+ RtemsStatusReqText_Pre_Code_InvalidAddress,
+ RtemsStatusReqText_Pre_Code_InvalidClock,
+ RtemsStatusReqText_Pre_Code_InvalidId,
+ RtemsStatusReqText_Pre_Code_InvalidName,
+ RtemsStatusReqText_Pre_Code_InvalidNode,
+ RtemsStatusReqText_Pre_Code_InvalidNumber,
+ RtemsStatusReqText_Pre_Code_InvalidPriority,
+ RtemsStatusReqText_Pre_Code_InvalidSize,
+ RtemsStatusReqText_Pre_Code_IoError,
+ RtemsStatusReqText_Pre_Code_MpNotConfigured,
+ RtemsStatusReqText_Pre_Code_NoMemory,
+ RtemsStatusReqText_Pre_Code_NotConfigured,
+ RtemsStatusReqText_Pre_Code_NotDefined,
+ RtemsStatusReqText_Pre_Code_NotImplemented,
+ RtemsStatusReqText_Pre_Code_NotOwnerOfResource,
+ RtemsStatusReqText_Pre_Code_ObjectWasDeleted,
+ RtemsStatusReqText_Pre_Code_ProxyBlocking,
+ RtemsStatusReqText_Pre_Code_ResourceInUse,
+ RtemsStatusReqText_Pre_Code_Successful,
+ RtemsStatusReqText_Pre_Code_TaskExitted,
+ RtemsStatusReqText_Pre_Code_Timeout,
+ RtemsStatusReqText_Pre_Code_TooMany,
+ RtemsStatusReqText_Pre_Code_Unsatisfied,
+ RtemsStatusReqText_Pre_Code_NotAStatusCode,
+ RtemsStatusReqText_Pre_Code_NA
+} RtemsStatusReqText_Pre_Code;
+
+typedef enum {
+ RtemsStatusReqText_Post_Result_AlreadySuspended,
+ RtemsStatusReqText_Post_Result_CalledFromIsr,
+ RtemsStatusReqText_Post_Result_IllegalOnRemoteObject,
+ RtemsStatusReqText_Post_Result_IllegalOnSelf,
+ RtemsStatusReqText_Post_Result_IncorrectState,
+ RtemsStatusReqText_Post_Result_InternalError,
+ RtemsStatusReqText_Post_Result_Interrupted,
+ RtemsStatusReqText_Post_Result_InvalidAddress,
+ RtemsStatusReqText_Post_Result_InvalidClock,
+ RtemsStatusReqText_Post_Result_InvalidId,
+ RtemsStatusReqText_Post_Result_InvalidName,
+ RtemsStatusReqText_Post_Result_InvalidNode,
+ RtemsStatusReqText_Post_Result_InvalidNumber,
+ RtemsStatusReqText_Post_Result_InvalidPriority,
+ RtemsStatusReqText_Post_Result_InvalidSize,
+ RtemsStatusReqText_Post_Result_IoError,
+ RtemsStatusReqText_Post_Result_MpNotConfigured,
+ RtemsStatusReqText_Post_Result_NoMemory,
+ RtemsStatusReqText_Post_Result_NotConfigured,
+ RtemsStatusReqText_Post_Result_NotDefined,
+ RtemsStatusReqText_Post_Result_NotImplemented,
+ RtemsStatusReqText_Post_Result_NotOwnerOfResource,
+ RtemsStatusReqText_Post_Result_ObjectWasDeleted,
+ RtemsStatusReqText_Post_Result_ProxyBlocking,
+ RtemsStatusReqText_Post_Result_ResourceInUse,
+ RtemsStatusReqText_Post_Result_Successful,
+ RtemsStatusReqText_Post_Result_TaskExitted,
+ RtemsStatusReqText_Post_Result_Timeout,
+ RtemsStatusReqText_Post_Result_TooMany,
+ RtemsStatusReqText_Post_Result_Unsatisfied,
+ RtemsStatusReqText_Post_Result_NotAStatusCode,
+ RtemsStatusReqText_Post_Result_NA
+} RtemsStatusReqText_Post_Result;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Code_NA : 1;
+ uint8_t Post_Result : 5;
+} RtemsStatusReqText_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/status/req/text test case.
+ */
+typedef struct {
+ /**
+ * @brief This member specifies the ``status_code`` parameter value.
+ */
+ rtems_status_code code;
+
+ /**
+ * @brief This member contains the return value of the rtems_status_text()
+ * call.
+ */
+ const char *result;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsStatusReqText_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsStatusReqText_Context;
+
+static RtemsStatusReqText_Context
+ RtemsStatusReqText_Instance;
+
+static const char * const RtemsStatusReqText_PreDesc_Code[] = {
+ "AlreadySuspended",
+ "CalledFromIsr",
+ "IllegalOnRemoteObject",
+ "IllegalOnSelf",
+ "IncorrectState",
+ "InternalError",
+ "Interrupted",
+ "InvalidAddress",
+ "InvalidClock",
+ "InvalidId",
+ "InvalidName",
+ "InvalidNode",
+ "InvalidNumber",
+ "InvalidPriority",
+ "InvalidSize",
+ "IoError",
+ "MpNotConfigured",
+ "NoMemory",
+ "NotConfigured",
+ "NotDefined",
+ "NotImplemented",
+ "NotOwnerOfResource",
+ "ObjectWasDeleted",
+ "ProxyBlocking",
+ "ResourceInUse",
+ "Successful",
+ "TaskExitted",
+ "Timeout",
+ "TooMany",
+ "Unsatisfied",
+ "NotAStatusCode",
+ "NA"
+};
+
+static const char * const * const RtemsStatusReqText_PreDesc[] = {
+ RtemsStatusReqText_PreDesc_Code,
+ NULL
+};
+
+static void RtemsStatusReqText_Pre_Code_Prepare(
+ RtemsStatusReqText_Context *ctx,
+ RtemsStatusReqText_Pre_Code state
+)
+{
+ switch ( state ) {
+ case RtemsStatusReqText_Pre_Code_AlreadySuspended: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_ALREADY_SUSPENDED.
+ */
+ ctx->code = RTEMS_ALREADY_SUSPENDED;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_CalledFromIsr: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_CALLED_FROM_ISR.
+ */
+ ctx->code = RTEMS_CALLED_FROM_ISR;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_IllegalOnRemoteObject: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_ILLEGAL_ON_REMOTE_OBJECT.
+ */
+
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_IllegalOnSelf: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_ILLEGAL_ON_SELF.
+ */
+ ctx->code = RTEMS_ILLEGAL_ON_SELF;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_IncorrectState: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_INCORRECT_STATE.
+ */
+ ctx->code = RTEMS_INCORRECT_STATE;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_InternalError: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_INTERNAL_ERROR.
+ */
+ ctx->code = RTEMS_INTERNAL_ERROR;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_Interrupted: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_INTERRUPTED.
+ */
+ ctx->code = RTEMS_INTERRUPTED;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_InvalidAddress: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_INVALID_ADDRESS.
+ */
+ ctx->code = RTEMS_INVALID_ADDRESS;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_InvalidClock: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_INVALID_CLOCK.
+ */
+ ctx->code = RTEMS_INVALID_CLOCK;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_InvalidId: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_INVALID_ID.
+ */
+ ctx->code = RTEMS_INVALID_ID;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_InvalidName: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_INVALID_NAME.
+ */
+ ctx->code = RTEMS_INVALID_NAME;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_InvalidNode: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_INVALID_NODE.
+ */
+ ctx->code = RTEMS_INVALID_NODE;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_InvalidNumber: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_INVALID_NUMBER.
+ */
+ ctx->code = RTEMS_INVALID_NUMBER;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_InvalidPriority: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_INVALID_PRIORITY.
+ */
+ ctx->code = RTEMS_INVALID_PRIORITY;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_InvalidSize: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_INVALID_SIZE.
+ */
+ ctx->code = RTEMS_INVALID_SIZE;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_IoError: {
+ /*
+ * While the ``status_code`` parameter value is equal to RTEMS_IO_ERROR.
+ */
+ ctx->code = RTEMS_IO_ERROR;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_MpNotConfigured: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_MP_NOT_CONFIGURED.
+ */
+ ctx->code = RTEMS_MP_NOT_CONFIGURED;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_NoMemory: {
+ /*
+ * While the ``status_code`` parameter value is equal to RTEMS_NO_MEMORY.
+ */
+ ctx->code = RTEMS_NO_MEMORY;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_NotConfigured: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_NOT_CONFIGURED.
+ */
+ ctx->code = RTEMS_NOT_CONFIGURED;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_NotDefined: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_NOT_DEFINED.
+ */
+ ctx->code = RTEMS_NOT_DEFINED;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_NotImplemented: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_NOT_IMPLEMENTED.
+ */
+ ctx->code = RTEMS_NOT_IMPLEMENTED;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_NotOwnerOfResource: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_NOT_OWNER_OF_RESOURCE.
+ */
+ ctx->code = RTEMS_NOT_OWNER_OF_RESOURCE;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_ObjectWasDeleted: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_OBJECT_WAS_DELETED.
+ */
+ ctx->code = RTEMS_OBJECT_WAS_DELETED;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_ProxyBlocking: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_PROXY_BLOCKING.
+ */
+ ctx->code = RTEMS_PROXY_BLOCKING;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_ResourceInUse: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_RESOURCE_IN_USE.
+ */
+ ctx->code = RTEMS_RESOURCE_IN_USE;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_Successful: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_SUCCESSFUL.
+ */
+ ctx->code = RTEMS_SUCCESSFUL;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_TaskExitted: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_TASK_EXITTED.
+ */
+ ctx->code = RTEMS_TASK_EXITTED;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_Timeout: {
+ /*
+ * While the ``status_code`` parameter value is equal to RTEMS_TIMEOUT.
+ */
+ ctx->code = RTEMS_TIMEOUT;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_TooMany: {
+ /*
+ * While the ``status_code`` parameter value is equal to RTEMS_TOO_MANY.
+ */
+ ctx->code = RTEMS_TOO_MANY;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_Unsatisfied: {
+ /*
+ * While the ``status_code`` parameter value is equal to
+ * RTEMS_UNSATISFIED.
+ */
+ ctx->code = RTEMS_UNSATISFIED;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_NotAStatusCode: {
+ /*
+ * While the ``status_code`` parameter is not equal to an enumerator of
+ * rtems_status_code.
+ */
+ ctx->code = (rtems_status_code) 123;
+ break;
+ }
+
+ case RtemsStatusReqText_Pre_Code_NA:
+ break;
+ }
+}
+
+static void RtemsStatusReqText_Post_Result_Check(
+ RtemsStatusReqText_Context *ctx,
+ RtemsStatusReqText_Post_Result state
+)
+{
+ switch ( state ) {
+ case RtemsStatusReqText_Post_Result_AlreadySuspended: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_ALREADY_SUSPENDED".
+ */
+ T_eq_str( ctx->result, "RTEMS_ALREADY_SUSPENDED" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_CalledFromIsr: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_CALLED_FROM_ISR".
+ */
+ T_eq_str( ctx->result, "RTEMS_CALLED_FROM_ISR" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_IllegalOnRemoteObject: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_ILLEGAL_ON_REMOTE_OBJECT".
+ */
+
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_IllegalOnSelf: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_ILLEGAL_ON_SELF".
+ */
+ T_eq_str( ctx->result, "RTEMS_ILLEGAL_ON_SELF" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_IncorrectState: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_INCORRECT_STATE".
+ */
+ T_eq_str( ctx->result, "RTEMS_INCORRECT_STATE" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_InternalError: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_INTERNAL_ERROR".
+ */
+ T_eq_str( ctx->result, "RTEMS_INTERNAL_ERROR" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_Interrupted: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_INTERRUPTED".
+ */
+ T_eq_str( ctx->result, "RTEMS_INTERRUPTED" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_InvalidAddress: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_INVALID_ADDRESS".
+ */
+ T_eq_str( ctx->result, "RTEMS_INVALID_ADDRESS" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_InvalidClock: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_INVALID_CLOCK".
+ */
+ T_eq_str( ctx->result, "RTEMS_INVALID_CLOCK" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_InvalidId: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_INVALID_ID".
+ */
+ T_eq_str( ctx->result, "RTEMS_INVALID_ID" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_InvalidName: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_INVALID_NAME".
+ */
+ T_eq_str( ctx->result, "RTEMS_INVALID_NAME" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_InvalidNode: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_INVALID_NODE".
+ */
+ T_eq_str( ctx->result, "RTEMS_INVALID_NODE" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_InvalidNumber: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_INVALID_NUMBER".
+ */
+ T_eq_str( ctx->result, "RTEMS_INVALID_NUMBER" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_InvalidPriority: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_INVALID_PRIORITY".
+ */
+ T_eq_str( ctx->result, "RTEMS_INVALID_PRIORITY" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_InvalidSize: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_INVALID_SIZE".
+ */
+ T_eq_str( ctx->result, "RTEMS_INVALID_SIZE" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_IoError: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_IO_ERROR".
+ */
+ T_eq_str( ctx->result, "RTEMS_IO_ERROR" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_MpNotConfigured: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_MP_NOT_CONFIGURED".
+ */
+ T_eq_str( ctx->result, "RTEMS_MP_NOT_CONFIGURED" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_NoMemory: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_NO_MEMORY".
+ */
+ T_eq_str( ctx->result, "RTEMS_NO_MEMORY" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_NotConfigured: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_NOT_CONFIGURED".
+ */
+ T_eq_str( ctx->result, "RTEMS_NOT_CONFIGURED" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_NotDefined: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_NOT_DEFINED".
+ */
+ T_eq_str( ctx->result, "RTEMS_NOT_DEFINED" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_NotImplemented: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_NOT_IMPLEMENTED".
+ */
+ T_eq_str( ctx->result, "RTEMS_NOT_IMPLEMENTED" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_NotOwnerOfResource: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_NOT_OWNER_OF_RESOURCE".
+ */
+ T_eq_str( ctx->result, "RTEMS_NOT_OWNER_OF_RESOURCE" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_ObjectWasDeleted: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_OBJECT_WAS_DELETED".
+ */
+ T_eq_str( ctx->result, "RTEMS_OBJECT_WAS_DELETED" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_ProxyBlocking: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_PROXY_BLOCKING".
+ */
+ T_eq_str( ctx->result, "RTEMS_PROXY_BLOCKING" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_ResourceInUse: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_RESOURCE_IN_USE".
+ */
+ T_eq_str( ctx->result, "RTEMS_RESOURCE_IN_USE" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_Successful: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_SUCCESSFUL".
+ */
+ T_eq_str( ctx->result, "RTEMS_SUCCESSFUL" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_TaskExitted: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_TASK_EXITTED".
+ */
+ T_eq_str( ctx->result, "RTEMS_TASK_EXITTED" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_Timeout: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_TIMEOUT".
+ */
+ T_eq_str( ctx->result, "RTEMS_TIMEOUT" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_TooMany: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_TOO_MANY".
+ */
+ T_eq_str( ctx->result, "RTEMS_TOO_MANY" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_Unsatisfied: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "RTEMS_UNSATISFIED".
+ */
+ T_eq_str( ctx->result, "RTEMS_UNSATISFIED" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_NotAStatusCode: {
+ /*
+ * The return value of rtems_status_text() shall reference a string which
+ * is equal to "?".
+ */
+ T_eq_str( ctx->result, "?" );
+ break;
+ }
+
+ case RtemsStatusReqText_Post_Result_NA:
+ break;
+ }
+}
+
+static void RtemsStatusReqText_Action( RtemsStatusReqText_Context *ctx )
+{
+ ctx->result = rtems_status_text( ctx->code );
+}
+
+static const RtemsStatusReqText_Entry
+RtemsStatusReqText_Entries[] = {
+ { 0, 0, RtemsStatusReqText_Post_Result_AlreadySuspended },
+ { 0, 0, RtemsStatusReqText_Post_Result_CalledFromIsr },
+ { 0, 0, RtemsStatusReqText_Post_Result_IllegalOnRemoteObject },
+ { 0, 0, RtemsStatusReqText_Post_Result_IllegalOnSelf },
+ { 0, 0, RtemsStatusReqText_Post_Result_IncorrectState },
+ { 0, 0, RtemsStatusReqText_Post_Result_InternalError },
+ { 0, 0, RtemsStatusReqText_Post_Result_Interrupted },
+ { 0, 0, RtemsStatusReqText_Post_Result_InvalidAddress },
+ { 0, 0, RtemsStatusReqText_Post_Result_InvalidClock },
+ { 0, 0, RtemsStatusReqText_Post_Result_InvalidId },
+ { 0, 0, RtemsStatusReqText_Post_Result_InvalidName },
+ { 0, 0, RtemsStatusReqText_Post_Result_InvalidNode },
+ { 0, 0, RtemsStatusReqText_Post_Result_InvalidNumber },
+ { 0, 0, RtemsStatusReqText_Post_Result_InvalidPriority },
+ { 0, 0, RtemsStatusReqText_Post_Result_InvalidSize },
+ { 0, 0, RtemsStatusReqText_Post_Result_IoError },
+ { 0, 0, RtemsStatusReqText_Post_Result_MpNotConfigured },
+ { 0, 0, RtemsStatusReqText_Post_Result_NoMemory },
+ { 0, 0, RtemsStatusReqText_Post_Result_NotConfigured },
+ { 0, 0, RtemsStatusReqText_Post_Result_NotDefined },
+ { 0, 0, RtemsStatusReqText_Post_Result_NotImplemented },
+ { 0, 0, RtemsStatusReqText_Post_Result_NotOwnerOfResource },
+ { 0, 0, RtemsStatusReqText_Post_Result_ObjectWasDeleted },
+ { 0, 0, RtemsStatusReqText_Post_Result_ProxyBlocking },
+ { 0, 0, RtemsStatusReqText_Post_Result_ResourceInUse },
+ { 0, 0, RtemsStatusReqText_Post_Result_Successful },
+ { 0, 0, RtemsStatusReqText_Post_Result_TaskExitted },
+ { 0, 0, RtemsStatusReqText_Post_Result_Timeout },
+ { 0, 0, RtemsStatusReqText_Post_Result_TooMany },
+ { 0, 0, RtemsStatusReqText_Post_Result_Unsatisfied },
+ { 0, 0, RtemsStatusReqText_Post_Result_NotAStatusCode }
+};
+
+static const uint8_t
+RtemsStatusReqText_Map[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 25, 26, 27, 28, 29, 30
+};
+
+static size_t RtemsStatusReqText_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsStatusReqText_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsStatusReqText_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsStatusReqText_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsStatusReqText_Scope,
+ .initial_context = &RtemsStatusReqText_Instance
+};
+
+static inline RtemsStatusReqText_Entry RtemsStatusReqText_PopEntry(
+ RtemsStatusReqText_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsStatusReqText_Entries[
+ RtemsStatusReqText_Map[ index ]
+ ];
+}
+
+static void RtemsStatusReqText_TestVariant( RtemsStatusReqText_Context *ctx )
+{
+ RtemsStatusReqText_Pre_Code_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsStatusReqText_Action( ctx );
+ RtemsStatusReqText_Post_Result_Check( ctx, ctx->Map.entry.Post_Result );
+}
+
+/**
+ * @fn void T_case_body_RtemsStatusReqText( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsStatusReqText, &RtemsStatusReqText_Fixture )
+{
+ RtemsStatusReqText_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsStatusReqText_Pre_Code_AlreadySuspended;
+ ctx->Map.pcs[ 0 ] < RtemsStatusReqText_Pre_Code_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = RtemsStatusReqText_PopEntry( ctx );
+ RtemsStatusReqText_TestVariant( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-status.c b/testsuites/validation/tc-status.c
new file mode 100644
index 0000000000..41752a7f7d
--- /dev/null
+++ b/testsuites/validation/tc-status.c
@@ -0,0 +1,121 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsStatusValStatus
+ */
+
+/*
+ * Copyright (C) 2021, 2023 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsStatusValStatus spec:/rtems/status/val/status
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests some @ref RTEMSAPIClassicStatus interfaces.
+ *
+ * This test case performs the following actions:
+ *
+ * - Validate the status code constants.
+ *
+ * - Assert that RTEMS_STATUS_CODES_FIRST has the expected value and is a
+ * constant expression.
+ *
+ * - Check that RTEMS_STATUS_CODES_FIRST has the expected value.
+ *
+ * - Assert that RTEMS_STATUS_CODES_LAST has the expected value and is a
+ * constant expression.
+ *
+ * - Check that RTEMS_STATUS_CODES_LAST has the expected value.
+ *
+ * @{
+ */
+
+/**
+ * @brief Validate the status code constants.
+ */
+static void RtemsStatusValStatus_Action_0( void )
+{
+ /* Nothing to do */
+
+ /*
+ * Assert that RTEMS_STATUS_CODES_FIRST has the expected value and is a
+ * constant expression.
+ */
+ RTEMS_STATIC_ASSERT( RTEMS_STATUS_CODES_FIRST == 0, FIRST );
+
+ /*
+ * Check that RTEMS_STATUS_CODES_FIRST has the expected value.
+ */
+ T_eq_int( RTEMS_STATUS_CODES_FIRST, 0 );
+
+ /*
+ * Assert that RTEMS_STATUS_CODES_LAST has the expected value and is a
+ * constant expression.
+ */
+ RTEMS_STATIC_ASSERT( RTEMS_STATUS_CODES_LAST == 29, LAST );
+
+ /*
+ * Check that RTEMS_STATUS_CODES_LAST has the expected value.
+ */
+ T_eq_int( RTEMS_STATUS_CODES_LAST, 29 );
+}
+
+/**
+ * @fn void T_case_body_RtemsStatusValStatus( void )
+ */
+T_TEST_CASE( RtemsStatusValStatus )
+{
+ RtemsStatusValStatus_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-support-is-name-valid.c b/testsuites/validation/tc-support-is-name-valid.c
new file mode 100644
index 0000000000..2a47d27cd5
--- /dev/null
+++ b/testsuites/validation/tc-support-is-name-valid.c
@@ -0,0 +1,293 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSupportReqIsNameValid
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSupportReqIsNameValid spec:/rtems/support/req/is-name-valid
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsSupportReqIsNameValid_Pre_Name_Valid,
+ RtemsSupportReqIsNameValid_Pre_Name_Invalid,
+ RtemsSupportReqIsNameValid_Pre_Name_NA
+} RtemsSupportReqIsNameValid_Pre_Name;
+
+typedef enum {
+ RtemsSupportReqIsNameValid_Post_Result_True,
+ RtemsSupportReqIsNameValid_Post_Result_False,
+ RtemsSupportReqIsNameValid_Post_Result_NA
+} RtemsSupportReqIsNameValid_Post_Result;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Name_NA : 1;
+ uint8_t Post_Result : 2;
+} RtemsSupportReqIsNameValid_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/support/req/is-name-valid test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the return value of the rtems_is_name_valid()
+ * call.
+ */
+ bool result;
+
+ /**
+ * @brief This member specifies if the ``name`` parameter value.
+ */
+ rtems_name name;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsSupportReqIsNameValid_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsSupportReqIsNameValid_Context;
+
+static RtemsSupportReqIsNameValid_Context
+ RtemsSupportReqIsNameValid_Instance;
+
+static const char * const RtemsSupportReqIsNameValid_PreDesc_Name[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const * const RtemsSupportReqIsNameValid_PreDesc[] = {
+ RtemsSupportReqIsNameValid_PreDesc_Name,
+ NULL
+};
+
+static void RtemsSupportReqIsNameValid_Pre_Name_Prepare(
+ RtemsSupportReqIsNameValid_Context *ctx,
+ RtemsSupportReqIsNameValid_Pre_Name state
+)
+{
+ switch ( state ) {
+ case RtemsSupportReqIsNameValid_Pre_Name_Valid: {
+ /*
+ * While the ``name`` parameter is not equal to zero.
+ */
+ ctx->name = 1;
+ break;
+ }
+
+ case RtemsSupportReqIsNameValid_Pre_Name_Invalid: {
+ /*
+ * While the ``name`` parameter is equal to zero.
+ */
+ ctx->name = 0;
+ break;
+ }
+
+ case RtemsSupportReqIsNameValid_Pre_Name_NA:
+ break;
+ }
+}
+
+static void RtemsSupportReqIsNameValid_Post_Result_Check(
+ RtemsSupportReqIsNameValid_Context *ctx,
+ RtemsSupportReqIsNameValid_Post_Result state
+)
+{
+ switch ( state ) {
+ case RtemsSupportReqIsNameValid_Post_Result_True: {
+ /*
+ * The return value of rtems_is_name_valid() shall be true.
+ */
+ T_true( ctx->result );
+ break;
+ }
+
+ case RtemsSupportReqIsNameValid_Post_Result_False: {
+ /*
+ * The return value of rtems_is_name_valid() shall be false.
+ */
+ T_false( ctx->result );
+ break;
+ }
+
+ case RtemsSupportReqIsNameValid_Post_Result_NA:
+ break;
+ }
+}
+
+static void RtemsSupportReqIsNameValid_Action(
+ RtemsSupportReqIsNameValid_Context *ctx
+)
+{
+ ctx->result = rtems_is_name_valid( ctx->name );
+}
+
+static const RtemsSupportReqIsNameValid_Entry
+RtemsSupportReqIsNameValid_Entries[] = {
+ { 0, 0, RtemsSupportReqIsNameValid_Post_Result_True },
+ { 0, 0, RtemsSupportReqIsNameValid_Post_Result_False }
+};
+
+static const uint8_t
+RtemsSupportReqIsNameValid_Map[] = {
+ 0, 1
+};
+
+static size_t RtemsSupportReqIsNameValid_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ RtemsSupportReqIsNameValid_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsSupportReqIsNameValid_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsSupportReqIsNameValid_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsSupportReqIsNameValid_Scope,
+ .initial_context = &RtemsSupportReqIsNameValid_Instance
+};
+
+static inline RtemsSupportReqIsNameValid_Entry
+RtemsSupportReqIsNameValid_PopEntry( RtemsSupportReqIsNameValid_Context *ctx )
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsSupportReqIsNameValid_Entries[
+ RtemsSupportReqIsNameValid_Map[ index ]
+ ];
+}
+
+static void RtemsSupportReqIsNameValid_TestVariant(
+ RtemsSupportReqIsNameValid_Context *ctx
+)
+{
+ RtemsSupportReqIsNameValid_Pre_Name_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsSupportReqIsNameValid_Action( ctx );
+ RtemsSupportReqIsNameValid_Post_Result_Check(
+ ctx,
+ ctx->Map.entry.Post_Result
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsSupportReqIsNameValid( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsSupportReqIsNameValid,
+ &RtemsSupportReqIsNameValid_Fixture
+)
+{
+ RtemsSupportReqIsNameValid_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsSupportReqIsNameValid_Pre_Name_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsSupportReqIsNameValid_Pre_Name_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = RtemsSupportReqIsNameValid_PopEntry( ctx );
+ RtemsSupportReqIsNameValid_TestVariant( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-support.c b/testsuites/validation/tc-support.c
new file mode 100644
index 0000000000..3e886c6027
--- /dev/null
+++ b/testsuites/validation/tc-support.c
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSupportValSupport
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSupportValSupport spec:/rtems/support/val/support
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests some @ref RTEMSAPIClassicSupport directives.
+ *
+ * This test case performs the following actions:
+ *
+ * - Validates the characters returned by the rtems_name_to_characters()
+ * directive.
+ *
+ * - Check that the first character is equal to 0x01.
+ *
+ * - Check that the second character is equal to 0x02.
+ *
+ * - Check that the third character is equal to 0x03.
+ *
+ * - Check that the fourth character is equal to 0x04.
+ *
+ * @{
+ */
+
+/**
+ * @brief Validates the characters returned by the rtems_name_to_characters()
+ * directive.
+ */
+static void RtemsSupportValSupport_Action_0( void )
+{
+ char c1;
+ char c2;
+ char c3;
+ char c4;
+
+ rtems_name_to_characters( 0x01020304, &c1, &c2, &c3, &c4 );
+
+ /*
+ * Check that the first character is equal to 0x01.
+ */
+ T_step_eq_char( 0, c1, 0x01 );
+
+ /*
+ * Check that the second character is equal to 0x02.
+ */
+ T_step_eq_char( 1, c2, 0x02 );
+
+ /*
+ * Check that the third character is equal to 0x03.
+ */
+ T_step_eq_char( 2, c3, 0x03 );
+
+ /*
+ * Check that the fourth character is equal to 0x04.
+ */
+ T_step_eq_char( 3, c4, 0x04 );
+}
+
+/**
+ * @fn void T_case_body_RtemsSupportValSupport( void )
+ */
+T_TEST_CASE( RtemsSupportValSupport )
+{
+ T_plan( 4 );
+
+ RtemsSupportValSupport_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-sys-lock.c b/testsuites/validation/tc-sys-lock.c
new file mode 100644
index 0000000000..56939a3dba
--- /dev/null
+++ b/testsuites/validation/tc-sys-lock.c
@@ -0,0 +1,433 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup NewlibValSysLock
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <errno.h>
+#include <string.h>
+#include <sys/lock.h>
+
+#include "tr-mtx-seize-try.h"
+#include "tr-mtx-seize-wait.h"
+#include "tr-mtx-surrender.h"
+#include "tr-tq-timeout-priority-inherit.h"
+#include "tx-thread-queue.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup NewlibValSysLock spec:/newlib/val/sys-lock
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests the <sys/lock.h> mutex directives.
+ *
+ * This test case performs the following actions:
+ *
+ * - Create a mutex and validate the mutex directives.
+ *
+ * - Validate the _Mutex_Try_acquire() directive.
+ *
+ * - Validate the _Mutex_Acquire_timed() directive for valid timeout
+ * parameters.
+ *
+ * - Validate the _Mutex_Acquire_timed() directive for an invalid timeout
+ * parameter.
+ *
+ * - Validate the _Mutex_Acquire_timed() timeout behaviour.
+ *
+ * - Validate the _Mutex_Acquire() directive.
+ *
+ * - Validate the _Mutex_Try_acquire() directive.
+ *
+ * - Destroy the mutex.
+ *
+ * - Create a recursive mutex and validate the mutex directives.
+ *
+ * - Validate the _Mutex_recursive_Try_acquire() directive.
+ *
+ * - Validate the _Mutex_recursive_Acquire_timed() directive for valid
+ * timeout parameters.
+ *
+ * - Validate the _Mutex_recursive_Acquire_timed() directive for an invalid
+ * timeout parameter.
+ *
+ * - Validate the _Mutex_recursive_Acquire_timed() timeout behaviour.
+ *
+ * - Validate the _Mutex_recursive_Acquire() directive.
+ *
+ * - Validate the _Mutex_recursive_Try_acquire() directive.
+ *
+ * - Destroy the mutex.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/newlib/val/sys-lock test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the thread queue test context.
+ */
+ TQMtxContext tq_mtx_ctx;
+} NewlibValSysLock_Context;
+
+static NewlibValSysLock_Context
+ NewlibValSysLock_Instance;
+
+static Status_Control Enqueue( TQContext *ctx, TQWait wait )
+{
+ const struct timespec abstime = {
+ .tv_sec = INT64_MAX,
+ .tv_nsec = 0
+ };
+ int eno;
+
+ switch ( wait ) {
+ case TQ_NO_WAIT:
+ eno = _Mutex_Try_acquire( ctx->thread_queue_object );
+ break;
+ case TQ_WAIT_FOREVER:
+ _Mutex_Acquire( ctx->thread_queue_object );
+ eno = 0;
+ break;
+ case TQ_WAIT_TIMED:
+ eno = _Mutex_Acquire_timed( ctx->thread_queue_object, &abstime );
+ break;
+ default:
+ T_unreachable();
+ break;
+ }
+
+ return STATUS_BUILD( 0, eno );
+}
+
+static Status_Control Surrender( TQContext *ctx )
+{
+ _Mutex_Release( ctx->thread_queue_object );
+
+ return STATUS_SUCCESSFUL;
+}
+
+static rtems_tcb *GetOwner( TQContext *ctx )
+{
+ const struct _Mutex_Control *mutex;
+
+ mutex = ctx->thread_queue_object;
+
+ return mutex->_Queue._owner;
+}
+
+static Status_Control RecursiveEnqueue( TQContext *ctx, TQWait wait )
+{
+ const struct timespec abstime = {
+ .tv_sec = INT64_MAX,
+ .tv_nsec = 0
+ };
+ int eno;
+
+ switch ( wait ) {
+ case TQ_NO_WAIT:
+ eno = _Mutex_recursive_Try_acquire( ctx->thread_queue_object );
+ break;
+ case TQ_WAIT_FOREVER:
+ _Mutex_recursive_Acquire( ctx->thread_queue_object );
+ eno = 0;
+ break;
+ case TQ_WAIT_TIMED:
+ eno = _Mutex_recursive_Acquire_timed(
+ ctx->thread_queue_object,
+ &abstime
+ );
+ break;
+ default:
+ T_unreachable();
+ break;
+ }
+
+ return STATUS_BUILD( 0, eno );
+}
+
+static Status_Control RecursiveSurrender( TQContext *ctx )
+{
+ _Mutex_recursive_Release( ctx->thread_queue_object );
+
+ return STATUS_SUCCESSFUL;
+}
+
+static rtems_tcb *RecursiveGetOwner( TQContext *ctx )
+{
+ const struct _Mutex_recursive_Control *mutex;
+
+ mutex = ctx->thread_queue_object;
+
+ return mutex->_Mutex._Queue._owner;
+}
+
+static void NewlibValSysLock_Setup( NewlibValSysLock_Context *ctx )
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->tq_mtx_ctx.base.enqueue_variant = TQ_ENQUEUE_BLOCKS;
+ ctx->tq_mtx_ctx.base.discipline = TQ_PRIORITY;
+ ctx->tq_mtx_ctx.base.deadlock = TQ_DEADLOCK_FATAL;
+ ctx->tq_mtx_ctx.base.convert_status = TQConvertStatusPOSIX;
+ ctx->tq_mtx_ctx.protocol = TQ_MTX_PRIORITY_INHERIT;
+ ctx->tq_mtx_ctx.owner_check = TQ_MTX_NO_OWNER_CHECK;
+ ctx->tq_mtx_ctx.priority_ceiling = PRIO_INVALID;
+ TQInitialize( &ctx->tq_mtx_ctx.base );
+}
+
+static void NewlibValSysLock_Setup_Wrap( void *arg )
+{
+ NewlibValSysLock_Context *ctx;
+
+ ctx = arg;
+ NewlibValSysLock_Setup( ctx );
+}
+
+static void NewlibValSysLock_Teardown( NewlibValSysLock_Context *ctx )
+{
+ TQDestroy( &ctx->tq_mtx_ctx.base );
+ RestoreRunnerPriority();
+}
+
+static void NewlibValSysLock_Teardown_Wrap( void *arg )
+{
+ NewlibValSysLock_Context *ctx;
+
+ ctx = arg;
+ NewlibValSysLock_Teardown( ctx );
+}
+
+static T_fixture NewlibValSysLock_Fixture = {
+ .setup = NewlibValSysLock_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NewlibValSysLock_Teardown_Wrap,
+ .scope = NULL,
+ .initial_context = &NewlibValSysLock_Instance
+};
+
+/**
+ * @brief Create a mutex and validate the mutex directives.
+ */
+static void NewlibValSysLock_Action_0( NewlibValSysLock_Context *ctx )
+{
+ const struct timespec invalid_abstime = {
+ .tv_sec = -1,
+ .tv_nsec = -1
+ };
+ int eno;
+ struct _Mutex_Control mutex;
+
+ _Mutex_Initialize( &mutex );
+
+ ctx->tq_mtx_ctx.base.thread_queue_object = &mutex;
+ ctx->tq_mtx_ctx.base.enqueue_prepare = TQEnqueuePrepareDefault;
+ ctx->tq_mtx_ctx.base.enqueue_done = TQEnqueueDoneDefault;
+ ctx->tq_mtx_ctx.base.enqueue = Enqueue;
+ ctx->tq_mtx_ctx.base.surrender = Surrender;
+ ctx->tq_mtx_ctx.base.get_owner = GetOwner;
+
+ /*
+ * Validate the _Mutex_Try_acquire() directive.
+ */
+ ctx->tq_mtx_ctx.base.wait = TQ_NO_WAIT;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_UNAVAILABLE;
+ ScoreMtxReqSeizeTry_Run( &ctx->tq_mtx_ctx );
+
+ /*
+ * Validate the _Mutex_Acquire_timed() directive for valid timeout
+ * parameters.
+ */
+ ctx->tq_mtx_ctx.base.wait = TQ_WAIT_TIMED;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_DEADLOCK;
+ ScoreMtxReqSeizeWait_Run( &ctx->tq_mtx_ctx );
+
+ /*
+ * Validate the _Mutex_Acquire_timed() directive for an invalid timeout
+ * parameter.
+ */
+ TQSetScheduler(
+ &ctx->tq_mtx_ctx.base,
+ TQ_HELPER_A,
+ SCHEDULER_A_ID,
+ PRIO_HIGH
+ );
+ TQSend( &ctx->tq_mtx_ctx.base, TQ_HELPER_A, TQ_EVENT_ENQUEUE );
+ eno = _Mutex_Acquire_timed( &mutex, &invalid_abstime );
+ T_eq_int( eno, EINVAL );
+ TQSend( &ctx->tq_mtx_ctx.base, TQ_HELPER_A, TQ_EVENT_SURRENDER );
+
+ /*
+ * Validate the _Mutex_Acquire_timed() timeout behaviour.
+ */
+ ctx->tq_mtx_ctx.base.wait = TQ_WAIT_FOREVER;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_DEADLOCK;
+ ScoreTqReqTimeoutPriorityInherit_Run(
+ &ctx->tq_mtx_ctx.base
+ );
+
+ /*
+ * Validate the _Mutex_Acquire() directive.
+ */
+ ctx->tq_mtx_ctx.base.wait = TQ_WAIT_FOREVER;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_DEADLOCK;
+ ScoreMtxReqSeizeWait_Run( &ctx->tq_mtx_ctx );
+
+ /*
+ * Validate the _Mutex_Try_acquire() directive.
+ */
+ ctx->tq_mtx_ctx.base.wait = TQ_WAIT_FOREVER;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_DEADLOCK;
+ ScoreMtxReqSurrender_Run( &ctx->tq_mtx_ctx );
+
+ /*
+ * Destroy the mutex.
+ */
+ _Mutex_Destroy( &mutex );
+}
+
+/**
+ * @brief Create a recursive mutex and validate the mutex directives.
+ */
+static void NewlibValSysLock_Action_1( NewlibValSysLock_Context *ctx )
+{
+ const struct timespec invalid_abstime = {
+ .tv_sec = -1,
+ .tv_nsec = -1
+ };
+ int eno;
+ struct _Mutex_recursive_Control mutex;
+
+ _Mutex_recursive_Initialize( &mutex );
+
+ ctx->tq_mtx_ctx.base.thread_queue_object = &mutex;
+ ctx->tq_mtx_ctx.base.enqueue_prepare = TQEnqueuePrepareDefault;
+ ctx->tq_mtx_ctx.base.enqueue_done = TQEnqueueDoneDefault;
+ ctx->tq_mtx_ctx.base.enqueue = RecursiveEnqueue;
+ ctx->tq_mtx_ctx.base.surrender = RecursiveSurrender;
+ ctx->tq_mtx_ctx.base.get_owner = RecursiveGetOwner;
+
+ /*
+ * Validate the _Mutex_recursive_Try_acquire() directive.
+ */
+ ctx->tq_mtx_ctx.base.wait = TQ_NO_WAIT;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
+ ScoreMtxReqSeizeTry_Run( &ctx->tq_mtx_ctx );
+
+ /*
+ * Validate the _Mutex_recursive_Acquire_timed() directive for valid timeout
+ * parameters.
+ */
+ ctx->tq_mtx_ctx.base.wait = TQ_WAIT_TIMED;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
+ ScoreMtxReqSeizeWait_Run( &ctx->tq_mtx_ctx );
+
+ /*
+ * Validate the _Mutex_recursive_Acquire_timed() directive for an invalid
+ * timeout parameter.
+ */
+ TQSetScheduler(
+ &ctx->tq_mtx_ctx.base,
+ TQ_HELPER_A,
+ SCHEDULER_A_ID,
+ PRIO_HIGH
+ );
+ TQSend( &ctx->tq_mtx_ctx.base, TQ_HELPER_A, TQ_EVENT_ENQUEUE );
+ eno = _Mutex_recursive_Acquire_timed( &mutex, &invalid_abstime );
+ T_eq_int( eno, EINVAL );
+ TQSend( &ctx->tq_mtx_ctx.base, TQ_HELPER_A, TQ_EVENT_SURRENDER );
+
+ /*
+ * Validate the _Mutex_recursive_Acquire_timed() timeout behaviour.
+ */
+ ctx->tq_mtx_ctx.base.wait = TQ_WAIT_FOREVER;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
+ ScoreTqReqTimeoutPriorityInherit_Run(
+ &ctx->tq_mtx_ctx.base
+ );
+
+ /*
+ * Validate the _Mutex_recursive_Acquire() directive.
+ */
+ ctx->tq_mtx_ctx.base.wait = TQ_WAIT_FOREVER;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
+ ScoreMtxReqSeizeWait_Run( &ctx->tq_mtx_ctx );
+
+ /*
+ * Validate the _Mutex_recursive_Try_acquire() directive.
+ */
+ ctx->tq_mtx_ctx.base.wait = TQ_WAIT_FOREVER;
+ ctx->tq_mtx_ctx.recursive = TQ_MTX_RECURSIVE_ALLOWED;
+ ScoreMtxReqSurrender_Run( &ctx->tq_mtx_ctx );
+
+ /*
+ * Destroy the mutex.
+ */
+ _Mutex_recursive_Destroy( &mutex );
+}
+
+/**
+ * @fn void T_case_body_NewlibValSysLock( void )
+ */
+T_TEST_CASE_FIXTURE( NewlibValSysLock, &NewlibValSysLock_Fixture )
+{
+ NewlibValSysLock_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ NewlibValSysLock_Action_0( ctx );
+ NewlibValSysLock_Action_1( ctx );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-construct-errors.c b/testsuites/validation/tc-task-construct-errors.c
deleted file mode 100644
index e6f8c5faa5..0000000000
--- a/testsuites/validation/tc-task-construct-errors.c
+++ /dev/null
@@ -1,1207 +0,0 @@
-/* SPDX-License-Identifier: BSD-2-Clause */
-
-/**
- * @file
- *
- * @ingroup RTEMSTestCaseRtemsTaskReqConstructErrors
- */
-
-/*
- * Copyright (C) 2020, 2021 embedded brains GmbH (http://www.embedded-brains.de)
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * This file is part of the RTEMS quality process and was automatically
- * generated. If you find something that needs to be fixed or
- * worded better please post a report or patch to an RTEMS mailing list
- * or raise a bug report:
- *
- * https://www.rtems.org/bugs.html
- *
- * For information on updating and regenerating please refer to the How-To
- * section in the Software Requirements Engineering chapter of the
- * RTEMS Software Engineering manual. The manual is provided as a part of
- * a release. For development sources please refer to the online
- * documentation at:
- *
- * https://docs.rtems.org
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <rtems.h>
-#include <string.h>
-#include <rtems/score/apimutex.h>
-#include <rtems/score/threadimpl.h>
-
-#include <rtems/test.h>
-
-/**
- * @defgroup RTEMSTestCaseRtemsTaskReqConstructErrors \
- * spec:/rtems/task/req/construct-errors
- *
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
- * @ingroup RTEMSTestSuiteTestsuitesValidation1
- *
- * @{
- */
-
-typedef enum {
- RtemsTaskReqConstructErrors_Pre_Config_Valid,
- RtemsTaskReqConstructErrors_Pre_Config_Null,
- RtemsTaskReqConstructErrors_Pre_Config_NA
-} RtemsTaskReqConstructErrors_Pre_Config;
-
-typedef enum {
- RtemsTaskReqConstructErrors_Pre_Name_Valid,
- RtemsTaskReqConstructErrors_Pre_Name_Inv,
- RtemsTaskReqConstructErrors_Pre_Name_NA
-} RtemsTaskReqConstructErrors_Pre_Name;
-
-typedef enum {
- RtemsTaskReqConstructErrors_Pre_Id_Valid,
- RtemsTaskReqConstructErrors_Pre_Id_Null,
- RtemsTaskReqConstructErrors_Pre_Id_NA
-} RtemsTaskReqConstructErrors_Pre_Id;
-
-typedef enum {
- RtemsTaskReqConstructErrors_Pre_SysTsk_Yes,
- RtemsTaskReqConstructErrors_Pre_SysTsk_No,
- RtemsTaskReqConstructErrors_Pre_SysTsk_NA
-} RtemsTaskReqConstructErrors_Pre_SysTsk;
-
-typedef enum {
- RtemsTaskReqConstructErrors_Pre_Prio_Valid,
- RtemsTaskReqConstructErrors_Pre_Prio_Zero,
- RtemsTaskReqConstructErrors_Pre_Prio_Inv,
- RtemsTaskReqConstructErrors_Pre_Prio_NA
-} RtemsTaskReqConstructErrors_Pre_Prio;
-
-typedef enum {
- RtemsTaskReqConstructErrors_Pre_Free_Yes,
- RtemsTaskReqConstructErrors_Pre_Free_No,
- RtemsTaskReqConstructErrors_Pre_Free_NA
-} RtemsTaskReqConstructErrors_Pre_Free;
-
-typedef enum {
- RtemsTaskReqConstructErrors_Pre_TLS_Enough,
- RtemsTaskReqConstructErrors_Pre_TLS_Small,
- RtemsTaskReqConstructErrors_Pre_TLS_NA
-} RtemsTaskReqConstructErrors_Pre_TLS;
-
-typedef enum {
- RtemsTaskReqConstructErrors_Pre_Stack_Enough,
- RtemsTaskReqConstructErrors_Pre_Stack_Small,
- RtemsTaskReqConstructErrors_Pre_Stack_NA
-} RtemsTaskReqConstructErrors_Pre_Stack;
-
-typedef enum {
- RtemsTaskReqConstructErrors_Pre_Ext_Ok,
- RtemsTaskReqConstructErrors_Pre_Ext_Err,
- RtemsTaskReqConstructErrors_Pre_Ext_NA
-} RtemsTaskReqConstructErrors_Pre_Ext;
-
-typedef enum {
- RtemsTaskReqConstructErrors_Post_Status_Ok,
- RtemsTaskReqConstructErrors_Post_Status_InvAddr,
- RtemsTaskReqConstructErrors_Post_Status_InvName,
- RtemsTaskReqConstructErrors_Post_Status_InvPrio,
- RtemsTaskReqConstructErrors_Post_Status_InvSize,
- RtemsTaskReqConstructErrors_Post_Status_TooMany,
- RtemsTaskReqConstructErrors_Post_Status_Unsat,
- RtemsTaskReqConstructErrors_Post_Status_NA
-} RtemsTaskReqConstructErrors_Post_Status;
-
-typedef enum {
- RtemsTaskReqConstructErrors_Post_Name_Valid,
- RtemsTaskReqConstructErrors_Post_Name_Invalid,
- RtemsTaskReqConstructErrors_Post_Name_NA
-} RtemsTaskReqConstructErrors_Post_Name;
-
-typedef enum {
- RtemsTaskReqConstructErrors_Post_IdVar_Set,
- RtemsTaskReqConstructErrors_Post_IdVar_Nop,
- RtemsTaskReqConstructErrors_Post_IdVar_NA
-} RtemsTaskReqConstructErrors_Post_IdVar;
-
-typedef enum {
- RtemsTaskReqConstructErrors_Post_CreateExt_Yes,
- RtemsTaskReqConstructErrors_Post_CreateExt_No,
- RtemsTaskReqConstructErrors_Post_CreateExt_NA
-} RtemsTaskReqConstructErrors_Post_CreateExt;
-
-typedef enum {
- RtemsTaskReqConstructErrors_Post_DelExt_Yes,
- RtemsTaskReqConstructErrors_Post_DelExt_No,
- RtemsTaskReqConstructErrors_Post_DelExt_NA
-} RtemsTaskReqConstructErrors_Post_DelExt;
-
-typedef enum {
- RtemsTaskReqConstructErrors_Post_StoFree_Yes,
- RtemsTaskReqConstructErrors_Post_StoFree_No,
- RtemsTaskReqConstructErrors_Post_StoFree_NA
-} RtemsTaskReqConstructErrors_Post_StoFree;
-
-/**
- * @brief Test context for spec:/rtems/task/req/construct-errors test case.
- */
-typedef struct {
- rtems_status_code status;
-
- const rtems_task_config *config;
-
- rtems_task_config config_value;
-
- rtems_id *id;
-
- rtems_id id_value;
-
- bool create_extension_status;
-
- uint32_t create_extension_calls;
-
- uint32_t delete_extension_calls;
-
- uint32_t storage_free_calls;
-
- size_t stack_size;
-
- rtems_id extension_id;
-
- void *seized_objects;
-
- /**
- * @brief This member defines the pre-condition states for the next action.
- */
- size_t pcs[ 9 ];
-
- /**
- * @brief This member indicates if the test action loop is currently
- * executed.
- */
- bool in_action_loop;
-} RtemsTaskReqConstructErrors_Context;
-
-static RtemsTaskReqConstructErrors_Context
- RtemsTaskReqConstructErrors_Instance;
-
-static const char * const RtemsTaskReqConstructErrors_PreDesc_Config[] = {
- "Valid",
- "Null",
- "NA"
-};
-
-static const char * const RtemsTaskReqConstructErrors_PreDesc_Name[] = {
- "Valid",
- "Inv",
- "NA"
-};
-
-static const char * const RtemsTaskReqConstructErrors_PreDesc_Id[] = {
- "Valid",
- "Null",
- "NA"
-};
-
-static const char * const RtemsTaskReqConstructErrors_PreDesc_SysTsk[] = {
- "Yes",
- "No",
- "NA"
-};
-
-static const char * const RtemsTaskReqConstructErrors_PreDesc_Prio[] = {
- "Valid",
- "Zero",
- "Inv",
- "NA"
-};
-
-static const char * const RtemsTaskReqConstructErrors_PreDesc_Free[] = {
- "Yes",
- "No",
- "NA"
-};
-
-static const char * const RtemsTaskReqConstructErrors_PreDesc_TLS[] = {
- "Enough",
- "Small",
- "NA"
-};
-
-static const char * const RtemsTaskReqConstructErrors_PreDesc_Stack[] = {
- "Enough",
- "Small",
- "NA"
-};
-
-static const char * const RtemsTaskReqConstructErrors_PreDesc_Ext[] = {
- "Ok",
- "Err",
- "NA"
-};
-
-static const char * const * const RtemsTaskReqConstructErrors_PreDesc[] = {
- RtemsTaskReqConstructErrors_PreDesc_Config,
- RtemsTaskReqConstructErrors_PreDesc_Name,
- RtemsTaskReqConstructErrors_PreDesc_Id,
- RtemsTaskReqConstructErrors_PreDesc_SysTsk,
- RtemsTaskReqConstructErrors_PreDesc_Prio,
- RtemsTaskReqConstructErrors_PreDesc_Free,
- RtemsTaskReqConstructErrors_PreDesc_TLS,
- RtemsTaskReqConstructErrors_PreDesc_Stack,
- RtemsTaskReqConstructErrors_PreDesc_Ext,
- NULL
-};
-
-#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
-
-#define INVALID_ID 0xffffffff
-
-typedef RtemsTaskReqConstructErrors_Context Context;
-
-static _Thread_local int tls_variable;
-
-#define MAX_TLS_SIZE RTEMS_ALIGN_UP( 128, RTEMS_TASK_STORAGE_ALIGNMENT )
-
-RTEMS_ALIGNED( RTEMS_TASK_STORAGE_ALIGNMENT ) static char task_storage[
- RTEMS_TASK_STORAGE_SIZE(
- MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE,
- RTEMS_FLOATING_POINT
- )
-];
-
-static const rtems_task_config seize_task_config = {
- .name = rtems_build_name( 'S', 'I', 'Z', 'E' ),
- .initial_priority = 1,
- .storage_area = task_storage,
- .storage_size = sizeof( task_storage ),
- .maximum_thread_local_storage_size = MAX_TLS_SIZE,
- .initial_modes = RTEMS_DEFAULT_MODES,
- .attributes = RTEMS_DEFAULT_MODES
-};
-
-static void StorageFree( void *ptr )
-{
- T_eq_ptr( ptr, task_storage );
- ++RtemsTaskReqConstructErrors_Instance.storage_free_calls;
-}
-
-static rtems_status_code Create( void *arg, uint32_t *id )
-{
- Context *ctx;
- bool create_extension_status;
- rtems_status_code sc;
-
- ctx = arg;
- create_extension_status = ctx->create_extension_status;
- ctx->create_extension_status = true;
- sc = rtems_task_construct( &seize_task_config, id );
- ctx->create_extension_status = create_extension_status;
-
- return sc;
-}
-
-static bool ThreadCreate( rtems_tcb *executing, rtems_tcb *created )
-{
- (void) executing;
- (void) created;
-
- ++RtemsTaskReqConstructErrors_Instance.create_extension_calls;
- return RtemsTaskReqConstructErrors_Instance.create_extension_status;
-}
-
-static void ThreadDelete( rtems_tcb *executing, rtems_tcb *deleted )
-{
- (void) executing;
- (void) deleted;
-
- ++RtemsTaskReqConstructErrors_Instance.delete_extension_calls;
-}
-
-static const rtems_extensions_table extensions = {
- .thread_create = ThreadCreate,
- .thread_delete = ThreadDelete
-};
-
-static void RtemsTaskReqConstructErrors_Pre_Config_Prepare(
- RtemsTaskReqConstructErrors_Context *ctx,
- RtemsTaskReqConstructErrors_Pre_Config state
-)
-{
- switch ( state ) {
- case RtemsTaskReqConstructErrors_Pre_Config_Valid: {
- /*
- * While the ``config`` parameter references an object of type
- * rtems_task_config.
- */
- ctx->config = &ctx->config_value;
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_Config_Null: {
- /*
- * While the ``config`` parameter is NULL.
- */
- ctx->config = NULL;
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_Config_NA:
- break;
- }
-}
-
-static void RtemsTaskReqConstructErrors_Pre_Name_Prepare(
- RtemsTaskReqConstructErrors_Context *ctx,
- RtemsTaskReqConstructErrors_Pre_Name state
-)
-{
- switch ( state ) {
- case RtemsTaskReqConstructErrors_Pre_Name_Valid: {
- /*
- * While the name of the task configuration is valid.
- */
- ctx->config_value.name = NAME;
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_Name_Inv: {
- /*
- * While the name of the task configuration is invalid.
- */
- ctx->config_value.name = 0;
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_Name_NA:
- break;
- }
-}
-
-static void RtemsTaskReqConstructErrors_Pre_Id_Prepare(
- RtemsTaskReqConstructErrors_Context *ctx,
- RtemsTaskReqConstructErrors_Pre_Id state
-)
-{
- switch ( state ) {
- case RtemsTaskReqConstructErrors_Pre_Id_Valid: {
- /*
- * While the ``id`` parameter references an object of type rtems_id.
- */
- ctx->id = &ctx->id_value;
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_Id_Null: {
- /*
- * While the ``id`` parameter is NULL.
- */
- ctx->id = NULL;
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_Id_NA:
- break;
- }
-}
-
-static void RtemsTaskReqConstructErrors_Pre_SysTsk_Prepare(
- RtemsTaskReqConstructErrors_Context *ctx,
- RtemsTaskReqConstructErrors_Pre_SysTsk state
-)
-{
- switch ( state ) {
- case RtemsTaskReqConstructErrors_Pre_SysTsk_Yes: {
- /*
- * While the attributes of the task configuration specifies a system
- * task.
- */
- ctx->config_value.attributes |= RTEMS_SYSTEM_TASK;
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_SysTsk_No: {
- /*
- * While the attributes of the task configuration specifies an
- * application task.
- */
- /* Nothing to do */
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_SysTsk_NA:
- break;
- }
-}
-
-static void RtemsTaskReqConstructErrors_Pre_Prio_Prepare(
- RtemsTaskReqConstructErrors_Context *ctx,
- RtemsTaskReqConstructErrors_Pre_Prio state
-)
-{
- switch ( state ) {
- case RtemsTaskReqConstructErrors_Pre_Prio_Valid: {
- /*
- * While the initial priority of the task configuration is valid and
- * non-zero.
- */
- ctx->config_value.initial_priority = 254;
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_Prio_Zero: {
- /*
- * While the initial priority of the task configuration is zero.
- */
- ctx->config_value.initial_priority = 0;
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_Prio_Inv: {
- /*
- * While the initial priority of the task configuration is invalid.
- */
- ctx->config_value.initial_priority = 0xffffffff;
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_Prio_NA:
- break;
- }
-}
-
-static void RtemsTaskReqConstructErrors_Pre_Free_Prepare(
- RtemsTaskReqConstructErrors_Context *ctx,
- RtemsTaskReqConstructErrors_Pre_Free state
-)
-{
- switch ( state ) {
- case RtemsTaskReqConstructErrors_Pre_Free_Yes: {
- /*
- * While the system has at least one inactive task object available.
- */
- /* Nothing to do */
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_Free_No: {
- /*
- * While the system has no inactive task object available.
- */
- ctx->seized_objects = T_seize_objects( Create, ctx );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_Free_NA:
- break;
- }
-}
-
-static void RtemsTaskReqConstructErrors_Pre_TLS_Prepare(
- RtemsTaskReqConstructErrors_Context *ctx,
- RtemsTaskReqConstructErrors_Pre_TLS state
-)
-{
- switch ( state ) {
- case RtemsTaskReqConstructErrors_Pre_TLS_Enough: {
- /*
- * While the maximum thread-local storage size of the task configuration
- * is greater than or equal to the thread-local storage size.
- */
- ctx->config_value.maximum_thread_local_storage_size = MAX_TLS_SIZE;
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_TLS_Small: {
- /*
- * While the maximum thread-local storage size of the task configuration
- * is less than the thread-local storage size.
- */
- ctx->config_value.maximum_thread_local_storage_size = 0;
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_TLS_NA:
- break;
- }
-}
-
-static void RtemsTaskReqConstructErrors_Pre_Stack_Prepare(
- RtemsTaskReqConstructErrors_Context *ctx,
- RtemsTaskReqConstructErrors_Pre_Stack state
-)
-{
- switch ( state ) {
- case RtemsTaskReqConstructErrors_Pre_Stack_Enough: {
- /*
- * While the task stack size of the task configuration is greater than or
- * equal to the configured minimum size.
- */
- ctx->stack_size = RTEMS_MINIMUM_STACK_SIZE;
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_Stack_Small: {
- /*
- * While the task stack size of the task configuration is less than the
- * configured minimum size.
- */
- ctx->stack_size = 0;
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_Stack_NA:
- break;
- }
-}
-
-static void RtemsTaskReqConstructErrors_Pre_Ext_Prepare(
- RtemsTaskReqConstructErrors_Context *ctx,
- RtemsTaskReqConstructErrors_Pre_Ext state
-)
-{
- switch ( state ) {
- case RtemsTaskReqConstructErrors_Pre_Ext_Ok: {
- /*
- * While none of the task create extensions fails.
- */
- ctx->create_extension_status = true;
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_Ext_Err: {
- /*
- * While at least one of the task create extensions fails.
- */
- ctx->create_extension_status = false;
- break;
- }
-
- case RtemsTaskReqConstructErrors_Pre_Ext_NA:
- break;
- }
-}
-
-static void RtemsTaskReqConstructErrors_Post_Status_Check(
- RtemsTaskReqConstructErrors_Context *ctx,
- RtemsTaskReqConstructErrors_Post_Status state
-)
-{
- switch ( state ) {
- case RtemsTaskReqConstructErrors_Post_Status_Ok: {
- /*
- * The return status of rtems_task_construct() shall be RTEMS_SUCCESSFUL.
- */
- T_rsc_success( ctx->status );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Post_Status_InvAddr: {
- /*
- * The return status of rtems_task_construct() shall be
- * RTEMS_INVALID_ADDRESS.
- */
- T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Post_Status_InvName: {
- /*
- * The return status of rtems_task_construct() shall be
- * RTEMS_INVALID_NAME.
- */
- T_rsc( ctx->status, RTEMS_INVALID_NAME );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Post_Status_InvPrio: {
- /*
- * The return status of rtems_task_construct() shall be
- * RTEMS_INVALID_PRIORITY.
- */
- T_rsc( ctx->status, RTEMS_INVALID_PRIORITY );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Post_Status_InvSize: {
- /*
- * The return status of rtems_task_construct() shall be
- * RTEMS_INVALID_SIZE.
- */
- T_rsc( ctx->status, RTEMS_INVALID_SIZE );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Post_Status_TooMany: {
- /*
- * The return status of rtems_task_construct() shall be RTEMS_TOO_MANY.
- */
- T_rsc( ctx->status, RTEMS_TOO_MANY );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Post_Status_Unsat: {
- /*
- * The return status of rtems_task_construct() shall be
- * RTEMS_UNSATISFIED.
- */
- T_rsc( ctx->status, RTEMS_UNSATISFIED );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Post_Status_NA:
- break;
- }
-}
-
-static void RtemsTaskReqConstructErrors_Post_Name_Check(
- RtemsTaskReqConstructErrors_Context *ctx,
- RtemsTaskReqConstructErrors_Post_Name state
-)
-{
- rtems_status_code sc;
- rtems_id id;
-
- switch ( state ) {
- case RtemsTaskReqConstructErrors_Post_Name_Valid: {
- /*
- * The unique object name shall identify the task constructed by the
- * rtems_task_construct() call.
- */
- id = 0;
- sc = rtems_task_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
- T_rsc_success( sc );
- T_eq_u32( id, ctx->id_value );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Post_Name_Invalid: {
- /*
- * The unique object name shall not identify a task.
- */
- sc = rtems_task_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
- T_rsc( sc, RTEMS_INVALID_NAME );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Post_Name_NA:
- break;
- }
-}
-
-static void RtemsTaskReqConstructErrors_Post_IdVar_Check(
- RtemsTaskReqConstructErrors_Context *ctx,
- RtemsTaskReqConstructErrors_Post_IdVar state
-)
-{
- switch ( state ) {
- case RtemsTaskReqConstructErrors_Post_IdVar_Set: {
- /*
- * The value of the object referenced by the ``id`` parameter shall be
- * set to the object identifier of the constructed task after the return
- * of the rtems_task_construct() call.
- */
- T_eq_ptr( ctx->id, &ctx->id_value );
- T_ne_u32( ctx->id_value, INVALID_ID );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Post_IdVar_Nop: {
- /*
- * Objects referenced by the ``id`` parameter in past calls to
- * rtems_task_construct() shall not be accessed by the
- * rtems_task_construct() call.
- */
- T_eq_u32( ctx->id_value, INVALID_ID );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Post_IdVar_NA:
- break;
- }
-}
-
-static void RtemsTaskReqConstructErrors_Post_CreateExt_Check(
- RtemsTaskReqConstructErrors_Context *ctx,
- RtemsTaskReqConstructErrors_Post_CreateExt state
-)
-{
- switch ( state ) {
- case RtemsTaskReqConstructErrors_Post_CreateExt_Yes: {
- /*
- * The create user extensions shall be invoked during the
- * rtems_task_construct() call.
- */
- T_eq_u32( ctx->create_extension_calls, 1 );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Post_CreateExt_No: {
- /*
- * The create user extensions shall not be invoked during the
- * rtems_task_construct() call.
- */
- T_eq_u32( ctx->create_extension_calls, 0 );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Post_CreateExt_NA:
- break;
- }
-}
-
-static void RtemsTaskReqConstructErrors_Post_DelExt_Check(
- RtemsTaskReqConstructErrors_Context *ctx,
- RtemsTaskReqConstructErrors_Post_DelExt state
-)
-{
- switch ( state ) {
- case RtemsTaskReqConstructErrors_Post_DelExt_Yes: {
- /*
- * The delete user extensions shall be invoked during the
- * rtems_task_construct() call.
- */
- T_eq_u32( ctx->delete_extension_calls, 1 );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Post_DelExt_No: {
- /*
- * The delete user extensions shall not be invoked during the
- * rtems_task_construct() call.
- */
- T_eq_u32( ctx->delete_extension_calls, 0 );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Post_DelExt_NA:
- break;
- }
-}
-
-static void RtemsTaskReqConstructErrors_Post_StoFree_Check(
- RtemsTaskReqConstructErrors_Context *ctx,
- RtemsTaskReqConstructErrors_Post_StoFree state
-)
-{
- switch ( state ) {
- case RtemsTaskReqConstructErrors_Post_StoFree_Yes: {
- /*
- * The storage free handler of the task configuration shall be invoked
- * during the rtems_task_construct() call.
- */
- T_eq_u32( ctx->storage_free_calls, 1 );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Post_StoFree_No: {
- /*
- * The storage free handler of the task configuration shall not be
- * invoked during the rtems_task_construct() call.
- */
- T_eq_u32( ctx->storage_free_calls, 0 );
- break;
- }
-
- case RtemsTaskReqConstructErrors_Post_StoFree_NA:
- break;
- }
-}
-
-static void RtemsTaskReqConstructErrors_Setup(
- RtemsTaskReqConstructErrors_Context *ctx
-)
-{
- rtems_status_code sc;
- int var;
-
- var = tls_variable;
- RTEMS_OBFUSCATE_VARIABLE( var );
- tls_variable = var;
-
- sc = rtems_extension_create(
- rtems_build_name( 'T', 'E', 'X', 'T' ),
- &extensions,
- &ctx->extension_id
- );
- T_rsc_success( sc );
-}
-
-static void RtemsTaskReqConstructErrors_Setup_Wrap( void *arg )
-{
- RtemsTaskReqConstructErrors_Context *ctx;
-
- ctx = arg;
- ctx->in_action_loop = false;
- RtemsTaskReqConstructErrors_Setup( ctx );
-}
-
-static void RtemsTaskReqConstructErrors_Teardown(
- RtemsTaskReqConstructErrors_Context *ctx
-)
-{
- rtems_status_code sc;
-
- sc = rtems_extension_delete( ctx->extension_id );
- T_rsc_success( sc );
-}
-
-static void RtemsTaskReqConstructErrors_Teardown_Wrap( void *arg )
-{
- RtemsTaskReqConstructErrors_Context *ctx;
-
- ctx = arg;
- ctx->in_action_loop = false;
- RtemsTaskReqConstructErrors_Teardown( ctx );
-}
-
-static void RtemsTaskReqConstructErrors_Prepare(
- RtemsTaskReqConstructErrors_Context *ctx
-)
-{
- _RTEMS_Lock_allocator();
- _Thread_Kill_zombies();
- _RTEMS_Unlock_allocator();
-
- ctx->id_value = INVALID_ID;
- memset( &ctx->config_value, 0, sizeof( ctx->config_value ) );
- ctx->config_value.storage_area = task_storage,
- ctx->config_value.storage_free = StorageFree;
-}
-
-static void RtemsTaskReqConstructErrors_Action(
- RtemsTaskReqConstructErrors_Context *ctx
-)
-{
- ctx->create_extension_calls = 0;
- ctx->delete_extension_calls = 0;
- ctx->storage_free_calls = 0;
- ctx->config_value.storage_size = RTEMS_TASK_STORAGE_SIZE(
- ctx->config_value.maximum_thread_local_storage_size + ctx->stack_size,
- ctx->config_value.attributes
- );
- ctx->status = rtems_task_construct( ctx->config, ctx->id );
-}
-
-static void RtemsTaskReqConstructErrors_Cleanup(
- RtemsTaskReqConstructErrors_Context *ctx
-)
-{
- if ( ctx->id_value != INVALID_ID ) {
- rtems_status_code sc;
-
- sc = rtems_task_delete( ctx->id_value );
- T_rsc_success( sc );
-
- ctx->id_value = INVALID_ID;
- }
-
- T_surrender_objects( &ctx->seized_objects, rtems_task_delete );
-}
-
-typedef struct {
- uint32_t Skip : 1;
- uint32_t Pre_Config_NA : 1;
- uint32_t Pre_Name_NA : 1;
- uint32_t Pre_Id_NA : 1;
- uint32_t Pre_SysTsk_NA : 1;
- uint32_t Pre_Prio_NA : 1;
- uint32_t Pre_Free_NA : 1;
- uint32_t Pre_TLS_NA : 1;
- uint32_t Pre_Stack_NA : 1;
- uint32_t Pre_Ext_NA : 1;
- uint32_t Post_Status : 3;
- uint32_t Post_Name : 2;
- uint32_t Post_IdVar : 2;
- uint32_t Post_CreateExt : 2;
- uint32_t Post_DelExt : 2;
- uint32_t Post_StoFree : 2;
-} RtemsTaskReqConstructErrors_Entry;
-
-static const RtemsTaskReqConstructErrors_Entry
-RtemsTaskReqConstructErrors_Entries[] = {
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- RtemsTaskReqConstructErrors_Post_Status_InvAddr,
- RtemsTaskReqConstructErrors_Post_Name_Invalid,
- RtemsTaskReqConstructErrors_Post_IdVar_Nop,
- RtemsTaskReqConstructErrors_Post_CreateExt_No,
- RtemsTaskReqConstructErrors_Post_DelExt_No,
- RtemsTaskReqConstructErrors_Post_StoFree_No },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- RtemsTaskReqConstructErrors_Post_Status_InvName,
- RtemsTaskReqConstructErrors_Post_Name_Invalid,
- RtemsTaskReqConstructErrors_Post_IdVar_Nop,
- RtemsTaskReqConstructErrors_Post_CreateExt_No,
- RtemsTaskReqConstructErrors_Post_DelExt_No,
- RtemsTaskReqConstructErrors_Post_StoFree_No },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- RtemsTaskReqConstructErrors_Post_Status_InvPrio,
- RtemsTaskReqConstructErrors_Post_Name_Invalid,
- RtemsTaskReqConstructErrors_Post_IdVar_Nop,
- RtemsTaskReqConstructErrors_Post_CreateExt_No,
- RtemsTaskReqConstructErrors_Post_DelExt_No,
- RtemsTaskReqConstructErrors_Post_StoFree_No },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- RtemsTaskReqConstructErrors_Post_Status_TooMany,
- RtemsTaskReqConstructErrors_Post_Name_Invalid,
- RtemsTaskReqConstructErrors_Post_IdVar_Nop,
- RtemsTaskReqConstructErrors_Post_CreateExt_No,
- RtemsTaskReqConstructErrors_Post_DelExt_No,
- RtemsTaskReqConstructErrors_Post_StoFree_No },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- RtemsTaskReqConstructErrors_Post_Status_InvSize,
- RtemsTaskReqConstructErrors_Post_Name_Invalid,
- RtemsTaskReqConstructErrors_Post_IdVar_Nop,
- RtemsTaskReqConstructErrors_Post_CreateExt_No,
- RtemsTaskReqConstructErrors_Post_DelExt_No,
- RtemsTaskReqConstructErrors_Post_StoFree_No },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqConstructErrors_Post_Status_Ok,
- RtemsTaskReqConstructErrors_Post_Name_Valid,
- RtemsTaskReqConstructErrors_Post_IdVar_Set,
- RtemsTaskReqConstructErrors_Post_CreateExt_Yes,
- RtemsTaskReqConstructErrors_Post_DelExt_No,
- RtemsTaskReqConstructErrors_Post_StoFree_No },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- RtemsTaskReqConstructErrors_Post_Status_Unsat,
- RtemsTaskReqConstructErrors_Post_Name_Invalid,
- RtemsTaskReqConstructErrors_Post_IdVar_Nop,
- RtemsTaskReqConstructErrors_Post_CreateExt_Yes,
- RtemsTaskReqConstructErrors_Post_DelExt_Yes,
- RtemsTaskReqConstructErrors_Post_StoFree_Yes }
-};
-
-static const uint8_t
-RtemsTaskReqConstructErrors_Map[] = {
- 5, 6, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 5, 6, 4, 4, 4, 4, 4, 4, 3, 3,
- 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 6, 4, 4,
- 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-static size_t RtemsTaskReqConstructErrors_Scope(
- void *arg,
- char *buf,
- size_t n
-)
-{
- RtemsTaskReqConstructErrors_Context *ctx;
-
- ctx = arg;
-
- if ( ctx->in_action_loop ) {
- return T_get_scope(
- RtemsTaskReqConstructErrors_PreDesc,
- buf,
- n,
- ctx->pcs
- );
- }
-
- return 0;
-}
-
-static T_fixture RtemsTaskReqConstructErrors_Fixture = {
- .setup = RtemsTaskReqConstructErrors_Setup_Wrap,
- .stop = NULL,
- .teardown = RtemsTaskReqConstructErrors_Teardown_Wrap,
- .scope = RtemsTaskReqConstructErrors_Scope,
- .initial_context = &RtemsTaskReqConstructErrors_Instance
-};
-
-static inline RtemsTaskReqConstructErrors_Entry
-RtemsTaskReqConstructErrors_GetEntry( size_t index )
-{
- return RtemsTaskReqConstructErrors_Entries[
- RtemsTaskReqConstructErrors_Map[ index ]
- ];
-}
-
-/**
- * @fn void T_case_body_RtemsTaskReqConstructErrors( void )
- */
-T_TEST_CASE_FIXTURE(
- RtemsTaskReqConstructErrors,
- &RtemsTaskReqConstructErrors_Fixture
-)
-{
- RtemsTaskReqConstructErrors_Context *ctx;
- size_t index;
-
- ctx = T_fixture_context();
- ctx->in_action_loop = true;
- index = 0;
-
- for (
- ctx->pcs[ 0 ] = RtemsTaskReqConstructErrors_Pre_Config_Valid;
- ctx->pcs[ 0 ] < RtemsTaskReqConstructErrors_Pre_Config_NA;
- ++ctx->pcs[ 0 ]
- ) {
- for (
- ctx->pcs[ 1 ] = RtemsTaskReqConstructErrors_Pre_Name_Valid;
- ctx->pcs[ 1 ] < RtemsTaskReqConstructErrors_Pre_Name_NA;
- ++ctx->pcs[ 1 ]
- ) {
- for (
- ctx->pcs[ 2 ] = RtemsTaskReqConstructErrors_Pre_Id_Valid;
- ctx->pcs[ 2 ] < RtemsTaskReqConstructErrors_Pre_Id_NA;
- ++ctx->pcs[ 2 ]
- ) {
- for (
- ctx->pcs[ 3 ] = RtemsTaskReqConstructErrors_Pre_SysTsk_Yes;
- ctx->pcs[ 3 ] < RtemsTaskReqConstructErrors_Pre_SysTsk_NA;
- ++ctx->pcs[ 3 ]
- ) {
- for (
- ctx->pcs[ 4 ] = RtemsTaskReqConstructErrors_Pre_Prio_Valid;
- ctx->pcs[ 4 ] < RtemsTaskReqConstructErrors_Pre_Prio_NA;
- ++ctx->pcs[ 4 ]
- ) {
- for (
- ctx->pcs[ 5 ] = RtemsTaskReqConstructErrors_Pre_Free_Yes;
- ctx->pcs[ 5 ] < RtemsTaskReqConstructErrors_Pre_Free_NA;
- ++ctx->pcs[ 5 ]
- ) {
- for (
- ctx->pcs[ 6 ] = RtemsTaskReqConstructErrors_Pre_TLS_Enough;
- ctx->pcs[ 6 ] < RtemsTaskReqConstructErrors_Pre_TLS_NA;
- ++ctx->pcs[ 6 ]
- ) {
- for (
- ctx->pcs[ 7 ] = RtemsTaskReqConstructErrors_Pre_Stack_Enough;
- ctx->pcs[ 7 ] < RtemsTaskReqConstructErrors_Pre_Stack_NA;
- ++ctx->pcs[ 7 ]
- ) {
- for (
- ctx->pcs[ 8 ] = RtemsTaskReqConstructErrors_Pre_Ext_Ok;
- ctx->pcs[ 8 ] < RtemsTaskReqConstructErrors_Pre_Ext_NA;
- ++ctx->pcs[ 8 ]
- ) {
- RtemsTaskReqConstructErrors_Entry entry;
-
- entry = RtemsTaskReqConstructErrors_GetEntry( index );
- ++index;
-
- RtemsTaskReqConstructErrors_Prepare( ctx );
- RtemsTaskReqConstructErrors_Pre_Config_Prepare(
- ctx,
- ctx->pcs[ 0 ]
- );
- RtemsTaskReqConstructErrors_Pre_Name_Prepare(
- ctx,
- ctx->pcs[ 1 ]
- );
- RtemsTaskReqConstructErrors_Pre_Id_Prepare(
- ctx,
- ctx->pcs[ 2 ]
- );
- RtemsTaskReqConstructErrors_Pre_SysTsk_Prepare(
- ctx,
- ctx->pcs[ 3 ]
- );
- RtemsTaskReqConstructErrors_Pre_Prio_Prepare(
- ctx,
- ctx->pcs[ 4 ]
- );
- RtemsTaskReqConstructErrors_Pre_Free_Prepare(
- ctx,
- ctx->pcs[ 5 ]
- );
- RtemsTaskReqConstructErrors_Pre_TLS_Prepare(
- ctx,
- ctx->pcs[ 6 ]
- );
- RtemsTaskReqConstructErrors_Pre_Stack_Prepare(
- ctx,
- ctx->pcs[ 7 ]
- );
- RtemsTaskReqConstructErrors_Pre_Ext_Prepare(
- ctx,
- ctx->pcs[ 8 ]
- );
- RtemsTaskReqConstructErrors_Action( ctx );
- RtemsTaskReqConstructErrors_Post_Status_Check(
- ctx,
- entry.Post_Status
- );
- RtemsTaskReqConstructErrors_Post_Name_Check(
- ctx,
- entry.Post_Name
- );
- RtemsTaskReqConstructErrors_Post_IdVar_Check(
- ctx,
- entry.Post_IdVar
- );
- RtemsTaskReqConstructErrors_Post_CreateExt_Check(
- ctx,
- entry.Post_CreateExt
- );
- RtemsTaskReqConstructErrors_Post_DelExt_Check(
- ctx,
- entry.Post_DelExt
- );
- RtemsTaskReqConstructErrors_Post_StoFree_Check(
- ctx,
- entry.Post_StoFree
- );
- RtemsTaskReqConstructErrors_Cleanup( ctx );
- }
- }
- }
- }
- }
- }
- }
- }
- }
-}
-
-/** @} */
diff --git a/testsuites/validation/tc-task-construct.c b/testsuites/validation/tc-task-construct.c
new file mode 100644
index 0000000000..5a7ca4f497
--- /dev/null
+++ b/testsuites/validation/tc-task-construct.c
@@ -0,0 +1,4950 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqConstruct
+ */
+
+/*
+ * Copyright (C) 2020, 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+#include <rtems/score/atomic.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/threadimpl.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqConstruct spec:/rtems/task/req/construct
+ *
+ * @ingroup TestsuitesValidation1
+ * @ingroup TestsuitesValidationOneCpu1
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqConstruct_Pre_CPUs_One,
+ RtemsTaskReqConstruct_Pre_CPUs_More,
+ RtemsTaskReqConstruct_Pre_CPUs_NA
+} RtemsTaskReqConstruct_Pre_CPUs;
+
+typedef enum {
+ RtemsTaskReqConstruct_Pre_Config_Valid,
+ RtemsTaskReqConstruct_Pre_Config_Null,
+ RtemsTaskReqConstruct_Pre_Config_NA
+} RtemsTaskReqConstruct_Pre_Config;
+
+typedef enum {
+ RtemsTaskReqConstruct_Pre_Name_Valid,
+ RtemsTaskReqConstruct_Pre_Name_Invalid,
+ RtemsTaskReqConstruct_Pre_Name_NA
+} RtemsTaskReqConstruct_Pre_Name;
+
+typedef enum {
+ RtemsTaskReqConstruct_Pre_Id_Valid,
+ RtemsTaskReqConstruct_Pre_Id_Null,
+ RtemsTaskReqConstruct_Pre_Id_NA
+} RtemsTaskReqConstruct_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqConstruct_Pre_SystemTask_Yes,
+ RtemsTaskReqConstruct_Pre_SystemTask_No,
+ RtemsTaskReqConstruct_Pre_SystemTask_NA
+} RtemsTaskReqConstruct_Pre_SystemTask;
+
+typedef enum {
+ RtemsTaskReqConstruct_Pre_Priority_Valid,
+ RtemsTaskReqConstruct_Pre_Priority_Zero,
+ RtemsTaskReqConstruct_Pre_Priority_Invalid,
+ RtemsTaskReqConstruct_Pre_Priority_NA
+} RtemsTaskReqConstruct_Pre_Priority;
+
+typedef enum {
+ RtemsTaskReqConstruct_Pre_Free_Yes,
+ RtemsTaskReqConstruct_Pre_Free_No,
+ RtemsTaskReqConstruct_Pre_Free_NA
+} RtemsTaskReqConstruct_Pre_Free;
+
+typedef enum {
+ RtemsTaskReqConstruct_Pre_TLS_Enough,
+ RtemsTaskReqConstruct_Pre_TLS_TooSmall,
+ RtemsTaskReqConstruct_Pre_TLS_NA
+} RtemsTaskReqConstruct_Pre_TLS;
+
+typedef enum {
+ RtemsTaskReqConstruct_Pre_Stack_Enough,
+ RtemsTaskReqConstruct_Pre_Stack_TooSmall,
+ RtemsTaskReqConstruct_Pre_Stack_NA
+} RtemsTaskReqConstruct_Pre_Stack;
+
+typedef enum {
+ RtemsTaskReqConstruct_Pre_Create_Ok,
+ RtemsTaskReqConstruct_Pre_Create_Error,
+ RtemsTaskReqConstruct_Pre_Create_NA
+} RtemsTaskReqConstruct_Pre_Create;
+
+typedef enum {
+ RtemsTaskReqConstruct_Pre_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Pre_FloatingPoint_No,
+ RtemsTaskReqConstruct_Pre_FloatingPoint_NA
+} RtemsTaskReqConstruct_Pre_FloatingPoint;
+
+typedef enum {
+ RtemsTaskReqConstruct_Pre_Preempt_Yes,
+ RtemsTaskReqConstruct_Pre_Preempt_No,
+ RtemsTaskReqConstruct_Pre_Preempt_NA
+} RtemsTaskReqConstruct_Pre_Preempt;
+
+typedef enum {
+ RtemsTaskReqConstruct_Pre_Timeslice_Yes,
+ RtemsTaskReqConstruct_Pre_Timeslice_No,
+ RtemsTaskReqConstruct_Pre_Timeslice_NA
+} RtemsTaskReqConstruct_Pre_Timeslice;
+
+typedef enum {
+ RtemsTaskReqConstruct_Pre_ASR_Yes,
+ RtemsTaskReqConstruct_Pre_ASR_No,
+ RtemsTaskReqConstruct_Pre_ASR_NA
+} RtemsTaskReqConstruct_Pre_ASR;
+
+typedef enum {
+ RtemsTaskReqConstruct_Pre_IntLvl_Zero,
+ RtemsTaskReqConstruct_Pre_IntLvl_Positive,
+ RtemsTaskReqConstruct_Pre_IntLvl_NA
+} RtemsTaskReqConstruct_Pre_IntLvl;
+
+typedef enum {
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Status_InvAddr,
+ RtemsTaskReqConstruct_Post_Status_InvName,
+ RtemsTaskReqConstruct_Post_Status_InvPrio,
+ RtemsTaskReqConstruct_Post_Status_InvSize,
+ RtemsTaskReqConstruct_Post_Status_TooMany,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Status_NA
+} RtemsTaskReqConstruct_Post_Status;
+
+typedef enum {
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_Name_NA
+} RtemsTaskReqConstruct_Post_Name;
+
+typedef enum {
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_IdObj_NA
+} RtemsTaskReqConstruct_Post_IdObj;
+
+typedef enum {
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_CreateNew_UpToFailing,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_NA
+} RtemsTaskReqConstruct_Post_CreateNew;
+
+typedef enum {
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_NA
+} RtemsTaskReqConstruct_Post_DeleteNew;
+
+typedef enum {
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_KillZombies_No,
+ RtemsTaskReqConstruct_Post_KillZombies_NA
+} RtemsTaskReqConstruct_Post_KillZombies;
+
+typedef enum {
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_StorageFree_NA
+} RtemsTaskReqConstruct_Post_StorageFree;
+
+typedef enum {
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA
+} RtemsTaskReqConstruct_Post_FloatingPoint;
+
+typedef enum {
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_No,
+ RtemsTaskReqConstruct_Post_Preempt_NA
+} RtemsTaskReqConstruct_Post_Preempt;
+
+typedef enum {
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_No,
+ RtemsTaskReqConstruct_Post_Timeslice_NA
+} RtemsTaskReqConstruct_Post_Timeslice;
+
+typedef enum {
+ RtemsTaskReqConstruct_Post_ASR_Yes,
+ RtemsTaskReqConstruct_Post_ASR_No,
+ RtemsTaskReqConstruct_Post_ASR_NA
+} RtemsTaskReqConstruct_Post_ASR;
+
+typedef enum {
+ RtemsTaskReqConstruct_Post_IntLvl_Zero,
+ RtemsTaskReqConstruct_Post_IntLvl_Positive,
+ RtemsTaskReqConstruct_Post_IntLvl_NA
+} RtemsTaskReqConstruct_Post_IntLvl;
+
+typedef struct {
+ uint64_t Skip : 1;
+ uint64_t Pre_CPUs_NA : 1;
+ uint64_t Pre_Config_NA : 1;
+ uint64_t Pre_Name_NA : 1;
+ uint64_t Pre_Id_NA : 1;
+ uint64_t Pre_SystemTask_NA : 1;
+ uint64_t Pre_Priority_NA : 1;
+ uint64_t Pre_Free_NA : 1;
+ uint64_t Pre_TLS_NA : 1;
+ uint64_t Pre_Stack_NA : 1;
+ uint64_t Pre_Create_NA : 1;
+ uint64_t Pre_FloatingPoint_NA : 1;
+ uint64_t Pre_Preempt_NA : 1;
+ uint64_t Pre_Timeslice_NA : 1;
+ uint64_t Pre_ASR_NA : 1;
+ uint64_t Pre_IntLvl_NA : 1;
+ uint64_t Post_Status : 3;
+ uint64_t Post_Name : 2;
+ uint64_t Post_IdObj : 2;
+ uint64_t Post_CreateNew : 2;
+ uint64_t Post_DeleteNew : 2;
+ uint64_t Post_KillZombies : 2;
+ uint64_t Post_StorageFree : 2;
+ uint64_t Post_FloatingPoint : 2;
+ uint64_t Post_Preempt : 2;
+ uint64_t Post_Timeslice : 2;
+ uint64_t Post_ASR : 2;
+ uint64_t Post_IntLvl : 2;
+} RtemsTaskReqConstruct_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/construct test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the scheduler B identifier.
+ */
+ rtems_id scheduler_b_id;
+
+ /**
+ * @brief This member contains the thread zombie registry ticket right before
+ * the task exit of the zombie task.
+ */
+ unsigned int thread_zombie_ticket;
+
+ /**
+ * @brief If this member is true, then the zombie thread is ready to get
+ * killed.
+ */
+ volatile bool zombie_ready;
+
+ /**
+ * @brief This member contains the actual modes of the constructed task.
+ */
+ rtems_mode actual_modes;
+
+ rtems_status_code status;
+
+ const rtems_task_config *config;
+
+ rtems_task_config config_obj;
+
+ rtems_id zombie_id;
+
+ rtems_id *id;
+
+ rtems_id id_obj;
+
+ bool create_extension_status;
+
+ uint32_t create_extension_calls;
+
+ uint32_t delete_extension_calls;
+
+ uint32_t delete_zombie_extension_calls;
+
+ uint32_t storage_free_calls;
+
+ size_t stack_size;
+
+ rtems_id extension_ids[ 2 ];
+
+ void *seized_objects;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 15 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqConstruct_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqConstruct_Context;
+
+static RtemsTaskReqConstruct_Context
+ RtemsTaskReqConstruct_Instance;
+
+static const char * const RtemsTaskReqConstruct_PreDesc_CPUs[] = {
+ "One",
+ "More",
+ "NA"
+};
+
+static const char * const RtemsTaskReqConstruct_PreDesc_Config[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsTaskReqConstruct_PreDesc_Name[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTaskReqConstruct_PreDesc_Id[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsTaskReqConstruct_PreDesc_SystemTask[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqConstruct_PreDesc_Priority[] = {
+ "Valid",
+ "Zero",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTaskReqConstruct_PreDesc_Free[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqConstruct_PreDesc_TLS[] = {
+ "Enough",
+ "TooSmall",
+ "NA"
+};
+
+static const char * const RtemsTaskReqConstruct_PreDesc_Stack[] = {
+ "Enough",
+ "TooSmall",
+ "NA"
+};
+
+static const char * const RtemsTaskReqConstruct_PreDesc_Create[] = {
+ "Ok",
+ "Error",
+ "NA"
+};
+
+static const char * const RtemsTaskReqConstruct_PreDesc_FloatingPoint[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqConstruct_PreDesc_Preempt[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqConstruct_PreDesc_Timeslice[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqConstruct_PreDesc_ASR[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqConstruct_PreDesc_IntLvl[] = {
+ "Zero",
+ "Positive",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqConstruct_PreDesc[] = {
+ RtemsTaskReqConstruct_PreDesc_CPUs,
+ RtemsTaskReqConstruct_PreDesc_Config,
+ RtemsTaskReqConstruct_PreDesc_Name,
+ RtemsTaskReqConstruct_PreDesc_Id,
+ RtemsTaskReqConstruct_PreDesc_SystemTask,
+ RtemsTaskReqConstruct_PreDesc_Priority,
+ RtemsTaskReqConstruct_PreDesc_Free,
+ RtemsTaskReqConstruct_PreDesc_TLS,
+ RtemsTaskReqConstruct_PreDesc_Stack,
+ RtemsTaskReqConstruct_PreDesc_Create,
+ RtemsTaskReqConstruct_PreDesc_FloatingPoint,
+ RtemsTaskReqConstruct_PreDesc_Preempt,
+ RtemsTaskReqConstruct_PreDesc_Timeslice,
+ RtemsTaskReqConstruct_PreDesc_ASR,
+ RtemsTaskReqConstruct_PreDesc_IntLvl,
+ NULL
+};
+
+#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+typedef RtemsTaskReqConstruct_Context Context;
+
+static volatile _Thread_local int tls_object;
+
+#define MAX_TLS_SIZE RTEMS_ALIGN_UP( 128, RTEMS_TASK_STORAGE_ALIGNMENT )
+
+RTEMS_ALIGNED( RTEMS_TASK_STORAGE_ALIGNMENT ) static char task_storage[
+ RTEMS_TASK_STORAGE_SIZE(
+ MAX_TLS_SIZE + TEST_MINIMUM_STACK_SIZE,
+ RTEMS_FLOATING_POINT
+ )
+];
+
+static const rtems_task_config seize_task_config = {
+ .name = rtems_build_name( 'S', 'I', 'Z', 'E' ),
+ .initial_priority = 1,
+ .storage_area = task_storage,
+ .storage_size = sizeof( task_storage ),
+ .maximum_thread_local_storage_size = MAX_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = RTEMS_DEFAULT_MODES
+};
+
+static void StorageFree( void *ptr )
+{
+ T_eq_ptr( ptr, task_storage );
+ ++RtemsTaskReqConstruct_Instance.storage_free_calls;
+}
+
+static rtems_status_code Create( void *arg, uint32_t *id )
+{
+ Context *ctx;
+ bool create_extension_status;
+ rtems_status_code sc;
+
+ ctx = arg;
+ create_extension_status = ctx->create_extension_status;
+ ctx->create_extension_status = true;
+ sc = rtems_task_construct( &seize_task_config, id );
+ ctx->create_extension_status = create_extension_status;
+
+ return sc;
+}
+
+static bool ThreadCreate( rtems_tcb *executing, rtems_tcb *created )
+{
+ (void) executing;
+ (void) created;
+
+ ++RtemsTaskReqConstruct_Instance.create_extension_calls;
+ return RtemsTaskReqConstruct_Instance.create_extension_status;
+}
+
+static bool SecondThreadCreate( rtems_tcb *executing, rtems_tcb *created )
+{
+ (void) executing;
+ (void) created;
+
+ ++RtemsTaskReqConstruct_Instance.create_extension_calls;
+ return true;
+}
+
+static void ThreadDelete( rtems_tcb *executing, rtems_tcb *deleted )
+{
+ Context *ctx;
+
+ (void) executing;
+
+ ctx = &RtemsTaskReqConstruct_Instance;
+
+ if ( deleted->Object.id == ctx->zombie_id ) {
+ ++ctx->delete_zombie_extension_calls;
+ } else {
+ ++ctx->delete_extension_calls;
+ }
+}
+
+#if defined(RTEMS_SMP)
+static void PreemptionIntervention( void *arg )
+{
+ Context *ctx;
+ unsigned int ticket;
+
+ ctx = arg;
+ T_false( ctx->zombie_ready );
+ ctx->zombie_ready = true;
+
+ do {
+ ticket = _Atomic_Load_uint(
+ &_Thread_Zombies.Lock.Lock.Ticket_lock.now_serving,
+ ATOMIC_ORDER_RELAXED
+ );
+ } while ( ( ticket - ctx->thread_zombie_ticket ) < 2 );
+
+ T_busy( 100 );
+}
+
+static void ThreadTerminate( rtems_tcb *executing )
+{
+ Context *ctx;
+
+ ctx = &RtemsTaskReqConstruct_Instance;
+
+ if (
+ ctx->scheduler_b_id != INVALID_ID &&
+ ctx->zombie_id == executing->Object.id
+ ) {
+ /*
+ * We use the ticket lock of the thread zombie registry to delay the thread
+ * dispatch and provoke an executing thread in
+ * _Thread_Kill_zombies(). The first acquire is done in the
+ * rtems_task_exit() below. The second acquire is done in
+ * _Thread_Kill_zombies().
+ */
+ ctx->thread_zombie_ticket = _Atomic_Fetch_add_uint(
+ &_Thread_Zombies.Lock.Lock.Ticket_lock.now_serving,
+ 0,
+ ATOMIC_ORDER_RELAXED
+ );
+ SetPreemptionIntervention(
+ _Per_CPU_Get_snapshot(),
+ PreemptionIntervention,
+ ctx
+ );
+ }
+}
+#endif
+
+static const rtems_extensions_table extensions[] = {
+ {
+#if defined(RTEMS_SMP)
+ .thread_terminate = ThreadTerminate,
+#endif
+ .thread_create = ThreadCreate,
+ .thread_delete = ThreadDelete
+ }, {
+ .thread_create = SecondThreadCreate,
+ .thread_delete = ThreadDelete
+ }
+};
+
+static void ZombieTask( rtems_task_argument arg )
+{
+ (void) arg;
+ rtems_task_exit();
+}
+
+static void PrepareZombie( Context *ctx )
+{
+ bool create_extension_status;
+
+ create_extension_status = ctx->create_extension_status;
+ ctx->create_extension_status = true;
+ ctx->zombie_id = CreateTask( "ZOMB", PRIO_HIGH );
+ ctx->create_extension_status = create_extension_status;
+#if defined(RTEMS_SMP)
+ if ( ctx->scheduler_b_id != INVALID_ID ) {
+ ctx->zombie_ready = false;
+ SetScheduler( ctx->zombie_id, ctx->scheduler_b_id, PRIO_NORMAL );
+ }
+#endif
+ StartTask( ctx->zombie_id, ZombieTask, ctx );
+#if defined(RTEMS_SMP)
+ while ( !ctx->zombie_ready ) {
+ /* Wait */
+ }
+#endif
+}
+
+static volatile double double_object;
+
+static RTEMS_NO_INLINE void UseFloatingPointUnit( void )
+{
+ double_object = ( 123.0 * double_object + double_object / 123.0 ) / 2.0;
+}
+
+static void WorkerTask( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+ ctx->actual_modes = GetMode();
+
+ /*
+ * We don't validate here that we cannot use the floating-point unit if the
+ * RTEMS_FLOATING_POINT attribute is not set. This is done elsewhere.
+ * Using the floating-point unit if the RTEMS_FLOATING_POINT attribute is
+ * not set may result in unrecoverable fatal errors.
+ */
+ if ( ( ctx->config_obj.attributes & RTEMS_FLOATING_POINT ) != 0 ) {
+ UseFloatingPointUnit();
+ }
+
+ SuspendSelf();
+}
+
+static void RtemsTaskReqConstruct_Pre_CPUs_Prepare(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Pre_CPUs state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Pre_CPUs_One: {
+ /*
+ * Where the system does not need inter-processor interrupts, where the
+ * scheduler does support the no-preempt mode.
+ */
+ if ( rtems_scheduler_get_processor_maximum() != 1 ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_CPUs_More: {
+ /*
+ * Where the system needs inter-processor interrupts, where the scheduler
+ * does not support the no-preempt mode.
+ */
+ if ( rtems_scheduler_get_processor_maximum() == 1 ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_CPUs_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Pre_Config_Prepare(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Pre_Config state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Pre_Config_Valid: {
+ /*
+ * While the ``config`` parameter references an object of type
+ * rtems_task_config.
+ */
+ ctx->config = &ctx->config_obj;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Config_Null: {
+ /*
+ * While the ``config`` parameter is NULL.
+ */
+ ctx->config = NULL;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Config_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Pre_Name_Prepare(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Pre_Name state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Pre_Name_Valid: {
+ /*
+ * While the name of the task configuration is valid.
+ */
+ ctx->config_obj.name = NAME;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Name_Invalid: {
+ /*
+ * While the name of the task configuration is invalid.
+ */
+ ctx->config_obj.name = 0;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Name_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Pre_Id_Prepare(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter references an object of type rtems_id.
+ */
+ ctx->id = &ctx->id_obj;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Id_Null: {
+ /*
+ * While the ``id`` parameter is NULL.
+ */
+ ctx->id = NULL;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Pre_SystemTask_Prepare(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Pre_SystemTask state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Pre_SystemTask_Yes: {
+ /*
+ * While the attributes of the task configuration specifies a system
+ * task.
+ */
+ ctx->config_obj.attributes |= RTEMS_SYSTEM_TASK;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_SystemTask_No: {
+ /*
+ * While the attributes of the task configuration specifies an
+ * application task.
+ */
+ ctx->config_obj.attributes |= RTEMS_APPLICATION_TASK;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_SystemTask_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Pre_Priority_Prepare(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Pre_Priority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Pre_Priority_Valid: {
+ /*
+ * While the initial priority of the task configuration is valid and
+ * non-zero.
+ */
+ ctx->config_obj.initial_priority = PRIO_HIGH;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Priority_Zero: {
+ /*
+ * While the initial priority of the task configuration is zero.
+ */
+ ctx->config_obj.initial_priority = 0;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Priority_Invalid: {
+ /*
+ * While the initial priority of the task configuration is invalid.
+ */
+ ctx->config_obj.initial_priority = 0xffffffff;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Priority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Pre_Free_Prepare(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Pre_Free state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Pre_Free_Yes: {
+ /*
+ * While the system has at least one inactive task object available.
+ */
+ /* Nothing to do */
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Free_No: {
+ /*
+ * While the system has no inactive task object available.
+ */
+ ctx->seized_objects = T_seize_objects( Create, ctx );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Free_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Pre_TLS_Prepare(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Pre_TLS state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Pre_TLS_Enough: {
+ /*
+ * While the maximum thread-local storage size of the task configuration
+ * is greater than or equal to the thread-local storage size.
+ */
+ ctx->config_obj.maximum_thread_local_storage_size = MAX_TLS_SIZE;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_TLS_TooSmall: {
+ /*
+ * While the maximum thread-local storage size of the task configuration
+ * is less than the thread-local storage size.
+ */
+ ctx->config_obj.maximum_thread_local_storage_size = 0;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_TLS_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Pre_Stack_Prepare(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Pre_Stack state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Pre_Stack_Enough: {
+ /*
+ * While the task stack size of the task configuration is greater than or
+ * equal to the configured minimum size.
+ */
+ ctx->stack_size = TEST_MINIMUM_STACK_SIZE;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Stack_TooSmall: {
+ /*
+ * While the task stack size of the task configuration is less than the
+ * configured minimum size.
+ */
+ ctx->stack_size = 0;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Stack_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Pre_Create_Prepare(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Pre_Create state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Pre_Create_Ok: {
+ /*
+ * While none of the thread create user extensions fails.
+ */
+ ctx->create_extension_status = true;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Create_Error: {
+ /*
+ * While at least one of the thread create user extensions fails.
+ */
+ ctx->create_extension_status = false;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Create_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Pre_FloatingPoint_Prepare(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Pre_FloatingPoint state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Pre_FloatingPoint_Yes: {
+ /*
+ * While the attributes of the task configuration specifies a
+ * floating-point task.
+ */
+ ctx->config_obj.attributes |= RTEMS_FLOATING_POINT;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_FloatingPoint_No: {
+ /*
+ * While the attributes of the task configuration specifies a
+ * non-floating-point task.
+ */
+ ctx->config_obj.attributes |= RTEMS_NO_FLOATING_POINT;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_FloatingPoint_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Pre_Preempt_Prepare(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Pre_Preempt state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Pre_Preempt_Yes: {
+ /*
+ * While the initial modes of the task configuration specify that
+ * preemption is enabled.
+ */
+ ctx->config_obj.initial_modes |= RTEMS_PREEMPT;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Preempt_No: {
+ /*
+ * While the initial modes of the task configuration specify that
+ * preemption is disabled.
+ */
+ ctx->config_obj.initial_modes |= RTEMS_NO_PREEMPT;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Preempt_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Pre_Timeslice_Prepare(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Pre_Timeslice state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Pre_Timeslice_Yes: {
+ /*
+ * While the initial modes of the task configuration specify that
+ * timeslicing is enabled.
+ */
+ ctx->config_obj.initial_modes |= RTEMS_TIMESLICE;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Timeslice_No: {
+ /*
+ * While the initial modes of the task configuration specify that
+ * timeslicing is disabled.
+ */
+ ctx->config_obj.initial_modes |= RTEMS_NO_TIMESLICE;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_Timeslice_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Pre_ASR_Prepare(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Pre_ASR state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Pre_ASR_Yes: {
+ /*
+ * While the initial modes of the task configuration specify that ASR
+ * processing is enabled.
+ */
+ ctx->config_obj.initial_modes |= RTEMS_ASR;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_ASR_No: {
+ /*
+ * While the initial modes of the task configuration specify that ASR
+ * processing is disabled.
+ */
+ ctx->config_obj.initial_modes |= RTEMS_NO_ASR;
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_ASR_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Pre_IntLvl_Prepare(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Pre_IntLvl state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Pre_IntLvl_Zero: {
+ /*
+ * While the initial modes of the task configuration specify an interrupt
+ * level of zero.
+ */
+ ctx->config_obj.initial_modes |= RTEMS_INTERRUPT_LEVEL( 0 );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_IntLvl_Positive: {
+ /*
+ * While the initial modes of the task configuration specify an interrupt
+ * level greater than zero and less than or equal to
+ * CPU_MODES_INTERRUPT_MASK.
+ */
+ ctx->config_obj.initial_modes |= RTEMS_INTERRUPT_LEVEL( 1 );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Pre_IntLvl_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Post_Status_Check(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_construct() shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_task_construct() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_Status_InvName: {
+ /*
+ * The return status of rtems_task_construct() shall be
+ * RTEMS_INVALID_NAME.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_Status_InvPrio: {
+ /*
+ * The return status of rtems_task_construct() shall be
+ * RTEMS_INVALID_PRIORITY.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_PRIORITY );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_Status_InvSize: {
+ /*
+ * The return status of rtems_task_construct() shall be
+ * RTEMS_INVALID_SIZE.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_SIZE );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_Status_TooMany: {
+ /*
+ * The return status of rtems_task_construct() shall be RTEMS_TOO_MANY.
+ */
+ T_rsc( ctx->status, RTEMS_TOO_MANY );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_Status_Unsat: {
+ /*
+ * The return status of rtems_task_construct() shall be
+ * RTEMS_UNSATISFIED.
+ */
+ T_rsc( ctx->status, RTEMS_UNSATISFIED );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Post_Name_Check(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Post_Name state
+)
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Post_Name_Valid: {
+ /*
+ * The unique object name shall identify the task constructed by the
+ * rtems_task_construct() call.
+ */
+ id = 0;
+ sc = rtems_task_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc_success( sc );
+ T_eq_u32( id, ctx->id_obj );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_Name_Invalid: {
+ /*
+ * The unique object name shall not identify a task.
+ */
+ sc = rtems_task_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
+ T_rsc( sc, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_Name_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Post_IdObj_Check(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Post_IdObj state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Post_IdObj_Set: {
+ /*
+ * The value of the object referenced by the ``id`` parameter shall be
+ * set to the object identifier of the constructed task after the return
+ * of the rtems_task_construct() call.
+ */
+ T_eq_ptr( ctx->id, &ctx->id_obj );
+ T_ne_u32( ctx->id_obj, INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_IdObj_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past calls to
+ * rtems_task_construct() shall not be accessed by the
+ * rtems_task_construct() call.
+ */
+ T_eq_u32( ctx->id_obj, INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_IdObj_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Post_CreateNew_Check(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Post_CreateNew state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Post_CreateNew_All: {
+ /*
+ * The thread create user extensions shall be invoked for the task under
+ * construction during the rtems_task_construct() call.
+ */
+ T_eq_u32( ctx->create_extension_calls, 2 );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_CreateNew_UpToFailing: {
+ /*
+ * The thread create user extensions up to the failing extension shall be
+ * invoked for the task under construction during the
+ * rtems_task_construct() call.
+ */
+ T_eq_u32( ctx->create_extension_calls, 1 );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_CreateNew_Nop: {
+ /*
+ * The thread create user extensions shall not be invoked for the task
+ * under construction during the rtems_task_construct() call.
+ */
+ T_eq_u32( ctx->create_extension_calls, 0 );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_CreateNew_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Post_DeleteNew_Check(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Post_DeleteNew state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Post_DeleteNew_All: {
+ /*
+ * The thread delete user extensions shall be invoked for the task under
+ * construction during the rtems_task_construct() call.
+ */
+ T_eq_u32( ctx->delete_extension_calls, 2 );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_DeleteNew_Nop: {
+ /*
+ * The thread delete user extensions shall not be invoked for the task
+ * under construction during the rtems_task_construct() call.
+ */
+ T_eq_u32( ctx->delete_extension_calls, 0 );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_DeleteNew_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Post_KillZombies_Check(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Post_KillZombies state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Post_KillZombies_Yes: {
+ /*
+ * The registered zombie threads shall be killed before an attempt to
+ * allocate a TCB is made by the rtems_task_construct() call.
+ */
+ /*
+ * We cannot check the zombie delete extension calls if we should call
+ * rtems_task_construct() without an inactive TCB available. Killing
+ * a zombie would make one inactive TCB available.
+ */
+ if ( ctx->seized_objects == NULL ) {
+ T_eq_u32( ctx->delete_zombie_extension_calls, 2 );
+ }
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_KillZombies_No: {
+ /*
+ * The registered zombie threads shall not be killed by the
+ * rtems_task_construct() call.
+ */
+ T_eq_u32( ctx->delete_zombie_extension_calls, 0 );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_KillZombies_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Post_StorageFree_Check(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Post_StorageFree state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Post_StorageFree_Yes: {
+ /*
+ * The storage free handler of the task configuration shall be invoked
+ * during the rtems_task_construct() call.
+ */
+ T_eq_u32( ctx->storage_free_calls, 1 );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_StorageFree_No: {
+ /*
+ * The storage free handler of the task configuration shall not be
+ * invoked during the rtems_task_construct() call.
+ */
+ T_eq_u32( ctx->storage_free_calls, 0 );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_StorageFree_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Post_FloatingPoint_Check(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Post_FloatingPoint state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Post_FloatingPoint_Yes: {
+ /*
+ * Where threads have a dedicated floating-point context, the task
+ * constructed by the rtems_task_construct() call shall be able to use
+ * the floating-point unit.
+ */
+ /* Validated by WorkerTask() */
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_FloatingPoint_No: {
+ /*
+ * Where threads have a dedicated floating-point context, the task
+ * constructed by the rtems_task_construct() call shall not be able to
+ * use the floating-point unit.
+ */
+ /* Validated by WorkerTask() */
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_FloatingPoint_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Post_Preempt_Check(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Post_Preempt state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Post_Preempt_Yes: {
+ /*
+ * Task preemption in the initial modes of the task constructed by the
+ * rtems_task_construct() call shall be enabled.
+ */
+ T_eq_u32( ctx->actual_modes & RTEMS_PREEMPT, RTEMS_PREEMPT );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_Preempt_No: {
+ /*
+ * Task preemption in the initial modes of the task constructed by the
+ * rtems_task_construct() call shall be disabled.
+ */
+ T_eq_u32( ctx->actual_modes & RTEMS_PREEMPT, 0 );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_Preempt_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Post_Timeslice_Check(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Post_Timeslice state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Post_Timeslice_Yes: {
+ /*
+ * Timeslicing in the initial modes of the task constructed by the
+ * rtems_task_construct() call shall be enabled.
+ */
+ T_eq_u32( ctx->actual_modes & RTEMS_TIMESLICE, RTEMS_TIMESLICE );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_Timeslice_No: {
+ /*
+ * Timeslicing in the initial modes of the task constructed by the
+ * rtems_task_construct() call shall be disabled.
+ */
+ T_eq_u32( ctx->actual_modes & RTEMS_TIMESLICE, 0 );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_Timeslice_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Post_ASR_Check(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Post_ASR state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Post_ASR_Yes: {
+ /*
+ * ASR processing in the initial modes of the task constructed by the
+ * rtems_task_construct() call shall be enabled.
+ */
+ T_eq_u32( ctx->actual_modes & RTEMS_ASR, RTEMS_ASR );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_ASR_No: {
+ /*
+ * ASR processing in the initial modes of the task constructed by the
+ * rtems_task_construct() call shall be disabled.
+ */
+ T_eq_u32( ctx->actual_modes & RTEMS_ASR, 0 );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_ASR_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Post_IntLvl_Check(
+ RtemsTaskReqConstruct_Context *ctx,
+ RtemsTaskReqConstruct_Post_IntLvl state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqConstruct_Post_IntLvl_Zero: {
+ /*
+ * The interrupt level in the initial modes of the task constructed by
+ * the rtems_task_construct() call shall be zero.
+ */
+ T_eq_u32( ctx->actual_modes & RTEMS_INTERRUPT_MASK, 0 );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_IntLvl_Positive: {
+ /*
+ * The interrupt level in the initial modes of the task constructed by
+ * the rtems_task_construct() call shall be the interrupt level specified
+ * by the initial modes of the task configuration mapped to an target
+ * architecture-specific positive value.
+ */
+ T_eq_u32(
+ ctx->actual_modes & RTEMS_INTERRUPT_MASK,
+ ctx->config_obj.initial_modes & RTEMS_INTERRUPT_MASK
+ );
+ break;
+ }
+
+ case RtemsTaskReqConstruct_Post_IntLvl_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqConstruct_Setup( RtemsTaskReqConstruct_Context *ctx )
+{
+ rtems_status_code sc;
+ int var;
+
+ var = tls_object;
+ RTEMS_OBFUSCATE_VARIABLE( var );
+ tls_object = var;
+
+ ctx->scheduler_b_id = INVALID_ID;
+ #if defined(RTEMS_SMP)
+ ctx->zombie_ready = true;
+ if ( rtems_scheduler_get_processor_maximum() > 1 ) {
+ sc = rtems_scheduler_ident(
+ TEST_SCHEDULER_B_NAME,
+ &ctx->scheduler_b_id
+ );
+ T_rsc_success( sc );
+ }
+ #endif
+
+ sc = rtems_extension_create(
+ rtems_build_name( 'E', 'X', 'T', '1' ),
+ &extensions[ 0 ],
+ &ctx->extension_ids[ 0 ]
+ );
+ T_rsc_success( sc );
+
+ sc = rtems_extension_create(
+ rtems_build_name( 'E', 'X', 'T', '2' ),
+ &extensions[ 1 ],
+ &ctx->extension_ids[ 1 ]
+ );
+ T_rsc_success( sc );
+
+ SetSelfPriority( PRIO_NORMAL );
+}
+
+static void RtemsTaskReqConstruct_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqConstruct_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqConstruct_Setup( ctx );
+}
+
+static void RtemsTaskReqConstruct_Teardown(
+ RtemsTaskReqConstruct_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ sc = rtems_extension_delete( ctx->extension_ids[ 0 ] );
+ T_rsc_success( sc );
+
+ sc = rtems_extension_delete( ctx->extension_ids[ 1 ] );
+ T_rsc_success( sc );
+
+ RestoreRunnerPriority();
+}
+
+static void RtemsTaskReqConstruct_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqConstruct_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqConstruct_Teardown( ctx );
+}
+
+static void RtemsTaskReqConstruct_Prepare( RtemsTaskReqConstruct_Context *ctx )
+{
+ KillZombies();
+ ctx->id_obj = INVALID_ID;
+ memset( &ctx->config_obj, 0, sizeof( ctx->config_obj ) );
+ ctx->config_obj.storage_area = task_storage,
+ ctx->config_obj.storage_free = StorageFree;
+}
+
+static void RtemsTaskReqConstruct_Action( RtemsTaskReqConstruct_Context *ctx )
+{
+ if ( ctx->seized_objects == NULL ) {
+ PrepareZombie( ctx );
+ }
+
+ ctx->actual_modes = UINT32_MAX;
+ ctx->create_extension_calls = 0;
+ ctx->delete_extension_calls = 0;
+ ctx->delete_zombie_extension_calls = 0;
+ ctx->storage_free_calls = 0;
+ ctx->config_obj.storage_size = RTEMS_TASK_STORAGE_SIZE(
+ ctx->config_obj.maximum_thread_local_storage_size + ctx->stack_size,
+ ctx->config_obj.attributes
+ );
+ ctx->status = rtems_task_construct( ctx->config, ctx->id );
+
+ if ( ctx->status == RTEMS_SUCCESSFUL ) {
+ StartTask( ctx->id_obj, WorkerTask, ctx );
+ }
+}
+
+static void RtemsTaskReqConstruct_Cleanup( RtemsTaskReqConstruct_Context *ctx )
+{
+ if ( ctx->id_obj != INVALID_ID ) {
+ rtems_status_code sc;
+
+ sc = rtems_task_delete( ctx->id_obj );
+ T_rsc_success( sc );
+
+ ctx->id_obj = INVALID_ID;
+ }
+
+ T_surrender_objects( &ctx->seized_objects, rtems_task_delete );
+}
+
+static const RtemsTaskReqConstruct_Entry
+RtemsTaskReqConstruct_Entries[] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_InvAddr,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_No,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_InvAddr,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_No,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_NA, RtemsTaskReqConstruct_Post_Name_NA,
+ RtemsTaskReqConstruct_Post_IdObj_NA,
+ RtemsTaskReqConstruct_Post_CreateNew_NA,
+ RtemsTaskReqConstruct_Post_DeleteNew_NA,
+ RtemsTaskReqConstruct_Post_KillZombies_NA,
+ RtemsTaskReqConstruct_Post_StorageFree_NA,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_InvName,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_No,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_InvName,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_No,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_NA, RtemsTaskReqConstruct_Post_Name_NA,
+ RtemsTaskReqConstruct_Post_IdObj_NA,
+ RtemsTaskReqConstruct_Post_CreateNew_NA,
+ RtemsTaskReqConstruct_Post_DeleteNew_NA,
+ RtemsTaskReqConstruct_Post_KillZombies_NA,
+ RtemsTaskReqConstruct_Post_StorageFree_NA,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_InvPrio,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_No,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_InvPrio,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_No,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_NA, RtemsTaskReqConstruct_Post_Name_NA,
+ RtemsTaskReqConstruct_Post_IdObj_NA,
+ RtemsTaskReqConstruct_Post_CreateNew_NA,
+ RtemsTaskReqConstruct_Post_DeleteNew_NA,
+ RtemsTaskReqConstruct_Post_KillZombies_NA,
+ RtemsTaskReqConstruct_Post_StorageFree_NA,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_TooMany,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_TooMany,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_NA, RtemsTaskReqConstruct_Post_Name_NA,
+ RtemsTaskReqConstruct_Post_IdObj_NA,
+ RtemsTaskReqConstruct_Post_CreateNew_NA,
+ RtemsTaskReqConstruct_Post_DeleteNew_NA,
+ RtemsTaskReqConstruct_Post_KillZombies_NA,
+ RtemsTaskReqConstruct_Post_StorageFree_NA,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_InvSize,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_InvSize,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_NA, RtemsTaskReqConstruct_Post_Name_NA,
+ RtemsTaskReqConstruct_Post_IdObj_NA,
+ RtemsTaskReqConstruct_Post_CreateNew_NA,
+ RtemsTaskReqConstruct_Post_DeleteNew_NA,
+ RtemsTaskReqConstruct_Post_KillZombies_NA,
+ RtemsTaskReqConstruct_Post_StorageFree_NA,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_NA, RtemsTaskReqConstruct_Post_Name_NA,
+ RtemsTaskReqConstruct_Post_IdObj_NA,
+ RtemsTaskReqConstruct_Post_CreateNew_NA,
+ RtemsTaskReqConstruct_Post_DeleteNew_NA,
+ RtemsTaskReqConstruct_Post_KillZombies_NA,
+ RtemsTaskReqConstruct_Post_StorageFree_NA,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_UpToFailing,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_UpToFailing,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_UpToFailing,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_NA, RtemsTaskReqConstruct_Post_Name_NA,
+ RtemsTaskReqConstruct_Post_IdObj_NA,
+ RtemsTaskReqConstruct_Post_CreateNew_NA,
+ RtemsTaskReqConstruct_Post_DeleteNew_NA,
+ RtemsTaskReqConstruct_Post_KillZombies_NA,
+ RtemsTaskReqConstruct_Post_StorageFree_NA,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_Yes, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_Yes,
+ RtemsTaskReqConstruct_Post_IntLvl_Positive },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_No, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_No,
+ RtemsTaskReqConstruct_Post_IntLvl_Positive },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_No,
+ RtemsTaskReqConstruct_Post_ASR_Yes, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_No,
+ RtemsTaskReqConstruct_Post_ASR_Yes,
+ RtemsTaskReqConstruct_Post_IntLvl_Positive },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_No, RtemsTaskReqConstruct_Post_ASR_No,
+ RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_No, RtemsTaskReqConstruct_Post_ASR_No,
+ RtemsTaskReqConstruct_Post_IntLvl_Positive },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_No,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_Yes, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_No,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_Yes,
+ RtemsTaskReqConstruct_Post_IntLvl_Positive },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_No,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_No, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_No,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_No,
+ RtemsTaskReqConstruct_Post_IntLvl_Positive },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_No,
+ RtemsTaskReqConstruct_Post_Timeslice_No,
+ RtemsTaskReqConstruct_Post_ASR_Yes, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_No,
+ RtemsTaskReqConstruct_Post_Timeslice_No,
+ RtemsTaskReqConstruct_Post_ASR_Yes,
+ RtemsTaskReqConstruct_Post_IntLvl_Positive },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_No,
+ RtemsTaskReqConstruct_Post_Timeslice_No, RtemsTaskReqConstruct_Post_ASR_No,
+ RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_No,
+ RtemsTaskReqConstruct_Post_Timeslice_No, RtemsTaskReqConstruct_Post_ASR_No,
+ RtemsTaskReqConstruct_Post_IntLvl_Positive },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_Yes, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_Yes,
+ RtemsTaskReqConstruct_Post_IntLvl_Positive },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_No, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_No,
+ RtemsTaskReqConstruct_Post_IntLvl_Positive },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_No,
+ RtemsTaskReqConstruct_Post_ASR_Yes, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_No,
+ RtemsTaskReqConstruct_Post_ASR_Yes,
+ RtemsTaskReqConstruct_Post_IntLvl_Positive },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_No, RtemsTaskReqConstruct_Post_ASR_No,
+ RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_No, RtemsTaskReqConstruct_Post_ASR_No,
+ RtemsTaskReqConstruct_Post_IntLvl_Positive },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_No,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_Yes, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_No,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_Yes,
+ RtemsTaskReqConstruct_Post_IntLvl_Positive },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_No,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_No, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_No,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_No,
+ RtemsTaskReqConstruct_Post_IntLvl_Positive },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_No,
+ RtemsTaskReqConstruct_Post_Timeslice_No,
+ RtemsTaskReqConstruct_Post_ASR_Yes, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_No,
+ RtemsTaskReqConstruct_Post_Timeslice_No,
+ RtemsTaskReqConstruct_Post_ASR_Yes,
+ RtemsTaskReqConstruct_Post_IntLvl_Positive },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_No,
+ RtemsTaskReqConstruct_Post_Timeslice_No, RtemsTaskReqConstruct_Post_ASR_No,
+ RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Unsat,
+ RtemsTaskReqConstruct_Post_Name_Invalid,
+ RtemsTaskReqConstruct_Post_IdObj_Nop,
+ RtemsTaskReqConstruct_Post_CreateNew_Nop,
+ RtemsTaskReqConstruct_Post_DeleteNew_All,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_Yes,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_No,
+ RtemsTaskReqConstruct_Post_Timeslice_No, RtemsTaskReqConstruct_Post_ASR_No,
+ RtemsTaskReqConstruct_Post_IntLvl_Positive },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_Yes, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_NA, RtemsTaskReqConstruct_Post_Name_NA,
+ RtemsTaskReqConstruct_Post_IdObj_NA,
+ RtemsTaskReqConstruct_Post_CreateNew_NA,
+ RtemsTaskReqConstruct_Post_DeleteNew_NA,
+ RtemsTaskReqConstruct_Post_KillZombies_NA,
+ RtemsTaskReqConstruct_Post_StorageFree_NA,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_No, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_NA, RtemsTaskReqConstruct_Post_Name_NA,
+ RtemsTaskReqConstruct_Post_IdObj_NA,
+ RtemsTaskReqConstruct_Post_CreateNew_NA,
+ RtemsTaskReqConstruct_Post_DeleteNew_NA,
+ RtemsTaskReqConstruct_Post_KillZombies_NA,
+ RtemsTaskReqConstruct_Post_StorageFree_NA,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_No,
+ RtemsTaskReqConstruct_Post_ASR_Yes, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_NA, RtemsTaskReqConstruct_Post_Name_NA,
+ RtemsTaskReqConstruct_Post_IdObj_NA,
+ RtemsTaskReqConstruct_Post_CreateNew_NA,
+ RtemsTaskReqConstruct_Post_DeleteNew_NA,
+ RtemsTaskReqConstruct_Post_KillZombies_NA,
+ RtemsTaskReqConstruct_Post_StorageFree_NA,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_Yes,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_No, RtemsTaskReqConstruct_Post_ASR_No,
+ RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_NA, RtemsTaskReqConstruct_Post_Name_NA,
+ RtemsTaskReqConstruct_Post_IdObj_NA,
+ RtemsTaskReqConstruct_Post_CreateNew_NA,
+ RtemsTaskReqConstruct_Post_DeleteNew_NA,
+ RtemsTaskReqConstruct_Post_KillZombies_NA,
+ RtemsTaskReqConstruct_Post_StorageFree_NA,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_Yes, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_NA, RtemsTaskReqConstruct_Post_Name_NA,
+ RtemsTaskReqConstruct_Post_IdObj_NA,
+ RtemsTaskReqConstruct_Post_CreateNew_NA,
+ RtemsTaskReqConstruct_Post_DeleteNew_NA,
+ RtemsTaskReqConstruct_Post_KillZombies_NA,
+ RtemsTaskReqConstruct_Post_StorageFree_NA,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_Yes,
+ RtemsTaskReqConstruct_Post_ASR_No, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_NA, RtemsTaskReqConstruct_Post_Name_NA,
+ RtemsTaskReqConstruct_Post_IdObj_NA,
+ RtemsTaskReqConstruct_Post_CreateNew_NA,
+ RtemsTaskReqConstruct_Post_DeleteNew_NA,
+ RtemsTaskReqConstruct_Post_KillZombies_NA,
+ RtemsTaskReqConstruct_Post_StorageFree_NA,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_No,
+ RtemsTaskReqConstruct_Post_ASR_Yes, RtemsTaskReqConstruct_Post_IntLvl_Zero },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_NA, RtemsTaskReqConstruct_Post_Name_NA,
+ RtemsTaskReqConstruct_Post_IdObj_NA,
+ RtemsTaskReqConstruct_Post_CreateNew_NA,
+ RtemsTaskReqConstruct_Post_DeleteNew_NA,
+ RtemsTaskReqConstruct_Post_KillZombies_NA,
+ RtemsTaskReqConstruct_Post_StorageFree_NA,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_Ok,
+ RtemsTaskReqConstruct_Post_Name_Valid,
+ RtemsTaskReqConstruct_Post_IdObj_Set,
+ RtemsTaskReqConstruct_Post_CreateNew_All,
+ RtemsTaskReqConstruct_Post_DeleteNew_Nop,
+ RtemsTaskReqConstruct_Post_KillZombies_Yes,
+ RtemsTaskReqConstruct_Post_StorageFree_No,
+ RtemsTaskReqConstruct_Post_FloatingPoint_No,
+ RtemsTaskReqConstruct_Post_Preempt_Yes,
+ RtemsTaskReqConstruct_Post_Timeslice_No, RtemsTaskReqConstruct_Post_ASR_No,
+ RtemsTaskReqConstruct_Post_IntLvl_Zero }
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqConstruct_Post_Status_NA, RtemsTaskReqConstruct_Post_Name_NA,
+ RtemsTaskReqConstruct_Post_IdObj_NA,
+ RtemsTaskReqConstruct_Post_CreateNew_NA,
+ RtemsTaskReqConstruct_Post_DeleteNew_NA,
+ RtemsTaskReqConstruct_Post_KillZombies_NA,
+ RtemsTaskReqConstruct_Post_StorageFree_NA,
+ RtemsTaskReqConstruct_Post_FloatingPoint_NA,
+ RtemsTaskReqConstruct_Post_Preempt_NA,
+ RtemsTaskReqConstruct_Post_Timeslice_NA, RtemsTaskReqConstruct_Post_ASR_NA,
+ RtemsTaskReqConstruct_Post_IntLvl_NA }
+#endif
+};
+
+static const uint8_t
+RtemsTaskReqConstruct_Map[] = {
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 11, 12, 11, 12, 11, 12,
+ 11, 12, 11, 12, 11, 12, 11, 12, 11, 12, 11, 12, 11, 12, 11, 12, 11, 12, 11,
+ 12, 11, 12, 11, 12, 11, 12, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 11, 12, 11, 12, 11, 12, 11, 12, 11, 12, 11, 12, 11,
+ 12, 11, 12, 11, 12, 11, 12, 11, 12, 11, 12, 11, 12, 11, 12, 11, 12, 11, 12,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 11, 12, 11, 12, 11, 12, 11,
+ 12, 11, 12, 11, 12, 11, 12, 11, 12, 11, 12, 11, 12, 11, 12, 11, 12, 11, 12,
+ 11, 12, 11, 12, 11, 12, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0,
+ 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 46, 10, 47, 10, 48, 10, 49, 10, 10, 10, 10, 10, 10, 10, 10, 10, 50, 10, 51,
+ 10, 52, 10, 53, 10, 10, 10, 10, 10, 10, 10, 10, 10, 13, 10, 13, 10, 13, 10,
+ 13, 10, 10, 10, 10, 10, 10, 10, 10, 10, 13, 10, 13, 10, 13, 10, 13, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 46, 10, 47, 10, 48, 10, 49,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 50, 10, 51, 10, 52, 10, 53, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 13, 10, 13, 10, 13, 10, 13, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 13, 10, 13, 10, 13, 10, 13, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 46,
+ 10, 47, 10, 48, 10, 49, 10, 10, 10, 10, 10, 10, 10, 10, 10, 50, 10, 51, 10,
+ 52, 10, 53, 10, 10, 10, 10, 10, 10, 10, 10, 10, 13, 10, 13, 10, 13, 10, 13,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 13, 10, 13, 10, 13, 10, 13, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+};
+
+static size_t RtemsTaskReqConstruct_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqConstruct_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsTaskReqConstruct_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqConstruct_Fixture = {
+ .setup = RtemsTaskReqConstruct_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqConstruct_Teardown_Wrap,
+ .scope = RtemsTaskReqConstruct_Scope,
+ .initial_context = &RtemsTaskReqConstruct_Instance
+};
+
+static const uint16_t RtemsTaskReqConstruct_Weights[] = {
+ 24576, 12288, 6144, 3072, 1536, 512, 256, 128, 64, 32, 16, 8, 4, 2, 1
+};
+
+static void RtemsTaskReqConstruct_Skip(
+ RtemsTaskReqConstruct_Context *ctx,
+ size_t index
+)
+{
+ switch ( index + 1 ) {
+ case 1:
+ ctx->Map.pcs[ 1 ] = RtemsTaskReqConstruct_Pre_Config_NA - 1;
+ /* Fall through */
+ case 2:
+ ctx->Map.pcs[ 2 ] = RtemsTaskReqConstruct_Pre_Name_NA - 1;
+ /* Fall through */
+ case 3:
+ ctx->Map.pcs[ 3 ] = RtemsTaskReqConstruct_Pre_Id_NA - 1;
+ /* Fall through */
+ case 4:
+ ctx->Map.pcs[ 4 ] = RtemsTaskReqConstruct_Pre_SystemTask_NA - 1;
+ /* Fall through */
+ case 5:
+ ctx->Map.pcs[ 5 ] = RtemsTaskReqConstruct_Pre_Priority_NA - 1;
+ /* Fall through */
+ case 6:
+ ctx->Map.pcs[ 6 ] = RtemsTaskReqConstruct_Pre_Free_NA - 1;
+ /* Fall through */
+ case 7:
+ ctx->Map.pcs[ 7 ] = RtemsTaskReqConstruct_Pre_TLS_NA - 1;
+ /* Fall through */
+ case 8:
+ ctx->Map.pcs[ 8 ] = RtemsTaskReqConstruct_Pre_Stack_NA - 1;
+ /* Fall through */
+ case 9:
+ ctx->Map.pcs[ 9 ] = RtemsTaskReqConstruct_Pre_Create_NA - 1;
+ /* Fall through */
+ case 10:
+ ctx->Map.pcs[ 10 ] = RtemsTaskReqConstruct_Pre_FloatingPoint_NA - 1;
+ /* Fall through */
+ case 11:
+ ctx->Map.pcs[ 11 ] = RtemsTaskReqConstruct_Pre_Preempt_NA - 1;
+ /* Fall through */
+ case 12:
+ ctx->Map.pcs[ 12 ] = RtemsTaskReqConstruct_Pre_Timeslice_NA - 1;
+ /* Fall through */
+ case 13:
+ ctx->Map.pcs[ 13 ] = RtemsTaskReqConstruct_Pre_ASR_NA - 1;
+ /* Fall through */
+ case 14:
+ ctx->Map.pcs[ 14 ] = RtemsTaskReqConstruct_Pre_IntLvl_NA - 1;
+ break;
+ }
+}
+
+static inline RtemsTaskReqConstruct_Entry RtemsTaskReqConstruct_PopEntry(
+ RtemsTaskReqConstruct_Context *ctx
+)
+{
+ size_t index;
+
+ if ( ctx->Map.skip ) {
+ size_t i;
+
+ ctx->Map.skip = false;
+ index = 0;
+
+ for ( i = 0; i < 15; ++i ) {
+ index += RtemsTaskReqConstruct_Weights[ i ] * ctx->Map.pcs[ i ];
+ }
+ } else {
+ index = ctx->Map.index;
+ }
+
+ ctx->Map.index = index + 1;
+
+ return RtemsTaskReqConstruct_Entries[
+ RtemsTaskReqConstruct_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqConstruct_TestVariant(
+ RtemsTaskReqConstruct_Context *ctx
+)
+{
+ RtemsTaskReqConstruct_Pre_CPUs_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+
+ if ( ctx->Map.skip ) {
+ RtemsTaskReqConstruct_Skip( ctx, 0 );
+ return;
+ }
+
+ RtemsTaskReqConstruct_Pre_Config_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqConstruct_Pre_Name_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTaskReqConstruct_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsTaskReqConstruct_Pre_SystemTask_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsTaskReqConstruct_Pre_Priority_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsTaskReqConstruct_Pre_Free_Prepare( ctx, ctx->Map.pcs[ 6 ] );
+ RtemsTaskReqConstruct_Pre_TLS_Prepare( ctx, ctx->Map.pcs[ 7 ] );
+ RtemsTaskReqConstruct_Pre_Stack_Prepare( ctx, ctx->Map.pcs[ 8 ] );
+ RtemsTaskReqConstruct_Pre_Create_Prepare( ctx, ctx->Map.pcs[ 9 ] );
+ RtemsTaskReqConstruct_Pre_FloatingPoint_Prepare( ctx, ctx->Map.pcs[ 10 ] );
+ RtemsTaskReqConstruct_Pre_Preempt_Prepare( ctx, ctx->Map.pcs[ 11 ] );
+ RtemsTaskReqConstruct_Pre_Timeslice_Prepare( ctx, ctx->Map.pcs[ 12 ] );
+ RtemsTaskReqConstruct_Pre_ASR_Prepare( ctx, ctx->Map.pcs[ 13 ] );
+ RtemsTaskReqConstruct_Pre_IntLvl_Prepare( ctx, ctx->Map.pcs[ 14 ] );
+ RtemsTaskReqConstruct_Action( ctx );
+ RtemsTaskReqConstruct_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsTaskReqConstruct_Post_Name_Check( ctx, ctx->Map.entry.Post_Name );
+ RtemsTaskReqConstruct_Post_IdObj_Check( ctx, ctx->Map.entry.Post_IdObj );
+ RtemsTaskReqConstruct_Post_CreateNew_Check(
+ ctx,
+ ctx->Map.entry.Post_CreateNew
+ );
+ RtemsTaskReqConstruct_Post_DeleteNew_Check(
+ ctx,
+ ctx->Map.entry.Post_DeleteNew
+ );
+ RtemsTaskReqConstruct_Post_KillZombies_Check(
+ ctx,
+ ctx->Map.entry.Post_KillZombies
+ );
+ RtemsTaskReqConstruct_Post_StorageFree_Check(
+ ctx,
+ ctx->Map.entry.Post_StorageFree
+ );
+ RtemsTaskReqConstruct_Post_FloatingPoint_Check(
+ ctx,
+ ctx->Map.entry.Post_FloatingPoint
+ );
+ RtemsTaskReqConstruct_Post_Preempt_Check( ctx, ctx->Map.entry.Post_Preempt );
+ RtemsTaskReqConstruct_Post_Timeslice_Check(
+ ctx,
+ ctx->Map.entry.Post_Timeslice
+ );
+ RtemsTaskReqConstruct_Post_ASR_Check( ctx, ctx->Map.entry.Post_ASR );
+ RtemsTaskReqConstruct_Post_IntLvl_Check( ctx, ctx->Map.entry.Post_IntLvl );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqConstruct( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTaskReqConstruct, &RtemsTaskReqConstruct_Fixture )
+{
+ RtemsTaskReqConstruct_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+ ctx->Map.skip = false;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsTaskReqConstruct_Pre_CPUs_One;
+ ctx->Map.pcs[ 0 ] < RtemsTaskReqConstruct_Pre_CPUs_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsTaskReqConstruct_Pre_Config_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsTaskReqConstruct_Pre_Config_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsTaskReqConstruct_Pre_Name_Valid;
+ ctx->Map.pcs[ 2 ] < RtemsTaskReqConstruct_Pre_Name_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsTaskReqConstruct_Pre_Id_Valid;
+ ctx->Map.pcs[ 3 ] < RtemsTaskReqConstruct_Pre_Id_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = RtemsTaskReqConstruct_Pre_SystemTask_Yes;
+ ctx->Map.pcs[ 4 ] < RtemsTaskReqConstruct_Pre_SystemTask_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 5 ] = RtemsTaskReqConstruct_Pre_Priority_Valid;
+ ctx->Map.pcs[ 5 ] < RtemsTaskReqConstruct_Pre_Priority_NA;
+ ++ctx->Map.pcs[ 5 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 6 ] = RtemsTaskReqConstruct_Pre_Free_Yes;
+ ctx->Map.pcs[ 6 ] < RtemsTaskReqConstruct_Pre_Free_NA;
+ ++ctx->Map.pcs[ 6 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 7 ] = RtemsTaskReqConstruct_Pre_TLS_Enough;
+ ctx->Map.pcs[ 7 ] < RtemsTaskReqConstruct_Pre_TLS_NA;
+ ++ctx->Map.pcs[ 7 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 8 ] = RtemsTaskReqConstruct_Pre_Stack_Enough;
+ ctx->Map.pcs[ 8 ] < RtemsTaskReqConstruct_Pre_Stack_NA;
+ ++ctx->Map.pcs[ 8 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 9 ] = RtemsTaskReqConstruct_Pre_Create_Ok;
+ ctx->Map.pcs[ 9 ] < RtemsTaskReqConstruct_Pre_Create_NA;
+ ++ctx->Map.pcs[ 9 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 10 ] = RtemsTaskReqConstruct_Pre_FloatingPoint_Yes;
+ ctx->Map.pcs[ 10 ] < RtemsTaskReqConstruct_Pre_FloatingPoint_NA;
+ ++ctx->Map.pcs[ 10 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 11 ] = RtemsTaskReqConstruct_Pre_Preempt_Yes;
+ ctx->Map.pcs[ 11 ] < RtemsTaskReqConstruct_Pre_Preempt_NA;
+ ++ctx->Map.pcs[ 11 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 12 ] = RtemsTaskReqConstruct_Pre_Timeslice_Yes;
+ ctx->Map.pcs[ 12 ] < RtemsTaskReqConstruct_Pre_Timeslice_NA;
+ ++ctx->Map.pcs[ 12 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 13 ] = RtemsTaskReqConstruct_Pre_ASR_Yes;
+ ctx->Map.pcs[ 13 ] < RtemsTaskReqConstruct_Pre_ASR_NA;
+ ++ctx->Map.pcs[ 13 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 14 ] = RtemsTaskReqConstruct_Pre_IntLvl_Zero;
+ ctx->Map.pcs[ 14 ] < RtemsTaskReqConstruct_Pre_IntLvl_NA;
+ ++ctx->Map.pcs[ 14 ]
+ ) {
+ ctx->Map.entry =
+ RtemsTaskReqConstruct_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsTaskReqConstruct_Prepare( ctx );
+ RtemsTaskReqConstruct_TestVariant( ctx );
+ RtemsTaskReqConstruct_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-create-errors.c b/testsuites/validation/tc-task-create-errors.c
index 1159773eed..2378e55020 100644
--- a/testsuites/validation/tc-task-create-errors.c
+++ b/testsuites/validation/tc-task-create-errors.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestCaseRtemsTaskReqCreateErrors
+ * @ingroup RtemsTaskReqCreateErrors
*/
/*
- * Copyright (C) 2020, 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2020, 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -57,14 +57,15 @@
#include <rtems/score/apimutex.h>
#include <rtems/score/threadimpl.h>
+#include "tx-support.h"
+
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestCaseRtemsTaskReqCreateErrors \
- * spec:/rtems/task/req/create-errors
+ * @defgroup RtemsTaskReqCreateErrors spec:/rtems/task/req/create-errors
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
- * @ingroup RTEMSTestSuiteTestsuitesValidation1
+ * @ingroup TestsuitesValidationNoClock0
+ * @ingroup TestsuitesValidationOneCpu0
*
* @{
*/
@@ -280,8 +281,6 @@ static const char * const * const RtemsTaskReqCreateErrors_PreDesc[] = {
#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
-#define INVALID_ID 0xffffffff
-
typedef RtemsTaskReqCreateErrors_Context Context;
static rtems_status_code Create( void *arg, uint32_t *id )
@@ -419,7 +418,7 @@ static void RtemsTaskReqCreateErrors_Pre_Prio_Prepare(
/*
* While the ``initial_priority`` parameter is valid and non-zero.
*/
- ctx->initial_priority = 254;
+ ctx->initial_priority = RTEMS_MAXIMUM_PRIORITY - 1;
break;
}
diff --git a/testsuites/validation/tc-task-delete.c b/testsuites/validation/tc-task-delete.c
new file mode 100644
index 0000000000..d917062d0d
--- /dev/null
+++ b/testsuites/validation/tc-task-delete.c
@@ -0,0 +1,4844 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqDelete
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <rtems.h>
+#include <setjmp.h>
+#include <rtems/bspIo.h>
+#include <rtems/test-scheduler.h>
+#include <rtems/score/statesimpl.h>
+#include <rtems/score/threaddispatch.h>
+#include <rtems/score/threadimpl.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqDelete spec:/rtems/task/req/delete
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqDelete_Pre_Id_Executing,
+ RtemsTaskReqDelete_Pre_Id_Other,
+ RtemsTaskReqDelete_Pre_Id_Invalid,
+ RtemsTaskReqDelete_Pre_Id_NA
+} RtemsTaskReqDelete_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqDelete_Pre_Context_Task,
+ RtemsTaskReqDelete_Pre_Context_Interrupt,
+ RtemsTaskReqDelete_Pre_Context_NA
+} RtemsTaskReqDelete_Pre_Context;
+
+typedef enum {
+ RtemsTaskReqDelete_Pre_ThreadDispatch_Disabled,
+ RtemsTaskReqDelete_Pre_ThreadDispatch_Enabled,
+ RtemsTaskReqDelete_Pre_ThreadDispatch_NA
+} RtemsTaskReqDelete_Pre_ThreadDispatch;
+
+typedef enum {
+ RtemsTaskReqDelete_Pre_CallerPriority_Vital,
+ RtemsTaskReqDelete_Pre_CallerPriority_Dispensable,
+ RtemsTaskReqDelete_Pre_CallerPriority_NA
+} RtemsTaskReqDelete_Pre_CallerPriority;
+
+typedef enum {
+ RtemsTaskReqDelete_Pre_Dormant_No,
+ RtemsTaskReqDelete_Pre_Dormant_Yes,
+ RtemsTaskReqDelete_Pre_Dormant_NA
+} RtemsTaskReqDelete_Pre_Dormant;
+
+typedef enum {
+ RtemsTaskReqDelete_Pre_Suspended_Yes,
+ RtemsTaskReqDelete_Pre_Suspended_No,
+ RtemsTaskReqDelete_Pre_Suspended_NA
+} RtemsTaskReqDelete_Pre_Suspended;
+
+typedef enum {
+ RtemsTaskReqDelete_Pre_Restarting_No,
+ RtemsTaskReqDelete_Pre_Restarting_Yes,
+ RtemsTaskReqDelete_Pre_Restarting_NA
+} RtemsTaskReqDelete_Pre_Restarting;
+
+typedef enum {
+ RtemsTaskReqDelete_Pre_Terminating_No,
+ RtemsTaskReqDelete_Pre_Terminating_Yes,
+ RtemsTaskReqDelete_Pre_Terminating_NA
+} RtemsTaskReqDelete_Pre_Terminating;
+
+typedef enum {
+ RtemsTaskReqDelete_Pre_Protected_Yes,
+ RtemsTaskReqDelete_Pre_Protected_No,
+ RtemsTaskReqDelete_Pre_Protected_NA
+} RtemsTaskReqDelete_Pre_Protected;
+
+typedef enum {
+ RtemsTaskReqDelete_Pre_State_Enqueued,
+ RtemsTaskReqDelete_Pre_State_Ready,
+ RtemsTaskReqDelete_Pre_State_Blocked,
+ RtemsTaskReqDelete_Pre_State_NA
+} RtemsTaskReqDelete_Pre_State;
+
+typedef enum {
+ RtemsTaskReqDelete_Pre_Timer_Inactive,
+ RtemsTaskReqDelete_Pre_Timer_Active,
+ RtemsTaskReqDelete_Pre_Timer_NA
+} RtemsTaskReqDelete_Pre_Timer;
+
+typedef enum {
+ RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_Status_InvId,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_Status_NA
+} RtemsTaskReqDelete_Post_Status;
+
+typedef enum {
+ RtemsTaskReqDelete_Post_FatalError_Yes,
+ RtemsTaskReqDelete_Post_FatalError_Nop,
+ RtemsTaskReqDelete_Post_FatalError_NA
+} RtemsTaskReqDelete_Post_FatalError;
+
+typedef enum {
+ RtemsTaskReqDelete_Post_Zombie_Yes,
+ RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_Zombie_NA
+} RtemsTaskReqDelete_Post_Zombie;
+
+typedef enum {
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_TaskPriority_NA
+} RtemsTaskReqDelete_Post_TaskPriority;
+
+typedef enum {
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_NA
+} RtemsTaskReqDelete_Post_RestartExtensions;
+
+typedef enum {
+ RtemsTaskReqDelete_Post_TerminateExtensions_Yes,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_NA
+} RtemsTaskReqDelete_Post_TerminateExtensions;
+
+typedef enum {
+ RtemsTaskReqDelete_Post_Dormant_Yes,
+ RtemsTaskReqDelete_Post_Dormant_No,
+ RtemsTaskReqDelete_Post_Dormant_NA
+} RtemsTaskReqDelete_Post_Dormant;
+
+typedef enum {
+ RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Suspended_NA
+} RtemsTaskReqDelete_Post_Suspended;
+
+typedef enum {
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Restarting_NA
+} RtemsTaskReqDelete_Post_Restarting;
+
+typedef enum {
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Terminating_NA
+} RtemsTaskReqDelete_Post_Terminating;
+
+typedef enum {
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_Protected_NA
+} RtemsTaskReqDelete_Post_Protected;
+
+typedef enum {
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_State_NA
+} RtemsTaskReqDelete_Post_State;
+
+typedef enum {
+ RtemsTaskReqDelete_Post_Timer_Active,
+ RtemsTaskReqDelete_Post_Timer_Inactive,
+ RtemsTaskReqDelete_Post_Timer_NA
+} RtemsTaskReqDelete_Post_Timer;
+
+typedef struct {
+ uint64_t Skip : 1;
+ uint64_t Pre_Id_NA : 1;
+ uint64_t Pre_Context_NA : 1;
+ uint64_t Pre_ThreadDispatch_NA : 1;
+ uint64_t Pre_CallerPriority_NA : 1;
+ uint64_t Pre_Dormant_NA : 1;
+ uint64_t Pre_Suspended_NA : 1;
+ uint64_t Pre_Restarting_NA : 1;
+ uint64_t Pre_Terminating_NA : 1;
+ uint64_t Pre_Protected_NA : 1;
+ uint64_t Pre_State_NA : 1;
+ uint64_t Pre_Timer_NA : 1;
+ uint64_t Post_Status : 3;
+ uint64_t Post_FatalError : 2;
+ uint64_t Post_Zombie : 2;
+ uint64_t Post_TaskPriority : 2;
+ uint64_t Post_RestartExtensions : 1;
+ uint64_t Post_TerminateExtensions : 2;
+ uint64_t Post_Dormant : 2;
+ uint64_t Post_Suspended : 2;
+ uint64_t Post_Restarting : 2;
+ uint64_t Post_Terminating : 2;
+ uint64_t Post_Protected : 2;
+ uint64_t Post_State : 2;
+ uint64_t Post_Timer : 2;
+} RtemsTaskReqDelete_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/delete test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides the scheduler operation records.
+ */
+ T_scheduler_log_10 scheduler_log;
+
+ /**
+ * @brief This member provides a jump context to resume a thread dispatch.
+ */
+ jmp_buf thread_dispatch_context;
+
+ /**
+ * @brief This member contains the identifier of the runner scheduler.
+ */
+ rtems_id scheduler_id;
+
+ /**
+ * @brief This member contains the identifier of the runner task.
+ */
+ rtems_id runner_id;
+
+ /**
+ * @brief This member references the TCB of the runner task.
+ */
+ rtems_tcb *runner_tcb;
+
+ /**
+ * @brief This member contains the identifier of the mutex.
+ */
+ rtems_id mutex_id;
+
+ /**
+ * @brief This member provides an event set used to set up the blocking
+ * conditions of the task to delete.
+ */
+ rtems_event_set events;
+
+ /**
+ * @brief This member contains the identifier of the worker task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member references the TCB of the worker task.
+ */
+ rtems_tcb *worker_tcb;
+
+ /**
+ * @brief This member contains the worker state at the end of the
+ * rtems_task_delete() call.
+ */
+ States_Control worker_state;
+
+ /**
+ * @brief This member contains the worker timer info at the end of the
+ * rtems_task_delete() call.
+ */
+ TaskTimerInfo worker_timer_info;
+
+ /**
+ * @brief This member contains the worker thread queue at the end of the
+ * rtems_task_delete() call.
+ */
+ const Thread_queue_Queue *worker_wait_queue;
+
+ /**
+ * @brief This member contains the worker thread life state at the end of the
+ * rtems_task_delete() call.
+ */
+ Thread_Life_state worker_life_state;
+
+ /**
+ * @brief This member contains the worker priority at the end of the
+ * rtems_task_delete() call.
+ */
+ rtems_task_priority worker_priority;
+
+ /**
+ * @brief This member contains the identifier of the deleter task.
+ */
+ rtems_id deleter_id;
+
+ /**
+ * @brief This member references the TCB of the deleter task.
+ */
+ rtems_tcb *deleter_tcb;
+
+ /**
+ * @brief This member contains the identifier of the second deleter task.
+ */
+ rtems_id deleter_2_id;
+
+ /**
+ * @brief This member references the TCB of the second deleter task.
+ */
+ rtems_tcb *deleter_2_tcb;
+
+ /**
+ * @brief This member contains the identifier of the test user extensions.
+ */
+ rtems_id extension_id;
+
+ /**
+ * @brief This member contains extension calls.
+ */
+ ExtensionCalls calls;
+
+ /**
+ * @brief This member contains extension calls after the rtems_task_delete()
+ * call.
+ */
+ ExtensionCalls calls_after_restart;
+
+ /**
+ * @brief This member contains the delete counter.
+ */
+ uint32_t restart_counter;
+
+ /**
+ * @brief If this member is true, then the worker shall be dormant before the
+ * rtems_task_delete() call.
+ */
+ bool dormant;
+
+ /**
+ * @brief If this member is true, then the worker shall be suspended before
+ * the rtems_task_delete() call.
+ */
+ bool suspended;
+
+ /**
+ * @brief If this member is true, then the thread life of the worker shall be
+ * protected before the rtems_task_delete() call.
+ */
+ bool protected;
+
+ /**
+ * @brief If this member is true, then the worker shall be restarting before
+ * the rtems_task_delete() call.
+ */
+ bool restarting;
+
+ /**
+ * @brief If this member is true, then the worker shall be terminating before
+ * the rtems_task_delete() call.
+ */
+ bool terminating;
+
+ /**
+ * @brief If this member is true, then the rtems_task_delete() shall be
+ * called from within interrupt context.
+ */
+ bool interrupt;
+
+ /**
+ * @brief If this member is true, then the worker shall be blocked before the
+ * rtems_task_delete() call.
+ */
+ bool blocked;
+
+ /**
+ * @brief If this member is true, then the worker shall be enqueued on a wait
+ * queue before the rtems_task_delete() call.
+ */
+ bool enqueued;
+
+ /**
+ * @brief If this member is true, then the worker obtained a mutex.
+ */
+ bool worker_is_mutex_owner;
+
+ /**
+ * @brief If this member is true, then the timer of the worker shall be
+ * active before the rtems_task_delete() call.
+ */
+ bool timer_active;
+
+ /**
+ * @brief If this member is true, then the deleter shall have a vital
+ * priority for the worker.
+ */
+ bool vital_deleter_priority;
+
+ /**
+ * @brief If this member is true, then thread dispatching is disabled by the
+ * worker task before the rtems_task_delete() call.
+ */
+ bool dispatch_disabled;
+
+ /**
+ * @brief If this member is true, then it is expected to delete the worker.
+ */
+ bool delete_worker_expected;
+
+ /**
+ * @brief This member contains the return value of the rtems_task_delete()
+ * call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 11 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 11 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqDelete_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqDelete_Context;
+
+static RtemsTaskReqDelete_Context
+ RtemsTaskReqDelete_Instance;
+
+static const char * const RtemsTaskReqDelete_PreDesc_Id[] = {
+ "Executing",
+ "Other",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTaskReqDelete_PreDesc_Context[] = {
+ "Task",
+ "Interrupt",
+ "NA"
+};
+
+static const char * const RtemsTaskReqDelete_PreDesc_ThreadDispatch[] = {
+ "Disabled",
+ "Enabled",
+ "NA"
+};
+
+static const char * const RtemsTaskReqDelete_PreDesc_CallerPriority[] = {
+ "Vital",
+ "Dispensable",
+ "NA"
+};
+
+static const char * const RtemsTaskReqDelete_PreDesc_Dormant[] = {
+ "No",
+ "Yes",
+ "NA"
+};
+
+static const char * const RtemsTaskReqDelete_PreDesc_Suspended[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqDelete_PreDesc_Restarting[] = {
+ "No",
+ "Yes",
+ "NA"
+};
+
+static const char * const RtemsTaskReqDelete_PreDesc_Terminating[] = {
+ "No",
+ "Yes",
+ "NA"
+};
+
+static const char * const RtemsTaskReqDelete_PreDesc_Protected[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqDelete_PreDesc_State[] = {
+ "Enqueued",
+ "Ready",
+ "Blocked",
+ "NA"
+};
+
+static const char * const RtemsTaskReqDelete_PreDesc_Timer[] = {
+ "Inactive",
+ "Active",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqDelete_PreDesc[] = {
+ RtemsTaskReqDelete_PreDesc_Id,
+ RtemsTaskReqDelete_PreDesc_Context,
+ RtemsTaskReqDelete_PreDesc_ThreadDispatch,
+ RtemsTaskReqDelete_PreDesc_CallerPriority,
+ RtemsTaskReqDelete_PreDesc_Dormant,
+ RtemsTaskReqDelete_PreDesc_Suspended,
+ RtemsTaskReqDelete_PreDesc_Restarting,
+ RtemsTaskReqDelete_PreDesc_Terminating,
+ RtemsTaskReqDelete_PreDesc_Protected,
+ RtemsTaskReqDelete_PreDesc_State,
+ RtemsTaskReqDelete_PreDesc_Timer,
+ NULL
+};
+
+typedef RtemsTaskReqDelete_Context Context;
+
+static void CaptureWorkerState( Context *ctx )
+{
+ T_scheduler_log *log;
+
+ log = T_scheduler_record( NULL );
+
+ if ( log != NULL ) {
+ T_eq_ptr( &log->header, &ctx->scheduler_log.header );
+
+ ctx->worker_wait_queue = ctx->worker_tcb->Wait.queue;
+ ctx->worker_state = ctx->worker_tcb->current_state;
+ ctx->worker_life_state = ctx->worker_tcb->Life.state;
+ ctx->worker_priority =
+ SCHEDULER_PRIORITY_UNMAP( _Thread_Get_priority( ctx->worker_tcb ) );
+ CopyExtensionCalls( &ctx->calls, &ctx->calls_after_restart );
+ GetTaskTimerInfoByThread( ctx->worker_tcb, &ctx->worker_timer_info );
+ }
+}
+
+static void TaskSwitch( rtems_tcb *executing, rtems_tcb *heir )
+{
+ (void) executing;
+ (void) heir;
+ CaptureWorkerState( T_fixture_context() );
+}
+
+static void VerifyTaskPreparation( const Context *ctx )
+{
+ if ( ctx->id != INVALID_ID ) {
+ States_Control state;
+ Thread_Life_state life_state;
+
+ state = STATES_READY;
+ life_state = ctx->worker_tcb->Life.state;
+
+ if ( ctx->suspended ) {
+ state |= STATES_SUSPENDED;
+ }
+
+ if ( ctx->dormant ) {
+ T_eq_int( life_state, 0 );
+ state |= STATES_DORMANT;
+ } else {
+ T_eq( ctx->protected, ( life_state & THREAD_LIFE_PROTECTED ) != 0 );
+ T_eq( ctx->restarting, ( life_state & THREAD_LIFE_RESTARTING ) != 0 );
+ T_eq( ctx->terminating, ( life_state & THREAD_LIFE_TERMINATING ) != 0 );
+
+ if ( ctx->blocked ) {
+ if ( ctx->enqueued ) {
+ state |= STATES_WAITING_FOR_MUTEX;
+ } else {
+ state |= STATES_WAITING_FOR_EVENT;
+ }
+ }
+ }
+
+ T_eq_u32( ctx->worker_tcb->current_state, state );
+ }
+}
+
+static void Fatal(
+ rtems_fatal_source source,
+ rtems_fatal_code code,
+ void *arg
+)
+{
+ Context *ctx;
+
+ T_eq_int( source, INTERNAL_ERROR_CORE );
+ T_eq_ulong( code, INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL );
+
+ ctx = arg;
+ ++ctx->calls.fatal;
+ T_assert_eq_int( ctx->calls.fatal, 1 );
+ longjmp( ctx->thread_dispatch_context, 1 );
+}
+
+static void ResumeThreadDispatch(
+ rtems_fatal_source source,
+ rtems_fatal_code code,
+ void *arg
+)
+{
+ Context *ctx;
+
+ T_eq_int( source, INTERNAL_ERROR_CORE );
+ T_eq_ulong( code, INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL );
+
+ ctx = arg;
+ SetFatalHandler( Fatal, ctx );
+ longjmp( ctx->thread_dispatch_context, 1 );
+}
+
+static void Delete( void *arg )
+{
+ Context *ctx;
+ T_scheduler_log *log;
+
+ ctx = arg;
+
+ if ( ctx->suspended && ctx->id != INVALID_ID ) {
+ if ( ctx->id != RTEMS_SELF || ctx->interrupt ) {
+ SuspendTask( ctx->worker_id );
+ } else {
+ Per_CPU_Control *cpu_self;
+
+ /*
+ * Where the system was built with SMP support enabled, a suspended
+ * executing thread during the rtems_task_delete() call can happen
+ * if the thread was suspended by another processor and the
+ * inter-processor interrupt did not yet arrive. Where the system was
+ * built with SMP support disabled, this state cannot happen with the
+ * current implementation. However, we still specify and validate this
+ * behaviour unconditionally since there exist alternative
+ * implementations which would lead to such a state if the executing
+ * thread is suspended by an ISR.
+ */
+ cpu_self = _Thread_Dispatch_disable();
+ SuspendSelf();
+ cpu_self->dispatch_necessary = false;
+ _Thread_Dispatch_enable( cpu_self );
+ }
+ }
+
+ if ( ctx->dispatch_disabled ) {
+ _Thread_Dispatch_disable();
+ }
+
+ VerifyTaskPreparation( ctx );
+ ClearExtensionCalls( &ctx->calls );
+
+ log = T_scheduler_record_10( &ctx->scheduler_log );
+ T_null( log );
+
+ if ( setjmp( ctx->thread_dispatch_context ) == 0 ) {
+ ctx->status = rtems_task_delete( ctx->id );
+ } else {
+ _Thread_Dispatch_unnest( _Per_CPU_Get() );
+ }
+
+ CaptureWorkerState( ctx );
+
+ if ( ctx->dispatch_disabled ) {
+ _Thread_Dispatch_enable( _Per_CPU_Get() );
+ }
+}
+
+static void Block( Context *ctx )
+{
+ rtems_interval ticks;
+
+ if ( ctx->timer_active ) {
+ ticks = UINT32_MAX;
+ } else {
+ ticks = RTEMS_NO_TIMEOUT;
+ }
+
+ if ( ctx->enqueued ) {
+ ObtainMutexTimed( ctx->mutex_id, ticks );
+ ctx->worker_is_mutex_owner = true;
+ } else {
+ /*
+ * Do not use a stack variable for the event set, since we may jump out
+ * of the directive call.
+ */
+ (void) rtems_event_receive(
+ RTEMS_ALL_EVENTS,
+ RTEMS_EVENT_ANY | RTEMS_WAIT,
+ ticks,
+ &ctx->events
+ );
+ }
+}
+
+static void BlockDone( Context *ctx )
+{
+ if ( ctx->enqueued ) {
+ ReleaseMutex( ctx->mutex_id );
+ }
+}
+
+static void Signal( rtems_signal_set signals )
+{
+ Context *ctx;
+
+ (void) signals;
+ ctx = T_fixture_context();
+
+ if ( ctx->id == RTEMS_SELF ) {
+ SetPriority( ctx->runner_id, PRIO_LOW );
+
+ if ( ctx->interrupt ) {
+ if ( ctx->blocked ) {
+ Per_CPU_Control *cpu_self;
+
+ SetFatalHandler( ResumeThreadDispatch, ctx );
+ cpu_self = _Thread_Dispatch_disable();
+
+ if ( setjmp( ctx->thread_dispatch_context ) == 0 ) {
+ Block( ctx );
+ } else {
+ _Thread_Dispatch_unnest( cpu_self );
+ }
+
+ CallWithinISR( Delete, ctx );
+
+ _Thread_Dispatch_direct( cpu_self );
+ BlockDone( ctx );
+ } else {
+ CallWithinISR( Delete, ctx );
+ }
+ } else {
+ Delete( ctx );
+ }
+ } else {
+ if ( ctx->blocked ) {
+ Block( ctx );
+ BlockDone( ctx );
+ } else {
+ SetPriority( ctx->runner_id, PRIO_HIGH );
+ }
+ }
+
+ if ( ctx->protected ) {
+ _Thread_Set_life_protection( 0 );
+ }
+}
+
+static void Deleter( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ if ( ctx != NULL ) {
+ /* We have to prevent the priority boost in the task delete below */
+ SetPriority( ctx->runner_id, PRIO_LOW );
+ SetSelfPriorityNoYield( PRIO_NORMAL );
+
+ DeleteTask( ctx->worker_id );
+ }
+
+ SuspendSelf();
+}
+
+static void SecondDeleter( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ if ( ctx != NULL ) {
+ if ( !ctx->vital_deleter_priority ) {
+ SetPriority( ctx->runner_id, PRIO_LOW );
+ SetSelfPriorityNoYield( PRIO_NORMAL );
+ }
+
+ Delete( ctx );
+ }
+
+ SuspendSelf();
+}
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+
+ if ( arg != 0 ) {
+ rtems_status_code sc;
+
+ sc = rtems_signal_catch( Signal, RTEMS_NO_ASR );
+ T_rsc_success( sc );
+
+ if ( ctx->protected ) {
+ _Thread_Set_life_protection( THREAD_LIFE_PROTECTED );
+ }
+
+ Yield();
+ }
+
+ if ( IsMutexOwner( ctx->mutex_id ) ) {
+ ReleaseMutex( ctx->mutex_id );
+ }
+
+ rtems_task_exit();
+}
+
+static void ThreadDelete( rtems_tcb *executing, rtems_tcb *deleted )
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+ ++ctx->calls.thread_delete;
+
+ T_eq_u32( executing->Object.id, ctx->runner_id );
+
+ if ( ctx->delete_worker_expected ) {
+ T_eq_u32( deleted->Object.id, ctx->worker_id );
+ }
+}
+
+static void ThreadRestart( rtems_tcb *executing, rtems_tcb *restarted )
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+ ++ctx->calls.thread_restart;
+}
+
+static void ThreadTerminate( rtems_tcb *executing )
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+ ++ctx->calls.thread_terminate;
+
+ T_eq_u32( executing->Object.id, ctx->worker_id );
+
+ if ( IsMutexOwner( ctx->mutex_id ) ) {
+ ReleaseMutex( ctx->mutex_id );
+ }
+}
+
+static void Cleanup( Context *ctx )
+{
+ SetSelfPriority( PRIO_VERY_LOW );
+
+ if ( ( ctx->id == RTEMS_SELF || ctx->interrupt ) && ctx->suspended ) {
+ ResumeTask( ctx->worker_id );
+ }
+
+ if ( ctx->protected && ctx->blocked ) {
+ if ( ctx->enqueued ) {
+ ReleaseMutex( ctx->mutex_id );
+ ObtainMutex( ctx->mutex_id );
+ } else {
+ SendEvents( ctx->worker_id, RTEMS_EVENT_0 );
+ }
+ }
+
+ if (
+ ctx->id == INVALID_ID ||
+ ( ctx->calls.thread_terminate == 0 &&
+ !( ctx->dormant && ctx->status != RTEMS_CALLED_FROM_ISR ) )
+ ) {
+ DeleteTask( ctx->worker_id );
+ }
+
+ SetSelfPriority( PRIO_NORMAL );
+}
+
+static const rtems_extensions_table extensions = {
+ .thread_delete = ThreadDelete,
+ .thread_restart = ThreadRestart,
+ .thread_terminate = ThreadTerminate
+};
+
+static void RtemsTaskReqDelete_Pre_Id_Prepare(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Pre_Id_Executing: {
+ /*
+ * While the ``id`` parameter is associated with the calling task.
+ */
+ ctx->id = RTEMS_SELF;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_Id_Other: {
+ /*
+ * While the ``id`` parameter is associated with a task other than the
+ * calling task.
+ */
+ ctx->id = ctx->worker_id;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Pre_Context_Prepare(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Pre_Context state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Pre_Context_Task: {
+ /*
+ * While the rtems_task_delete() directive is called from within task
+ * context.
+ */
+ ctx->interrupt = false;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_Context_Interrupt: {
+ /*
+ * While the rtems_task_delete() directive is called from within
+ * interrupt context.
+ */
+ ctx->interrupt = true;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_Context_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Pre_ThreadDispatch_Prepare(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Pre_ThreadDispatch state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Pre_ThreadDispatch_Disabled: {
+ /*
+ * While thread dispatching is disabled for the calling task.
+ */
+ ctx->dispatch_disabled = true;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_ThreadDispatch_Enabled: {
+ /*
+ * While thread dispatching is enabled for the calling task.
+ */
+ ctx->dispatch_disabled = false;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_ThreadDispatch_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Pre_CallerPriority_Prepare(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Pre_CallerPriority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Pre_CallerPriority_Vital: {
+ /*
+ * While at least one priority of the calling task is higher than the
+ * highest priority of the task specified by the ``id`` parameter.
+ */
+ ctx->vital_deleter_priority = true;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_CallerPriority_Dispensable: {
+ /*
+ * While all priorities of the calling task are lower than or equal to
+ * the highest priority of the task specified by the ``id`` parameter.
+ */
+ ctx->vital_deleter_priority = false;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_CallerPriority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Pre_Dormant_Prepare(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Pre_Dormant state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Pre_Dormant_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not dormant.
+ */
+ ctx->dormant = false;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_Dormant_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is dormant.
+ */
+ ctx->dormant = true;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_Dormant_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Pre_Suspended_Prepare(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Pre_Suspended state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Pre_Suspended_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is suspended.
+ */
+ ctx->suspended = true;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_Suspended_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not suspended.
+ */
+ ctx->suspended = false;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_Suspended_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Pre_Restarting_Prepare(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Pre_Restarting state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Pre_Restarting_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not restarting.
+ */
+ ctx->restarting = false;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_Restarting_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is restarting.
+ */
+ ctx->restarting = true;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_Restarting_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Pre_Terminating_Prepare(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Pre_Terminating state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Pre_Terminating_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not terminating.
+ */
+ ctx->terminating = false;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_Terminating_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is terminating.
+ */
+ ctx->terminating = true;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_Terminating_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Pre_Protected_Prepare(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Pre_Protected state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Pre_Protected_Yes: {
+ /*
+ * While thread life of the task specified by the ``id`` parameter is
+ * protected.
+ */
+ ctx->protected = true;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_Protected_No: {
+ /*
+ * While thread life of the task specified by the ``id`` parameter is not
+ * protected.
+ */
+ ctx->protected = false;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_Protected_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Pre_State_Prepare(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Pre_State state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Pre_State_Enqueued: {
+ /*
+ * While the task specified by the ``id`` parameter is enqueued on a wait
+ * queue.
+ */
+ ctx->blocked = true;
+ ctx->enqueued = true;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_State_Ready: {
+ /*
+ * While the task specified by the ``id`` parameter is a ready task or a
+ * scheduled task.
+ */
+ ctx->blocked = false;
+ ctx->enqueued = false;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_State_Blocked: {
+ /*
+ * While the task specified by the ``id`` parameter is blocked.
+ */
+ ctx->blocked = true;
+ ctx->enqueued = false;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_State_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Pre_Timer_Prepare(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Pre_Timer state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Pre_Timer_Inactive: {
+ /*
+ * While timer of the task specified by the ``id`` parameter is inactive.
+ */
+ ctx->timer_active = false;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_Timer_Active: {
+ /*
+ * While timer of the task specified by the ``id`` parameter is active.
+ */
+ ctx->timer_active = true;
+ break;
+ }
+
+ case RtemsTaskReqDelete_Pre_Timer_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Post_Status_Check(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_delete() shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_delete() shall be RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Status_CalledFromISR: {
+ /*
+ * The return status of rtems_task_delete() shall be
+ * RTEMS_CALLED_FROM_ISR.
+ */
+ T_rsc( ctx->status, RTEMS_CALLED_FROM_ISR );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Status_NoReturn: {
+ /*
+ * The rtems_task_delete() call shall not return.
+ */
+ T_rsc( ctx->status, RTEMS_NOT_IMPLEMENTED );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Post_FatalError_Check(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Post_FatalError state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Post_FatalError_Yes: {
+ /*
+ * The fatal error with a fatal source of INTERNAL_ERROR_CORE and a fatal
+ * code of INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL shall occur
+ * through the rtems_task_delete() call.
+ */
+ T_eq_u32( ctx->calls.fatal, 1 );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_FatalError_Nop: {
+ /*
+ * No fatal error shall occur through the rtems_task_delete() call.
+ */
+ T_eq_u32( ctx->calls.fatal, 0 );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_FatalError_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Post_Zombie_Check(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Post_Zombie state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Post_Zombie_Yes: {
+ /*
+ * The task specified by the ``id`` parameter shall be in the zombie
+ * state after the rtems_task_delete() call.
+ */
+ T_eq_u32( ctx->worker_state & STATES_ZOMBIE, STATES_ZOMBIE )
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Zombie_No: {
+ /*
+ * The task specified by the ``id`` parameter shall not be in the zombie
+ * state after the rtems_task_delete() call.
+ */
+ T_eq_u32( ctx->worker_state & STATES_ZOMBIE, 0 )
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Zombie_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Post_TaskPriority_Check(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Post_TaskPriority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Post_TaskPriority_Raise: {
+ /*
+ * Each priority of the calling task which is higher than the highest
+ * priority of the task specified by the ``id`` parameter shall be made
+ * the highest priority of the task.
+ */
+ T_eq_u32( ctx->worker_priority, PRIO_ULTRA_HIGH );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_TaskPriority_Nop: {
+ /*
+ * The priorities of the task specified by the ``id`` parameter shall not
+ * be changed by the rtems_task_delete() call.
+ */
+ T_eq_u32( ctx->worker_priority, PRIO_NORMAL );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_TaskPriority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Post_RestartExtensions_Check(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Post_RestartExtensions state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Post_RestartExtensions_Nop: {
+ /*
+ * The thread delete user extensions shall not be invoked by the
+ * rtems_task_delete() call.
+ */
+ T_eq_u32( ctx->calls_after_restart.thread_restart, 0 );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_RestartExtensions_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Post_TerminateExtensions_Check(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Post_TerminateExtensions state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Post_TerminateExtensions_Yes: {
+ /*
+ * The thread terminate user extensions shall be invoked by the
+ * rtems_task_delete() call.
+ */
+ T_eq_u32( ctx->calls_after_restart.thread_terminate, 1 );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_TerminateExtensions_Nop: {
+ /*
+ * The thread terminate user extensions shall not be invoked by the
+ * rtems_task_delete() call.
+ */
+ T_eq_u32( ctx->calls_after_restart.thread_terminate, 0 );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_TerminateExtensions_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Post_Dormant_Check(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Post_Dormant state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Post_Dormant_Yes: {
+ /*
+ * The task specified by the ``id`` parameter shall be dormant after the
+ * rtems_task_delete() call.
+ */
+ T_eq_u32( ctx->worker_state & STATES_DORMANT, STATES_DORMANT )
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Dormant_No: {
+ /*
+ * The task specified by the ``id`` parameter shall not be dormant after
+ * the rtems_task_delete() call.
+ */
+ T_eq_u32( ctx->worker_state & STATES_DORMANT, 0 )
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Dormant_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Post_Suspended_Check(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Post_Suspended state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Post_Suspended_Yes: {
+ /*
+ * The task specified by the ``id`` parameter shall be suspended after
+ * the rtems_task_delete() call.
+ */
+ T_eq_u32( ctx->worker_state & STATES_SUSPENDED, STATES_SUSPENDED )
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Suspended_No: {
+ /*
+ * The task specified by the ``id`` parameter shall not be suspended
+ * after the rtems_task_delete() call.
+ */
+ T_eq_u32( ctx->worker_state & STATES_SUSPENDED, 0 )
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Suspended_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Post_Restarting_Check(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Post_Restarting state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Post_Restarting_Yes: {
+ /*
+ * The task specified by the ``id`` parameter shall be restarting after
+ * the rtems_task_delete() call.
+ */
+ T_ne_int( ctx->worker_life_state & THREAD_LIFE_RESTARTING, 0 );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Restarting_No: {
+ /*
+ * The task specified by the ``id`` parameter shall not be restarting
+ * after the rtems_task_delete() call.
+ */
+ T_eq_int( ctx->worker_life_state & THREAD_LIFE_RESTARTING, 0 );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Restarting_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Post_Terminating_Check(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Post_Terminating state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Post_Terminating_Yes: {
+ /*
+ * The task specified by the ``id`` parameter shall be terminating after
+ * the rtems_task_delete() call.
+ */
+ T_ne_int( ctx->worker_life_state & THREAD_LIFE_TERMINATING, 0 );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Terminating_No: {
+ /*
+ * The task specified by the ``id`` parameter shall not be terminating
+ * after the rtems_task_delete() call.
+ */
+ T_eq_int( ctx->worker_life_state & THREAD_LIFE_TERMINATING, 0 );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Terminating_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Post_Protected_Check(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Post_Protected state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Post_Protected_Yes: {
+ /*
+ * The thread life of the task specified by the ``id`` parameter be
+ * protected after the rtems_task_delete() call.
+ */
+ T_ne_int( ctx->worker_life_state & THREAD_LIFE_PROTECTED, 0 );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Protected_No: {
+ /*
+ * The thread life of the task specified by the ``id`` parameter shall
+ * not be protected after the rtems_task_delete() call.
+ */
+ T_eq_int( ctx->worker_life_state & THREAD_LIFE_PROTECTED, 0 );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Protected_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Post_State_Check(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Post_State state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Post_State_Enqueued: {
+ /*
+ * The task specified by the ``id`` parameter shall be enqueued on a wait
+ * queue and blocked.
+ */
+ T_ne_u32( ctx->worker_state & STATES_BLOCKED, 0 )
+ T_not_null( ctx->worker_wait_queue );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_State_Ready: {
+ /*
+ * The task specified by the ``id`` parameter shall not be enqueued on a
+ * wait queue and not blocked.
+ */
+ T_eq_u32( ctx->worker_state & STATES_BLOCKED, 0 )
+ T_null( ctx->worker_wait_queue );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_State_Blocked: {
+ /*
+ * The task specified by the ``id`` parameter shall be not enqueued on a
+ * wait queue and blocked.
+ */
+ T_ne_u32( ctx->worker_state & STATES_BLOCKED, 0 )
+ T_null( ctx->worker_wait_queue );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_State_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Post_Timer_Check(
+ RtemsTaskReqDelete_Context *ctx,
+ RtemsTaskReqDelete_Post_Timer state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqDelete_Post_Timer_Active: {
+ /*
+ * The timer of the task specified by the ``id`` parameter shall be
+ * active after the rtems_task_delete() call.
+ */
+ T_eq_int( ctx->worker_timer_info.state, TASK_TIMER_TICKS );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Timer_Inactive: {
+ /*
+ * The timer of the task specified by the ``id`` parameter shall be
+ * inactive after the rtems_task_delete() call.
+ */
+ T_eq_int( ctx->worker_timer_info.state, TASK_TIMER_INACTIVE );
+ break;
+ }
+
+ case RtemsTaskReqDelete_Post_Timer_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqDelete_Setup( RtemsTaskReqDelete_Context *ctx )
+{
+ rtems_status_code sc;
+
+ ctx->runner_id = rtems_task_self();
+ ctx->runner_tcb = GetThread( ctx->runner_id );
+ ctx->scheduler_id = GetSelfScheduler();
+ ctx->mutex_id = CreateMutexNoProtocol();
+ ObtainMutex( ctx->mutex_id );
+
+ sc = rtems_extension_create(
+ rtems_build_name( 'T', 'E', 'S', 'T' ),
+ &extensions,
+ &ctx->extension_id
+ );
+ T_rsc_success( sc );
+
+ SetFatalHandler( Fatal, ctx );
+ SetTaskSwitchExtension( TaskSwitch );
+ SetSelfPriority( PRIO_NORMAL );
+
+ ctx->deleter_id = CreateTask( "DELE", PRIO_HIGH );
+ ctx->deleter_tcb = GetThread( ctx->deleter_id );
+ StartTask( ctx->deleter_id, Deleter, NULL );
+
+ ctx->deleter_2_id = CreateTask( "DEL2", PRIO_ULTRA_HIGH );
+ ctx->deleter_2_tcb = GetThread( ctx->deleter_2_id );
+ StartTask( ctx->deleter_2_id, SecondDeleter, NULL );
+}
+
+static void RtemsTaskReqDelete_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqDelete_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqDelete_Setup( ctx );
+}
+
+static void RtemsTaskReqDelete_Teardown( RtemsTaskReqDelete_Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_extension_delete( ctx->extension_id );
+ T_rsc_success( sc );
+
+ SetFatalHandler( NULL, NULL );
+ SetTaskSwitchExtension( NULL );
+ DeleteTask( ctx->deleter_id );
+ DeleteTask( ctx->deleter_2_id );
+ ReleaseMutex( ctx->mutex_id );
+ DeleteMutex( ctx->mutex_id );
+ RestoreRunnerASR();
+ RestoreRunnerPriority();
+}
+
+static void RtemsTaskReqDelete_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqDelete_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqDelete_Teardown( ctx );
+}
+
+static void RtemsTaskReqDelete_Prepare( RtemsTaskReqDelete_Context *ctx )
+{
+ ctx->status = RTEMS_NOT_IMPLEMENTED;
+ ctx->restart_counter = 0;
+
+ ctx->delete_worker_expected = false;
+ ctx->worker_id = CreateTask( "WORK", PRIO_NORMAL );
+ ctx->delete_worker_expected = true;
+
+ ctx->worker_tcb = GetThread( ctx->worker_id );
+ ctx->worker_state = UINT32_MAX;
+ ctx->worker_life_state = INT_MAX;
+ ctx->worker_priority = UINT32_MAX;
+}
+
+static void RtemsTaskReqDelete_Action( RtemsTaskReqDelete_Context *ctx )
+{
+ rtems_status_code sc;
+
+ if ( ctx->id != INVALID_ID && !ctx->dormant ) {
+ ctx->worker_is_mutex_owner = false;
+ StartTask( ctx->worker_id, Worker, ctx );
+
+ /* Let the worker catch signals and set the thread life protection state */
+ Yield();
+
+ sc = rtems_signal_send( ctx->worker_id, RTEMS_SIGNAL_0 );
+ T_rsc_success( sc );
+
+ if ( ctx->restarting ) {
+ sc = rtems_task_restart( ctx->worker_id, 0 );
+ T_rsc_success( sc );
+ }
+
+ if ( ctx->terminating ) {
+ sc = rtems_task_restart( ctx->deleter_id, (rtems_task_argument) ctx );
+ T_rsc_success( sc );
+ } else {
+ Yield();
+ }
+ }
+
+ if ( ctx->id != RTEMS_SELF ) {
+ if ( ctx->interrupt ) {
+ CallWithinISR( Delete, ctx );
+ } else {
+ sc = rtems_task_restart( ctx->deleter_2_id, (rtems_task_argument) ctx );
+ T_rsc_success( sc );
+ }
+ }
+
+ Cleanup( ctx );
+}
+
+static const RtemsTaskReqDelete_Entry
+RtemsTaskReqDelete_Entries[] = {
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_NA,
+ RtemsTaskReqDelete_Post_FatalError_NA, RtemsTaskReqDelete_Post_Zombie_NA,
+ RtemsTaskReqDelete_Post_TaskPriority_NA,
+ RtemsTaskReqDelete_Post_RestartExtensions_NA,
+ RtemsTaskReqDelete_Post_TerminateExtensions_NA,
+ RtemsTaskReqDelete_Post_Dormant_NA, RtemsTaskReqDelete_Post_Suspended_NA,
+ RtemsTaskReqDelete_Post_Restarting_NA,
+ RtemsTaskReqDelete_Post_Terminating_NA,
+ RtemsTaskReqDelete_Post_Protected_NA, RtemsTaskReqDelete_Post_State_NA,
+ RtemsTaskReqDelete_Post_Timer_NA },
+ { 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, RtemsTaskReqDelete_Post_Status_InvId,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_NA,
+ RtemsTaskReqDelete_Post_TaskPriority_NA,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_NA, RtemsTaskReqDelete_Post_Suspended_NA,
+ RtemsTaskReqDelete_Post_Restarting_NA,
+ RtemsTaskReqDelete_Post_Terminating_NA,
+ RtemsTaskReqDelete_Post_Protected_NA, RtemsTaskReqDelete_Post_State_NA,
+ RtemsTaskReqDelete_Post_Timer_NA },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_NA,
+ RtemsTaskReqDelete_Post_FatalError_NA, RtemsTaskReqDelete_Post_Zombie_NA,
+ RtemsTaskReqDelete_Post_TaskPriority_NA,
+ RtemsTaskReqDelete_Post_RestartExtensions_NA,
+ RtemsTaskReqDelete_Post_TerminateExtensions_NA,
+ RtemsTaskReqDelete_Post_Dormant_NA, RtemsTaskReqDelete_Post_Suspended_NA,
+ RtemsTaskReqDelete_Post_Restarting_NA,
+ RtemsTaskReqDelete_Post_Terminating_NA,
+ RtemsTaskReqDelete_Post_Protected_NA, RtemsTaskReqDelete_Post_State_NA,
+ RtemsTaskReqDelete_Post_Timer_NA },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_NA,
+ RtemsTaskReqDelete_Post_FatalError_NA, RtemsTaskReqDelete_Post_Zombie_NA,
+ RtemsTaskReqDelete_Post_TaskPriority_NA,
+ RtemsTaskReqDelete_Post_RestartExtensions_NA,
+ RtemsTaskReqDelete_Post_TerminateExtensions_NA,
+ RtemsTaskReqDelete_Post_Dormant_NA, RtemsTaskReqDelete_Post_Suspended_NA,
+ RtemsTaskReqDelete_Post_Restarting_NA,
+ RtemsTaskReqDelete_Post_Terminating_NA,
+ RtemsTaskReqDelete_Post_Protected_NA, RtemsTaskReqDelete_Post_State_NA,
+ RtemsTaskReqDelete_Post_Timer_NA },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_NA,
+ RtemsTaskReqDelete_Post_FatalError_NA, RtemsTaskReqDelete_Post_Zombie_NA,
+ RtemsTaskReqDelete_Post_TaskPriority_NA,
+ RtemsTaskReqDelete_Post_RestartExtensions_NA,
+ RtemsTaskReqDelete_Post_TerminateExtensions_NA,
+ RtemsTaskReqDelete_Post_Dormant_NA, RtemsTaskReqDelete_Post_Suspended_NA,
+ RtemsTaskReqDelete_Post_Restarting_NA,
+ RtemsTaskReqDelete_Post_Terminating_NA,
+ RtemsTaskReqDelete_Post_Protected_NA, RtemsTaskReqDelete_Post_State_NA,
+ RtemsTaskReqDelete_Post_Timer_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_Yes,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_Yes, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_Yes,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_Yes, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_Yes, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_Yes, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_Yes,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Yes,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_Yes,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Yes,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_NoReturn,
+ RtemsTaskReqDelete_Post_FatalError_Yes, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Raise,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqDelete_Post_Status_Ok,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_Yes,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_No,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_No,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_Yes,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Enqueued,
+ RtemsTaskReqDelete_Post_Timer_Active },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No, RtemsTaskReqDelete_Post_State_Ready,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked,
+ RtemsTaskReqDelete_Post_Timer_Inactive },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqDelete_Post_Status_CalledFromISR,
+ RtemsTaskReqDelete_Post_FatalError_Nop, RtemsTaskReqDelete_Post_Zombie_No,
+ RtemsTaskReqDelete_Post_TaskPriority_Nop,
+ RtemsTaskReqDelete_Post_RestartExtensions_Nop,
+ RtemsTaskReqDelete_Post_TerminateExtensions_Nop,
+ RtemsTaskReqDelete_Post_Dormant_No, RtemsTaskReqDelete_Post_Suspended_No,
+ RtemsTaskReqDelete_Post_Restarting_Yes,
+ RtemsTaskReqDelete_Post_Terminating_Yes,
+ RtemsTaskReqDelete_Post_Protected_No,
+ RtemsTaskReqDelete_Post_State_Blocked, RtemsTaskReqDelete_Post_Timer_Active }
+};
+
+static const uint8_t
+RtemsTaskReqDelete_Map[] = {
+ 3, 3, 19, 4, 3, 3, 3, 3, 20, 4, 3, 3, 3, 3, 19, 4, 3, 3, 3, 3, 20, 4, 3, 3,
+ 3, 3, 21, 4, 3, 3, 3, 3, 22, 4, 3, 3, 3, 3, 21, 4, 3, 3, 3, 3, 22, 4, 3, 3,
+ 3, 3, 23, 4, 3, 3, 3, 3, 24, 4, 3, 3, 3, 3, 23, 4, 3, 3, 3, 3, 24, 4, 3, 3,
+ 3, 3, 25, 4, 3, 3, 3, 3, 26, 4, 3, 3, 3, 3, 25, 4, 3, 3, 3, 3, 26, 4, 3, 3,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 19, 4, 3, 3, 3,
+ 3, 20, 4, 3, 3, 3, 3, 19, 4, 3, 3, 3, 3, 20, 4, 3, 3, 3, 3, 21, 4, 3, 3, 3,
+ 3, 22, 4, 3, 3, 3, 3, 21, 4, 3, 3, 3, 3, 22, 4, 3, 3, 3, 3, 23, 4, 3, 3, 3,
+ 3, 24, 4, 3, 3, 3, 3, 23, 4, 3, 3, 3, 3, 24, 4, 3, 3, 3, 3, 25, 4, 3, 3, 3,
+ 3, 26, 4, 3, 3, 3, 3, 25, 4, 3, 3, 3, 3, 26, 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 27, 4, 3, 3, 3, 3, 28, 4, 3, 3, 3, 3, 27,
+ 4, 3, 3, 3, 3, 28, 4, 3, 3, 3, 3, 29, 4, 3, 3, 3, 3, 30, 4, 3, 3, 3, 3, 29,
+ 4, 3, 3, 3, 3, 30, 4, 3, 3, 3, 3, 17, 4, 3, 3, 3, 3, 17, 4, 3, 3, 3, 3, 17,
+ 4, 3, 3, 3, 3, 17, 4, 3, 3, 3, 3, 18, 4, 3, 3, 3, 3, 18, 4, 3, 3, 3, 3, 18,
+ 4, 3, 3, 3, 3, 18, 4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 3, 3, 27, 4, 3, 3, 3, 3, 28, 4, 3, 3, 3, 3, 27, 4, 3, 3, 3, 3, 28, 4,
+ 3, 3, 3, 3, 29, 4, 3, 3, 3, 3, 30, 4, 3, 3, 3, 3, 29, 4, 3, 3, 3, 3, 30, 4,
+ 3, 3, 3, 3, 17, 4, 3, 3, 3, 3, 17, 4, 3, 3, 3, 3, 17, 4, 3, 3, 3, 3, 17, 4,
+ 3, 3, 3, 3, 18, 4, 3, 3, 3, 3, 18, 4, 3, 3, 3, 3, 18, 4, 3, 3, 3, 3, 18, 4,
+ 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 71, 72, 73, 4,
+ 74, 75, 76, 77, 78, 4, 79, 80, 81, 82, 83, 4, 84, 85, 86, 87, 88, 4, 89, 90,
+ 91, 92, 93, 4, 94, 95, 96, 97, 98, 4, 99, 100, 101, 102, 103, 4, 104, 105,
+ 106, 107, 108, 4, 109, 110, 111, 112, 113, 4, 114, 115, 116, 117, 118, 4,
+ 119, 120, 121, 122, 123, 4, 124, 125, 126, 127, 128, 4, 129, 130, 131, 132,
+ 133, 4, 134, 135, 136, 137, 138, 4, 139, 140, 141, 142, 143, 4, 144, 145,
+ 146, 147, 148, 4, 149, 150, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 71, 72, 73, 4, 74, 75, 76, 77, 78, 4, 79, 80, 81, 82, 83, 4, 84, 85,
+ 86, 87, 88, 4, 89, 90, 91, 92, 93, 4, 94, 95, 96, 97, 98, 4, 99, 100, 101,
+ 102, 103, 4, 104, 105, 106, 107, 108, 4, 109, 110, 111, 112, 113, 4, 114,
+ 115, 116, 117, 118, 4, 119, 120, 121, 122, 123, 4, 124, 125, 126, 127, 128,
+ 4, 129, 130, 131, 132, 133, 4, 134, 135, 136, 137, 138, 4, 139, 140, 141,
+ 142, 143, 4, 144, 145, 146, 147, 148, 4, 149, 150, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 31, 32, 33, 4, 34, 35, 9, 9, 9, 4, 9, 9, 31, 32, 33, 4, 34, 35, 9,
+ 9, 9, 4, 9, 9, 36, 37, 38, 4, 39, 40, 10, 10, 10, 4, 10, 10, 36, 37, 38, 4,
+ 39, 40, 10, 10, 10, 4, 10, 10, 31, 32, 33, 4, 34, 35, 9, 9, 9, 4, 9, 9, 31,
+ 32, 33, 4, 34, 35, 9, 9, 9, 4, 9, 9, 36, 37, 38, 4, 39, 40, 10, 10, 10, 4,
+ 10, 10, 36, 37, 38, 4, 39, 40, 10, 10, 10, 4, 10, 10, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 41, 42, 43, 4, 44, 45, 11, 11, 11, 4, 11, 11,
+ 41, 42, 43, 4, 44, 45, 11, 11, 11, 4, 11, 11, 46, 47, 48, 4, 49, 50, 12, 12,
+ 12, 4, 12, 12, 46, 47, 48, 4, 49, 50, 12, 12, 12, 4, 12, 12, 41, 42, 43, 4,
+ 44, 45, 11, 11, 11, 4, 11, 11, 41, 42, 43, 4, 44, 45, 11, 11, 11, 4, 11, 11,
+ 46, 47, 48, 4, 49, 50, 12, 12, 12, 4, 12, 12, 46, 47, 48, 4, 49, 50, 12, 12,
+ 12, 4, 12, 12, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 51, 52,
+ 53, 4, 54, 55, 13, 13, 13, 4, 13, 13, 51, 52, 53, 4, 54, 55, 13, 13, 13, 4,
+ 13, 13, 56, 57, 58, 4, 59, 60, 14, 14, 14, 4, 14, 14, 56, 57, 58, 4, 59, 60,
+ 14, 14, 14, 4, 14, 14, 51, 52, 53, 4, 54, 55, 13, 13, 13, 4, 13, 13, 51, 52,
+ 53, 4, 54, 55, 13, 13, 13, 4, 13, 13, 56, 57, 58, 4, 59, 60, 14, 14, 14, 4,
+ 14, 14, 56, 57, 58, 4, 59, 60, 14, 14, 14, 4, 14, 14, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 61, 62, 63, 4, 64, 65, 15, 15, 15, 4, 15, 15,
+ 61, 62, 63, 4, 64, 65, 15, 15, 15, 4, 15, 15, 66, 67, 68, 4, 69, 70, 16, 16,
+ 16, 4, 16, 16, 66, 67, 68, 4, 69, 70, 16, 16, 16, 4, 16, 16, 61, 62, 63, 4,
+ 64, 65, 15, 15, 15, 4, 15, 15, 61, 62, 63, 4, 64, 65, 15, 15, 15, 4, 15, 15,
+ 66, 67, 68, 4, 69, 70, 16, 16, 16, 4, 16, 16, 66, 67, 68, 4, 69, 70, 16, 16,
+ 16, 4, 16, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 151,
+ 152, 153, 4, 154, 155, 156, 157, 158, 4, 159, 160, 161, 162, 163, 4, 164,
+ 165, 166, 167, 168, 4, 169, 170, 171, 172, 173, 4, 174, 175, 176, 177, 178,
+ 4, 179, 180, 181, 182, 183, 4, 184, 185, 186, 187, 188, 4, 189, 190, 191,
+ 192, 193, 4, 194, 195, 196, 197, 198, 4, 199, 200, 201, 202, 203, 4, 204,
+ 205, 206, 207, 208, 4, 209, 210, 211, 212, 213, 4, 214, 215, 216, 217, 218,
+ 4, 219, 220, 221, 222, 223, 4, 224, 225, 226, 227, 228, 4, 229, 230, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 151, 152, 153, 4, 154, 155, 156,
+ 157, 158, 4, 159, 160, 161, 162, 163, 4, 164, 165, 166, 167, 168, 4, 169,
+ 170, 171, 172, 173, 4, 174, 175, 176, 177, 178, 4, 179, 180, 181, 182, 183,
+ 4, 184, 185, 186, 187, 188, 4, 189, 190, 191, 192, 193, 4, 194, 195, 196,
+ 197, 198, 4, 199, 200, 201, 202, 203, 4, 204, 205, 206, 207, 208, 4, 209,
+ 210, 211, 212, 213, 4, 214, 215, 216, 217, 218, 4, 219, 220, 221, 222, 223,
+ 4, 224, 225, 226, 227, 228, 4, 229, 230, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0
+};
+
+static size_t RtemsTaskReqDelete_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqDelete_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsTaskReqDelete_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqDelete_Fixture = {
+ .setup = RtemsTaskReqDelete_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqDelete_Teardown_Wrap,
+ .scope = RtemsTaskReqDelete_Scope,
+ .initial_context = &RtemsTaskReqDelete_Instance
+};
+
+static inline RtemsTaskReqDelete_Entry RtemsTaskReqDelete_PopEntry(
+ RtemsTaskReqDelete_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqDelete_Entries[
+ RtemsTaskReqDelete_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqDelete_SetPreConditionStates(
+ RtemsTaskReqDelete_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+
+ if ( ctx->Map.entry.Pre_CallerPriority_NA ) {
+ ctx->Map.pcs[ 3 ] = RtemsTaskReqDelete_Pre_CallerPriority_NA;
+ } else {
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Dormant_NA ) {
+ ctx->Map.pcs[ 4 ] = RtemsTaskReqDelete_Pre_Dormant_NA;
+ } else {
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Suspended_NA ) {
+ ctx->Map.pcs[ 5 ] = RtemsTaskReqDelete_Pre_Suspended_NA;
+ } else {
+ ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Restarting_NA ) {
+ ctx->Map.pcs[ 6 ] = RtemsTaskReqDelete_Pre_Restarting_NA;
+ } else {
+ ctx->Map.pcs[ 6 ] = ctx->Map.pci[ 6 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Terminating_NA ) {
+ ctx->Map.pcs[ 7 ] = RtemsTaskReqDelete_Pre_Terminating_NA;
+ } else {
+ ctx->Map.pcs[ 7 ] = ctx->Map.pci[ 7 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Protected_NA ) {
+ ctx->Map.pcs[ 8 ] = RtemsTaskReqDelete_Pre_Protected_NA;
+ } else {
+ ctx->Map.pcs[ 8 ] = ctx->Map.pci[ 8 ];
+ }
+
+ if ( ctx->Map.entry.Pre_State_NA ) {
+ ctx->Map.pcs[ 9 ] = RtemsTaskReqDelete_Pre_State_NA;
+ } else {
+ ctx->Map.pcs[ 9 ] = ctx->Map.pci[ 9 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Timer_NA ) {
+ ctx->Map.pcs[ 10 ] = RtemsTaskReqDelete_Pre_Timer_NA;
+ } else {
+ ctx->Map.pcs[ 10 ] = ctx->Map.pci[ 10 ];
+ }
+}
+
+static void RtemsTaskReqDelete_TestVariant( RtemsTaskReqDelete_Context *ctx )
+{
+ RtemsTaskReqDelete_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqDelete_Pre_Context_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqDelete_Pre_ThreadDispatch_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTaskReqDelete_Pre_CallerPriority_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsTaskReqDelete_Pre_Dormant_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsTaskReqDelete_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsTaskReqDelete_Pre_Restarting_Prepare( ctx, ctx->Map.pcs[ 6 ] );
+ RtemsTaskReqDelete_Pre_Terminating_Prepare( ctx, ctx->Map.pcs[ 7 ] );
+ RtemsTaskReqDelete_Pre_Protected_Prepare( ctx, ctx->Map.pcs[ 8 ] );
+ RtemsTaskReqDelete_Pre_State_Prepare( ctx, ctx->Map.pcs[ 9 ] );
+ RtemsTaskReqDelete_Pre_Timer_Prepare( ctx, ctx->Map.pcs[ 10 ] );
+ RtemsTaskReqDelete_Action( ctx );
+ RtemsTaskReqDelete_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsTaskReqDelete_Post_FatalError_Check(
+ ctx,
+ ctx->Map.entry.Post_FatalError
+ );
+ RtemsTaskReqDelete_Post_Zombie_Check( ctx, ctx->Map.entry.Post_Zombie );
+ RtemsTaskReqDelete_Post_TaskPriority_Check(
+ ctx,
+ ctx->Map.entry.Post_TaskPriority
+ );
+ RtemsTaskReqDelete_Post_RestartExtensions_Check(
+ ctx,
+ ctx->Map.entry.Post_RestartExtensions
+ );
+ RtemsTaskReqDelete_Post_TerminateExtensions_Check(
+ ctx,
+ ctx->Map.entry.Post_TerminateExtensions
+ );
+ RtemsTaskReqDelete_Post_Dormant_Check( ctx, ctx->Map.entry.Post_Dormant );
+ RtemsTaskReqDelete_Post_Suspended_Check(
+ ctx,
+ ctx->Map.entry.Post_Suspended
+ );
+ RtemsTaskReqDelete_Post_Restarting_Check(
+ ctx,
+ ctx->Map.entry.Post_Restarting
+ );
+ RtemsTaskReqDelete_Post_Terminating_Check(
+ ctx,
+ ctx->Map.entry.Post_Terminating
+ );
+ RtemsTaskReqDelete_Post_Protected_Check(
+ ctx,
+ ctx->Map.entry.Post_Protected
+ );
+ RtemsTaskReqDelete_Post_State_Check( ctx, ctx->Map.entry.Post_State );
+ RtemsTaskReqDelete_Post_Timer_Check( ctx, ctx->Map.entry.Post_Timer );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqDelete( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTaskReqDelete, &RtemsTaskReqDelete_Fixture )
+{
+ RtemsTaskReqDelete_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsTaskReqDelete_Pre_Id_Executing;
+ ctx->Map.pci[ 0 ] < RtemsTaskReqDelete_Pre_Id_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsTaskReqDelete_Pre_Context_Task;
+ ctx->Map.pci[ 1 ] < RtemsTaskReqDelete_Pre_Context_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsTaskReqDelete_Pre_ThreadDispatch_Disabled;
+ ctx->Map.pci[ 2 ] < RtemsTaskReqDelete_Pre_ThreadDispatch_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = RtemsTaskReqDelete_Pre_CallerPriority_Vital;
+ ctx->Map.pci[ 3 ] < RtemsTaskReqDelete_Pre_CallerPriority_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ for (
+ ctx->Map.pci[ 4 ] = RtemsTaskReqDelete_Pre_Dormant_No;
+ ctx->Map.pci[ 4 ] < RtemsTaskReqDelete_Pre_Dormant_NA;
+ ++ctx->Map.pci[ 4 ]
+ ) {
+ for (
+ ctx->Map.pci[ 5 ] = RtemsTaskReqDelete_Pre_Suspended_Yes;
+ ctx->Map.pci[ 5 ] < RtemsTaskReqDelete_Pre_Suspended_NA;
+ ++ctx->Map.pci[ 5 ]
+ ) {
+ for (
+ ctx->Map.pci[ 6 ] = RtemsTaskReqDelete_Pre_Restarting_No;
+ ctx->Map.pci[ 6 ] < RtemsTaskReqDelete_Pre_Restarting_NA;
+ ++ctx->Map.pci[ 6 ]
+ ) {
+ for (
+ ctx->Map.pci[ 7 ] = RtemsTaskReqDelete_Pre_Terminating_No;
+ ctx->Map.pci[ 7 ] < RtemsTaskReqDelete_Pre_Terminating_NA;
+ ++ctx->Map.pci[ 7 ]
+ ) {
+ for (
+ ctx->Map.pci[ 8 ] = RtemsTaskReqDelete_Pre_Protected_Yes;
+ ctx->Map.pci[ 8 ] < RtemsTaskReqDelete_Pre_Protected_NA;
+ ++ctx->Map.pci[ 8 ]
+ ) {
+ for (
+ ctx->Map.pci[ 9 ] = RtemsTaskReqDelete_Pre_State_Enqueued;
+ ctx->Map.pci[ 9 ] < RtemsTaskReqDelete_Pre_State_NA;
+ ++ctx->Map.pci[ 9 ]
+ ) {
+ for (
+ ctx->Map.pci[ 10 ] = RtemsTaskReqDelete_Pre_Timer_Inactive;
+ ctx->Map.pci[ 10 ] < RtemsTaskReqDelete_Pre_Timer_NA;
+ ++ctx->Map.pci[ 10 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqDelete_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsTaskReqDelete_SetPreConditionStates( ctx );
+ RtemsTaskReqDelete_Prepare( ctx );
+ RtemsTaskReqDelete_TestVariant( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-exit.c b/testsuites/validation/tc-task-exit.c
new file mode 100644
index 0000000000..24373f6c47
--- /dev/null
+++ b/testsuites/validation/tc-task-exit.c
@@ -0,0 +1,989 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqExit
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/test-scheduler.h>
+#include <rtems/score/apimutex.h>
+#include <rtems/score/statesimpl.h>
+#include <rtems/score/threaddispatch.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqExit spec:/rtems/task/req/exit
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqExit_Pre_Restarting_Yes,
+ RtemsTaskReqExit_Pre_Restarting_No,
+ RtemsTaskReqExit_Pre_Restarting_NA
+} RtemsTaskReqExit_Pre_Restarting;
+
+typedef enum {
+ RtemsTaskReqExit_Pre_Terminating_Yes,
+ RtemsTaskReqExit_Pre_Terminating_No,
+ RtemsTaskReqExit_Pre_Terminating_NA
+} RtemsTaskReqExit_Pre_Terminating;
+
+typedef enum {
+ RtemsTaskReqExit_Pre_Protected_Yes,
+ RtemsTaskReqExit_Pre_Protected_No,
+ RtemsTaskReqExit_Pre_Protected_NA
+} RtemsTaskReqExit_Pre_Protected;
+
+typedef enum {
+ RtemsTaskReqExit_Pre_ThreadDispatch_Enabled,
+ RtemsTaskReqExit_Pre_ThreadDispatch_Disabled,
+ RtemsTaskReqExit_Pre_ThreadDispatch_NA
+} RtemsTaskReqExit_Pre_ThreadDispatch;
+
+typedef enum {
+ RtemsTaskReqExit_Post_FatalError_Yes,
+ RtemsTaskReqExit_Post_FatalError_Nop,
+ RtemsTaskReqExit_Post_FatalError_NA
+} RtemsTaskReqExit_Post_FatalError;
+
+typedef enum {
+ RtemsTaskReqExit_Post_DeleteExtensions_Nop,
+ RtemsTaskReqExit_Post_DeleteExtensions_NA
+} RtemsTaskReqExit_Post_DeleteExtensions;
+
+typedef enum {
+ RtemsTaskReqExit_Post_RestartExtensions_Nop,
+ RtemsTaskReqExit_Post_RestartExtensions_NA
+} RtemsTaskReqExit_Post_RestartExtensions;
+
+typedef enum {
+ RtemsTaskReqExit_Post_TerminateExtensions_Yes,
+ RtemsTaskReqExit_Post_TerminateExtensions_Nop,
+ RtemsTaskReqExit_Post_TerminateExtensions_NA
+} RtemsTaskReqExit_Post_TerminateExtensions;
+
+typedef enum {
+ RtemsTaskReqExit_Post_Zombie_Yes,
+ RtemsTaskReqExit_Post_Zombie_No,
+ RtemsTaskReqExit_Post_Zombie_NA
+} RtemsTaskReqExit_Post_Zombie;
+
+typedef enum {
+ RtemsTaskReqExit_Post_ID_Valid,
+ RtemsTaskReqExit_Post_ID_Invalid,
+ RtemsTaskReqExit_Post_ID_NA
+} RtemsTaskReqExit_Post_ID;
+
+typedef enum {
+ RtemsTaskReqExit_Post_Delete_NextAllocate,
+ RtemsTaskReqExit_Post_Delete_Nop,
+ RtemsTaskReqExit_Post_Delete_NA
+} RtemsTaskReqExit_Post_Delete;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_Restarting_NA : 1;
+ uint32_t Pre_Terminating_NA : 1;
+ uint32_t Pre_Protected_NA : 1;
+ uint32_t Pre_ThreadDispatch_NA : 1;
+ uint32_t Post_FatalError : 2;
+ uint32_t Post_DeleteExtensions : 1;
+ uint32_t Post_RestartExtensions : 1;
+ uint32_t Post_TerminateExtensions : 2;
+ uint32_t Post_Zombie : 2;
+ uint32_t Post_ID : 2;
+ uint32_t Post_Delete : 2;
+} RtemsTaskReqExit_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/exit test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides the scheduler operation records.
+ */
+ T_scheduler_log_4 scheduler_log;
+
+ /**
+ * @brief This member contains the identifier of the runner task.
+ */
+ rtems_id runner_id;
+
+ /**
+ * @brief This member contains the identifier of the worker task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member contains the identifier of the deleter task.
+ */
+ rtems_id deleter_id;
+
+ /**
+ * @brief This member contains the identifier of the test user extensions.
+ */
+ rtems_id extension_id;
+
+ /**
+ * @brief This member contains the count of fatal extension calls.
+ */
+ uint32_t fatal_extension_calls;
+
+ /**
+ * @brief This member contains the count of thread delete extension calls.
+ */
+ uint32_t delete_extension_calls;
+
+ /**
+ * @brief This member contains the count of thread restart extension calls.
+ */
+ uint32_t restart_extension_calls;
+
+ /**
+ * @brief This member contains the count of thread terminate extension calls.
+ */
+ uint32_t terminate_extension_calls;
+
+ /**
+ * @brief If this member is true, then the thread life of the worker is
+ * protected before the rtems_task_exit() call.
+ */
+ bool protected;
+
+ /**
+ * @brief If this member is true, then the worker locked the allocator.
+ */
+ bool allocator_locked;
+
+ /**
+ * @brief If this member is true, then the worker is restarting before the
+ * rtems_task_exit() call.
+ */
+ bool restarting;
+
+ /**
+ * @brief If this member is true, then the worker is terminating before the
+ * rtems_task_exit() call.
+ */
+ bool terminating;
+
+ /**
+ * @brief If this member is true, then thread dispatching is disabled by the
+ * worker task before the rtems_task_exit() call.
+ */
+ bool dispatch_disabled;
+
+ /**
+ * @brief If this member is true, then it is expected to delete the worker.
+ */
+ bool delete_worker_expected;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 4 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqExit_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqExit_Context;
+
+static RtemsTaskReqExit_Context
+ RtemsTaskReqExit_Instance;
+
+static const char * const RtemsTaskReqExit_PreDesc_Restarting[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqExit_PreDesc_Terminating[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqExit_PreDesc_Protected[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqExit_PreDesc_ThreadDispatch[] = {
+ "Enabled",
+ "Disabled",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqExit_PreDesc[] = {
+ RtemsTaskReqExit_PreDesc_Restarting,
+ RtemsTaskReqExit_PreDesc_Terminating,
+ RtemsTaskReqExit_PreDesc_Protected,
+ RtemsTaskReqExit_PreDesc_ThreadDispatch,
+ NULL
+};
+
+typedef RtemsTaskReqExit_Context Context;
+
+static void Signal( rtems_signal_set signals )
+{
+ Context *ctx;
+ T_scheduler_log *log;
+ Thread_Life_state life_state;
+
+ (void) signals;
+ ctx = T_fixture_context();
+
+ if ( ctx->dispatch_disabled ) {
+ _Thread_Dispatch_disable();
+ }
+
+ /* Check that the thread life state was prepared correctly */
+ life_state = GetExecuting()->Life.state;
+ T_eq( ctx->protected, ( life_state & THREAD_LIFE_PROTECTED ) != 0 );
+ T_eq( ctx->restarting, ( life_state & THREAD_LIFE_RESTARTING ) != 0 );
+ T_eq( ctx->terminating, ( life_state & THREAD_LIFE_TERMINATING ) != 0 );
+
+ log = T_scheduler_record_4( &ctx->scheduler_log );
+ T_null( log );
+
+ ctx->delete_extension_calls = 0;
+ ctx->fatal_extension_calls = 0;
+ ctx->restart_extension_calls = 0;
+ ctx->terminate_extension_calls = 0;
+
+ rtems_task_exit();
+}
+
+static void Deleter( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ if ( ctx != NULL ) {
+ DeleteTask( ctx->worker_id );
+ }
+
+ SuspendSelf();
+}
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+ rtems_status_code sc;
+
+ ctx = (Context *) arg;
+
+ sc = rtems_signal_catch( Signal, RTEMS_NO_ASR );
+ T_rsc_success( sc );
+
+ if ( ctx->protected ) {
+ _RTEMS_Lock_allocator();
+ ctx->allocator_locked = true;
+ }
+
+ Yield();
+}
+
+static void UnlockAllocator( Context *ctx )
+{
+ if ( ctx->allocator_locked ) {
+ ctx->allocator_locked = false;
+ _RTEMS_Unlock_allocator();
+ }
+}
+
+static void Fatal(
+ rtems_fatal_source source,
+ rtems_fatal_code code,
+ void *arg
+)
+{
+ Context *ctx;
+ T_scheduler_log *log;
+ Per_CPU_Control *cpu_self;
+
+ ctx = arg;
+ ++ctx->fatal_extension_calls;
+
+ T_eq_int( source, INTERNAL_ERROR_CORE );
+ T_eq_ulong( code, INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL );
+ T_assert_eq_int( ctx->fatal_extension_calls, 1 );
+
+ log = T_scheduler_record( NULL );
+ T_eq_ptr( &log->header, &ctx->scheduler_log.header );
+
+ UnlockAllocator( ctx );
+ SuspendSelf();
+
+ cpu_self = _Per_CPU_Get();
+ _Thread_Dispatch_unnest( cpu_self );
+ _Thread_Dispatch_direct_no_return( cpu_self );
+}
+
+static void ThreadDelete( rtems_tcb *executing, rtems_tcb *deleted )
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+ ++ctx->delete_extension_calls;
+
+ T_eq_u32( executing->Object.id, ctx->runner_id );
+
+ if ( ctx->delete_worker_expected ) {
+ T_eq_u32( deleted->Object.id, ctx->worker_id );
+ }
+}
+
+static void ThreadRestart( rtems_tcb *executing, rtems_tcb *restarted )
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+ ++ctx->restart_extension_calls;
+}
+
+static void ThreadTerminate( rtems_tcb *executing )
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+ ++ctx->terminate_extension_calls;
+
+ T_eq_u32( executing->Object.id, ctx->worker_id );
+
+ UnlockAllocator( ctx );
+}
+
+static const rtems_extensions_table extensions = {
+ .thread_delete = ThreadDelete,
+ .thread_restart = ThreadRestart,
+ .thread_terminate = ThreadTerminate
+};
+
+static void RtemsTaskReqExit_Pre_Restarting_Prepare(
+ RtemsTaskReqExit_Context *ctx,
+ RtemsTaskReqExit_Pre_Restarting state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqExit_Pre_Restarting_Yes: {
+ /*
+ * While the calling task is restarting.
+ */
+ ctx->restarting = true;
+ break;
+ }
+
+ case RtemsTaskReqExit_Pre_Restarting_No: {
+ /*
+ * While the calling task is not restarting.
+ */
+ ctx->restarting = false;
+ break;
+ }
+
+ case RtemsTaskReqExit_Pre_Restarting_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqExit_Pre_Terminating_Prepare(
+ RtemsTaskReqExit_Context *ctx,
+ RtemsTaskReqExit_Pre_Terminating state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqExit_Pre_Terminating_Yes: {
+ /*
+ * While the calling task is terminating.
+ */
+ ctx->terminating = true;
+ break;
+ }
+
+ case RtemsTaskReqExit_Pre_Terminating_No: {
+ /*
+ * While the calling task is not terminating.
+ */
+ ctx->terminating = false;
+ break;
+ }
+
+ case RtemsTaskReqExit_Pre_Terminating_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqExit_Pre_Protected_Prepare(
+ RtemsTaskReqExit_Context *ctx,
+ RtemsTaskReqExit_Pre_Protected state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqExit_Pre_Protected_Yes: {
+ /*
+ * While the thread life of the calling task is protected.
+ */
+ ctx->protected = true;
+ break;
+ }
+
+ case RtemsTaskReqExit_Pre_Protected_No: {
+ /*
+ * While the thread life of the calling task is not protected.
+ */
+ ctx->protected = false;
+ break;
+ }
+
+ case RtemsTaskReqExit_Pre_Protected_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqExit_Pre_ThreadDispatch_Prepare(
+ RtemsTaskReqExit_Context *ctx,
+ RtemsTaskReqExit_Pre_ThreadDispatch state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqExit_Pre_ThreadDispatch_Enabled: {
+ /*
+ * While thread dispatching is enabled for the calling task.
+ */
+ ctx->dispatch_disabled = false;
+ break;
+ }
+
+ case RtemsTaskReqExit_Pre_ThreadDispatch_Disabled: {
+ /*
+ * While thread dispatching is disabled for the calling task.
+ */
+ ctx->dispatch_disabled = true;
+ break;
+ }
+
+ case RtemsTaskReqExit_Pre_ThreadDispatch_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqExit_Post_FatalError_Check(
+ RtemsTaskReqExit_Context *ctx,
+ RtemsTaskReqExit_Post_FatalError state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqExit_Post_FatalError_Yes: {
+ /*
+ * The fatal error with a fatal source of INTERNAL_ERROR_CORE and a fatal
+ * code of INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL shall occur
+ * by the rtems_task_exit() call.
+ */
+ T_eq_u32( ctx->fatal_extension_calls, 1 );
+ break;
+ }
+
+ case RtemsTaskReqExit_Post_FatalError_Nop: {
+ /*
+ * No fatal error shall occur by the rtems_task_exit() call.
+ */
+ T_eq_u32( ctx->fatal_extension_calls, 0 );
+ break;
+ }
+
+ case RtemsTaskReqExit_Post_FatalError_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqExit_Post_DeleteExtensions_Check(
+ RtemsTaskReqExit_Context *ctx,
+ RtemsTaskReqExit_Post_DeleteExtensions state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqExit_Post_DeleteExtensions_Nop: {
+ /*
+ * The thread delete user extensions shall not be invoked by the
+ * rtems_task_exit() call.
+ */
+ T_eq_u32( ctx->delete_extension_calls, 0 );
+ break;
+ }
+
+ case RtemsTaskReqExit_Post_DeleteExtensions_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqExit_Post_RestartExtensions_Check(
+ RtemsTaskReqExit_Context *ctx,
+ RtemsTaskReqExit_Post_RestartExtensions state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqExit_Post_RestartExtensions_Nop: {
+ /*
+ * The thread restart user extensions shall not be invoked by the
+ * rtems_task_exit() call.
+ */
+ T_eq_u32( ctx->restart_extension_calls, 0 );
+ break;
+ }
+
+ case RtemsTaskReqExit_Post_RestartExtensions_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqExit_Post_TerminateExtensions_Check(
+ RtemsTaskReqExit_Context *ctx,
+ RtemsTaskReqExit_Post_TerminateExtensions state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqExit_Post_TerminateExtensions_Yes: {
+ /*
+ * The thread terminate user extensions shall be invoked by the
+ * rtems_task_exit() call.
+ */
+ if ( ctx->protected ) {
+ T_eq_u32( ctx->terminate_extension_calls, 2 );
+ } else {
+ T_eq_u32( ctx->terminate_extension_calls, 1 );
+ }
+ break;
+ }
+
+ case RtemsTaskReqExit_Post_TerminateExtensions_Nop: {
+ /*
+ * The thread terminate user extensions shall not be invoked by the
+ * rtems_task_exit() call.
+ */
+ T_eq_u32( ctx->terminate_extension_calls, 0 );
+ break;
+ }
+
+ case RtemsTaskReqExit_Post_TerminateExtensions_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqExit_Post_Zombie_Check(
+ RtemsTaskReqExit_Context *ctx,
+ RtemsTaskReqExit_Post_Zombie state
+)
+{
+ const T_scheduler_event *event;
+ size_t index;
+
+ index = 0;
+
+ switch ( state ) {
+ case RtemsTaskReqExit_Post_Zombie_Yes: {
+ /*
+ * The thread state of the calling task shall be set to the zombie state
+ * by the rtems_task_exit() call.
+ */
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_BLOCK );
+ T_eq_u32( event->thread->Object.id, ctx->worker_id );
+ T_eq_u32( event->thread->current_state, STATES_ZOMBIE );
+
+ if ( ctx->terminating ) {
+ /* The thread waiting for the worker exit was unblocked */
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_UNBLOCK );
+ T_eq_u32( event->thread->Object.id, ctx->deleter_id );
+
+ /* Inherited priority was removed */
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_UPDATE_PRIORITY );
+ T_eq_u32( event->thread->Object.id, ctx->worker_id );
+
+ /* The deleter task suspended itself */
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_BLOCK );
+ T_eq_u32( event->thread->Object.id, ctx->deleter_id );
+ }
+
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_NOP );
+ break;
+ }
+
+ case RtemsTaskReqExit_Post_Zombie_No: {
+ /*
+ * The thread state of the calling task shall be not modified by the
+ * rtems_task_exit() call.
+ */
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ break;
+ }
+
+ case RtemsTaskReqExit_Post_Zombie_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqExit_Post_ID_Check(
+ RtemsTaskReqExit_Context *ctx,
+ RtemsTaskReqExit_Post_ID state
+)
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ sc = rtems_task_get_scheduler( ctx->worker_id, &id );
+
+ switch ( state ) {
+ case RtemsTaskReqExit_Post_ID_Valid: {
+ /*
+ * The object identifier of the calling task shall be valid.
+ */
+ T_rsc_success( sc );
+ break;
+ }
+
+ case RtemsTaskReqExit_Post_ID_Invalid: {
+ /*
+ * The object identifier of the calling task shall be invalid.
+ */
+ T_rsc( sc, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqExit_Post_ID_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqExit_Post_Delete_Check(
+ RtemsTaskReqExit_Context *ctx,
+ RtemsTaskReqExit_Post_Delete state
+)
+{
+ rtems_id id;
+
+ id = CreateTask( "TEMP", PRIO_LOW );
+
+ switch ( state ) {
+ case RtemsTaskReqExit_Post_Delete_NextAllocate: {
+ /*
+ * The calling task shall be deleted by the next directive which
+ * allocates a task.
+ */
+ T_eq_u32( ctx->delete_extension_calls, 1 );
+ break;
+ }
+
+ case RtemsTaskReqExit_Post_Delete_Nop: {
+ /*
+ * The calling task shall not be deleted by the next directive which
+ * allocates a task.
+ */
+ T_eq_u32( ctx->delete_extension_calls, 0 );
+ break;
+ }
+
+ case RtemsTaskReqExit_Post_Delete_NA:
+ break;
+ }
+
+ DeleteTask( id );
+}
+
+static void RtemsTaskReqExit_Setup( RtemsTaskReqExit_Context *ctx )
+{
+ rtems_status_code sc;
+
+ ctx->runner_id = rtems_task_self();
+
+ sc = rtems_extension_create(
+ rtems_build_name( 'T', 'E', 'S', 'T' ),
+ &extensions,
+ &ctx->extension_id
+ );
+ T_rsc_success( sc );
+
+ SetFatalHandler( Fatal, ctx );
+ SetSelfPriority( PRIO_NORMAL );
+
+ ctx->deleter_id = CreateTask( "DELE", PRIO_HIGH );
+ StartTask( ctx->deleter_id, Deleter, NULL );
+}
+
+static void RtemsTaskReqExit_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqExit_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqExit_Setup( ctx );
+}
+
+static void RtemsTaskReqExit_Teardown( RtemsTaskReqExit_Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_extension_delete( ctx->extension_id );
+ T_rsc_success( sc );
+
+ SetFatalHandler( NULL, NULL );
+ DeleteTask( ctx->deleter_id );
+ RestoreRunnerASR();
+ RestoreRunnerPriority();
+}
+
+static void RtemsTaskReqExit_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqExit_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqExit_Teardown( ctx );
+}
+
+static void RtemsTaskReqExit_Action( RtemsTaskReqExit_Context *ctx )
+{
+ rtems_status_code sc;
+
+ ctx->delete_worker_expected = false;
+ ctx->worker_id = CreateTask( "WORK", PRIO_NORMAL );
+ ctx->delete_worker_expected = true;
+
+ StartTask( ctx->worker_id, Worker, ctx );
+
+ /* Let the worker catch signals and set the thread life protection state */
+ Yield();
+
+ sc = rtems_signal_send( ctx->worker_id, RTEMS_SIGNAL_0 );
+ T_rsc_success( sc );
+
+ if ( ctx->restarting ) {
+ sc = rtems_task_restart( ctx->worker_id, (rtems_task_argument) ctx );
+ T_rsc_success( sc );
+ }
+
+ if ( ctx->terminating ) {
+ sc = rtems_task_restart( ctx->deleter_id, (rtems_task_argument) ctx );
+ T_rsc_success( sc );
+ } else {
+ Yield();
+ }
+
+ if ( !ctx->dispatch_disabled ) {
+ T_scheduler_log *log;
+
+ log = T_scheduler_record( NULL );
+ T_eq_ptr( &log->header, &ctx->scheduler_log.header );
+ }
+}
+
+static void RtemsTaskReqExit_Cleanup( RtemsTaskReqExit_Context *ctx )
+{
+ if ( ctx->dispatch_disabled ) {
+ DeleteTask( ctx->worker_id );
+ }
+}
+
+static const RtemsTaskReqExit_Entry
+RtemsTaskReqExit_Entries[] = {
+ { 0, 0, 0, 0, 0, RtemsTaskReqExit_Post_FatalError_Nop,
+ RtemsTaskReqExit_Post_DeleteExtensions_Nop,
+ RtemsTaskReqExit_Post_RestartExtensions_Nop,
+ RtemsTaskReqExit_Post_TerminateExtensions_Yes,
+ RtemsTaskReqExit_Post_Zombie_Yes, RtemsTaskReqExit_Post_ID_Invalid,
+ RtemsTaskReqExit_Post_Delete_NextAllocate },
+ { 0, 0, 0, 0, 0, RtemsTaskReqExit_Post_FatalError_Yes,
+ RtemsTaskReqExit_Post_DeleteExtensions_Nop,
+ RtemsTaskReqExit_Post_RestartExtensions_Nop,
+ RtemsTaskReqExit_Post_TerminateExtensions_Nop,
+ RtemsTaskReqExit_Post_Zombie_No, RtemsTaskReqExit_Post_ID_Valid,
+ RtemsTaskReqExit_Post_Delete_Nop }
+};
+
+static const uint8_t
+RtemsTaskReqExit_Map[] = {
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1
+};
+
+static size_t RtemsTaskReqExit_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqExit_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsTaskReqExit_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqExit_Fixture = {
+ .setup = RtemsTaskReqExit_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqExit_Teardown_Wrap,
+ .scope = RtemsTaskReqExit_Scope,
+ .initial_context = &RtemsTaskReqExit_Instance
+};
+
+static inline RtemsTaskReqExit_Entry RtemsTaskReqExit_PopEntry(
+ RtemsTaskReqExit_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqExit_Entries[
+ RtemsTaskReqExit_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqExit_TestVariant( RtemsTaskReqExit_Context *ctx )
+{
+ RtemsTaskReqExit_Pre_Restarting_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqExit_Pre_Terminating_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqExit_Pre_Protected_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTaskReqExit_Pre_ThreadDispatch_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsTaskReqExit_Action( ctx );
+ RtemsTaskReqExit_Post_FatalError_Check(
+ ctx,
+ ctx->Map.entry.Post_FatalError
+ );
+ RtemsTaskReqExit_Post_DeleteExtensions_Check(
+ ctx,
+ ctx->Map.entry.Post_DeleteExtensions
+ );
+ RtemsTaskReqExit_Post_RestartExtensions_Check(
+ ctx,
+ ctx->Map.entry.Post_RestartExtensions
+ );
+ RtemsTaskReqExit_Post_TerminateExtensions_Check(
+ ctx,
+ ctx->Map.entry.Post_TerminateExtensions
+ );
+ RtemsTaskReqExit_Post_Zombie_Check( ctx, ctx->Map.entry.Post_Zombie );
+ RtemsTaskReqExit_Post_ID_Check( ctx, ctx->Map.entry.Post_ID );
+ RtemsTaskReqExit_Post_Delete_Check( ctx, ctx->Map.entry.Post_Delete );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqExit( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTaskReqExit, &RtemsTaskReqExit_Fixture )
+{
+ RtemsTaskReqExit_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsTaskReqExit_Pre_Restarting_Yes;
+ ctx->Map.pcs[ 0 ] < RtemsTaskReqExit_Pre_Restarting_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsTaskReqExit_Pre_Terminating_Yes;
+ ctx->Map.pcs[ 1 ] < RtemsTaskReqExit_Pre_Terminating_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsTaskReqExit_Pre_Protected_Yes;
+ ctx->Map.pcs[ 2 ] < RtemsTaskReqExit_Pre_Protected_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsTaskReqExit_Pre_ThreadDispatch_Enabled;
+ ctx->Map.pcs[ 3 ] < RtemsTaskReqExit_Pre_ThreadDispatch_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqExit_PopEntry( ctx );
+ RtemsTaskReqExit_TestVariant( ctx );
+ RtemsTaskReqExit_Cleanup( ctx );
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-get-affinity.c b/testsuites/validation/tc-task-get-affinity.c
new file mode 100644
index 0000000000..54244560df
--- /dev/null
+++ b/testsuites/validation/tc-task-get-affinity.c
@@ -0,0 +1,519 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqGetAffinity
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqGetAffinity spec:/rtems/task/req/get-affinity
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqGetAffinity_Pre_Id_Invalid,
+ RtemsTaskReqGetAffinity_Pre_Id_Task,
+ RtemsTaskReqGetAffinity_Pre_Id_NA
+} RtemsTaskReqGetAffinity_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqGetAffinity_Pre_CPUSetSize_Valid,
+ RtemsTaskReqGetAffinity_Pre_CPUSetSize_TooSmall,
+ RtemsTaskReqGetAffinity_Pre_CPUSetSize_Askew,
+ RtemsTaskReqGetAffinity_Pre_CPUSetSize_NA
+} RtemsTaskReqGetAffinity_Pre_CPUSetSize;
+
+typedef enum {
+ RtemsTaskReqGetAffinity_Pre_CPUSet_Valid,
+ RtemsTaskReqGetAffinity_Pre_CPUSet_Null,
+ RtemsTaskReqGetAffinity_Pre_CPUSet_NA
+} RtemsTaskReqGetAffinity_Pre_CPUSet;
+
+typedef enum {
+ RtemsTaskReqGetAffinity_Post_Status_Ok,
+ RtemsTaskReqGetAffinity_Post_Status_InvAddr,
+ RtemsTaskReqGetAffinity_Post_Status_InvId,
+ RtemsTaskReqGetAffinity_Post_Status_InvSize,
+ RtemsTaskReqGetAffinity_Post_Status_NA
+} RtemsTaskReqGetAffinity_Post_Status;
+
+typedef enum {
+ RtemsTaskReqGetAffinity_Post_CPUSetObj_Set,
+ RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop,
+ RtemsTaskReqGetAffinity_Post_CPUSetObj_NA
+} RtemsTaskReqGetAffinity_Post_CPUSetObj;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_CPUSetSize_NA : 1;
+ uint16_t Pre_CPUSet_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_CPUSetObj : 2;
+} RtemsTaskReqGetAffinity_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/get-affinity test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides the object referenced by the ``cpuset``
+ * parameter.
+ */
+ cpu_set_t cpuset_obj;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_task_get_affinity() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member specifies if the ``cpusetsize`` parameter value.
+ */
+ size_t cpusetsize;
+
+ /**
+ * @brief This member specifies if the ``cpuset`` parameter value.
+ */
+ cpu_set_t *cpuset;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqGetAffinity_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqGetAffinity_Context;
+
+static RtemsTaskReqGetAffinity_Context
+ RtemsTaskReqGetAffinity_Instance;
+
+static const char * const RtemsTaskReqGetAffinity_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqGetAffinity_PreDesc_CPUSetSize[] = {
+ "Valid",
+ "TooSmall",
+ "Askew",
+ "NA"
+};
+
+static const char * const RtemsTaskReqGetAffinity_PreDesc_CPUSet[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqGetAffinity_PreDesc[] = {
+ RtemsTaskReqGetAffinity_PreDesc_Id,
+ RtemsTaskReqGetAffinity_PreDesc_CPUSetSize,
+ RtemsTaskReqGetAffinity_PreDesc_CPUSet,
+ NULL
+};
+
+static void RtemsTaskReqGetAffinity_Pre_Id_Prepare(
+ RtemsTaskReqGetAffinity_Context *ctx,
+ RtemsTaskReqGetAffinity_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetAffinity_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Pre_Id_Task: {
+ /*
+ * While the ``id`` parameter is associated with a task.
+ */
+ ctx->id = RTEMS_SELF;
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetAffinity_Pre_CPUSetSize_Prepare(
+ RtemsTaskReqGetAffinity_Context *ctx,
+ RtemsTaskReqGetAffinity_Pre_CPUSetSize state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetAffinity_Pre_CPUSetSize_Valid: {
+ /*
+ * While the ``cpusetsize`` parameter is an integral multiple of the size
+ * of long, while the ``cpusetsize`` parameter specifies a processor set
+ * which is large enough to contain the processor affinity set of the
+ * task.
+ */
+ ctx->cpusetsize = sizeof( ctx->cpuset_obj );
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Pre_CPUSetSize_TooSmall: {
+ /*
+ * While the ``cpusetsize`` parameter is an integral multiple of the size
+ * of long, while the ``cpusetsize`` parameter specifies a processor set
+ * which is not large enough to contain the processor affinity set of the
+ * task.
+ */
+ ctx->cpusetsize = 0;
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Pre_CPUSetSize_Askew: {
+ /*
+ * While the ``cpusetsize`` parameter is not an integral multiple of the
+ * size of long.
+ */
+ ctx->cpusetsize = SIZE_MAX;
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Pre_CPUSetSize_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetAffinity_Pre_CPUSet_Prepare(
+ RtemsTaskReqGetAffinity_Context *ctx,
+ RtemsTaskReqGetAffinity_Pre_CPUSet state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetAffinity_Pre_CPUSet_Valid: {
+ /*
+ * While the ``cpuset`` parameter references an object of type cpu_set_t.
+ */
+ ctx->cpuset = &ctx->cpuset_obj;
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Pre_CPUSet_Null: {
+ /*
+ * While the ``cpuset`` parameter is equal to NULL.
+ */
+ ctx->cpuset = NULL;
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Pre_CPUSet_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetAffinity_Post_Status_Check(
+ RtemsTaskReqGetAffinity_Context *ctx,
+ RtemsTaskReqGetAffinity_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetAffinity_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_get_affinity() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_task_get_affinity() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_get_affinity() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Post_Status_InvSize: {
+ /*
+ * The return status of rtems_task_get_affinity() shall be
+ * RTEMS_INVALID_SIZE.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_SIZE );
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetAffinity_Post_CPUSetObj_Check(
+ RtemsTaskReqGetAffinity_Context *ctx,
+ RtemsTaskReqGetAffinity_Post_CPUSetObj state
+)
+{
+ cpu_set_t set;
+ uint32_t cpu_index;
+ uint32_t cpu_max;
+
+ switch ( state ) {
+ case RtemsTaskReqGetAffinity_Post_CPUSetObj_Set: {
+ /*
+ * The value of the object referenced by the ``cpuset`` parameter shall
+ * be set to the processor affinity set of the task specified by the
+ * ``id`` parameter at some point during the call after the return of the
+ * rtems_task_get_affinity() call.
+ */
+ CPU_ZERO( &set );
+
+ cpu_max = rtems_scheduler_get_processor_maximum();
+
+ /* We need the online processors */
+ if ( cpu_max > 4 ) {
+ cpu_max = 4;
+ }
+
+ for ( cpu_index = 0; cpu_index < cpu_max; ++cpu_index ) {
+ CPU_SET( (int) cpu_index, &set );
+ }
+
+ T_eq_int( CPU_CMP( &ctx->cpuset_obj, &set ), 0 );
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop: {
+ /*
+ * Objects referenced by the ``cpuset`` parameter in past calls to
+ * rtems_task_get_affinity() shall not be accessed by the
+ * rtems_task_get_affinity() call.
+ */
+ CPU_ZERO( &set );
+ T_eq_int( CPU_CMP( &ctx->cpuset_obj, &set ), 0 );
+ break;
+ }
+
+ case RtemsTaskReqGetAffinity_Post_CPUSetObj_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetAffinity_Prepare(
+ RtemsTaskReqGetAffinity_Context *ctx
+)
+{
+ CPU_ZERO( &ctx->cpuset_obj );
+}
+
+static void RtemsTaskReqGetAffinity_Action(
+ RtemsTaskReqGetAffinity_Context *ctx
+)
+{
+ ctx->status = rtems_task_get_affinity(
+ ctx->id,
+ ctx->cpusetsize,
+ ctx->cpuset
+ );
+}
+
+static const RtemsTaskReqGetAffinity_Entry
+RtemsTaskReqGetAffinity_Entries[] = {
+ { 0, 0, 0, 0, RtemsTaskReqGetAffinity_Post_Status_InvAddr,
+ RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop },
+ { 0, 0, 0, 0, RtemsTaskReqGetAffinity_Post_Status_InvId,
+ RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop },
+ { 0, 0, 0, 0, RtemsTaskReqGetAffinity_Post_Status_InvSize,
+ RtemsTaskReqGetAffinity_Post_CPUSetObj_Nop },
+ { 0, 0, 0, 0, RtemsTaskReqGetAffinity_Post_Status_Ok,
+ RtemsTaskReqGetAffinity_Post_CPUSetObj_Set }
+};
+
+static const uint8_t
+RtemsTaskReqGetAffinity_Map[] = {
+ 1, 0, 1, 0, 1, 0, 3, 0, 2, 0, 2, 0
+};
+
+static size_t RtemsTaskReqGetAffinity_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqGetAffinity_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsTaskReqGetAffinity_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqGetAffinity_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsTaskReqGetAffinity_Scope,
+ .initial_context = &RtemsTaskReqGetAffinity_Instance
+};
+
+static inline RtemsTaskReqGetAffinity_Entry RtemsTaskReqGetAffinity_PopEntry(
+ RtemsTaskReqGetAffinity_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqGetAffinity_Entries[
+ RtemsTaskReqGetAffinity_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqGetAffinity_TestVariant(
+ RtemsTaskReqGetAffinity_Context *ctx
+)
+{
+ RtemsTaskReqGetAffinity_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqGetAffinity_Pre_CPUSetSize_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqGetAffinity_Pre_CPUSet_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTaskReqGetAffinity_Action( ctx );
+ RtemsTaskReqGetAffinity_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsTaskReqGetAffinity_Post_CPUSetObj_Check(
+ ctx,
+ ctx->Map.entry.Post_CPUSetObj
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqGetAffinity( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTaskReqGetAffinity,
+ &RtemsTaskReqGetAffinity_Fixture
+)
+{
+ RtemsTaskReqGetAffinity_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsTaskReqGetAffinity_Pre_Id_Invalid;
+ ctx->Map.pcs[ 0 ] < RtemsTaskReqGetAffinity_Pre_Id_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsTaskReqGetAffinity_Pre_CPUSetSize_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsTaskReqGetAffinity_Pre_CPUSetSize_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsTaskReqGetAffinity_Pre_CPUSet_Valid;
+ ctx->Map.pcs[ 2 ] < RtemsTaskReqGetAffinity_Pre_CPUSet_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqGetAffinity_PopEntry( ctx );
+ RtemsTaskReqGetAffinity_Prepare( ctx );
+ RtemsTaskReqGetAffinity_TestVariant( ctx );
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-get-priority.c b/testsuites/validation/tc-task-get-priority.c
new file mode 100644
index 0000000000..83170e8353
--- /dev/null
+++ b/testsuites/validation/tc-task-get-priority.c
@@ -0,0 +1,619 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqGetPriority
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqGetPriority spec:/rtems/task/req/get-priority
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqGetPriority_Pre_TaskId_Invalid,
+ RtemsTaskReqGetPriority_Pre_TaskId_Task,
+ RtemsTaskReqGetPriority_Pre_TaskId_NA
+} RtemsTaskReqGetPriority_Pre_TaskId;
+
+typedef enum {
+ RtemsTaskReqGetPriority_Pre_SchedulerId_Invalid,
+ RtemsTaskReqGetPriority_Pre_SchedulerId_Scheduler,
+ RtemsTaskReqGetPriority_Pre_SchedulerId_NA
+} RtemsTaskReqGetPriority_Pre_SchedulerId;
+
+typedef enum {
+ RtemsTaskReqGetPriority_Pre_Scheduler_Eligible,
+ RtemsTaskReqGetPriority_Pre_Scheduler_Ineligible,
+ RtemsTaskReqGetPriority_Pre_Scheduler_NA
+} RtemsTaskReqGetPriority_Pre_Scheduler;
+
+typedef enum {
+ RtemsTaskReqGetPriority_Pre_Priority_Valid,
+ RtemsTaskReqGetPriority_Pre_Priority_Null,
+ RtemsTaskReqGetPriority_Pre_Priority_NA
+} RtemsTaskReqGetPriority_Pre_Priority;
+
+typedef enum {
+ RtemsTaskReqGetPriority_Post_Status_Ok,
+ RtemsTaskReqGetPriority_Post_Status_InvAddr,
+ RtemsTaskReqGetPriority_Post_Status_InvId,
+ RtemsTaskReqGetPriority_Post_Status_NotDef,
+ RtemsTaskReqGetPriority_Post_Status_NA
+} RtemsTaskReqGetPriority_Post_Status;
+
+typedef enum {
+ RtemsTaskReqGetPriority_Post_PriorityObj_Set,
+ RtemsTaskReqGetPriority_Post_PriorityObj_Nop,
+ RtemsTaskReqGetPriority_Post_PriorityObj_NA
+} RtemsTaskReqGetPriority_Post_PriorityObj;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_TaskId_NA : 1;
+ uint16_t Pre_SchedulerId_NA : 1;
+ uint16_t Pre_Scheduler_NA : 1;
+ uint16_t Pre_Priority_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_PriorityObj : 2;
+} RtemsTaskReqGetPriority_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/get-priority test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the scheduler A identifier.
+ */
+ rtems_id scheduler_a_id;
+
+ /**
+ * @brief This member contains the scheduler B identifier.
+ */
+ rtems_id scheduler_b_id;
+
+ /**
+ * @brief This member provides the object referenced by the ``priority``
+ * parameter.
+ */
+ rtems_task_priority priority_obj;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_task_get_priority() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``task_id`` parameter value.
+ */
+ rtems_id task_id;
+
+ /**
+ * @brief This member specifies if the ``scheduler_id`` parameter value.
+ */
+ rtems_id scheduler_id;
+
+ /**
+ * @brief This member specifies if the ``priority`` parameter value.
+ */
+ rtems_id *priority;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 4 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 4 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqGetPriority_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqGetPriority_Context;
+
+static RtemsTaskReqGetPriority_Context
+ RtemsTaskReqGetPriority_Instance;
+
+static const char * const RtemsTaskReqGetPriority_PreDesc_TaskId[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqGetPriority_PreDesc_SchedulerId[] = {
+ "Invalid",
+ "Scheduler",
+ "NA"
+};
+
+static const char * const RtemsTaskReqGetPriority_PreDesc_Scheduler[] = {
+ "Eligible",
+ "Ineligible",
+ "NA"
+};
+
+static const char * const RtemsTaskReqGetPriority_PreDesc_Priority[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqGetPriority_PreDesc[] = {
+ RtemsTaskReqGetPriority_PreDesc_TaskId,
+ RtemsTaskReqGetPriority_PreDesc_SchedulerId,
+ RtemsTaskReqGetPriority_PreDesc_Scheduler,
+ RtemsTaskReqGetPriority_PreDesc_Priority,
+ NULL
+};
+
+static void RtemsTaskReqGetPriority_Pre_TaskId_Prepare(
+ RtemsTaskReqGetPriority_Context *ctx,
+ RtemsTaskReqGetPriority_Pre_TaskId state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetPriority_Pre_TaskId_Invalid: {
+ /*
+ * While the ``task_id`` parameter is not associated with a task.
+ */
+ ctx->task_id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Pre_TaskId_Task: {
+ /*
+ * While the ``task_id`` parameter is associated with a task.
+ */
+ ctx->task_id = RTEMS_SELF;
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Pre_TaskId_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetPriority_Pre_SchedulerId_Prepare(
+ RtemsTaskReqGetPriority_Context *ctx,
+ RtemsTaskReqGetPriority_Pre_SchedulerId state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetPriority_Pre_SchedulerId_Invalid: {
+ /*
+ * While the ``scheduler_id`` parameter is not associated with a
+ * scheduler.
+ */
+ ctx->scheduler_id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Pre_SchedulerId_Scheduler: {
+ /*
+ * While the ``scheduler_id`` parameter is associated with a scheduler.
+ */
+ ctx->scheduler_id = ctx->scheduler_a_id;
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Pre_SchedulerId_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetPriority_Pre_Scheduler_Prepare(
+ RtemsTaskReqGetPriority_Context *ctx,
+ RtemsTaskReqGetPriority_Pre_Scheduler state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetPriority_Pre_Scheduler_Eligible: {
+ /*
+ * While the ``scheduler_id`` parameter is associated with an eligible
+ * scheduler of the task specified by ``task_id``.
+ */
+ ctx->scheduler_id = ctx->scheduler_a_id;
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Pre_Scheduler_Ineligible: {
+ /*
+ * While the ``scheduler_id`` parameter is associated with an ineligible
+ * scheduler of the task specified by ``task_id``.
+ */
+ ctx->scheduler_id = ctx->scheduler_b_id;
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Pre_Scheduler_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetPriority_Pre_Priority_Prepare(
+ RtemsTaskReqGetPriority_Context *ctx,
+ RtemsTaskReqGetPriority_Pre_Priority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetPriority_Pre_Priority_Valid: {
+ /*
+ * While the ``priority`` parameter references an object of type
+ * rtems_task_priority.
+ */
+ ctx->priority = &ctx->priority_obj;
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Pre_Priority_Null: {
+ /*
+ * While the ``priority`` parameter is equal to NULL.
+ */
+ ctx->priority = NULL;
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Pre_Priority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetPriority_Post_Status_Check(
+ RtemsTaskReqGetPriority_Context *ctx,
+ RtemsTaskReqGetPriority_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetPriority_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_get_priority() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_task_get_priority() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_get_priority() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Post_Status_NotDef: {
+ /*
+ * The return status of rtems_task_get_priority() shall be
+ * RTEMS_NOT_DEFINED.
+ */
+ T_rsc( ctx->status, RTEMS_NOT_DEFINED );
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetPriority_Post_PriorityObj_Check(
+ RtemsTaskReqGetPriority_Context *ctx,
+ RtemsTaskReqGetPriority_Post_PriorityObj state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetPriority_Post_PriorityObj_Set: {
+ /*
+ * The value of the object referenced by the ``scheduler_id`` parameter
+ * shall be set to the object identifier of the home scheduler of the
+ * task specified by the ``task_id`` parameter at some point during the
+ * call after the return of the rtems_task_get_priority() call.
+ */
+ T_eq_u32( ctx->priority_obj, PRIO_DEFAULT );
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Post_PriorityObj_Nop: {
+ /*
+ * Objects referenced by the ``scheduler_id`` parameter in past calls to
+ * rtems_task_get_priority() shall not be accessed by the
+ * rtems_task_get_priority() call.
+ */
+ T_eq_u32( ctx->priority_obj, PRIO_INVALID );
+ break;
+ }
+
+ case RtemsTaskReqGetPriority_Post_PriorityObj_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetPriority_Setup(
+ RtemsTaskReqGetPriority_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ sc = rtems_scheduler_ident(
+ TEST_SCHEDULER_A_NAME,
+ &ctx->scheduler_a_id
+ );
+ T_rsc_success( sc );
+
+ #if defined(RTEMS_SMP)
+ sc = rtems_scheduler_ident(
+ TEST_SCHEDULER_B_NAME,
+ &ctx->scheduler_b_id
+ );
+ T_rsc_success( sc );
+ #endif
+}
+
+static void RtemsTaskReqGetPriority_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqGetPriority_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqGetPriority_Setup( ctx );
+}
+
+static void RtemsTaskReqGetPriority_Prepare(
+ RtemsTaskReqGetPriority_Context *ctx
+)
+{
+ ctx->priority_obj = PRIO_INVALID;
+}
+
+static void RtemsTaskReqGetPriority_Action(
+ RtemsTaskReqGetPriority_Context *ctx
+)
+{
+ ctx->status = rtems_task_get_priority(
+ ctx->task_id,
+ ctx->scheduler_id,
+ ctx->priority
+ );
+}
+
+static const RtemsTaskReqGetPriority_Entry
+RtemsTaskReqGetPriority_Entries[] = {
+ { 0, 0, 0, 1, 0, RtemsTaskReqGetPriority_Post_Status_InvId,
+ RtemsTaskReqGetPriority_Post_PriorityObj_Nop },
+ { 0, 0, 0, 1, 0, RtemsTaskReqGetPriority_Post_Status_InvAddr,
+ RtemsTaskReqGetPriority_Post_PriorityObj_Nop },
+ { 0, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_Ok,
+ RtemsTaskReqGetPriority_Post_PriorityObj_Set },
+ { 0, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_InvAddr,
+ RtemsTaskReqGetPriority_Post_PriorityObj_Nop },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_NotDef,
+ RtemsTaskReqGetPriority_Post_PriorityObj_Nop },
+#else
+ { 1, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_NA,
+ RtemsTaskReqGetPriority_Post_PriorityObj_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_InvAddr,
+ RtemsTaskReqGetPriority_Post_PriorityObj_Nop }
+#else
+ { 1, 0, 0, 0, 0, RtemsTaskReqGetPriority_Post_Status_NA,
+ RtemsTaskReqGetPriority_Post_PriorityObj_NA }
+#endif
+};
+
+static const uint8_t
+RtemsTaskReqGetPriority_Map[] = {
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 4, 5
+};
+
+static size_t RtemsTaskReqGetPriority_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqGetPriority_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsTaskReqGetPriority_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqGetPriority_Fixture = {
+ .setup = RtemsTaskReqGetPriority_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsTaskReqGetPriority_Scope,
+ .initial_context = &RtemsTaskReqGetPriority_Instance
+};
+
+static inline RtemsTaskReqGetPriority_Entry RtemsTaskReqGetPriority_PopEntry(
+ RtemsTaskReqGetPriority_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqGetPriority_Entries[
+ RtemsTaskReqGetPriority_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqGetPriority_SetPreConditionStates(
+ RtemsTaskReqGetPriority_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+
+ if ( ctx->Map.entry.Pre_Scheduler_NA ) {
+ ctx->Map.pcs[ 2 ] = RtemsTaskReqGetPriority_Pre_Scheduler_NA;
+ } else {
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ }
+
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+}
+
+static void RtemsTaskReqGetPriority_TestVariant(
+ RtemsTaskReqGetPriority_Context *ctx
+)
+{
+ RtemsTaskReqGetPriority_Pre_TaskId_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqGetPriority_Pre_SchedulerId_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqGetPriority_Pre_Scheduler_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTaskReqGetPriority_Pre_Priority_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsTaskReqGetPriority_Action( ctx );
+ RtemsTaskReqGetPriority_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsTaskReqGetPriority_Post_PriorityObj_Check(
+ ctx,
+ ctx->Map.entry.Post_PriorityObj
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqGetPriority( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTaskReqGetPriority,
+ &RtemsTaskReqGetPriority_Fixture
+)
+{
+ RtemsTaskReqGetPriority_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsTaskReqGetPriority_Pre_TaskId_Invalid;
+ ctx->Map.pci[ 0 ] < RtemsTaskReqGetPriority_Pre_TaskId_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsTaskReqGetPriority_Pre_SchedulerId_Invalid;
+ ctx->Map.pci[ 1 ] < RtemsTaskReqGetPriority_Pre_SchedulerId_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsTaskReqGetPriority_Pre_Scheduler_Eligible;
+ ctx->Map.pci[ 2 ] < RtemsTaskReqGetPriority_Pre_Scheduler_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = RtemsTaskReqGetPriority_Pre_Priority_Valid;
+ ctx->Map.pci[ 3 ] < RtemsTaskReqGetPriority_Pre_Priority_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqGetPriority_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsTaskReqGetPriority_SetPreConditionStates( ctx );
+ RtemsTaskReqGetPriority_Prepare( ctx );
+ RtemsTaskReqGetPriority_TestVariant( ctx );
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-get-scheduler.c b/testsuites/validation/tc-task-get-scheduler.c
new file mode 100644
index 0000000000..41e0063b53
--- /dev/null
+++ b/testsuites/validation/tc-task-get-scheduler.c
@@ -0,0 +1,419 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqGetScheduler
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqGetScheduler spec:/rtems/task/req/get-scheduler
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqGetScheduler_Pre_Id_Invalid,
+ RtemsTaskReqGetScheduler_Pre_Id_Task,
+ RtemsTaskReqGetScheduler_Pre_Id_NA
+} RtemsTaskReqGetScheduler_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqGetScheduler_Pre_SchedulerID_Valid,
+ RtemsTaskReqGetScheduler_Pre_SchedulerID_Null,
+ RtemsTaskReqGetScheduler_Pre_SchedulerID_NA
+} RtemsTaskReqGetScheduler_Pre_SchedulerID;
+
+typedef enum {
+ RtemsTaskReqGetScheduler_Post_Status_Ok,
+ RtemsTaskReqGetScheduler_Post_Status_InvAddr,
+ RtemsTaskReqGetScheduler_Post_Status_InvId,
+ RtemsTaskReqGetScheduler_Post_Status_NA
+} RtemsTaskReqGetScheduler_Post_Status;
+
+typedef enum {
+ RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Set,
+ RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Nop,
+ RtemsTaskReqGetScheduler_Post_SchedulerIDObj_NA
+} RtemsTaskReqGetScheduler_Post_SchedulerIDObj;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Pre_SchedulerID_NA : 1;
+ uint8_t Post_Status : 2;
+ uint8_t Post_SchedulerIDObj : 2;
+} RtemsTaskReqGetScheduler_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/get-scheduler test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides the object referenced by the ``scheduler_id``
+ * parameter.
+ */
+ rtems_id scheduler_id_obj;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_task_get_scheduler() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``task_id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member specifies if the ``scheduler_id`` parameter value.
+ */
+ rtems_id *scheduler_id;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqGetScheduler_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqGetScheduler_Context;
+
+static RtemsTaskReqGetScheduler_Context
+ RtemsTaskReqGetScheduler_Instance;
+
+static const char * const RtemsTaskReqGetScheduler_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqGetScheduler_PreDesc_SchedulerID[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqGetScheduler_PreDesc[] = {
+ RtemsTaskReqGetScheduler_PreDesc_Id,
+ RtemsTaskReqGetScheduler_PreDesc_SchedulerID,
+ NULL
+};
+
+static void RtemsTaskReqGetScheduler_Pre_Id_Prepare(
+ RtemsTaskReqGetScheduler_Context *ctx,
+ RtemsTaskReqGetScheduler_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetScheduler_Pre_Id_Invalid: {
+ /*
+ * While the ``task_id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Pre_Id_Task: {
+ /*
+ * While the ``task_id`` parameter is associated with a task.
+ */
+ ctx->id = RTEMS_SELF;
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetScheduler_Pre_SchedulerID_Prepare(
+ RtemsTaskReqGetScheduler_Context *ctx,
+ RtemsTaskReqGetScheduler_Pre_SchedulerID state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetScheduler_Pre_SchedulerID_Valid: {
+ /*
+ * While the ``scheduler_id`` parameter references an object of type
+ * rtems_id.
+ */
+ ctx->scheduler_id = &ctx->scheduler_id_obj;
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Pre_SchedulerID_Null: {
+ /*
+ * While the ``scheduler_id`` parameter is equal to NULL.
+ */
+ ctx->scheduler_id = NULL;
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Pre_SchedulerID_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetScheduler_Post_Status_Check(
+ RtemsTaskReqGetScheduler_Context *ctx,
+ RtemsTaskReqGetScheduler_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetScheduler_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_get_scheduler() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_task_get_scheduler() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_get_scheduler() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Check(
+ RtemsTaskReqGetScheduler_Context *ctx,
+ RtemsTaskReqGetScheduler_Post_SchedulerIDObj state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Set: {
+ /*
+ * The value of the object referenced by the ``scheduler_id`` parameter
+ * shall be set to the object identifier of the home scheduler of the
+ * task specified by the ``task_id`` parameter at some point during the
+ * call after the return of the rtems_task_get_scheduler() call.
+ */
+ T_eq_u32( ctx->scheduler_id_obj, 0x0f010001 );
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Nop: {
+ /*
+ * Objects referenced by the ``scheduler_id`` parameter in past calls to
+ * rtems_task_get_scheduler() shall not be accessed by the
+ * rtems_task_get_scheduler() call.
+ */
+ T_eq_u32( ctx->scheduler_id_obj, INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqGetScheduler_Post_SchedulerIDObj_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqGetScheduler_Prepare(
+ RtemsTaskReqGetScheduler_Context *ctx
+)
+{
+ ctx->scheduler_id_obj = INVALID_ID;
+}
+
+static void RtemsTaskReqGetScheduler_Action(
+ RtemsTaskReqGetScheduler_Context *ctx
+)
+{
+ ctx->status = rtems_task_get_scheduler( ctx->id, ctx->scheduler_id );
+}
+
+static const RtemsTaskReqGetScheduler_Entry
+RtemsTaskReqGetScheduler_Entries[] = {
+ { 0, 0, 0, RtemsTaskReqGetScheduler_Post_Status_InvAddr,
+ RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Nop },
+ { 0, 0, 0, RtemsTaskReqGetScheduler_Post_Status_InvId,
+ RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Nop },
+ { 0, 0, 0, RtemsTaskReqGetScheduler_Post_Status_Ok,
+ RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Set }
+};
+
+static const uint8_t
+RtemsTaskReqGetScheduler_Map[] = {
+ 1, 0, 2, 0
+};
+
+static size_t RtemsTaskReqGetScheduler_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqGetScheduler_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsTaskReqGetScheduler_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqGetScheduler_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsTaskReqGetScheduler_Scope,
+ .initial_context = &RtemsTaskReqGetScheduler_Instance
+};
+
+static inline RtemsTaskReqGetScheduler_Entry RtemsTaskReqGetScheduler_PopEntry(
+ RtemsTaskReqGetScheduler_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqGetScheduler_Entries[
+ RtemsTaskReqGetScheduler_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqGetScheduler_TestVariant(
+ RtemsTaskReqGetScheduler_Context *ctx
+)
+{
+ RtemsTaskReqGetScheduler_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqGetScheduler_Pre_SchedulerID_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqGetScheduler_Action( ctx );
+ RtemsTaskReqGetScheduler_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ RtemsTaskReqGetScheduler_Post_SchedulerIDObj_Check(
+ ctx,
+ ctx->Map.entry.Post_SchedulerIDObj
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqGetScheduler( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTaskReqGetScheduler,
+ &RtemsTaskReqGetScheduler_Fixture
+)
+{
+ RtemsTaskReqGetScheduler_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsTaskReqGetScheduler_Pre_Id_Invalid;
+ ctx->Map.pcs[ 0 ] < RtemsTaskReqGetScheduler_Pre_Id_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsTaskReqGetScheduler_Pre_SchedulerID_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsTaskReqGetScheduler_Pre_SchedulerID_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqGetScheduler_PopEntry( ctx );
+ RtemsTaskReqGetScheduler_Prepare( ctx );
+ RtemsTaskReqGetScheduler_TestVariant( ctx );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-ident.c b/testsuites/validation/tc-task-ident.c
new file mode 100644
index 0000000000..214e6e99c5
--- /dev/null
+++ b/testsuites/validation/tc-task-ident.c
@@ -0,0 +1,338 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqIdent
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-object-ident.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqIdent spec:/rtems/task/req/ident
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqIdent_Pre_Name_WhoAmI,
+ RtemsTaskReqIdent_Pre_Name_NotWhoAmI,
+ RtemsTaskReqIdent_Pre_Name_NA
+} RtemsTaskReqIdent_Pre_Name;
+
+typedef enum {
+ RtemsTaskReqIdent_Post_Status_OkAndWhoAmI,
+ RtemsTaskReqIdent_Post_Status_Skip,
+ RtemsTaskReqIdent_Post_Status_NA
+} RtemsTaskReqIdent_Post_Status;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Name_NA : 1;
+ uint8_t Post_Status : 2;
+} RtemsTaskReqIdent_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/ident test case.
+ */
+typedef struct {
+ rtems_status_code status;
+
+ rtems_id *id;
+
+ rtems_id id_value;
+
+ rtems_id id_local_object;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqIdent_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqIdent_Context;
+
+static RtemsTaskReqIdent_Context
+ RtemsTaskReqIdent_Instance;
+
+static const char * const RtemsTaskReqIdent_PreDesc_Name[] = {
+ "WhoAmI",
+ "NotWhoAmI",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqIdent_PreDesc[] = {
+ RtemsTaskReqIdent_PreDesc_Name,
+ NULL
+};
+
+static rtems_status_code ClassicTaskIdentAction(
+ rtems_name name,
+ uint32_t node,
+ rtems_id *id
+)
+{
+ return rtems_task_ident( name, node, id );
+}
+
+static void RtemsTaskReqIdent_Pre_Name_Prepare(
+ RtemsTaskReqIdent_Context *ctx,
+ RtemsTaskReqIdent_Pre_Name state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqIdent_Pre_Name_WhoAmI: {
+ /*
+ * While the ``name`` parameter is equal to RTEMS_WHO_AM_I, while ``id``
+ * parameter is not equal to NULL.
+ */
+ ctx->id_value = 0xffffffff;
+ ctx->id = &ctx->id_value;
+ break;
+ }
+
+ case RtemsTaskReqIdent_Pre_Name_NotWhoAmI: {
+ /*
+ * While the ``name`` is not equal to RTEMS_WHO_AM_I or ``id`` parameter
+ * is equal to NULL, the behaviour of rtems_task_ident() shall be
+ * specified by spec:/rtems/req/ident.
+ */
+ ctx->id = NULL;
+ /* Preparation performed by RtemsReqIdent_Run() */
+ break;
+ }
+
+ case RtemsTaskReqIdent_Pre_Name_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqIdent_Post_Status_Check(
+ RtemsTaskReqIdent_Context *ctx,
+ RtemsTaskReqIdent_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqIdent_Post_Status_OkAndWhoAmI: {
+ /*
+ * The return status of rtems_task_ident() shall be RTEMS_SUCCESSFUL.
+ * The value of the object identifier referenced by the ``name``
+ * parameter shall be the identifier of the executing thread.
+ */
+ T_rsc( ctx->status, RTEMS_SUCCESSFUL );
+ T_eq_ptr( ctx->id, &ctx->id_value );
+ T_eq_u32( ctx->id_value, rtems_task_self() );
+ break;
+ }
+
+ case RtemsTaskReqIdent_Post_Status_Skip: {
+ /*
+ * There is no status to validate.
+ */
+ /* Checks performed by RtemsReqIdent_Run() */
+ break;
+ }
+
+ case RtemsTaskReqIdent_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqIdent_Setup( RtemsTaskReqIdent_Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_task_construct(
+ &DefaultTaskConfig,
+ &ctx->id_local_object
+ );
+ T_assert_rsc_success( sc );
+}
+
+static void RtemsTaskReqIdent_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqIdent_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqIdent_Setup( ctx );
+}
+
+static void RtemsTaskReqIdent_Teardown( RtemsTaskReqIdent_Context *ctx )
+{
+ if ( ctx->id_local_object != 0 ) {
+ rtems_status_code sc;
+
+ sc = rtems_task_delete( ctx->id_local_object );
+ T_rsc_success( sc );
+ }
+}
+
+static void RtemsTaskReqIdent_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqIdent_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqIdent_Teardown( ctx );
+}
+
+static void RtemsTaskReqIdent_Action( RtemsTaskReqIdent_Context *ctx )
+{
+ if ( ctx->id != NULL ) {
+ ctx->status = rtems_task_ident( RTEMS_SELF, 0xdeadbeef, ctx->id );
+ } else {
+ RtemsReqIdent_Run(
+ ctx->id_local_object,
+ DefaultTaskConfig.name,
+ ClassicTaskIdentAction
+ );
+ }
+}
+
+static const RtemsTaskReqIdent_Entry
+RtemsTaskReqIdent_Entries[] = {
+ { 0, 0, RtemsTaskReqIdent_Post_Status_OkAndWhoAmI },
+ { 0, 0, RtemsTaskReqIdent_Post_Status_Skip }
+};
+
+static const uint8_t
+RtemsTaskReqIdent_Map[] = {
+ 0, 1
+};
+
+static size_t RtemsTaskReqIdent_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqIdent_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsTaskReqIdent_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqIdent_Fixture = {
+ .setup = RtemsTaskReqIdent_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqIdent_Teardown_Wrap,
+ .scope = RtemsTaskReqIdent_Scope,
+ .initial_context = &RtemsTaskReqIdent_Instance
+};
+
+static inline RtemsTaskReqIdent_Entry RtemsTaskReqIdent_PopEntry(
+ RtemsTaskReqIdent_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqIdent_Entries[
+ RtemsTaskReqIdent_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqIdent_TestVariant( RtemsTaskReqIdent_Context *ctx )
+{
+ RtemsTaskReqIdent_Pre_Name_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqIdent_Action( ctx );
+ RtemsTaskReqIdent_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqIdent( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTaskReqIdent, &RtemsTaskReqIdent_Fixture )
+{
+ RtemsTaskReqIdent_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsTaskReqIdent_Pre_Name_WhoAmI;
+ ctx->Map.pcs[ 0 ] < RtemsTaskReqIdent_Pre_Name_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqIdent_PopEntry( ctx );
+ RtemsTaskReqIdent_TestVariant( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-is-suspended.c b/testsuites/validation/tc-task-is-suspended.c
new file mode 100644
index 0000000000..d61c14f560
--- /dev/null
+++ b/testsuites/validation/tc-task-is-suspended.c
@@ -0,0 +1,429 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqIsSuspended
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqIsSuspended spec:/rtems/task/req/is-suspended
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqIsSuspended_Pre_Id_Invalid,
+ RtemsTaskReqIsSuspended_Pre_Id_Task,
+ RtemsTaskReqIsSuspended_Pre_Id_NA
+} RtemsTaskReqIsSuspended_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqIsSuspended_Pre_Suspended_Yes,
+ RtemsTaskReqIsSuspended_Pre_Suspended_No,
+ RtemsTaskReqIsSuspended_Pre_Suspended_NA
+} RtemsTaskReqIsSuspended_Pre_Suspended;
+
+typedef enum {
+ RtemsTaskReqIsSuspended_Post_Status_Ok,
+ RtemsTaskReqIsSuspended_Post_Status_InvId,
+ RtemsTaskReqIsSuspended_Post_Status_AlrdySus,
+ RtemsTaskReqIsSuspended_Post_Status_NA
+} RtemsTaskReqIsSuspended_Post_Status;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Pre_Suspended_NA : 1;
+ uint8_t Post_Status : 2;
+} RtemsTaskReqIsSuspended_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/is-suspended test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the identifier of a task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief If this member is true, then the worker is suspended before the
+ * rtems_task_is_suspended() call.
+ */
+ bool suspend;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_task_is_suspended() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 2 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqIsSuspended_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqIsSuspended_Context;
+
+static RtemsTaskReqIsSuspended_Context
+ RtemsTaskReqIsSuspended_Instance;
+
+static const char * const RtemsTaskReqIsSuspended_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqIsSuspended_PreDesc_Suspended[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqIsSuspended_PreDesc[] = {
+ RtemsTaskReqIsSuspended_PreDesc_Id,
+ RtemsTaskReqIsSuspended_PreDesc_Suspended,
+ NULL
+};
+
+static void Worker( rtems_task_argument arg )
+{
+ while ( true ) {
+ /* Do nothing */
+ }
+}
+
+static void RtemsTaskReqIsSuspended_Pre_Id_Prepare(
+ RtemsTaskReqIsSuspended_Context *ctx,
+ RtemsTaskReqIsSuspended_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqIsSuspended_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqIsSuspended_Pre_Id_Task: {
+ /*
+ * While the ``id`` parameter is associated with a task.
+ */
+ ctx->id = ctx->worker_id;
+ break;
+ }
+
+ case RtemsTaskReqIsSuspended_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqIsSuspended_Pre_Suspended_Prepare(
+ RtemsTaskReqIsSuspended_Context *ctx,
+ RtemsTaskReqIsSuspended_Pre_Suspended state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqIsSuspended_Pre_Suspended_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is suspended.
+ */
+ ctx->suspend = true;
+ break;
+ }
+
+ case RtemsTaskReqIsSuspended_Pre_Suspended_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not suspended.
+ */
+ ctx->suspend = false;
+ break;
+ }
+
+ case RtemsTaskReqIsSuspended_Pre_Suspended_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqIsSuspended_Post_Status_Check(
+ RtemsTaskReqIsSuspended_Context *ctx,
+ RtemsTaskReqIsSuspended_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqIsSuspended_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_is_suspended() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqIsSuspended_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_is_suspended() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqIsSuspended_Post_Status_AlrdySus: {
+ /*
+ * The return status of rtems_task_is_suspended() shall be
+ * RTEMS_ALREADY_SUSPENDED.
+ */
+ T_rsc( ctx->status, RTEMS_ALREADY_SUSPENDED );
+ break;
+ }
+
+ case RtemsTaskReqIsSuspended_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqIsSuspended_Setup(
+ RtemsTaskReqIsSuspended_Context *ctx
+)
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+static void RtemsTaskReqIsSuspended_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqIsSuspended_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqIsSuspended_Setup( ctx );
+}
+
+static void RtemsTaskReqIsSuspended_Teardown(
+ RtemsTaskReqIsSuspended_Context *ctx
+)
+{
+ DeleteTask( ctx->worker_id );
+}
+
+static void RtemsTaskReqIsSuspended_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqIsSuspended_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqIsSuspended_Teardown( ctx );
+}
+
+static void RtemsTaskReqIsSuspended_Action(
+ RtemsTaskReqIsSuspended_Context *ctx
+)
+{
+ if ( ctx->suspend ) {
+ SuspendTask( ctx->worker_id );
+ }
+
+ ctx->status = rtems_task_is_suspended( ctx->id );
+
+ if ( ctx->suspend ) {
+ ResumeTask( ctx->worker_id );
+ }
+}
+
+static const RtemsTaskReqIsSuspended_Entry
+RtemsTaskReqIsSuspended_Entries[] = {
+ { 0, 0, 1, RtemsTaskReqIsSuspended_Post_Status_InvId },
+ { 0, 0, 0, RtemsTaskReqIsSuspended_Post_Status_AlrdySus },
+ { 0, 0, 0, RtemsTaskReqIsSuspended_Post_Status_Ok }
+};
+
+static const uint8_t
+RtemsTaskReqIsSuspended_Map[] = {
+ 0, 0, 1, 2
+};
+
+static size_t RtemsTaskReqIsSuspended_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqIsSuspended_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsTaskReqIsSuspended_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqIsSuspended_Fixture = {
+ .setup = RtemsTaskReqIsSuspended_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqIsSuspended_Teardown_Wrap,
+ .scope = RtemsTaskReqIsSuspended_Scope,
+ .initial_context = &RtemsTaskReqIsSuspended_Instance
+};
+
+static inline RtemsTaskReqIsSuspended_Entry RtemsTaskReqIsSuspended_PopEntry(
+ RtemsTaskReqIsSuspended_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqIsSuspended_Entries[
+ RtemsTaskReqIsSuspended_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqIsSuspended_SetPreConditionStates(
+ RtemsTaskReqIsSuspended_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+
+ if ( ctx->Map.entry.Pre_Suspended_NA ) {
+ ctx->Map.pcs[ 1 ] = RtemsTaskReqIsSuspended_Pre_Suspended_NA;
+ } else {
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ }
+}
+
+static void RtemsTaskReqIsSuspended_TestVariant(
+ RtemsTaskReqIsSuspended_Context *ctx
+)
+{
+ RtemsTaskReqIsSuspended_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqIsSuspended_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqIsSuspended_Action( ctx );
+ RtemsTaskReqIsSuspended_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqIsSuspended( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTaskReqIsSuspended,
+ &RtemsTaskReqIsSuspended_Fixture
+)
+{
+ RtemsTaskReqIsSuspended_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsTaskReqIsSuspended_Pre_Id_Invalid;
+ ctx->Map.pci[ 0 ] < RtemsTaskReqIsSuspended_Pre_Id_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsTaskReqIsSuspended_Pre_Suspended_Yes;
+ ctx->Map.pci[ 1 ] < RtemsTaskReqIsSuspended_Pre_Suspended_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqIsSuspended_PopEntry( ctx );
+ RtemsTaskReqIsSuspended_SetPreConditionStates( ctx );
+ RtemsTaskReqIsSuspended_TestVariant( ctx );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-mode.c b/testsuites/validation/tc-task-mode.c
new file mode 100644
index 0000000000..ac045e4176
--- /dev/null
+++ b/testsuites/validation/tc-task-mode.c
@@ -0,0 +1,2019 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqMode
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqMode spec:/rtems/task/req/mode
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ * @ingroup TestsuitesValidationOneCpu0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqMode_Pre_PrevMode_Valid,
+ RtemsTaskReqMode_Pre_PrevMode_Null,
+ RtemsTaskReqMode_Pre_PrevMode_NA
+} RtemsTaskReqMode_Pre_PrevMode;
+
+typedef enum {
+ RtemsTaskReqMode_Pre_PreemptCur_Yes,
+ RtemsTaskReqMode_Pre_PreemptCur_No,
+ RtemsTaskReqMode_Pre_PreemptCur_NA
+} RtemsTaskReqMode_Pre_PreemptCur;
+
+typedef enum {
+ RtemsTaskReqMode_Pre_TimesliceCur_Yes,
+ RtemsTaskReqMode_Pre_TimesliceCur_No,
+ RtemsTaskReqMode_Pre_TimesliceCur_NA
+} RtemsTaskReqMode_Pre_TimesliceCur;
+
+typedef enum {
+ RtemsTaskReqMode_Pre_ASRCur_Yes,
+ RtemsTaskReqMode_Pre_ASRCur_No,
+ RtemsTaskReqMode_Pre_ASRCur_NA
+} RtemsTaskReqMode_Pre_ASRCur;
+
+typedef enum {
+ RtemsTaskReqMode_Pre_IntLvlCur_Zero,
+ RtemsTaskReqMode_Pre_IntLvlCur_Positive,
+ RtemsTaskReqMode_Pre_IntLvlCur_NA
+} RtemsTaskReqMode_Pre_IntLvlCur;
+
+typedef enum {
+ RtemsTaskReqMode_Pre_Preempt_Yes,
+ RtemsTaskReqMode_Pre_Preempt_No,
+ RtemsTaskReqMode_Pre_Preempt_NA
+} RtemsTaskReqMode_Pre_Preempt;
+
+typedef enum {
+ RtemsTaskReqMode_Pre_Timeslice_Yes,
+ RtemsTaskReqMode_Pre_Timeslice_No,
+ RtemsTaskReqMode_Pre_Timeslice_NA
+} RtemsTaskReqMode_Pre_Timeslice;
+
+typedef enum {
+ RtemsTaskReqMode_Pre_ASR_Yes,
+ RtemsTaskReqMode_Pre_ASR_No,
+ RtemsTaskReqMode_Pre_ASR_NA
+} RtemsTaskReqMode_Pre_ASR;
+
+typedef enum {
+ RtemsTaskReqMode_Pre_IntLvl_Zero,
+ RtemsTaskReqMode_Pre_IntLvl_Positive,
+ RtemsTaskReqMode_Pre_IntLvl_NA
+} RtemsTaskReqMode_Pre_IntLvl;
+
+typedef enum {
+ RtemsTaskReqMode_Pre_PreemptMsk_Yes,
+ RtemsTaskReqMode_Pre_PreemptMsk_No,
+ RtemsTaskReqMode_Pre_PreemptMsk_NA
+} RtemsTaskReqMode_Pre_PreemptMsk;
+
+typedef enum {
+ RtemsTaskReqMode_Pre_TimesliceMsk_Yes,
+ RtemsTaskReqMode_Pre_TimesliceMsk_No,
+ RtemsTaskReqMode_Pre_TimesliceMsk_NA
+} RtemsTaskReqMode_Pre_TimesliceMsk;
+
+typedef enum {
+ RtemsTaskReqMode_Pre_ASRMsk_Yes,
+ RtemsTaskReqMode_Pre_ASRMsk_No,
+ RtemsTaskReqMode_Pre_ASRMsk_NA
+} RtemsTaskReqMode_Pre_ASRMsk;
+
+typedef enum {
+ RtemsTaskReqMode_Pre_IntLvlMsk_Yes,
+ RtemsTaskReqMode_Pre_IntLvlMsk_No,
+ RtemsTaskReqMode_Pre_IntLvlMsk_NA
+} RtemsTaskReqMode_Pre_IntLvlMsk;
+
+typedef enum {
+ RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Status_InvAddr,
+ RtemsTaskReqMode_Post_Status_NotImplIntLvl,
+ RtemsTaskReqMode_Post_Status_NotImplIntLvlSMP,
+ RtemsTaskReqMode_Post_Status_NotImplNoPreempt,
+ RtemsTaskReqMode_Post_Status_NA
+} RtemsTaskReqMode_Post_Status;
+
+typedef enum {
+ RtemsTaskReqMode_Post_Preempt_Yes,
+ RtemsTaskReqMode_Post_Preempt_No,
+ RtemsTaskReqMode_Post_Preempt_Maybe,
+ RtemsTaskReqMode_Post_Preempt_NA
+} RtemsTaskReqMode_Post_Preempt;
+
+typedef enum {
+ RtemsTaskReqMode_Post_ASR_Yes,
+ RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_ASR_Maybe,
+ RtemsTaskReqMode_Post_ASR_NA
+} RtemsTaskReqMode_Post_ASR;
+
+typedef enum {
+ RtemsTaskReqMode_Post_PMVar_Set,
+ RtemsTaskReqMode_Post_PMVar_Nop,
+ RtemsTaskReqMode_Post_PMVar_Maybe,
+ RtemsTaskReqMode_Post_PMVar_NA
+} RtemsTaskReqMode_Post_PMVar;
+
+typedef enum {
+ RtemsTaskReqMode_Post_Mode_Set,
+ RtemsTaskReqMode_Post_Mode_Nop,
+ RtemsTaskReqMode_Post_Mode_Maybe,
+ RtemsTaskReqMode_Post_Mode_NA
+} RtemsTaskReqMode_Post_Mode;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_PrevMode_NA : 1;
+ uint32_t Pre_PreemptCur_NA : 1;
+ uint32_t Pre_TimesliceCur_NA : 1;
+ uint32_t Pre_ASRCur_NA : 1;
+ uint32_t Pre_IntLvlCur_NA : 1;
+ uint32_t Pre_Preempt_NA : 1;
+ uint32_t Pre_Timeslice_NA : 1;
+ uint32_t Pre_ASR_NA : 1;
+ uint32_t Pre_IntLvl_NA : 1;
+ uint32_t Pre_PreemptMsk_NA : 1;
+ uint32_t Pre_TimesliceMsk_NA : 1;
+ uint32_t Pre_ASRMsk_NA : 1;
+ uint32_t Pre_IntLvlMsk_NA : 1;
+ uint32_t Post_Status : 3;
+ uint32_t Post_Preempt : 2;
+ uint32_t Post_ASR : 2;
+ uint32_t Post_PMVar : 2;
+ uint32_t Post_Mode : 2;
+} RtemsTaskReqMode_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/mode test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the object identifier of the worker task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief null If this member is contains the initial mode of the runner.
+ */
+ rtems_mode runner_mode;
+
+ /**
+ * @brief This member provides a value for the previous mode set.
+ */
+ rtems_mode previous_mode_set_value;
+
+ /**
+ * @brief This member specifies the task mode in which rtems_task_mode() is
+ * called.
+ */
+ rtems_mode current_mode;
+
+ /**
+ * @brief This member counts worker activity.
+ */
+ uint32_t worker_counter;
+
+ /**
+ * @brief This member contains worker counter before the rtems_task_mode()
+ * call.
+ */
+ uint32_t worker_counter_before;
+
+ /**
+ * @brief This member contains worker counter after the rtems_task_mode()
+ * call.
+ */
+ uint32_t worker_counter_after;
+
+ /**
+ * @brief This member counts signal handler activity.
+ */
+ uint32_t signal_counter;
+
+ /**
+ * @brief This member contains signal counter before the rtems_task_mode()
+ * call.
+ */
+ uint32_t signal_counter_before;
+
+ /**
+ * @brief This member contains signal counter after the rtems_task_mode()
+ * call.
+ */
+ uint32_t signal_counter_after;
+
+ /**
+ * @brief This member specifies the ``mode_set`` parameter for
+ * rtems_task_mode().
+ */
+ rtems_mode mode_set;
+
+ /**
+ * @brief This member specifies the mode mask ``mask`` parameter for
+ * rtems_task_mode() for the action.
+ */
+ rtems_mode mode_mask;
+
+ /**
+ * @brief This member specifies the previous mode set ``previous_mode_set``
+ * parameter for rtems_task_mode().
+ */
+ rtems_mode *previous_mode_set;
+
+ /**
+ * @brief This member contains the return status of the rtems_task_mode()
+ * call.
+ */
+ rtems_status_code status;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 13 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqMode_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqMode_Context;
+
+static RtemsTaskReqMode_Context
+ RtemsTaskReqMode_Instance;
+
+static const char * const RtemsTaskReqMode_PreDesc_PrevMode[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsTaskReqMode_PreDesc_PreemptCur[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqMode_PreDesc_TimesliceCur[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqMode_PreDesc_ASRCur[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqMode_PreDesc_IntLvlCur[] = {
+ "Zero",
+ "Positive",
+ "NA"
+};
+
+static const char * const RtemsTaskReqMode_PreDesc_Preempt[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqMode_PreDesc_Timeslice[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqMode_PreDesc_ASR[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqMode_PreDesc_IntLvl[] = {
+ "Zero",
+ "Positive",
+ "NA"
+};
+
+static const char * const RtemsTaskReqMode_PreDesc_PreemptMsk[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqMode_PreDesc_TimesliceMsk[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqMode_PreDesc_ASRMsk[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqMode_PreDesc_IntLvlMsk[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqMode_PreDesc[] = {
+ RtemsTaskReqMode_PreDesc_PrevMode,
+ RtemsTaskReqMode_PreDesc_PreemptCur,
+ RtemsTaskReqMode_PreDesc_TimesliceCur,
+ RtemsTaskReqMode_PreDesc_ASRCur,
+ RtemsTaskReqMode_PreDesc_IntLvlCur,
+ RtemsTaskReqMode_PreDesc_Preempt,
+ RtemsTaskReqMode_PreDesc_Timeslice,
+ RtemsTaskReqMode_PreDesc_ASR,
+ RtemsTaskReqMode_PreDesc_IntLvl,
+ RtemsTaskReqMode_PreDesc_PreemptMsk,
+ RtemsTaskReqMode_PreDesc_TimesliceMsk,
+ RtemsTaskReqMode_PreDesc_ASRMsk,
+ RtemsTaskReqMode_PreDesc_IntLvlMsk,
+ NULL
+};
+
+#define INVALID_MODE 0xffffffff
+
+#define EVENT_MAKE_READY RTEMS_EVENT_0
+
+#define EVENT_TIMESLICE RTEMS_EVENT_1
+
+typedef RtemsTaskReqMode_Context Context;
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ while ( true ) {
+ rtems_event_set events;
+
+ events = ReceiveAnyEvents();
+
+ if ( ( events & EVENT_TIMESLICE ) != 0 ) {
+ SetSelfPriority( PRIO_NORMAL );
+ SetSelfPriority( PRIO_HIGH );
+ }
+
+ ++ctx->worker_counter;
+ }
+}
+
+static void SignalHandler( rtems_signal_set signal_set )
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+ ++ctx->signal_counter;
+ T_eq_u32( signal_set, 0xdeadbeef );
+}
+
+static void ExhaustTimeslice( void )
+{
+ uint32_t ticks;
+
+ for (
+ ticks = 0;
+ ticks < rtems_configuration_get_ticks_per_timeslice();
+ ++ticks
+ ) {
+ ClockTick();
+ }
+}
+
+static void CheckMode(
+ Context *ctx,
+ rtems_mode mode,
+ rtems_mode mask,
+ rtems_mode set
+)
+{
+ rtems_status_code sc;
+ uint32_t counter;
+
+ mode &= ~mask;
+ mode |= set & mask;
+
+ counter = ctx->worker_counter;
+ SendEvents( ctx->worker_id, EVENT_MAKE_READY );
+
+ if ( ( mode & RTEMS_PREEMPT_MASK ) == RTEMS_PREEMPT ) {
+ T_eq_u32( ctx->worker_counter, counter + 1 );
+ } else {
+ T_eq_u32( ctx->worker_counter, counter );
+ }
+
+ counter = ctx->worker_counter;
+ SendEvents( ctx->worker_id, EVENT_TIMESLICE );
+ ExhaustTimeslice();
+
+ if ( ( mode & RTEMS_PREEMPT_MASK ) == RTEMS_PREEMPT ) {
+ if ( ( mode & RTEMS_TIMESLICE_MASK ) == RTEMS_TIMESLICE ) {
+ T_eq_u32( ctx->worker_counter, counter + 1 );
+ } else {
+ T_eq_u32( ctx->worker_counter, counter );
+ }
+ } else {
+ T_eq_u32( ctx->worker_counter, counter );
+ }
+
+ counter = ctx->signal_counter;
+ sc = rtems_signal_send( RTEMS_SELF, 0xdeadbeef );
+ T_rsc_success( sc );
+
+ if ( ( mode & RTEMS_ASR_MASK ) == RTEMS_ASR ) {
+ T_eq_u32( ctx->signal_counter, counter + 1 );
+ } else {
+ T_eq_u32( ctx->signal_counter, counter );
+ }
+
+ T_eq_u32( mode & RTEMS_INTERRUPT_MASK, _ISR_Get_level() );
+}
+
+static void RtemsTaskReqMode_Pre_PrevMode_Prepare(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Pre_PrevMode state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Pre_PrevMode_Valid: {
+ /*
+ * While the ``previous_mode_set`` parameter references an object of type
+ * rtems_mode.
+ */
+ ctx->previous_mode_set = &ctx->previous_mode_set_value;
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_PrevMode_Null: {
+ /*
+ * While the ``previous_mode_set`` parameter is NULL.
+ */
+ ctx->previous_mode_set = NULL;
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_PrevMode_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Pre_PreemptCur_Prepare(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Pre_PreemptCur state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Pre_PreemptCur_Yes: {
+ /*
+ * While the calling task has preemption enabled.
+ */
+ ctx->current_mode |= RTEMS_PREEMPT;
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_PreemptCur_No: {
+ /*
+ * Where the scheduler does not support the no-preempt mode, while the
+ * calling task has preemption enabled.
+ *
+ * Where the scheduler does support the no-preempt mode, while the
+ * calling task has preemption disabled.
+ */
+ if ( rtems_configuration_get_maximum_processors() > 1 ) {
+ ctx->current_mode |= RTEMS_PREEMPT;
+ } else {
+ ctx->current_mode |= RTEMS_NO_PREEMPT;
+ }
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_PreemptCur_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Pre_TimesliceCur_Prepare(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Pre_TimesliceCur state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Pre_TimesliceCur_Yes: {
+ /*
+ * While the calling task has timeslicing enabled.
+ */
+ ctx->current_mode |= RTEMS_TIMESLICE;
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_TimesliceCur_No: {
+ /*
+ * While the calling task has timeslicing disabled.
+ */
+ ctx->current_mode |= RTEMS_NO_TIMESLICE;
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_TimesliceCur_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Pre_ASRCur_Prepare(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Pre_ASRCur state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Pre_ASRCur_Yes: {
+ /*
+ * While the calling task has ASR processing enabled.
+ */
+ ctx->current_mode |= RTEMS_ASR;
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_ASRCur_No: {
+ /*
+ * While the calling task has ASR processing disabled.
+ */
+ ctx->current_mode |= RTEMS_NO_ASR;
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_ASRCur_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Pre_IntLvlCur_Prepare(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Pre_IntLvlCur state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Pre_IntLvlCur_Zero: {
+ /*
+ * While the calling task executes with an interrupt level of zero.
+ */
+ ctx->current_mode |= RTEMS_INTERRUPT_LEVEL( 0 );
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_IntLvlCur_Positive: {
+ /*
+ * Where the system needs inter-processor interrupts, while the calling
+ * task executes with an interrupt level of zero.
+ *
+ * Where the system does not need inter-processor interrupts, while the
+ * calling task executes with an an interrupt level greater than zero and
+ * less than or equal to CPU_MODES_INTERRUPT_MASK.
+ */
+ if ( rtems_configuration_get_maximum_processors() > 1 ) {
+ ctx->current_mode |= RTEMS_INTERRUPT_LEVEL( 0 );
+ } else {
+ ctx->current_mode |= RTEMS_INTERRUPT_LEVEL( 1 );
+ }
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_IntLvlCur_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Pre_Preempt_Prepare(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Pre_Preempt state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Pre_Preempt_Yes: {
+ /*
+ * While the ``mode_set`` parameter specifies that preemption is enabled.
+ */
+ ctx->mode_set |= RTEMS_PREEMPT;
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_Preempt_No: {
+ /*
+ * While the ``mode_set`` parameter specifies that preemption is
+ * disabled.
+ */
+ ctx->mode_set |= RTEMS_NO_PREEMPT;
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_Preempt_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Pre_Timeslice_Prepare(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Pre_Timeslice state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Pre_Timeslice_Yes: {
+ /*
+ * While the ``mode_set`` parameter specifies that timeslicing is
+ * enabled.
+ */
+ ctx->mode_set |= RTEMS_TIMESLICE;
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_Timeslice_No: {
+ /*
+ * While the ``mode_set`` parameter specifies that timeslicing is
+ * disabled.
+ */
+ ctx->mode_set |= RTEMS_NO_TIMESLICE;
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_Timeslice_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Pre_ASR_Prepare(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Pre_ASR state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Pre_ASR_Yes: {
+ /*
+ * While the ``mode_set`` parameter specifies that ASR processing is
+ * enabled.
+ */
+ ctx->mode_set |= RTEMS_ASR;
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_ASR_No: {
+ /*
+ * While the ``mode_set`` parameter specifies that ASR processing is
+ * disabled.
+ */
+ ctx->mode_set |= RTEMS_NO_ASR;
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_ASR_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Pre_IntLvl_Prepare(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Pre_IntLvl state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Pre_IntLvl_Zero: {
+ /*
+ * While the ``mode_set`` parameter specifies an interrupt level of zero.
+ */
+ ctx->mode_set |= RTEMS_INTERRUPT_LEVEL( 0 );
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_IntLvl_Positive: {
+ /*
+ * While the ``mode_set`` parameter specifies an interrupt level greater
+ * than zero and less than or equal to CPU_MODES_INTERRUPT_MASK.
+ */
+ ctx->mode_set |= RTEMS_INTERRUPT_LEVEL( 1 );
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_IntLvl_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Pre_PreemptMsk_Prepare(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Pre_PreemptMsk state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Pre_PreemptMsk_Yes: {
+ /*
+ * While the ``mask`` parameter specifies that the preemption mode shall
+ * be set.
+ */
+ ctx->mode_mask |= RTEMS_PREEMPT_MASK;
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_PreemptMsk_No: {
+ /*
+ * While the ``mask`` parameter specifies that the preemption mode shall
+ * not be set.
+ */
+ /* This is the default mode mask */
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_PreemptMsk_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Pre_TimesliceMsk_Prepare(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Pre_TimesliceMsk state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Pre_TimesliceMsk_Yes: {
+ /*
+ * While the ``mask`` parameter specifies that the timeslicing mode shall
+ * be set.
+ */
+ ctx->mode_mask |= RTEMS_TIMESLICE_MASK;
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_TimesliceMsk_No: {
+ /*
+ * While the ``mask`` parameter specifies that the timeslicing mode shall
+ * not be set.
+ */
+ /* This is the default mode mask */
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_TimesliceMsk_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Pre_ASRMsk_Prepare(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Pre_ASRMsk state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Pre_ASRMsk_Yes: {
+ /*
+ * While the ``mask`` parameter specifies that the ASR processing mode
+ * shall be set.
+ */
+ ctx->mode_mask |= RTEMS_ASR_MASK;
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_ASRMsk_No: {
+ /*
+ * While the ``mask`` parameter specifies that the ASR processing mode
+ * shall not be set.
+ */
+ /* This is the default mode mask */
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_ASRMsk_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Pre_IntLvlMsk_Prepare(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Pre_IntLvlMsk state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Pre_IntLvlMsk_Yes: {
+ /*
+ * While the ``mask`` parameter specifies that the interrupt level shall
+ * be set.
+ */
+ ctx->mode_mask |= RTEMS_INTERRUPT_MASK;
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_IntLvlMsk_No: {
+ /*
+ * While the ``mask`` parameter specifies that the interrupt level shall
+ * not be set.
+ */
+ /* This is the default mode mask */
+ break;
+ }
+
+ case RtemsTaskReqMode_Pre_IntLvlMsk_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Post_Status_Check(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_mode() shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqMode_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_task_mode() shall be RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTaskReqMode_Post_Status_NotImplIntLvl: {
+ /*
+ * The return status of rtems_task_mode() shall be RTEMS_NOT_IMPLEMENTED.
+ */
+ T_rsc( ctx->status, RTEMS_NOT_IMPLEMENTED );
+ break;
+ }
+
+ case RtemsTaskReqMode_Post_Status_NotImplIntLvlSMP: {
+ /*
+ * Where the system needs inter-processor interrupts, the return status
+ * of rtems_task_mode() shall be RTEMS_NOT_IMPLEMENTED.
+ *
+ * Where the system does not need inter-processor interrupts, the return
+ * status of rtems_task_mode() shall be RTEMS_SUCCESSFUL.
+ */
+ if ( rtems_configuration_get_maximum_processors() > 1 ) {
+ T_rsc( ctx->status, RTEMS_NOT_IMPLEMENTED );
+ } else {
+ T_rsc_success( ctx->status );
+ }
+ break;
+ }
+
+ case RtemsTaskReqMode_Post_Status_NotImplNoPreempt: {
+ /*
+ * Where the scheduler does not support the no-preempt mode, the return
+ * status of rtems_task_mode() shall be RTEMS_NOT_IMPLEMENTED.
+ *
+ * Where the scheduler does support the no-preempt mode, the return
+ * status of rtems_task_mode() shall be RTEMS_SUCCESSFUL.
+ */
+ if ( rtems_configuration_get_maximum_processors() > 1 ) {
+ T_rsc( ctx->status, RTEMS_NOT_IMPLEMENTED );
+ } else {
+ T_rsc_success( ctx->status );
+ }
+ break;
+ }
+
+ case RtemsTaskReqMode_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Post_Preempt_Check(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Post_Preempt state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Post_Preempt_Yes: {
+ /*
+ * The calling task shall be preempted by a higher priority ready task
+ * during the rtems_task_mode() call.
+ */
+ T_eq_u32( ctx->worker_counter_after, ctx->worker_counter_before + 1 );
+ break;
+ }
+
+ case RtemsTaskReqMode_Post_Preempt_No: {
+ /*
+ * The calling task shall not be preempted during the rtems_task_mode()
+ * call.
+ */
+ T_eq_u32( ctx->worker_counter_after, ctx->worker_counter_before );
+ break;
+ }
+
+ case RtemsTaskReqMode_Post_Preempt_Maybe: {
+ /*
+ * Where the scheduler does not support the no-preempt mode, the calling
+ * task shall not be preempted during the rtems_task_mode() call.
+ *
+ * Where the scheduler does support the no-preempt mode, the calling task
+ * shall be preempted by a higher priority ready task during the
+ * rtems_task_mode() call.
+ */
+ if ( rtems_configuration_get_maximum_processors() > 1 ) {
+ T_eq_u32( ctx->worker_counter_after, ctx->worker_counter_before );
+ } else {
+ T_eq_u32( ctx->worker_counter_after, ctx->worker_counter_before + 1 );
+ }
+ break;
+ }
+
+ case RtemsTaskReqMode_Post_Preempt_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Post_ASR_Check(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Post_ASR state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Post_ASR_Yes: {
+ /*
+ * The calling task shall process pending signals during the
+ * rtems_task_mode() call.
+ */
+ T_eq_u32( ctx->signal_counter_after, ctx->signal_counter_before + 1 );
+ break;
+ }
+
+ case RtemsTaskReqMode_Post_ASR_No: {
+ /*
+ * The calling task shall not process signals during the
+ * rtems_task_mode() call.
+ */
+ T_eq_u32( ctx->signal_counter_after, ctx->signal_counter_before );
+ break;
+ }
+
+ case RtemsTaskReqMode_Post_ASR_Maybe: {
+ /*
+ * Where the scheduler does not support the no-preempt mode, the calling
+ * task shall not process signals during the rtems_task_mode() call.
+ *
+ * Where the scheduler does support the no-preempt mode, the calling task
+ * shall process pending signals during the rtems_task_mode() call.
+ */
+ if ( rtems_configuration_get_maximum_processors() > 1 ) {
+ T_eq_u32( ctx->signal_counter_after, ctx->signal_counter_before );
+ } else {
+ T_eq_u32( ctx->signal_counter_after, ctx->signal_counter_before + 1 );
+ }
+ break;
+ }
+
+ case RtemsTaskReqMode_Post_ASR_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Post_PMVar_Check(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Post_PMVar state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Post_PMVar_Set: {
+ /*
+ * The value of the object referenced by the ``previous_mode_set``
+ * parameter shall be set to the task modes of the calling task on entry
+ * of the call to rtems_task_mode().
+ */
+ T_eq_ptr( ctx->previous_mode_set, &ctx->previous_mode_set_value );
+ T_eq_u32( ctx->previous_mode_set_value, ctx->current_mode );
+ break;
+ }
+
+ case RtemsTaskReqMode_Post_PMVar_Nop: {
+ /*
+ * Objects referenced by the ``stack_size`` parameter in past calls to
+ * rtems_task_mode() shall not be accessed by the rtems_task_mode() call.
+ */
+ T_eq_u32( ctx->previous_mode_set_value, INVALID_MODE );
+ break;
+ }
+
+ case RtemsTaskReqMode_Post_PMVar_Maybe: {
+ /*
+ * Where the scheduler does not support the no-preempt mode, objects
+ * referenced by the ``stack_size`` parameter in past calls to
+ * rtems_task_mode() shall not be accessed by the rtems_task_mode() call.
+ *
+ * Where the scheduler does support the no-preempt mode, the value of the
+ * object referenced by the ``previous_mode_set`` parameter shall be set
+ * to the task modes of the calling task on entry of the call to
+ * rtems_task_mode().
+ */
+ T_eq_ptr( ctx->previous_mode_set, &ctx->previous_mode_set_value );
+
+ if ( rtems_configuration_get_maximum_processors() > 1 ) {
+ T_eq_u32( ctx->previous_mode_set_value, INVALID_MODE );
+ } else {
+ T_eq_u32( ctx->previous_mode_set_value, ctx->current_mode );
+ }
+ break;
+ }
+
+ case RtemsTaskReqMode_Post_PMVar_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Post_Mode_Check(
+ RtemsTaskReqMode_Context *ctx,
+ RtemsTaskReqMode_Post_Mode state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqMode_Post_Mode_Set: {
+ /*
+ * The task modes of the calling task indicated by the ``mask`` parameter
+ * shall be set to the corrsponding modes specified by the ``mode_set``
+ * parameter.
+ */
+ CheckMode( ctx, ctx->current_mode, ctx->mode_mask, ctx->mode_set );
+ break;
+ }
+
+ case RtemsTaskReqMode_Post_Mode_Nop: {
+ /*
+ * The task modes of the calling task shall not be modified by the
+ * rtems_task_mode() call.
+ */
+ CheckMode( ctx, ctx->current_mode, 0, 0 );
+ break;
+ }
+
+ case RtemsTaskReqMode_Post_Mode_Maybe: {
+ /*
+ * Where the scheduler does not support the no-preempt mode, the task
+ * modes of the calling task shall not be modified by the
+ * rtems_task_mode() call.
+ *
+ * Where the scheduler does support the no-preempt mode, the task modes
+ * of the calling task indicated by the ``mask`` parameter shall be set
+ * to the corrsponding modes specified by the ``mode_set`` parameter.
+ */
+ if ( rtems_configuration_get_maximum_processors() > 1 ) {
+ CheckMode( ctx, ctx->current_mode, 0, 0 );
+ } else {
+ CheckMode( ctx, ctx->current_mode, ctx->mode_mask, ctx->mode_set );
+ }
+ break;
+ }
+
+ case RtemsTaskReqMode_Post_Mode_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqMode_Setup( RtemsTaskReqMode_Context *ctx )
+{
+ rtems_status_code sc;
+
+ memset( ctx, 0, sizeof( *ctx ) );
+
+ sc = rtems_task_mode(
+ RTEMS_DEFAULT_MODES,
+ RTEMS_CURRENT_MODE,
+ &ctx->runner_mode
+ );
+ T_rsc_success( sc );
+
+ SetSelfPriority( PRIO_NORMAL );
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+static void RtemsTaskReqMode_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqMode_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqMode_Setup( ctx );
+}
+
+static void RtemsTaskReqMode_Teardown( RtemsTaskReqMode_Context *ctx )
+{
+ DeleteTask( ctx->worker_id );
+ RestoreRunnerMode();
+ RestoreRunnerPriority();
+}
+
+static void RtemsTaskReqMode_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqMode_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqMode_Teardown( ctx );
+}
+
+static void RtemsTaskReqMode_Prepare( RtemsTaskReqMode_Context *ctx )
+{
+ ctx->current_mode = RTEMS_DEFAULT_MODES;
+ ctx->mode_set = RTEMS_DEFAULT_MODES;
+ ctx->mode_mask = RTEMS_CURRENT_MODE;
+ ctx->previous_mode_set_value = INVALID_MODE;
+}
+
+static void RtemsTaskReqMode_Action( RtemsTaskReqMode_Context *ctx )
+{
+ rtems_status_code sc;
+ rtems_mode mode;
+
+ sc = rtems_task_mode( ctx->current_mode, RTEMS_ALL_MODE_MASKS, &mode );
+ T_rsc_success( sc );
+
+ SendEvents( ctx->worker_id, EVENT_MAKE_READY );
+
+ sc = rtems_signal_catch( SignalHandler, ctx->current_mode | RTEMS_NO_ASR );
+ T_rsc_success( sc );
+
+ sc = rtems_signal_send( RTEMS_SELF, 0xdeadbeef );
+ T_rsc_success( sc );
+
+ ctx->worker_counter_before = ctx->worker_counter;
+ ctx->signal_counter_before = ctx->signal_counter;
+ ctx->status = rtems_task_mode(
+ ctx->mode_set,
+ ctx->mode_mask,
+ ctx->previous_mode_set
+ );
+ ctx->worker_counter_after = ctx->worker_counter;
+ ctx->signal_counter_after = ctx->signal_counter;
+}
+
+static void RtemsTaskReqMode_Cleanup( RtemsTaskReqMode_Context *ctx )
+{
+ rtems_status_code sc;
+ rtems_mode mode;
+
+ sc = rtems_task_mode( RTEMS_DEFAULT_MODES, RTEMS_ALL_MODE_MASKS, &mode );
+ T_rsc_success( sc );
+
+ sc = rtems_task_wake_after( RTEMS_YIELD_PROCESSOR );
+ T_rsc_success( sc );
+
+ sc = rtems_signal_catch( NULL, RTEMS_DEFAULT_MODES );
+ T_rsc_success( sc );
+}
+
+static const RtemsTaskReqMode_Entry
+RtemsTaskReqMode_Entries[] = {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_InvAddr, RtemsTaskReqMode_Post_Preempt_No,
+ RtemsTaskReqMode_Post_ASR_No, RtemsTaskReqMode_Post_PMVar_Nop,
+ RtemsTaskReqMode_Post_Mode_Nop },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_NA,
+ RtemsTaskReqMode_Post_Preempt_NA, RtemsTaskReqMode_Post_ASR_NA,
+ RtemsTaskReqMode_Post_PMVar_NA, RtemsTaskReqMode_Post_Mode_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_InvAddr, RtemsTaskReqMode_Post_Preempt_No,
+ RtemsTaskReqMode_Post_ASR_No, RtemsTaskReqMode_Post_PMVar_Nop,
+ RtemsTaskReqMode_Post_Mode_Nop },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_NA,
+ RtemsTaskReqMode_Post_Preempt_NA, RtemsTaskReqMode_Post_ASR_NA,
+ RtemsTaskReqMode_Post_PMVar_NA, RtemsTaskReqMode_Post_Mode_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_NA,
+ RtemsTaskReqMode_Post_Preempt_NA, RtemsTaskReqMode_Post_ASR_NA,
+ RtemsTaskReqMode_Post_PMVar_NA, RtemsTaskReqMode_Post_Mode_NA },
+#elif defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplNoPreempt,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Maybe, RtemsTaskReqMode_Post_Mode_Maybe },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplNoPreempt,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Maybe, RtemsTaskReqMode_Post_Mode_Maybe },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplIntLvl,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Nop, RtemsTaskReqMode_Post_Mode_Nop },
+#elif defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplIntLvlSMP,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Maybe, RtemsTaskReqMode_Post_Mode_Maybe },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_NA,
+ RtemsTaskReqMode_Post_Preempt_NA, RtemsTaskReqMode_Post_ASR_NA,
+ RtemsTaskReqMode_Post_PMVar_NA, RtemsTaskReqMode_Post_Mode_NA },
+#elif defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplIntLvlSMP,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Maybe, RtemsTaskReqMode_Post_Mode_Maybe },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_Maybe, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_Yes, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_NA,
+ RtemsTaskReqMode_Post_Preempt_NA, RtemsTaskReqMode_Post_ASR_NA,
+ RtemsTaskReqMode_Post_PMVar_NA, RtemsTaskReqMode_Post_Mode_NA },
+#elif defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_Maybe, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_Yes, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_Yes,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_NA,
+ RtemsTaskReqMode_Post_Preempt_NA, RtemsTaskReqMode_Post_ASR_NA,
+ RtemsTaskReqMode_Post_PMVar_NA, RtemsTaskReqMode_Post_Mode_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_Yes,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplIntLvl,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Nop, RtemsTaskReqMode_Post_Mode_Nop },
+#elif defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplNoPreempt,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Maybe, RtemsTaskReqMode_Post_Mode_Maybe },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_NA,
+ RtemsTaskReqMode_Post_Preempt_NA, RtemsTaskReqMode_Post_ASR_NA,
+ RtemsTaskReqMode_Post_PMVar_NA, RtemsTaskReqMode_Post_Mode_NA },
+#elif defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplNoPreempt,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_Maybe,
+ RtemsTaskReqMode_Post_PMVar_Maybe, RtemsTaskReqMode_Post_Mode_Maybe },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_Yes,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplIntLvl,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Nop, RtemsTaskReqMode_Post_Mode_Nop },
+#elif defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplIntLvlSMP,
+ RtemsTaskReqMode_Post_Preempt_Maybe, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Maybe, RtemsTaskReqMode_Post_Mode_Maybe },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_Yes, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_NA,
+ RtemsTaskReqMode_Post_Preempt_NA, RtemsTaskReqMode_Post_ASR_NA,
+ RtemsTaskReqMode_Post_PMVar_NA, RtemsTaskReqMode_Post_Mode_NA },
+#elif defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplIntLvlSMP,
+ RtemsTaskReqMode_Post_Preempt_Maybe, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Maybe, RtemsTaskReqMode_Post_Mode_Maybe },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_Yes, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplNoPreempt,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_Maybe,
+ RtemsTaskReqMode_Post_PMVar_Maybe, RtemsTaskReqMode_Post_Mode_Maybe },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_Yes,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplIntLvl,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Nop, RtemsTaskReqMode_Post_Mode_Nop },
+#elif defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplIntLvlSMP,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_Maybe,
+ RtemsTaskReqMode_Post_PMVar_Maybe, RtemsTaskReqMode_Post_Mode_Maybe },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_Yes,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_NA,
+ RtemsTaskReqMode_Post_Preempt_NA, RtemsTaskReqMode_Post_ASR_NA,
+ RtemsTaskReqMode_Post_PMVar_NA, RtemsTaskReqMode_Post_Mode_NA },
+#elif defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplIntLvlSMP,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_Maybe,
+ RtemsTaskReqMode_Post_PMVar_Maybe, RtemsTaskReqMode_Post_Mode_Maybe },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_Yes,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_Maybe, RtemsTaskReqMode_Post_ASR_Yes,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_Yes, RtemsTaskReqMode_Post_ASR_Yes,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_NA,
+ RtemsTaskReqMode_Post_Preempt_NA, RtemsTaskReqMode_Post_ASR_NA,
+ RtemsTaskReqMode_Post_PMVar_NA, RtemsTaskReqMode_Post_Mode_NA },
+#elif defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_Maybe, RtemsTaskReqMode_Post_ASR_Yes,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_Yes, RtemsTaskReqMode_Post_ASR_Yes,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplIntLvl,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Nop, RtemsTaskReqMode_Post_Mode_Nop },
+#elif defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplNoPreempt,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_Maybe,
+ RtemsTaskReqMode_Post_PMVar_Maybe, RtemsTaskReqMode_Post_Mode_Maybe },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_Yes,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplIntLvl,
+ RtemsTaskReqMode_Post_Preempt_No, RtemsTaskReqMode_Post_ASR_No,
+ RtemsTaskReqMode_Post_PMVar_Nop, RtemsTaskReqMode_Post_Mode_Nop },
+#elif defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplIntLvlSMP,
+ RtemsTaskReqMode_Post_Preempt_Maybe, RtemsTaskReqMode_Post_ASR_Maybe,
+ RtemsTaskReqMode_Post_PMVar_Maybe, RtemsTaskReqMode_Post_Mode_Maybe },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_Yes, RtemsTaskReqMode_Post_ASR_Yes,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set },
+#endif
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_NA,
+ RtemsTaskReqMode_Post_Preempt_NA, RtemsTaskReqMode_Post_ASR_NA,
+ RtemsTaskReqMode_Post_PMVar_NA, RtemsTaskReqMode_Post_Mode_NA }
+#elif defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqMode_Post_Status_NotImplIntLvlSMP,
+ RtemsTaskReqMode_Post_Preempt_Maybe, RtemsTaskReqMode_Post_ASR_Maybe,
+ RtemsTaskReqMode_Post_PMVar_Maybe, RtemsTaskReqMode_Post_Mode_Maybe }
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqMode_Post_Status_Ok,
+ RtemsTaskReqMode_Post_Preempt_Yes, RtemsTaskReqMode_Post_ASR_Yes,
+ RtemsTaskReqMode_Post_PMVar_Set, RtemsTaskReqMode_Post_Mode_Set }
+#endif
+};
+
+static const uint8_t
+RtemsTaskReqMode_Map[] = {
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2,
+ 6, 2, 6, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 6, 2,
+ 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 5, 5,
+ 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 12, 5, 12, 5, 12, 5, 12, 5, 6, 2,
+ 6, 2, 6, 2, 6, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 12, 5, 12,
+ 5, 12, 5, 12, 5, 6, 2, 6, 2, 6, 2, 6, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2,
+ 2, 2, 2, 2, 12, 5, 12, 5, 12, 5, 12, 5, 6, 2, 6, 2, 6, 2, 6, 2, 5, 5, 5, 5,
+ 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 12, 5, 12, 5, 12, 5, 12, 5, 6, 2, 6, 2,
+ 6, 2, 6, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 7, 3, 7, 3,
+ 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3,
+ 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+ 7, 3, 7, 3, 7, 3, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4,
+ 4, 4, 4, 4, 4, 4, 7, 3, 7, 3, 7, 3, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3,
+ 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 3, 7, 3, 7, 3, 7, 3, 4, 4, 4, 4, 4, 4,
+ 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 3, 7, 3, 7, 3, 7, 3,
+ 10, 10, 2, 2, 10, 10, 2, 2, 10, 10, 2, 2, 10, 10, 2, 2, 17, 10, 6, 2, 17, 10,
+ 6, 2, 17, 10, 6, 2, 17, 10, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 10, 10, 2, 2, 10, 10,
+ 2, 2, 10, 10, 2, 2, 10, 10, 2, 2, 17, 10, 6, 2, 17, 10, 6, 2, 17, 10, 6, 2,
+ 17, 10, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 6, 2, 6,
+ 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 16, 16, 5, 5, 16, 16, 5, 5, 10, 10, 2, 2,
+ 10, 10, 2, 2, 21, 16, 12, 5, 21, 16, 12, 5, 17, 10, 6, 2, 17, 10, 6, 2, 5, 5,
+ 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 12, 5, 12, 5, 12, 5, 12, 5, 6, 2,
+ 6, 2, 6, 2, 6, 2, 16, 16, 5, 5, 16, 16, 5, 5, 10, 10, 2, 2, 10, 10, 2, 2, 21,
+ 16, 12, 5, 21, 16, 12, 5, 17, 10, 6, 2, 17, 10, 6, 2, 5, 5, 5, 5, 5, 5, 5, 5,
+ 2, 2, 2, 2, 2, 2, 2, 2, 12, 5, 12, 5, 12, 5, 12, 5, 6, 2, 6, 2, 6, 2, 6, 2,
+ 11, 11, 3, 3, 11, 11, 3, 3, 11, 11, 3, 3, 11, 11, 3, 3, 18, 11, 7, 3, 18, 11,
+ 7, 3, 18, 11, 7, 3, 18, 11, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 11, 11, 3, 3, 11, 11,
+ 3, 3, 11, 11, 3, 3, 11, 11, 3, 3, 18, 11, 7, 3, 18, 11, 7, 3, 18, 11, 7, 3,
+ 18, 11, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 7, 3, 7,
+ 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 13, 13, 4, 4, 13, 13, 4, 4, 11, 11, 3, 3,
+ 11, 11, 3, 3, 13, 13, 4, 4, 13, 13, 4, 4, 18, 11, 7, 3, 18, 11, 7, 3, 4, 4,
+ 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 3, 7, 3,
+ 7, 3, 7, 3, 13, 13, 4, 4, 13, 13, 4, 4, 11, 11, 3, 3, 11, 11, 3, 3, 13, 13,
+ 4, 4, 13, 13, 4, 4, 18, 11, 7, 3, 18, 11, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3,
+ 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 3, 7, 3, 7, 3, 7, 3, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2,
+ 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 6, 2, 6, 2, 6, 2,
+ 6, 2, 6, 2, 6, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2,
+ 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 5, 5, 5, 5, 5, 5,
+ 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 12, 5, 12, 5, 12, 5, 12, 5, 6, 2, 6, 2, 6, 2,
+ 6, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 12, 5, 12, 5, 12, 5,
+ 12, 5, 6, 2, 6, 2, 6, 2, 6, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2,
+ 2, 12, 5, 12, 5, 12, 5, 12, 5, 6, 2, 6, 2, 6, 2, 6, 2, 5, 5, 5, 5, 5, 5, 5,
+ 5, 2, 2, 2, 2, 2, 2, 2, 2, 12, 5, 12, 5, 12, 5, 12, 5, 6, 2, 6, 2, 6, 2, 6,
+ 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7,
+ 3, 7, 3, 7, 3, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 7,
+ 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 4,
+ 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 3, 7,
+ 3, 7, 3, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4,
+ 4, 4, 4, 7, 3, 7, 3, 7, 3, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3,
+ 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 3, 7, 3, 7, 3, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3,
+ 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 3, 7, 3, 7, 3, 7, 3, 10, 10,
+ 2, 2, 10, 10, 2, 2, 10, 10, 2, 2, 10, 10, 2, 2, 17, 10, 6, 2, 17, 10, 6, 2,
+ 17, 10, 6, 2, 17, 10, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 6, 2, 10, 10, 2, 2, 10, 10, 2, 2,
+ 10, 10, 2, 2, 10, 10, 2, 2, 17, 10, 6, 2, 17, 10, 6, 2, 17, 10, 6, 2, 17, 10,
+ 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 6, 2, 6, 2, 6, 2, 6, 2,
+ 6, 2, 6, 2, 6, 2, 6, 2, 16, 16, 5, 5, 16, 16, 5, 5, 10, 10, 2, 2, 10, 10, 2,
+ 2, 21, 16, 12, 5, 21, 16, 12, 5, 17, 10, 6, 2, 17, 10, 6, 2, 5, 5, 5, 5, 5,
+ 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 12, 5, 12, 5, 12, 5, 12, 5, 6, 2, 6, 2, 6,
+ 2, 6, 2, 16, 16, 5, 5, 16, 16, 5, 5, 10, 10, 2, 2, 10, 10, 2, 2, 21, 16, 12,
+ 5, 21, 16, 12, 5, 17, 10, 6, 2, 17, 10, 6, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2,
+ 2, 2, 2, 2, 2, 2, 12, 5, 12, 5, 12, 5, 12, 5, 6, 2, 6, 2, 6, 2, 6, 2, 11, 11,
+ 3, 3, 11, 11, 3, 3, 11, 11, 3, 3, 11, 11, 3, 3, 18, 11, 7, 3, 18, 11, 7, 3,
+ 18, 11, 7, 3, 18, 11, 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 7, 3, 11, 11, 3, 3, 11, 11, 3, 3,
+ 11, 11, 3, 3, 11, 11, 3, 3, 18, 11, 7, 3, 18, 11, 7, 3, 18, 11, 7, 3, 18, 11,
+ 7, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 7, 3, 7, 3, 7, 3, 7, 3,
+ 7, 3, 7, 3, 7, 3, 7, 3, 13, 13, 4, 4, 13, 13, 4, 4, 11, 11, 3, 3, 11, 11, 3,
+ 3, 13, 13, 4, 4, 13, 13, 4, 4, 18, 11, 7, 3, 18, 11, 7, 3, 4, 4, 4, 4, 4, 4,
+ 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 3, 7, 3, 7, 3, 7, 3,
+ 13, 13, 4, 4, 13, 13, 4, 4, 11, 11, 3, 3, 11, 11, 3, 3, 13, 13, 4, 4, 13, 13,
+ 4, 4, 18, 11, 7, 3, 18, 11, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3,
+ 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 3, 7, 3, 7, 3, 7, 3, 8, 8, 8, 8, 8, 8, 8, 8,
+ 2, 2, 2, 2, 2, 2, 2, 2, 14, 8, 14, 8, 14, 8, 14, 8, 6, 2, 6, 2, 6, 2, 6, 2,
+ 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 14, 8, 14, 8, 14, 8, 14, 8,
+ 6, 2, 6, 2, 6, 2, 6, 2, 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 14,
+ 8, 14, 8, 14, 8, 14, 8, 6, 2, 6, 2, 6, 2, 6, 2, 8, 8, 8, 8, 8, 8, 8, 8, 2, 2,
+ 2, 2, 2, 2, 2, 2, 14, 8, 14, 8, 14, 8, 14, 8, 6, 2, 6, 2, 6, 2, 6, 2, 5, 5,
+ 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 12, 5, 12, 5, 12, 5, 12, 5, 6, 2,
+ 6, 2, 6, 2, 6, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 12, 5, 12,
+ 5, 12, 5, 12, 5, 6, 2, 6, 2, 6, 2, 6, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2,
+ 2, 2, 2, 2, 12, 5, 12, 5, 12, 5, 12, 5, 6, 2, 6, 2, 6, 2, 6, 2, 5, 5, 5, 5,
+ 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 12, 5, 12, 5, 12, 5, 12, 5, 6, 2, 6, 2,
+ 6, 2, 6, 2, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 3, 3, 15, 9, 15, 9, 15,
+ 9, 15, 9, 7, 3, 7, 3, 7, 3, 7, 3, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3,
+ 3, 3, 15, 9, 15, 9, 15, 9, 15, 9, 7, 3, 7, 3, 7, 3, 7, 3, 9, 9, 9, 9, 9, 9,
+ 9, 9, 3, 3, 3, 3, 3, 3, 3, 3, 15, 9, 15, 9, 15, 9, 15, 9, 7, 3, 7, 3, 7, 3,
+ 7, 3, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 3, 3, 15, 9, 15, 9, 15, 9,
+ 15, 9, 7, 3, 7, 3, 7, 3, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3,
+ 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 3, 7, 3, 7, 3, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3,
+ 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 3, 7, 3, 7, 3, 7, 3, 4, 4, 4,
+ 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 3, 7, 3, 7,
+ 3, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4,
+ 4, 7, 3, 7, 3, 7, 3, 7, 3, 19, 19, 8, 8, 19, 19, 8, 8, 10, 10, 2, 2, 10, 10,
+ 2, 2, 22, 19, 14, 8, 22, 19, 14, 8, 17, 10, 6, 2, 17, 10, 6, 2, 8, 8, 8, 8,
+ 8, 8, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 14, 8, 14, 8, 14, 8, 14, 8, 6, 2, 6, 2,
+ 6, 2, 6, 2, 19, 19, 8, 8, 19, 19, 8, 8, 10, 10, 2, 2, 10, 10, 2, 2, 22, 19,
+ 14, 8, 22, 19, 14, 8, 17, 10, 6, 2, 17, 10, 6, 2, 8, 8, 8, 8, 8, 8, 8, 8, 2,
+ 2, 2, 2, 2, 2, 2, 2, 14, 8, 14, 8, 14, 8, 14, 8, 6, 2, 6, 2, 6, 2, 6, 2, 16,
+ 16, 5, 5, 16, 16, 5, 5, 10, 10, 2, 2, 10, 10, 2, 2, 21, 16, 12, 5, 21, 16,
+ 12, 5, 17, 10, 6, 2, 17, 10, 6, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2,
+ 2, 2, 12, 5, 12, 5, 12, 5, 12, 5, 6, 2, 6, 2, 6, 2, 6, 2, 16, 16, 5, 5, 16,
+ 16, 5, 5, 10, 10, 2, 2, 10, 10, 2, 2, 21, 16, 12, 5, 21, 16, 12, 5, 17, 10,
+ 6, 2, 17, 10, 6, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 12, 5,
+ 12, 5, 12, 5, 12, 5, 6, 2, 6, 2, 6, 2, 6, 2, 20, 20, 9, 9, 20, 20, 9, 9, 11,
+ 11, 3, 3, 11, 11, 3, 3, 23, 20, 15, 9, 23, 20, 15, 9, 18, 11, 7, 3, 18, 11,
+ 7, 3, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 3, 3, 15, 9, 15, 9, 15, 9,
+ 15, 9, 7, 3, 7, 3, 7, 3, 7, 3, 20, 20, 9, 9, 20, 20, 9, 9, 11, 11, 3, 3, 11,
+ 11, 3, 3, 23, 20, 15, 9, 23, 20, 15, 9, 18, 11, 7, 3, 18, 11, 7, 3, 9, 9, 9,
+ 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 3, 3, 15, 9, 15, 9, 15, 9, 15, 9, 7, 3, 7,
+ 3, 7, 3, 7, 3, 13, 13, 4, 4, 13, 13, 4, 4, 11, 11, 3, 3, 11, 11, 3, 3, 13,
+ 13, 4, 4, 13, 13, 4, 4, 18, 11, 7, 3, 18, 11, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+ 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 3, 7, 3, 7, 3, 7, 3, 13,
+ 13, 4, 4, 13, 13, 4, 4, 11, 11, 3, 3, 11, 11, 3, 3, 13, 13, 4, 4, 13, 13, 4,
+ 4, 18, 11, 7, 3, 18, 11, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3,
+ 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 3, 7, 3, 7, 3, 7, 3, 8, 8, 8, 8, 8, 8, 8, 8, 2,
+ 2, 2, 2, 2, 2, 2, 2, 14, 8, 14, 8, 14, 8, 14, 8, 6, 2, 6, 2, 6, 2, 6, 2, 8,
+ 8, 8, 8, 8, 8, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 14, 8, 14, 8, 14, 8, 14, 8, 6,
+ 2, 6, 2, 6, 2, 6, 2, 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 14, 8,
+ 14, 8, 14, 8, 14, 8, 6, 2, 6, 2, 6, 2, 6, 2, 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, 2,
+ 2, 2, 2, 2, 2, 14, 8, 14, 8, 14, 8, 14, 8, 6, 2, 6, 2, 6, 2, 6, 2, 5, 5, 5,
+ 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 12, 5, 12, 5, 12, 5, 12, 5, 6, 2, 6,
+ 2, 6, 2, 6, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 12, 5, 12, 5,
+ 12, 5, 12, 5, 6, 2, 6, 2, 6, 2, 6, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2,
+ 2, 2, 2, 12, 5, 12, 5, 12, 5, 12, 5, 6, 2, 6, 2, 6, 2, 6, 2, 5, 5, 5, 5, 5,
+ 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 12, 5, 12, 5, 12, 5, 12, 5, 6, 2, 6, 2, 6,
+ 2, 6, 2, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 3, 3, 15, 9, 15, 9, 15, 9,
+ 15, 9, 7, 3, 7, 3, 7, 3, 7, 3, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 3,
+ 3, 15, 9, 15, 9, 15, 9, 15, 9, 7, 3, 7, 3, 7, 3, 7, 3, 9, 9, 9, 9, 9, 9, 9,
+ 9, 3, 3, 3, 3, 3, 3, 3, 3, 15, 9, 15, 9, 15, 9, 15, 9, 7, 3, 7, 3, 7, 3, 7,
+ 3, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 3, 3, 15, 9, 15, 9, 15, 9, 15,
+ 9, 7, 3, 7, 3, 7, 3, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4,
+ 4, 4, 4, 4, 4, 4, 4, 7, 3, 7, 3, 7, 3, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3,
+ 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 3, 7, 3, 7, 3, 7, 3, 4, 4, 4, 4, 4,
+ 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 3, 7, 3, 7, 3, 7,
+ 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7,
+ 3, 7, 3, 7, 3, 7, 3, 19, 19, 8, 8, 19, 19, 8, 8, 10, 10, 2, 2, 10, 10, 2, 2,
+ 22, 19, 14, 8, 22, 19, 14, 8, 17, 10, 6, 2, 17, 10, 6, 2, 8, 8, 8, 8, 8, 8,
+ 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 14, 8, 14, 8, 14, 8, 14, 8, 6, 2, 6, 2, 6, 2,
+ 6, 2, 19, 19, 8, 8, 19, 19, 8, 8, 10, 10, 2, 2, 10, 10, 2, 2, 22, 19, 14, 8,
+ 22, 19, 14, 8, 17, 10, 6, 2, 17, 10, 6, 2, 8, 8, 8, 8, 8, 8, 8, 8, 2, 2, 2,
+ 2, 2, 2, 2, 2, 14, 8, 14, 8, 14, 8, 14, 8, 6, 2, 6, 2, 6, 2, 6, 2, 16, 16, 5,
+ 5, 16, 16, 5, 5, 10, 10, 2, 2, 10, 10, 2, 2, 21, 16, 12, 5, 21, 16, 12, 5,
+ 17, 10, 6, 2, 17, 10, 6, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2,
+ 12, 5, 12, 5, 12, 5, 12, 5, 6, 2, 6, 2, 6, 2, 6, 2, 16, 16, 5, 5, 16, 16, 5,
+ 5, 10, 10, 2, 2, 10, 10, 2, 2, 21, 16, 12, 5, 21, 16, 12, 5, 17, 10, 6, 2,
+ 17, 10, 6, 2, 5, 5, 5, 5, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2, 12, 5, 12, 5,
+ 12, 5, 12, 5, 6, 2, 6, 2, 6, 2, 6, 2, 20, 20, 9, 9, 20, 20, 9, 9, 11, 11, 3,
+ 3, 11, 11, 3, 3, 23, 20, 15, 9, 23, 20, 15, 9, 18, 11, 7, 3, 18, 11, 7, 3, 9,
+ 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 3, 3, 15, 9, 15, 9, 15, 9, 15, 9, 7,
+ 3, 7, 3, 7, 3, 7, 3, 20, 20, 9, 9, 20, 20, 9, 9, 11, 11, 3, 3, 11, 11, 3, 3,
+ 23, 20, 15, 9, 23, 20, 15, 9, 18, 11, 7, 3, 18, 11, 7, 3, 9, 9, 9, 9, 9, 9,
+ 9, 9, 3, 3, 3, 3, 3, 3, 3, 3, 15, 9, 15, 9, 15, 9, 15, 9, 7, 3, 7, 3, 7, 3,
+ 7, 3, 13, 13, 4, 4, 13, 13, 4, 4, 11, 11, 3, 3, 11, 11, 3, 3, 13, 13, 4, 4,
+ 13, 13, 4, 4, 18, 11, 7, 3, 18, 11, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3,
+ 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 7, 3, 7, 3, 7, 3, 7, 3, 13, 13, 4, 4, 13,
+ 13, 4, 4, 11, 11, 3, 3, 11, 11, 3, 3, 13, 13, 4, 4, 13, 13, 4, 4, 18, 11, 7,
+ 3, 18, 11, 7, 3, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
+ 4, 4, 4, 4, 7, 3, 7, 3, 7, 3, 7, 3, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 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, 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, 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, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
+};
+
+static size_t RtemsTaskReqMode_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqMode_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsTaskReqMode_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqMode_Fixture = {
+ .setup = RtemsTaskReqMode_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqMode_Teardown_Wrap,
+ .scope = RtemsTaskReqMode_Scope,
+ .initial_context = &RtemsTaskReqMode_Instance
+};
+
+static inline RtemsTaskReqMode_Entry RtemsTaskReqMode_PopEntry(
+ RtemsTaskReqMode_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqMode_Entries[
+ RtemsTaskReqMode_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqMode_TestVariant( RtemsTaskReqMode_Context *ctx )
+{
+ RtemsTaskReqMode_Pre_PrevMode_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqMode_Pre_PreemptCur_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqMode_Pre_TimesliceCur_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTaskReqMode_Pre_ASRCur_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsTaskReqMode_Pre_IntLvlCur_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsTaskReqMode_Pre_Preempt_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsTaskReqMode_Pre_Timeslice_Prepare( ctx, ctx->Map.pcs[ 6 ] );
+ RtemsTaskReqMode_Pre_ASR_Prepare( ctx, ctx->Map.pcs[ 7 ] );
+ RtemsTaskReqMode_Pre_IntLvl_Prepare( ctx, ctx->Map.pcs[ 8 ] );
+ RtemsTaskReqMode_Pre_PreemptMsk_Prepare( ctx, ctx->Map.pcs[ 9 ] );
+ RtemsTaskReqMode_Pre_TimesliceMsk_Prepare( ctx, ctx->Map.pcs[ 10 ] );
+ RtemsTaskReqMode_Pre_ASRMsk_Prepare( ctx, ctx->Map.pcs[ 11 ] );
+ RtemsTaskReqMode_Pre_IntLvlMsk_Prepare( ctx, ctx->Map.pcs[ 12 ] );
+ RtemsTaskReqMode_Action( ctx );
+ RtemsTaskReqMode_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsTaskReqMode_Post_Preempt_Check( ctx, ctx->Map.entry.Post_Preempt );
+ RtemsTaskReqMode_Post_ASR_Check( ctx, ctx->Map.entry.Post_ASR );
+ RtemsTaskReqMode_Post_PMVar_Check( ctx, ctx->Map.entry.Post_PMVar );
+ RtemsTaskReqMode_Post_Mode_Check( ctx, ctx->Map.entry.Post_Mode );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqMode( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTaskReqMode, &RtemsTaskReqMode_Fixture )
+{
+ RtemsTaskReqMode_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsTaskReqMode_Pre_PrevMode_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsTaskReqMode_Pre_PrevMode_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsTaskReqMode_Pre_PreemptCur_Yes;
+ ctx->Map.pcs[ 1 ] < RtemsTaskReqMode_Pre_PreemptCur_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsTaskReqMode_Pre_TimesliceCur_Yes;
+ ctx->Map.pcs[ 2 ] < RtemsTaskReqMode_Pre_TimesliceCur_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsTaskReqMode_Pre_ASRCur_Yes;
+ ctx->Map.pcs[ 3 ] < RtemsTaskReqMode_Pre_ASRCur_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = RtemsTaskReqMode_Pre_IntLvlCur_Zero;
+ ctx->Map.pcs[ 4 ] < RtemsTaskReqMode_Pre_IntLvlCur_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 5 ] = RtemsTaskReqMode_Pre_Preempt_Yes;
+ ctx->Map.pcs[ 5 ] < RtemsTaskReqMode_Pre_Preempt_NA;
+ ++ctx->Map.pcs[ 5 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 6 ] = RtemsTaskReqMode_Pre_Timeslice_Yes;
+ ctx->Map.pcs[ 6 ] < RtemsTaskReqMode_Pre_Timeslice_NA;
+ ++ctx->Map.pcs[ 6 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 7 ] = RtemsTaskReqMode_Pre_ASR_Yes;
+ ctx->Map.pcs[ 7 ] < RtemsTaskReqMode_Pre_ASR_NA;
+ ++ctx->Map.pcs[ 7 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 8 ] = RtemsTaskReqMode_Pre_IntLvl_Zero;
+ ctx->Map.pcs[ 8 ] < RtemsTaskReqMode_Pre_IntLvl_NA;
+ ++ctx->Map.pcs[ 8 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 9 ] = RtemsTaskReqMode_Pre_PreemptMsk_Yes;
+ ctx->Map.pcs[ 9 ] < RtemsTaskReqMode_Pre_PreemptMsk_NA;
+ ++ctx->Map.pcs[ 9 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 10 ] = RtemsTaskReqMode_Pre_TimesliceMsk_Yes;
+ ctx->Map.pcs[ 10 ] < RtemsTaskReqMode_Pre_TimesliceMsk_NA;
+ ++ctx->Map.pcs[ 10 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 11 ] = RtemsTaskReqMode_Pre_ASRMsk_Yes;
+ ctx->Map.pcs[ 11 ] < RtemsTaskReqMode_Pre_ASRMsk_NA;
+ ++ctx->Map.pcs[ 11 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 12 ] = RtemsTaskReqMode_Pre_IntLvlMsk_Yes;
+ ctx->Map.pcs[ 12 ] < RtemsTaskReqMode_Pre_IntLvlMsk_NA;
+ ++ctx->Map.pcs[ 12 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqMode_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsTaskReqMode_Prepare( ctx );
+ RtemsTaskReqMode_TestVariant( ctx );
+ RtemsTaskReqMode_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-performance.c b/testsuites/validation/tc-task-performance.c
new file mode 100644
index 0000000000..3fac8f4f4e
--- /dev/null
+++ b/testsuites/validation/tc-task-performance.c
@@ -0,0 +1,1152 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskValPerf
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskValPerf spec:/rtems/task/val/perf
+ *
+ * @ingroup TestsuitesPerformanceNoClock0
+ *
+ * @brief This test case provides a context to run @ref RTEMSAPIClassicTasks
+ * performance tests.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/rtems/task/val/perf test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides a worker identifier.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member provides a second worker identifier.
+ */
+ rtems_id worker_2_id;
+
+ /**
+ * @brief This member provides a status code.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member references the measure runtime context.
+ */
+ T_measure_runtime_context *context;
+
+ /**
+ * @brief This member provides the measure runtime request.
+ */
+ T_measure_runtime_request request;
+
+ /**
+ * @brief This member provides an optional measurement begin time point.
+ */
+ T_ticks begin;
+
+ /**
+ * @brief This member provides an optional measurement end time point.
+ */
+ T_ticks end;
+} RtemsTaskValPerf_Context;
+
+static RtemsTaskValPerf_Context
+ RtemsTaskValPerf_Instance;
+
+#define EVENT_RESTART RTEMS_EVENT_0
+
+#define EVENT_SET_END RTEMS_EVENT_1
+
+#define EVENT_BUSY RTEMS_EVENT_2
+
+typedef RtemsTaskValPerf_Context Context;
+
+RTEMS_ALIGNED( RTEMS_TASK_STORAGE_ALIGNMENT ) static char task_storage[
+ RTEMS_TASK_STORAGE_SIZE(
+ TEST_MAXIMUM_TLS_SIZE + TEST_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_ATTRIBUTES
+ )
+];
+
+static const rtems_task_config config = {
+ .name = OBJECT_NAME,
+ .initial_priority = PRIO_NORMAL,
+ .storage_area = task_storage,
+ .storage_size = sizeof( task_storage ),
+ .maximum_thread_local_storage_size = 0,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = RTEMS_DEFAULT_ATTRIBUTES
+};
+
+static void Send( const Context *ctx, rtems_event_set events )
+{
+ SendEvents( ctx->worker_id, events );
+}
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+ ctx->end = T_tick();
+
+ while ( true ) {
+ rtems_event_set events;
+ T_ticks ticks;
+
+ events = ReceiveAnyEvents();
+ ticks = T_tick();
+
+ if ( ( events & EVENT_RESTART ) != 0 ) {
+ ctx->begin = T_tick();
+ (void) rtems_task_restart( RTEMS_SELF, (rtems_task_argument) ctx );
+ }
+
+ if ( ( events & EVENT_SET_END ) != 0 ) {
+ ctx->end = ticks;
+ }
+
+ if ( ( events & EVENT_BUSY ) != 0 ) {
+ (void) _CPU_Thread_Idle_body( 0 );
+ }
+ }
+}
+
+static void RtemsTaskValPerf_Setup_Context( RtemsTaskValPerf_Context *ctx )
+{
+ T_measure_runtime_config config;
+
+ memset( &config, 0, sizeof( config ) );
+ config.sample_count = 100;
+ ctx->request.arg = ctx;
+ ctx->request.flags = T_MEASURE_RUNTIME_REPORT_SAMPLES;
+ ctx->context = T_measure_runtime_create( &config );
+ T_assert_not_null( ctx->context );
+}
+
+/**
+ * @brief Set the runner priority.
+ */
+static void RtemsTaskValPerf_Setup( RtemsTaskValPerf_Context *ctx )
+{
+ SetSelfPriority( PRIO_NORMAL );
+}
+
+static void RtemsTaskValPerf_Setup_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskValPerf_Setup_Context( ctx );
+ RtemsTaskValPerf_Setup( ctx );
+}
+
+/**
+ * @brief Restore the runner priority.
+ */
+static void RtemsTaskValPerf_Teardown( RtemsTaskValPerf_Context *ctx )
+{
+ RestoreRunnerPriority();
+}
+
+static void RtemsTaskValPerf_Teardown_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskValPerf_Teardown( ctx );
+}
+
+static T_fixture RtemsTaskValPerf_Fixture = {
+ .setup = RtemsTaskValPerf_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskValPerf_Teardown_Wrap,
+ .scope = NULL,
+ .initial_context = &RtemsTaskValPerf_Instance
+};
+
+/**
+ * @defgroup RtemsTaskReqPerfConstruct spec:/rtems/task/req/perf-construct
+ *
+ * @{
+ */
+
+/**
+ * @brief Construct a worker task.
+ */
+static void RtemsTaskReqPerfConstruct_Body( RtemsTaskValPerf_Context *ctx )
+{
+ ctx->status = rtems_task_construct( &config, &ctx->worker_id );
+}
+
+static void RtemsTaskReqPerfConstruct_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfConstruct_Body( ctx );
+}
+
+/**
+ * @brief Delete the worker. Discard samples interrupted by a clock tick.
+ */
+static bool RtemsTaskReqPerfConstruct_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ DeleteTask( ctx->worker_id );
+ KillZombies();
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfConstruct_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfConstruct_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/** @} */
+
+/**
+ * @defgroup RtemsTaskReqPerfRestart spec:/rtems/task/req/perf-restart
+ *
+ * @{
+ */
+
+/**
+ * @brief Create and start a worker task.
+ */
+static void RtemsTaskReqPerfRestart_Prepare( RtemsTaskValPerf_Context *ctx )
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+/**
+ * @brief Restart the worker task.
+ */
+static void RtemsTaskReqPerfRestart_Body( RtemsTaskValPerf_Context *ctx )
+{
+ ctx->status = rtems_task_restart(
+ ctx->worker_id,
+ (rtems_task_argument) ctx
+ );
+}
+
+static void RtemsTaskReqPerfRestart_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfRestart_Body( ctx );
+}
+
+/**
+ * @brief Discard samples interrupted by a clock tick.
+ */
+static bool RtemsTaskReqPerfRestart_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfRestart_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfRestart_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/**
+ * @brief Delete the worker task.
+ */
+static void RtemsTaskReqPerfRestart_Cleanup( RtemsTaskValPerf_Context *ctx )
+{
+ DeleteTask( ctx->worker_id );
+}
+
+/** @} */
+
+/**
+ * @defgroup RtemsTaskReqPerfRestartPreempt \
+ * spec:/rtems/task/req/perf-restart-preempt
+ *
+ * @{
+ */
+
+/**
+ * @brief Create and start a worker task.
+ */
+static void RtemsTaskReqPerfRestartPreempt_Prepare(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+/**
+ * @brief Restart the worker task.
+ */
+static void RtemsTaskReqPerfRestartPreempt_Body(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->begin = T_tick();
+ ctx->status = rtems_task_restart(
+ ctx->worker_id,
+ (rtems_task_argument) ctx
+ );
+}
+
+static void RtemsTaskReqPerfRestartPreempt_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfRestartPreempt_Body( ctx );
+}
+
+/**
+ * @brief Set the measured runtime. Discard samples interrupted by a clock
+ * tick.
+ */
+static bool RtemsTaskReqPerfRestartPreempt_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfRestartPreempt_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfRestartPreempt_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/**
+ * @brief Delete the worker task.
+ */
+static void RtemsTaskReqPerfRestartPreempt_Cleanup(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ DeleteTask( ctx->worker_id );
+}
+
+/** @} */
+
+/**
+ * @defgroup RtemsTaskReqPerfRestartSelf spec:/rtems/task/req/perf-restart-self
+ *
+ * @{
+ */
+
+/**
+ * @brief Create and start a worker task.
+ */
+static void RtemsTaskReqPerfRestartSelf_Prepare(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+/**
+ * @brief Restart the worker task.
+ */
+static void RtemsTaskReqPerfRestartSelf_Body( RtemsTaskValPerf_Context *ctx )
+{
+ Send( ctx, EVENT_RESTART );
+}
+
+static void RtemsTaskReqPerfRestartSelf_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfRestartSelf_Body( ctx );
+}
+
+/**
+ * @brief Set the measured runtime. Discard samples interrupted by a clock
+ * tick.
+ */
+static bool RtemsTaskReqPerfRestartSelf_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfRestartSelf_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfRestartSelf_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/**
+ * @brief Delete the worker task.
+ */
+static void RtemsTaskReqPerfRestartSelf_Cleanup(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ DeleteTask( ctx->worker_id );
+}
+
+/** @} */
+
+#if defined(RTEMS_SMP)
+/**
+ * @defgroup RtemsTaskReqPerfSetSchedulerMove \
+ * spec:/rtems/task/req/perf-set-scheduler-move
+ *
+ * @{
+ */
+
+/**
+ * @brief Set the runner affinity.
+ */
+static void RtemsTaskReqPerfSetSchedulerMove_Prepare(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ SetSelfAffinityAll();
+}
+
+/**
+ * @brief Set the scheduler of the runner.
+ */
+static void RtemsTaskReqPerfSetSchedulerMove_Body(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->status = rtems_task_set_scheduler(
+ RTEMS_SELF,
+ SCHEDULER_B_ID,
+ PRIO_NORMAL
+ );
+}
+
+static void RtemsTaskReqPerfSetSchedulerMove_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfSetSchedulerMove_Body( ctx );
+}
+
+/**
+ * @brief Discard samples interrupted by a clock tick.
+ */
+static bool RtemsTaskReqPerfSetSchedulerMove_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_NORMAL );
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfSetSchedulerMove_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfSetSchedulerMove_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/**
+ * @brief Restore the runner affinity.
+ */
+static void RtemsTaskReqPerfSetSchedulerMove_Cleanup(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ SetSelfAffinityOne( 0 );
+}
+
+/** @} */
+#endif
+
+/**
+ * @defgroup RtemsTaskReqPerfSetSchedulerNop \
+ * spec:/rtems/task/req/perf-set-scheduler-nop
+ *
+ * @{
+ */
+
+/**
+ * @brief Set the scheduler of the runner.
+ */
+static void RtemsTaskReqPerfSetSchedulerNop_Body(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->status = rtems_task_set_scheduler(
+ RTEMS_SELF,
+ SCHEDULER_A_ID,
+ PRIO_NORMAL
+ );
+}
+
+static void RtemsTaskReqPerfSetSchedulerNop_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfSetSchedulerNop_Body( ctx );
+}
+
+/**
+ * @brief Discard samples interrupted by a clock tick.
+ */
+static bool RtemsTaskReqPerfSetSchedulerNop_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfSetSchedulerNop_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfSetSchedulerNop_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/** @} */
+
+#if defined(RTEMS_SMP)
+/**
+ * @defgroup RtemsTaskReqPerfSetSchedulerOther \
+ * spec:/rtems/task/req/perf-set-scheduler-other
+ *
+ * @{
+ */
+
+/**
+ * @brief Create and start a worker task for scheduler B.
+ */
+static void RtemsTaskReqPerfSetSchedulerOther_Prepare(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_NORMAL );
+ SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+/**
+ * @brief Move the worker to scheduler A.
+ */
+static void RtemsTaskReqPerfSetSchedulerOther_Body(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->status = rtems_task_set_scheduler(
+ ctx->worker_id,
+ SCHEDULER_A_ID,
+ PRIO_LOW
+ );
+}
+
+static void RtemsTaskReqPerfSetSchedulerOther_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfSetSchedulerOther_Body( ctx );
+}
+
+/**
+ * @brief Move the worker back to scheduler B. Discard samples interrupted by
+ * a clock tick.
+ */
+static bool RtemsTaskReqPerfSetSchedulerOther_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfSetSchedulerOther_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfSetSchedulerOther_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/**
+ * @brief Delete the worker task.
+ */
+static void RtemsTaskReqPerfSetSchedulerOther_Cleanup(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ DeleteTask( ctx->worker_id );
+}
+
+/** @} */
+#endif
+
+#if defined(RTEMS_SMP)
+/**
+ * @defgroup RtemsTaskReqPerfSetSchedulerPreempt \
+ * spec:/rtems/task/req/perf-set-scheduler-preempt
+ *
+ * @{
+ */
+
+/**
+ * @brief Create and start two worker tasks for scheduler B. Make the second
+ * worker busy.
+ */
+static void RtemsTaskReqPerfSetSchedulerPreempt_Prepare(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_NORMAL );
+ SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+ StartTask( ctx->worker_id, Worker, ctx );
+ Send( ctx, EVENT_SET_END );
+ WaitForNextTask( 1, ctx->worker_id );
+
+ ctx->worker_2_id = CreateTask( "WRK2", PRIO_NORMAL );
+ SetScheduler( ctx->worker_2_id, SCHEDULER_B_ID, PRIO_HIGH );
+ StartTask( ctx->worker_2_id, Worker, ctx );
+ SendEvents( ctx->worker_2_id, EVENT_BUSY );
+ SuspendTask( ctx->worker_2_id );
+}
+
+/**
+ * @brief Move the worker to scheduler B. Make the worker ready to set the end
+ * time.
+ */
+static void RtemsTaskReqPerfSetSchedulerPreempt_Setup(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ResumeTask( ctx->worker_2_id );
+ SetScheduler( ctx->worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+ Send( ctx, EVENT_SET_END );
+}
+
+static void RtemsTaskReqPerfSetSchedulerPreempt_Setup_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfSetSchedulerPreempt_Setup( ctx );
+}
+
+/**
+ * @brief Move the worker to scheduler A.
+ */
+static void RtemsTaskReqPerfSetSchedulerPreempt_Body(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ctx->begin = T_tick();
+ ctx->status = rtems_task_set_scheduler(
+ ctx->worker_id,
+ SCHEDULER_A_ID,
+ PRIO_HIGH
+ );
+}
+
+static void RtemsTaskReqPerfSetSchedulerPreempt_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfSetSchedulerPreempt_Body( ctx );
+}
+
+/**
+ * @brief Set the measured runtime. Discard samples interrupted by a clock
+ * tick.
+ */
+static bool RtemsTaskReqPerfSetSchedulerPreempt_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+ SuspendTask( ctx->worker_2_id );
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfSetSchedulerPreempt_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfSetSchedulerPreempt_Teardown(
+ ctx,
+ delta,
+ tic,
+ toc,
+ retry
+ );
+}
+
+/**
+ * @brief Delete the worker tasks.
+ */
+static void RtemsTaskReqPerfSetSchedulerPreempt_Cleanup(
+ RtemsTaskValPerf_Context *ctx
+)
+{
+ ResumeTask( ctx->worker_2_id );
+ DeleteTask( ctx->worker_2_id );
+ DeleteTask( ctx->worker_id );
+}
+
+/** @} */
+#endif
+
+/**
+ * @defgroup RtemsTaskReqPerfStart spec:/rtems/task/req/perf-start
+ *
+ * @{
+ */
+
+/**
+ * @brief Create a worker task.
+ */
+static void RtemsTaskReqPerfStart_Setup( RtemsTaskValPerf_Context *ctx )
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+}
+
+static void RtemsTaskReqPerfStart_Setup_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfStart_Setup( ctx );
+}
+
+/**
+ * @brief Start the worker task.
+ */
+static void RtemsTaskReqPerfStart_Body( RtemsTaskValPerf_Context *ctx )
+{
+ ctx->status = rtems_task_start(
+ ctx->worker_id,
+ Worker,
+ (rtems_task_argument) ctx
+ );
+}
+
+static void RtemsTaskReqPerfStart_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfStart_Body( ctx );
+}
+
+/**
+ * @brief Delete the worker. Discard samples interrupted by a clock tick.
+ */
+static bool RtemsTaskReqPerfStart_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ DeleteTask( ctx->worker_id );
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfStart_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfStart_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/** @} */
+
+/**
+ * @defgroup RtemsTaskReqPerfStartPreempt \
+ * spec:/rtems/task/req/perf-start-preempt
+ *
+ * @{
+ */
+
+/**
+ * @brief Create a worker task.
+ */
+static void RtemsTaskReqPerfStartPreempt_Setup( RtemsTaskValPerf_Context *ctx )
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+}
+
+static void RtemsTaskReqPerfStartPreempt_Setup_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfStartPreempt_Setup( ctx );
+}
+
+/**
+ * @brief Start the worker task.
+ */
+static void RtemsTaskReqPerfStartPreempt_Body( RtemsTaskValPerf_Context *ctx )
+{
+ ctx->begin = T_tick();
+ ctx->status = rtems_task_start(
+ ctx->worker_id,
+ Worker,
+ (rtems_task_argument) ctx
+ );
+}
+
+static void RtemsTaskReqPerfStartPreempt_Body_Wrap( void *arg )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ RtemsTaskReqPerfStartPreempt_Body( ctx );
+}
+
+/**
+ * @brief Set the measured runtime. Delete the worker. Discard samples
+ * interrupted by a clock tick.
+ */
+static bool RtemsTaskReqPerfStartPreempt_Teardown(
+ RtemsTaskValPerf_Context *ctx,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ T_quiet_rsc_success( ctx->status );
+
+ *delta = ctx->end - ctx->begin;
+ DeleteTask( ctx->worker_id );
+
+ return tic == toc;
+}
+
+static bool RtemsTaskReqPerfStartPreempt_Teardown_Wrap(
+ void *arg,
+ T_ticks *delta,
+ uint32_t tic,
+ uint32_t toc,
+ unsigned int retry
+)
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = arg;
+ return RtemsTaskReqPerfStartPreempt_Teardown( ctx, delta, tic, toc, retry );
+}
+
+/** @} */
+
+/**
+ * @fn void T_case_body_RtemsTaskValPerf( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTaskValPerf, &RtemsTaskValPerf_Fixture )
+{
+ RtemsTaskValPerf_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ ctx->request.name = "RtemsTaskReqPerfConstruct";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsTaskReqPerfConstruct_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfConstruct_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ RtemsTaskReqPerfRestart_Prepare( ctx );
+ ctx->request.name = "RtemsTaskReqPerfRestart";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsTaskReqPerfRestart_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfRestart_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsTaskReqPerfRestart_Cleanup( ctx );
+
+ RtemsTaskReqPerfRestartPreempt_Prepare( ctx );
+ ctx->request.name = "RtemsTaskReqPerfRestartPreempt";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsTaskReqPerfRestartPreempt_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfRestartPreempt_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsTaskReqPerfRestartPreempt_Cleanup( ctx );
+
+ RtemsTaskReqPerfRestartSelf_Prepare( ctx );
+ ctx->request.name = "RtemsTaskReqPerfRestartSelf";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsTaskReqPerfRestartSelf_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfRestartSelf_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsTaskReqPerfRestartSelf_Cleanup( ctx );
+
+ #if defined(RTEMS_SMP)
+ RtemsTaskReqPerfSetSchedulerMove_Prepare( ctx );
+ ctx->request.name = "RtemsTaskReqPerfSetSchedulerMove";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsTaskReqPerfSetSchedulerMove_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfSetSchedulerMove_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsTaskReqPerfSetSchedulerMove_Cleanup( ctx );
+ #endif
+
+ ctx->request.name = "RtemsTaskReqPerfSetSchedulerNop";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsTaskReqPerfSetSchedulerNop_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfSetSchedulerNop_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ #if defined(RTEMS_SMP)
+ RtemsTaskReqPerfSetSchedulerOther_Prepare( ctx );
+ ctx->request.name = "RtemsTaskReqPerfSetSchedulerOther";
+ ctx->request.setup = NULL;
+ ctx->request.body = RtemsTaskReqPerfSetSchedulerOther_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfSetSchedulerOther_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsTaskReqPerfSetSchedulerOther_Cleanup( ctx );
+ #endif
+
+ #if defined(RTEMS_SMP)
+ RtemsTaskReqPerfSetSchedulerPreempt_Prepare( ctx );
+ ctx->request.name = "RtemsTaskReqPerfSetSchedulerPreempt";
+ ctx->request.setup = RtemsTaskReqPerfSetSchedulerPreempt_Setup_Wrap;
+ ctx->request.body = RtemsTaskReqPerfSetSchedulerPreempt_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfSetSchedulerPreempt_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+ RtemsTaskReqPerfSetSchedulerPreempt_Cleanup( ctx );
+ #endif
+
+ ctx->request.name = "RtemsTaskReqPerfStart";
+ ctx->request.setup = RtemsTaskReqPerfStart_Setup_Wrap;
+ ctx->request.body = RtemsTaskReqPerfStart_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfStart_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+
+ ctx->request.name = "RtemsTaskReqPerfStartPreempt";
+ ctx->request.setup = RtemsTaskReqPerfStartPreempt_Setup_Wrap;
+ ctx->request.body = RtemsTaskReqPerfStartPreempt_Body_Wrap;
+ ctx->request.teardown = RtemsTaskReqPerfStartPreempt_Teardown_Wrap;
+ T_measure_runtime( ctx->context, &ctx->request );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-restart.c b/testsuites/validation/tc-task-restart.c
new file mode 100644
index 0000000000..c915f01a49
--- /dev/null
+++ b/testsuites/validation/tc-task-restart.c
@@ -0,0 +1,2760 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqRestart
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <limits.h>
+#include <rtems.h>
+#include <setjmp.h>
+#include <rtems/test-scheduler.h>
+#include <rtems/score/statesimpl.h>
+#include <rtems/score/threaddispatch.h>
+#include <rtems/score/threadimpl.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqRestart spec:/rtems/task/req/restart
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqRestart_Pre_Id_Invalid,
+ RtemsTaskReqRestart_Pre_Id_Executing,
+ RtemsTaskReqRestart_Pre_Id_Other,
+ RtemsTaskReqRestart_Pre_Id_NA
+} RtemsTaskReqRestart_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqRestart_Pre_Dormant_Yes,
+ RtemsTaskReqRestart_Pre_Dormant_No,
+ RtemsTaskReqRestart_Pre_Dormant_NA
+} RtemsTaskReqRestart_Pre_Dormant;
+
+typedef enum {
+ RtemsTaskReqRestart_Pre_Suspended_Yes,
+ RtemsTaskReqRestart_Pre_Suspended_No,
+ RtemsTaskReqRestart_Pre_Suspended_NA
+} RtemsTaskReqRestart_Pre_Suspended;
+
+typedef enum {
+ RtemsTaskReqRestart_Pre_Restarting_Yes,
+ RtemsTaskReqRestart_Pre_Restarting_No,
+ RtemsTaskReqRestart_Pre_Restarting_NA
+} RtemsTaskReqRestart_Pre_Restarting;
+
+typedef enum {
+ RtemsTaskReqRestart_Pre_Terminating_Yes,
+ RtemsTaskReqRestart_Pre_Terminating_No,
+ RtemsTaskReqRestart_Pre_Terminating_NA
+} RtemsTaskReqRestart_Pre_Terminating;
+
+typedef enum {
+ RtemsTaskReqRestart_Pre_Protected_Yes,
+ RtemsTaskReqRestart_Pre_Protected_No,
+ RtemsTaskReqRestart_Pre_Protected_NA
+} RtemsTaskReqRestart_Pre_Protected;
+
+typedef enum {
+ RtemsTaskReqRestart_Pre_Context_Task,
+ RtemsTaskReqRestart_Pre_Context_Interrupt,
+ RtemsTaskReqRestart_Pre_Context_NestedRequest,
+ RtemsTaskReqRestart_Pre_Context_NA
+} RtemsTaskReqRestart_Pre_Context;
+
+typedef enum {
+ RtemsTaskReqRestart_Pre_State_Ready,
+ RtemsTaskReqRestart_Pre_State_Blocked,
+ RtemsTaskReqRestart_Pre_State_Enqueued,
+ RtemsTaskReqRestart_Pre_State_NA
+} RtemsTaskReqRestart_Pre_State;
+
+typedef enum {
+ RtemsTaskReqRestart_Pre_Timer_Inactive,
+ RtemsTaskReqRestart_Pre_Timer_Active,
+ RtemsTaskReqRestart_Pre_Timer_NA
+} RtemsTaskReqRestart_Pre_Timer;
+
+typedef enum {
+ RtemsTaskReqRestart_Pre_RealPriority_Initial,
+ RtemsTaskReqRestart_Pre_RealPriority_Changed,
+ RtemsTaskReqRestart_Pre_RealPriority_NA
+} RtemsTaskReqRestart_Pre_RealPriority;
+
+typedef enum {
+ RtemsTaskReqRestart_Pre_ThreadDispatch_Disabled,
+ RtemsTaskReqRestart_Pre_ThreadDispatch_Enabled,
+ RtemsTaskReqRestart_Pre_ThreadDispatch_NA
+} RtemsTaskReqRestart_Pre_ThreadDispatch;
+
+typedef enum {
+ RtemsTaskReqRestart_Post_Status_Ok,
+ RtemsTaskReqRestart_Post_Status_InvId,
+ RtemsTaskReqRestart_Post_Status_IncStat,
+ RtemsTaskReqRestart_Post_Status_NoReturn,
+ RtemsTaskReqRestart_Post_Status_NA
+} RtemsTaskReqRestart_Post_Status;
+
+typedef enum {
+ RtemsTaskReqRestart_Post_FatalError_Yes,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_FatalError_NA
+} RtemsTaskReqRestart_Post_FatalError;
+
+typedef enum {
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_Argument_Nop,
+ RtemsTaskReqRestart_Post_Argument_NA
+} RtemsTaskReqRestart_Post_Argument;
+
+typedef enum {
+ RtemsTaskReqRestart_Post_State_Dormant,
+ RtemsTaskReqRestart_Post_State_DormantSuspended,
+ RtemsTaskReqRestart_Post_State_Blocked,
+ RtemsTaskReqRestart_Post_State_Ready,
+ RtemsTaskReqRestart_Post_State_Zombie,
+ RtemsTaskReqRestart_Post_State_Nop,
+ RtemsTaskReqRestart_Post_State_NA
+} RtemsTaskReqRestart_Post_State;
+
+typedef enum {
+ RtemsTaskReqRestart_Post_Enqueued_Yes,
+ RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Enqueued_NA
+} RtemsTaskReqRestart_Post_Enqueued;
+
+typedef enum {
+ RtemsTaskReqRestart_Post_Timer_Active,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Timer_NA
+} RtemsTaskReqRestart_Post_Timer;
+
+typedef enum {
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Restarting_No,
+ RtemsTaskReqRestart_Post_Restarting_NA
+} RtemsTaskReqRestart_Post_Restarting;
+
+typedef enum {
+ RtemsTaskReqRestart_Post_Terminating_Yes,
+ RtemsTaskReqRestart_Post_Terminating_No,
+ RtemsTaskReqRestart_Post_Terminating_NA
+} RtemsTaskReqRestart_Post_Terminating;
+
+typedef enum {
+ RtemsTaskReqRestart_Post_Protected_Yes,
+ RtemsTaskReqRestart_Post_Protected_No,
+ RtemsTaskReqRestart_Post_Protected_NA
+} RtemsTaskReqRestart_Post_Protected;
+
+typedef enum {
+ RtemsTaskReqRestart_Post_RestartExtensions_Yes,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_RestartExtensions_NA
+} RtemsTaskReqRestart_Post_RestartExtensions;
+
+typedef enum {
+ RtemsTaskReqRestart_Post_TerminateExtensions_Yes,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_NA
+} RtemsTaskReqRestart_Post_TerminateExtensions;
+
+typedef struct {
+ uint64_t Skip : 1;
+ uint64_t Pre_Id_NA : 1;
+ uint64_t Pre_Dormant_NA : 1;
+ uint64_t Pre_Suspended_NA : 1;
+ uint64_t Pre_Restarting_NA : 1;
+ uint64_t Pre_Terminating_NA : 1;
+ uint64_t Pre_Protected_NA : 1;
+ uint64_t Pre_Context_NA : 1;
+ uint64_t Pre_State_NA : 1;
+ uint64_t Pre_Timer_NA : 1;
+ uint64_t Pre_RealPriority_NA : 1;
+ uint64_t Pre_ThreadDispatch_NA : 1;
+ uint64_t Post_Status : 3;
+ uint64_t Post_FatalError : 2;
+ uint64_t Post_Argument : 2;
+ uint64_t Post_State : 3;
+ uint64_t Post_Enqueued : 2;
+ uint64_t Post_Timer : 2;
+ uint64_t Post_Restarting : 2;
+ uint64_t Post_Terminating : 2;
+ uint64_t Post_Protected : 2;
+ uint64_t Post_RestartExtensions : 2;
+ uint64_t Post_TerminateExtensions : 2;
+} RtemsTaskReqRestart_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/restart test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides the scheduler operation records.
+ */
+ T_scheduler_log_10 scheduler_log;
+
+ /**
+ * @brief This member provides a jump context to resume a thread dispatch.
+ */
+ jmp_buf thread_dispatch_context;
+
+ /**
+ * @brief This member provides the context to wrap thread queue operations.
+ */
+ WrapThreadQueueContext wrap_tq_ctx;
+
+ /**
+ * @brief This member contains the identifier of the runner scheduler.
+ */
+ rtems_id scheduler_id;
+
+ /**
+ * @brief This member contains the identifier of the runner task.
+ */
+ rtems_id runner_id;
+
+ /**
+ * @brief This member contains the identifier of the mutex.
+ */
+ rtems_id mutex_id;
+
+ /**
+ * @brief This member provides an event set used to set up the blocking
+ * conditions of the task to restart.
+ */
+ rtems_event_set events;
+
+ /**
+ * @brief This member contains the identifier of the worker task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member references the TCB of the worker task.
+ */
+ rtems_tcb *worker_tcb;
+
+ /**
+ * @brief This member contains the worker state at the end of the
+ * rtems_task_restart() call.
+ */
+ States_Control worker_state;
+
+ /**
+ * @brief This member contains the worker thread life state at the end of the
+ * rtems_task_restart() call.
+ */
+ Thread_Life_state worker_life_state;
+
+ /**
+ * @brief This member contains the identifier of the deleter task.
+ */
+ rtems_id deleter_id;
+
+ /**
+ * @brief This member references the TCB of the deleter task.
+ */
+ rtems_tcb *deleter_tcb;
+
+ /**
+ * @brief This member contains the identifier of the test user extensions.
+ */
+ rtems_id extension_id;
+
+ /**
+ * @brief This member contains extension calls.
+ */
+ ExtensionCalls calls;
+
+ /**
+ * @brief This member contains extension calls after the rtems_task_restart()
+ * call.
+ */
+ ExtensionCalls calls_after_restart;
+
+ /**
+ * @brief This member contains the actual argument passed to the entry point.
+ */
+ rtems_task_argument actual_argument;
+
+ /**
+ * @brief This member contains the restart counter.
+ */
+ uint32_t restart_counter;
+
+ /**
+ * @brief If this member is true, then the worker shall be dormant before the
+ * rtems_task_restart() call.
+ */
+ bool dormant;
+
+ /**
+ * @brief If this member is true, then the worker shall be suspended before
+ * the rtems_task_restart() call.
+ */
+ bool suspended;
+
+ /**
+ * @brief If this member is true, then the thread life of the worker shall be
+ * protected before the rtems_task_restart() call.
+ */
+ bool protected;
+
+ /**
+ * @brief If this member is true, then the worker shall be restarting before
+ * the rtems_task_restart() call.
+ */
+ bool restarting;
+
+ /**
+ * @brief If this member is true, then the worker shall be terminating before
+ * the rtems_task_restart() call.
+ */
+ bool terminating;
+
+ /**
+ * @brief If this member is true, then the rtems_task_restart() shall be
+ * called from within interrupt context.
+ */
+ bool interrupt;
+
+ /**
+ * @brief If this member is true, then the rtems_task_restart() shall be
+ * called during another rtems_task_restart() call with the same task as a
+ * nested request.
+ */
+ bool nested_request;
+
+ /**
+ * @brief If this member is true, then the worker shall be blocked before the
+ * rtems_task_restart() call.
+ */
+ bool blocked;
+
+ /**
+ * @brief If this member is true, then the worker shall be enqueued on a wait
+ * queue before the rtems_task_restart() call.
+ */
+ bool enqueued;
+
+ /**
+ * @brief If this member is true, then the timer of the worker shall be
+ * active before the rtems_task_restart() call.
+ */
+ bool timer_active;
+
+ /**
+ * @brief If this member is true, then the real priority of the worker shall
+ * be equal to its initial priority before the rtems_task_restart() call.
+ */
+ bool real_priority_is_initial;
+
+ /**
+ * @brief If this member is true, then thread dispatching is disabled by the
+ * worker task before the rtems_task_restart() call.
+ */
+ bool dispatch_disabled;
+
+ /**
+ * @brief If this member is true, then it is expected to delete the worker.
+ */
+ bool delete_worker_expected;
+
+ /**
+ * @brief This member contains the return value of the rtems_task_restart()
+ * call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 11 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 11 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqRestart_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqRestart_Context;
+
+static RtemsTaskReqRestart_Context
+ RtemsTaskReqRestart_Instance;
+
+static const char * const RtemsTaskReqRestart_PreDesc_Id[] = {
+ "Invalid",
+ "Executing",
+ "Other",
+ "NA"
+};
+
+static const char * const RtemsTaskReqRestart_PreDesc_Dormant[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqRestart_PreDesc_Suspended[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqRestart_PreDesc_Restarting[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqRestart_PreDesc_Terminating[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqRestart_PreDesc_Protected[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqRestart_PreDesc_Context[] = {
+ "Task",
+ "Interrupt",
+ "NestedRequest",
+ "NA"
+};
+
+static const char * const RtemsTaskReqRestart_PreDesc_State[] = {
+ "Ready",
+ "Blocked",
+ "Enqueued",
+ "NA"
+};
+
+static const char * const RtemsTaskReqRestart_PreDesc_Timer[] = {
+ "Inactive",
+ "Active",
+ "NA"
+};
+
+static const char * const RtemsTaskReqRestart_PreDesc_RealPriority[] = {
+ "Initial",
+ "Changed",
+ "NA"
+};
+
+static const char * const RtemsTaskReqRestart_PreDesc_ThreadDispatch[] = {
+ "Disabled",
+ "Enabled",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqRestart_PreDesc[] = {
+ RtemsTaskReqRestart_PreDesc_Id,
+ RtemsTaskReqRestart_PreDesc_Dormant,
+ RtemsTaskReqRestart_PreDesc_Suspended,
+ RtemsTaskReqRestart_PreDesc_Restarting,
+ RtemsTaskReqRestart_PreDesc_Terminating,
+ RtemsTaskReqRestart_PreDesc_Protected,
+ RtemsTaskReqRestart_PreDesc_Context,
+ RtemsTaskReqRestart_PreDesc_State,
+ RtemsTaskReqRestart_PreDesc_Timer,
+ RtemsTaskReqRestart_PreDesc_RealPriority,
+ RtemsTaskReqRestart_PreDesc_ThreadDispatch,
+ NULL
+};
+
+#if CPU_SIZEOF_POINTER > 4
+#define RESTART_ARGUMENT 0xfedcba0987654321U
+#else
+#define RESTART_ARGUMENT 0x87654321U
+#endif
+
+#define UNSET_ARGUMENT 1
+
+typedef RtemsTaskReqRestart_Context Context;
+
+static void PrepareRealPriority( Context *ctx )
+{
+ if ( !ctx->real_priority_is_initial ) {
+ SetScheduler( ctx->worker_id, ctx->scheduler_id, PRIO_LOW );
+ SetPriority( ctx->worker_id, PRIO_NORMAL );
+ }
+}
+
+static void CaptureWorkerState( Context *ctx )
+{
+ T_scheduler_log *log;
+
+ log = T_scheduler_record( NULL );
+
+ if ( log != NULL ) {
+ T_eq_ptr( &log->header, &ctx->scheduler_log.header );
+
+ ctx->worker_state = ctx->worker_tcb->current_state;
+ ctx->worker_life_state = ctx->worker_tcb->Life.state;
+ CopyExtensionCalls( &ctx->calls, &ctx->calls_after_restart );
+ }
+}
+
+static void VerifyTaskPreparation( const Context *ctx )
+{
+ if ( ctx->id != INVALID_ID ) {
+ States_Control state;
+ Thread_Life_state life_state;
+
+ state = STATES_READY;
+ life_state = ctx->worker_tcb->Life.state;
+
+ if ( ctx->suspended ) {
+ state |= STATES_SUSPENDED;
+ }
+
+ if ( ctx->dormant ) {
+ T_eq_int( life_state, 0 );
+ state |= STATES_DORMANT;
+ } else {
+ T_eq( ctx->protected, ( life_state & THREAD_LIFE_PROTECTED ) != 0 );
+ T_eq( ctx->restarting, ( life_state & THREAD_LIFE_RESTARTING ) != 0 );
+ T_eq( ctx->terminating, ( life_state & THREAD_LIFE_TERMINATING ) != 0 );
+
+ if ( ctx->blocked ) {
+ if ( ctx->enqueued ) {
+ state |= STATES_WAITING_FOR_MUTEX;
+ } else {
+ state |= STATES_WAITING_FOR_EVENT;
+ }
+ }
+
+ if ( ctx->nested_request ) {
+ state |= STATES_LIFE_IS_CHANGING;
+ }
+ }
+
+ T_eq_u32( ctx->worker_tcb->current_state, state );
+ }
+}
+
+static void Restart( void *arg )
+{
+ Context *ctx;
+ T_scheduler_log *log;
+
+ ctx = arg;
+
+ if ( ctx->suspended && ctx->id != INVALID_ID ) {
+ if ( ctx->id != RTEMS_SELF || ctx->interrupt ) {
+ SuspendTask( ctx->worker_id );
+ } else {
+ Per_CPU_Control *cpu_self;
+
+ /*
+ * Where the system was built with SMP support enabled, a suspended
+ * executing thread during the rtems_task_restart() call can happen
+ * if the thread was suspended by another processor and the
+ * inter-processor interrupt did not yet arrive. Where the system was
+ * built with SMP support disabled, this state cannot happen with the
+ * current implementation. However, we still specify and validate this
+ * behaviour unconditionally since there exist alternative
+ * implementations which would lead to such a state if the executing
+ * thread is suspended by an ISR.
+ */
+ cpu_self = _Thread_Dispatch_disable();
+ SuspendSelf();
+ cpu_self->dispatch_necessary = false;
+ _Thread_Dispatch_enable( cpu_self );
+ }
+ }
+
+ if ( ctx->dispatch_disabled ) {
+ _Thread_Dispatch_disable();
+ }
+
+ VerifyTaskPreparation( ctx );
+ ClearExtensionCalls( &ctx->calls );
+
+ log = T_scheduler_record_10( &ctx->scheduler_log );
+ T_null( log );
+
+ ctx->status = rtems_task_restart( ctx->id, RESTART_ARGUMENT );
+
+ CaptureWorkerState( ctx );
+
+ if ( ctx->dispatch_disabled ) {
+ _Thread_Dispatch_enable( _Per_CPU_Get() );
+ }
+}
+
+static void Block( Context *ctx )
+{
+ rtems_interval ticks;
+
+ if ( ctx->timer_active ) {
+ ticks = UINT32_MAX;
+ } else {
+ ticks = RTEMS_NO_TIMEOUT;
+ }
+
+ if ( ctx->enqueued ) {
+ ObtainMutexTimed( ctx->mutex_id, ticks );
+ } else {
+ /*
+ * Do not use a stack variable for the event set, since we may jump out
+ * of the directive call.
+ */
+ (void) rtems_event_receive(
+ RTEMS_ALL_EVENTS,
+ RTEMS_EVENT_ANY | RTEMS_WAIT,
+ ticks,
+ &ctx->events
+ );
+ }
+}
+
+static void BlockDone( const Context *ctx )
+{
+ if ( ctx->enqueued ) {
+ ReleaseMutex( ctx->mutex_id );
+ }
+}
+
+static void Fatal(
+ rtems_fatal_source source,
+ rtems_fatal_code code,
+ void *arg
+)
+{
+ Context *ctx;
+ Per_CPU_Control *cpu_self;
+
+ T_eq_int( source, INTERNAL_ERROR_CORE );
+ T_eq_ulong( code, INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL );
+
+ ctx = arg;
+ ++ctx->calls.fatal;
+ T_assert_eq_int( ctx->calls.fatal, 1 );
+
+ CaptureWorkerState( ctx );
+
+ cpu_self = _Per_CPU_Get();
+ _Thread_Dispatch_unnest( cpu_self );
+ _Thread_Dispatch_direct_no_return( cpu_self );
+}
+
+static void ResumeThreadDispatch(
+ rtems_fatal_source source,
+ rtems_fatal_code code,
+ void *arg
+)
+{
+ Context *ctx;
+
+ T_eq_int( source, INTERNAL_ERROR_CORE );
+ T_eq_ulong( code, INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL );
+
+ ctx = arg;
+ SetFatalHandler( Fatal, ctx );
+ longjmp( ctx->thread_dispatch_context, 1 );
+}
+
+static void TriggerNestedRequestViaSelfRestart(
+ Context *ctx,
+ Per_CPU_Control *cpu_self
+)
+{
+ WrapThreadQueueExtract( &ctx->wrap_tq_ctx, ctx->worker_tcb );
+ SetFatalHandler( ResumeThreadDispatch, ctx );
+
+ if ( setjmp( ctx->thread_dispatch_context ) == 0 ) {
+ (void) rtems_task_restart(
+ RTEMS_SELF,
+ (rtems_task_argument) ctx
+ );
+ } else {
+ _Thread_Dispatch_unnest( cpu_self );
+ }
+}
+
+static void Signal( rtems_signal_set signals )
+{
+ Context *ctx;
+
+ (void) signals;
+ ctx = T_fixture_context();
+
+ if ( ctx->id == RTEMS_SELF ) {
+ Per_CPU_Control *cpu_self;
+
+ SetPriority( ctx->runner_id, PRIO_VERY_LOW );
+ SetPriority( ctx->deleter_id, PRIO_VERY_LOW );
+
+ if ( ctx->interrupt || ctx->nested_request ) {
+ if ( ctx->blocked ) {
+ SetFatalHandler( ResumeThreadDispatch, ctx );
+ cpu_self = _Thread_Dispatch_disable();
+
+ if ( setjmp( ctx->thread_dispatch_context ) == 0 ) {
+ Block( ctx );
+ } else {
+ _Thread_Dispatch_unnest( cpu_self );
+ }
+
+ if ( ctx->interrupt ) {
+ CallWithinISR( Restart, ctx );
+ } else {
+ TriggerNestedRequestViaSelfRestart( ctx, cpu_self );
+ }
+
+ _Thread_Dispatch_direct( cpu_self );
+ BlockDone( ctx );
+ } else {
+ if ( ctx->interrupt ) {
+ CallWithinISR( Restart, ctx );
+ } else {
+ cpu_self = _Thread_Dispatch_disable();
+ TriggerNestedRequestViaSelfRestart( ctx, cpu_self );
+ _Thread_Dispatch_direct( cpu_self );
+ }
+ }
+ } else {
+ Restart( ctx );
+ }
+ } else {
+ if ( ctx->blocked ) {
+ Block( ctx );
+ BlockDone( ctx );
+ } else if ( ctx->nested_request ) {
+ Yield();
+ } else {
+ SetPriority( ctx->runner_id, PRIO_VERY_HIGH );
+ }
+ }
+
+ if ( ctx->protected ) {
+ _Thread_Set_life_protection( 0 );
+ }
+}
+
+static void Deleter( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ if ( ctx != NULL ) {
+ if ( ctx->real_priority_is_initial ) {
+ /*
+ * We have to prevent a potential priority boost in the task delete
+ * below.
+ */
+ if ( ctx->nested_request ) {
+ /* Lower the priority to PRIO_NORMAL without an * implicit yield */
+ SetSelfPriorityNoYield( PRIO_NORMAL );
+ } else {
+ SetScheduler( ctx->worker_id, ctx->scheduler_id, PRIO_HIGH );
+ }
+ }
+
+ if ( ctx->nested_request ) {
+ WrapThreadQueueExtract( &ctx->wrap_tq_ctx, ctx->worker_tcb );
+ DeleteTask( ctx->worker_id );
+ } else {
+ DeleteTask( ctx->worker_id );
+ }
+ }
+
+ SuspendSelf();
+}
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+ rtems_status_code sc;
+
+ ctx = T_fixture_context();
+
+ if ( arg == 0 ) {
+ sc = rtems_signal_catch( Signal, RTEMS_NO_ASR );
+ T_rsc_success( sc );
+
+ if ( ctx->protected ) {
+ _Thread_Set_life_protection( THREAD_LIFE_PROTECTED );
+ }
+
+ Yield();
+ } else {
+ ctx->actual_argument = arg;
+ ++ctx->restart_counter;
+
+ CaptureWorkerState( ctx );
+ SuspendSelf();
+ }
+}
+
+static void ThreadDelete( rtems_tcb *executing, rtems_tcb *deleted )
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+ ++ctx->calls.thread_delete;
+
+ T_eq_u32( executing->Object.id, ctx->runner_id );
+
+ if ( ctx->delete_worker_expected ) {
+ T_eq_u32( deleted->Object.id, ctx->worker_id );
+ }
+}
+
+static void ThreadRestart( rtems_tcb *executing, rtems_tcb *restarted )
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+ ++ctx->calls.thread_restart;
+}
+
+static void ThreadTerminate( rtems_tcb *executing )
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+ ++ctx->calls.thread_terminate;
+
+ T_eq_u32( executing->Object.id, ctx->worker_id );
+}
+
+static const rtems_extensions_table extensions = {
+ .thread_delete = ThreadDelete,
+ .thread_restart = ThreadRestart,
+ .thread_terminate = ThreadTerminate
+};
+
+static void RtemsTaskReqRestart_Pre_Id_Prepare(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Id_Executing: {
+ /*
+ * While the ``id`` parameter is associated with the calling task.
+ */
+ ctx->id = RTEMS_SELF;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Id_Other: {
+ /*
+ * While the ``id`` parameter is associated with a task other than the
+ * calling task.
+ */
+ ctx->id = ctx->worker_id;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Pre_Dormant_Prepare(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Pre_Dormant state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Pre_Dormant_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is dormant.
+ */
+ ctx->dormant = true;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Dormant_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not dormant.
+ */
+ ctx->dormant = false;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Dormant_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Pre_Suspended_Prepare(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Pre_Suspended state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Pre_Suspended_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is suspended.
+ */
+ ctx->suspended = true;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Suspended_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not suspended.
+ */
+ ctx->suspended = false;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Suspended_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Pre_Restarting_Prepare(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Pre_Restarting state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Pre_Restarting_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is restarting.
+ */
+ ctx->restarting = true;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Restarting_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not restarting.
+ */
+ ctx->restarting = false;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Restarting_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Pre_Terminating_Prepare(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Pre_Terminating state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Pre_Terminating_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is terminating.
+ */
+ ctx->terminating = true;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Terminating_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not terminating.
+ */
+ ctx->terminating = false;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Terminating_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Pre_Protected_Prepare(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Pre_Protected state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Pre_Protected_Yes: {
+ /*
+ * While thread life of the task specified by the ``id`` parameter is
+ * protected.
+ */
+ ctx->protected = true;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Protected_No: {
+ /*
+ * While thread life of the task specified by the ``id`` parameter is not
+ * protected.
+ */
+ ctx->protected = false;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Protected_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Pre_Context_Prepare(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Pre_Context state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Pre_Context_Task: {
+ /*
+ * While the rtems_task_restart() directive is called from within task
+ * context.
+ */
+ ctx->interrupt = false;
+ ctx->nested_request = false;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Context_Interrupt: {
+ /*
+ * While the rtems_task_restart() directive is called from within
+ * interrupt context.
+ */
+ ctx->interrupt = true;
+ ctx->nested_request = false;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Context_NestedRequest: {
+ /*
+ * While the rtems_task_restart() directive is called during another
+ * rtems_task_restart() call with the same task as a nested request.
+ */
+ ctx->interrupt = false;
+ ctx->nested_request = true;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Context_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Pre_State_Prepare(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Pre_State state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Pre_State_Ready: {
+ /*
+ * While the task specified by the ``id`` parameter is a ready task or
+ * scheduled task.
+ */
+ ctx->blocked = false;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_State_Blocked: {
+ /*
+ * While the task specified by the ``id`` parameter is blocked.
+ */
+ ctx->blocked = true;
+ ctx->enqueued = false;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_State_Enqueued: {
+ /*
+ * While the task specified by the ``id`` parameter is enqueued on a wait
+ * queue.
+ */
+ ctx->blocked = true;
+ ctx->enqueued = true;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_State_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Pre_Timer_Prepare(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Pre_Timer state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Pre_Timer_Inactive: {
+ /*
+ * While timer of the task specified by the ``id`` parameter is inactive.
+ */
+ ctx->timer_active = false;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Timer_Active: {
+ /*
+ * While timer of the task specified by the ``id`` parameter is active.
+ */
+ ctx->timer_active = true;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_Timer_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Pre_RealPriority_Prepare(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Pre_RealPriority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Pre_RealPriority_Initial: {
+ /*
+ * While real priority of the task specified by the ``id`` parameter is
+ * equal to the initial priority.
+ */
+ ctx->real_priority_is_initial = true;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_RealPriority_Changed: {
+ /*
+ * While real priority of the task specified by the ``id`` parameter is
+ * not equal to the initial priority.
+ */
+ ctx->real_priority_is_initial = false;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_RealPriority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Pre_ThreadDispatch_Prepare(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Pre_ThreadDispatch state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Pre_ThreadDispatch_Disabled: {
+ /*
+ * While thread dispatching is disabled for the calling task.
+ */
+ ctx->dispatch_disabled = true;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_ThreadDispatch_Enabled: {
+ /*
+ * While thread dispatching is enabled for the calling task.
+ */
+ ctx->dispatch_disabled = false;
+ break;
+ }
+
+ case RtemsTaskReqRestart_Pre_ThreadDispatch_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Post_Status_Check(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_restart() shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_restart() shall be RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Status_IncStat: {
+ /*
+ * The return status of rtems_task_restart() shall be
+ * RTEMS_INCORRECT_STATE.
+ */
+ T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Status_NoReturn: {
+ /*
+ * The rtems_task_restart() call shall not return.
+ */
+ T_rsc( ctx->status, RTEMS_NOT_IMPLEMENTED );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Post_FatalError_Check(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Post_FatalError state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Post_FatalError_Yes: {
+ /*
+ * The fatal error with a fatal source of INTERNAL_ERROR_CORE and a fatal
+ * code of INTERNAL_ERROR_BAD_THREAD_DISPATCH_DISABLE_LEVEL shall occur
+ * through the rtems_task_restart() call.
+ */
+ T_eq_u32( ctx->calls.fatal, 1 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_FatalError_Nop: {
+ /*
+ * No fatal error shall occur through the rtems_task_restart() call.
+ */
+ T_eq_u32( ctx->calls.fatal, 0 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_FatalError_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Post_Argument_Check(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Post_Argument state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Post_Argument_Set: {
+ /*
+ * The entry point argument of the task specified by the ``id`` parameter
+ * shall be set to the value specified by the ``argument`` parameter
+ * before the task is unblocked by the rtems_task_restart() call.
+ */
+ if ( ctx->restart_counter != 0 ) {
+ #if CPU_SIZEOF_POINTER > 4
+ T_eq_u64( ctx->actual_argument, RESTART_ARGUMENT );
+ #else
+ T_eq_u32( ctx->actual_argument, RESTART_ARGUMENT );
+ #endif
+
+ T_eq_u32( ctx->restart_counter, 1 );
+ } else {
+ #if CPU_SIZEOF_POINTER > 4
+ T_eq_u64(
+ ctx->worker_tcb->Start.Entry.Kinds.Numeric.argument,
+ RESTART_ARGUMENT
+ );
+ T_eq_u64( ctx->actual_argument, UNSET_ARGUMENT );
+ #else
+ T_eq_u32(
+ ctx->worker_tcb->Start.Entry.Kinds.Numeric.argument,
+ RESTART_ARGUMENT
+ );
+ T_eq_u32( ctx->actual_argument, UNSET_ARGUMENT );
+ #endif
+ }
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Argument_Nop: {
+ /*
+ * No entry point argument of a task shall be modified by the
+ * rtems_task_restart() call.
+ */
+ T_eq_u32( ctx->actual_argument, UNSET_ARGUMENT );
+ T_eq_u32( ctx->restart_counter, 0 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Argument_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Post_State_Check(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Post_State state
+)
+{
+ const T_scheduler_event *event;
+ size_t index;
+
+ index = 0;
+
+ switch ( state ) {
+ case RtemsTaskReqRestart_Post_State_Dormant: {
+ /*
+ * The state of the task specified by the ``id`` parameter shall be
+ * dormant after the rtems_task_restart() call.
+ */
+ T_eq_u32( ctx->worker_state, STATES_DORMANT )
+
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_NOP );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_State_DormantSuspended: {
+ /*
+ * The state of the task specified by the ``id`` parameter shall be
+ * dormant and suspended after the rtems_task_restart() call.
+ */
+ T_eq_u32( ctx->worker_state, STATES_DORMANT | STATES_SUSPENDED )
+
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_NOP );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_State_Blocked: {
+ /*
+ * The state of the task specified by the ``id`` parameter shall be
+ * blocked after the rtems_task_restart() call.
+ */
+ T_ne_u32( ctx->worker_state & STATES_BLOCKED, 0 )
+ T_eq_u32( ctx->worker_state & STATES_BLOCKED, ctx->worker_state )
+
+ if ( ctx->suspended && !ctx->blocked ) {
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_UNBLOCK );
+ T_eq_ptr( event->thread, ctx->worker_tcb );
+ }
+
+ if ( !ctx->real_priority_is_initial && !ctx->terminating ) {
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_UPDATE_PRIORITY );
+ T_eq_ptr( event->thread, ctx->worker_tcb );
+ }
+
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_NOP );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_State_Ready: {
+ /*
+ * The state of the task specified by the ``id`` parameter shall be ready
+ * after the rtems_task_restart() call.
+ */
+ T_eq_u32( ctx->worker_state, STATES_READY )
+
+ if ( ctx->protected ) {
+ if ( ctx->suspended ) {
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_UNBLOCK );
+ T_eq_ptr( event->thread, ctx->worker_tcb );
+ }
+ } else {
+ if ( ctx->suspended || ctx->blocked ) {
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_UNBLOCK );
+ T_eq_ptr( event->thread, ctx->worker_tcb );
+ } else {
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_BLOCK );
+ T_eq_ptr( event->thread, ctx->worker_tcb );
+
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_UNBLOCK );
+ T_eq_ptr( event->thread, ctx->worker_tcb );
+ }
+ }
+
+ if ( !ctx->real_priority_is_initial && !ctx->terminating ) {
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_UPDATE_PRIORITY );
+ T_eq_ptr( event->thread, ctx->worker_tcb );
+ }
+
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_NOP );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_State_Zombie: {
+ /*
+ * The state of the task specified by the ``id`` parameter shall be the
+ * zombie state after the rtems_task_restart() call.
+ */
+ T_eq_u32( ctx->worker_state, STATES_ZOMBIE )
+
+ if ( ctx->protected ) {
+ if ( ctx->suspended ) {
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_UNBLOCK );
+ T_eq_ptr( event->thread, ctx->worker_tcb );
+ }
+ } else {
+ if ( ctx->suspended ) {
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_UNBLOCK );
+ T_eq_ptr( event->thread, ctx->worker_tcb );
+ } else {
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_BLOCK );
+ T_eq_ptr( event->thread, ctx->worker_tcb );
+
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_UNBLOCK );
+ T_eq_ptr( event->thread, ctx->worker_tcb );
+ }
+ }
+
+ if ( !ctx->real_priority_is_initial && !ctx->terminating ) {
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_UPDATE_PRIORITY );
+ T_eq_ptr( event->thread, ctx->worker_tcb );
+ }
+
+ /* Set zombie state */
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_BLOCK );
+ T_eq_ptr( event->thread, ctx->worker_tcb );
+
+ /* Wake up deleter */
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_UNBLOCK );
+ T_eq_ptr( event->thread, ctx->deleter_tcb );
+
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_NOP );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_State_Nop: {
+ /*
+ * The state of the task specified by the ``id`` parameter shall not be
+ * modified by the rtems_task_restart() call.
+ */
+ T_ne_u32( ctx->worker_state & STATES_LIFE_IS_CHANGING, 0 )
+
+ if ( !ctx->real_priority_is_initial ) {
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_UPDATE_PRIORITY );
+ T_eq_ptr( event->thread, ctx->worker_tcb );
+ }
+
+ event = T_scheduler_next_any( &ctx->scheduler_log.header, &index );
+ T_eq_int( event->operation, T_SCHEDULER_NOP );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_State_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Post_Enqueued_Check(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Post_Enqueued state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Post_Enqueued_Yes: {
+ /*
+ * The task specified by the ``id`` parameter shall be enqueued on a wait
+ * queue after the rtems_task_restart() call.
+ */
+ T_not_null( ctx->worker_tcb->Wait.queue );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Enqueued_No: {
+ /*
+ * The task specified by the ``id`` parameter shall not be enqueued on a
+ * wait queue after the rtems_task_restart() call.
+ */
+ T_null( ctx->worker_tcb->Wait.queue );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Enqueued_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Post_Timer_Check(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Post_Timer state
+)
+{
+ TaskTimerInfo info;
+
+ switch ( state ) {
+ case RtemsTaskReqRestart_Post_Timer_Active: {
+ /*
+ * The timer of the task specified by the ``id`` parameter shall be
+ * active after the rtems_task_restart() call.
+ */
+ GetTaskTimerInfoByThread( ctx->worker_tcb, &info);
+ T_eq_int( info.state, TASK_TIMER_TICKS );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Timer_Inactive: {
+ /*
+ * The timer of the task specified by the ``id`` parameter shall be
+ * inactive after the rtems_task_restart() call.
+ */
+ GetTaskTimerInfoByThread( ctx->worker_tcb, &info);
+ T_eq_int( info.state, TASK_TIMER_INACTIVE );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Timer_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Post_Restarting_Check(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Post_Restarting state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Post_Restarting_Yes: {
+ /*
+ * The task specified by the ``id`` parameter shall be restarting after
+ * the rtems_task_restart() call.
+ */
+ T_ne_int( ctx->worker_life_state & THREAD_LIFE_RESTARTING, 0 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Restarting_No: {
+ /*
+ * The task specified by the ``id`` parameter shall not be restarting
+ * after the rtems_task_restart() call.
+ */
+ T_eq_int( ctx->worker_life_state & THREAD_LIFE_RESTARTING, 0 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Restarting_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Post_Terminating_Check(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Post_Terminating state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Post_Terminating_Yes: {
+ /*
+ * The task specified by the ``id`` parameter shall be terminating after
+ * the rtems_task_restart() call.
+ */
+ T_ne_int( ctx->worker_life_state & THREAD_LIFE_TERMINATING, 0 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Terminating_No: {
+ /*
+ * The task specified by the ``id`` parameter shall not be terminating
+ * after the rtems_task_restart() call.
+ */
+ T_eq_int( ctx->worker_life_state & THREAD_LIFE_TERMINATING, 0 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Terminating_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Post_Protected_Check(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Post_Protected state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Post_Protected_Yes: {
+ /*
+ * The thread life of the task specified by the ``id`` parameter be
+ * protected after the rtems_task_restart() call.
+ */
+ T_ne_int( ctx->worker_life_state & THREAD_LIFE_PROTECTED, 0 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Protected_No: {
+ /*
+ * The thread life of the task specified by the ``id`` parameter shall
+ * not be protected after the rtems_task_restart() call.
+ */
+ T_eq_int( ctx->worker_life_state & THREAD_LIFE_PROTECTED, 0 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_Protected_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Post_RestartExtensions_Check(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Post_RestartExtensions state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Post_RestartExtensions_Yes: {
+ /*
+ * The thread restart user extensions shall be invoked by the
+ * rtems_task_restart() call.
+ */
+ T_eq_u32( ctx->calls_after_restart.thread_restart, 1 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_RestartExtensions_Nop: {
+ /*
+ * The thread restart user extensions shall not be invoked by the
+ * rtems_task_restart() call.
+ */
+ T_eq_u32( ctx->calls_after_restart.thread_restart, 0 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_RestartExtensions_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Post_TerminateExtensions_Check(
+ RtemsTaskReqRestart_Context *ctx,
+ RtemsTaskReqRestart_Post_TerminateExtensions state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqRestart_Post_TerminateExtensions_Yes: {
+ /*
+ * The thread terminate user extensions shall be invoked by the
+ * rtems_task_restart() call.
+ */
+ T_eq_u32( ctx->calls_after_restart.thread_terminate, 1 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_TerminateExtensions_Nop: {
+ /*
+ * The thread terminate user extensions shall not be invoked by the
+ * rtems_task_restart() call.
+ */
+ T_eq_u32( ctx->calls_after_restart.thread_terminate, 0 );
+ break;
+ }
+
+ case RtemsTaskReqRestart_Post_TerminateExtensions_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqRestart_Setup( RtemsTaskReqRestart_Context *ctx )
+{
+ rtems_status_code sc;
+
+ ctx->runner_id = rtems_task_self();
+ ctx->scheduler_id = GetSelfScheduler();
+ ctx->mutex_id = CreateMutexNoProtocol();
+ ObtainMutex( ctx->mutex_id );
+ WrapThreadQueueInitialize( &ctx->wrap_tq_ctx, Restart, ctx );
+
+ sc = rtems_extension_create(
+ rtems_build_name( 'T', 'E', 'S', 'T' ),
+ &extensions,
+ &ctx->extension_id
+ );
+ T_rsc_success( sc );
+
+ SetFatalHandler( Fatal, ctx );
+ SetSelfPriority( PRIO_NORMAL );
+
+ ctx->deleter_id = CreateTask( "DELE", PRIO_HIGH );
+ ctx->deleter_tcb = GetThread( ctx->deleter_id );
+ StartTask( ctx->deleter_id, Deleter, NULL );
+}
+
+static void RtemsTaskReqRestart_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqRestart_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqRestart_Setup( ctx );
+}
+
+static void RtemsTaskReqRestart_Teardown( RtemsTaskReqRestart_Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_extension_delete( ctx->extension_id );
+ T_rsc_success( sc );
+
+ SetFatalHandler( NULL, NULL );
+ DeleteTask( ctx->deleter_id );
+ ReleaseMutex( ctx->mutex_id );
+ DeleteMutex( ctx->mutex_id );
+ RestoreRunnerASR();
+ RestoreRunnerPriority();
+ WrapThreadQueueDestroy( &ctx->wrap_tq_ctx );
+}
+
+static void RtemsTaskReqRestart_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqRestart_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqRestart_Teardown( ctx );
+}
+
+static void RtemsTaskReqRestart_Prepare( RtemsTaskReqRestart_Context *ctx )
+{
+ ctx->status = RTEMS_NOT_IMPLEMENTED;
+ ctx->actual_argument = UNSET_ARGUMENT;
+ ctx->restart_counter = 0;
+
+ ctx->delete_worker_expected = false;
+ ctx->worker_id = CreateTask( "WORK", PRIO_NORMAL );
+ ctx->delete_worker_expected = true;
+
+ ctx->worker_tcb = GetThread( ctx->worker_id );
+ ctx->worker_state = UINT32_MAX;
+ ctx->worker_life_state = INT_MAX;
+
+ SetPriority( ctx->deleter_id, PRIO_HIGH );
+}
+
+static void RtemsTaskReqRestart_Action( RtemsTaskReqRestart_Context *ctx )
+{
+ rtems_status_code sc;
+
+ if ( ctx->id != INVALID_ID ) {
+ if ( ctx->dormant ) {
+ PrepareRealPriority( ctx );
+ } else {
+ StartTask( ctx->worker_id, Worker, NULL );
+
+ /* Let the worker catch signals and set the thread life protection state */
+ Yield();
+
+ sc = rtems_signal_send( ctx->worker_id, RTEMS_SIGNAL_0 );
+ T_rsc_success( sc );
+
+ if (
+ ctx->restarting &&
+ ( !ctx->nested_request || ( ctx->nested_request && ctx->terminating ) )
+ ) {
+ sc = rtems_task_restart( ctx->worker_id, (rtems_task_argument) ctx );
+ T_rsc_success( sc );
+ }
+
+ if ( ctx->terminating && !ctx->nested_request ) {
+ sc = rtems_task_restart( ctx->deleter_id, (rtems_task_argument) ctx );
+ T_rsc_success( sc );
+ } else {
+ PrepareRealPriority( ctx );
+ Yield();
+ }
+ }
+ }
+
+ if ( ctx->id == RTEMS_SELF ) {
+ CaptureWorkerState( ctx );
+ } else {
+ if ( ctx->nested_request ) {
+ if ( ctx->terminating ) {
+ sc = rtems_task_restart( ctx->deleter_id, (rtems_task_argument) ctx );
+ T_rsc_success( sc );
+ } else {
+ WrapThreadQueueExtract( &ctx->wrap_tq_ctx, ctx->worker_tcb );
+
+ sc = rtems_task_restart( ctx->worker_id, (rtems_task_argument) ctx );
+ T_rsc_success( sc );
+ }
+ } else {
+ SetSelfPriority( PRIO_VERY_HIGH );
+
+ if ( ctx->interrupt ) {
+ CallWithinISR( Restart, ctx );
+ } else {
+ Restart( ctx );
+ }
+ }
+ }
+}
+
+static void RtemsTaskReqRestart_Cleanup( RtemsTaskReqRestart_Context *ctx )
+{
+ SetSelfPriority( PRIO_VERY_LOW );
+
+ if ( ctx->protected && ctx->blocked ) {
+ if ( ctx->enqueued ) {
+ ReleaseMutex( ctx->mutex_id );
+ ObtainMutex( ctx->mutex_id );
+ } else {
+ SendEvents( ctx->worker_id, RTEMS_EVENT_0 );
+ }
+ }
+
+ if ( ctx->id == INVALID_ID || ctx->dormant || !ctx->terminating ) {
+ DeleteTask( ctx->worker_id );
+ }
+
+ SetSelfPriority( PRIO_NORMAL );
+}
+
+static const RtemsTaskReqRestart_Entry
+RtemsTaskReqRestart_Entries[] = {
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA,
+ RtemsTaskReqRestart_Post_FatalError_NA,
+ RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA,
+ RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA,
+ RtemsTaskReqRestart_Post_Restarting_NA,
+ RtemsTaskReqRestart_Post_Terminating_NA,
+ RtemsTaskReqRestart_Post_Protected_NA,
+ RtemsTaskReqRestart_Post_RestartExtensions_NA,
+ RtemsTaskReqRestart_Post_TerminateExtensions_NA },
+ { 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, RtemsTaskReqRestart_Post_Status_InvId,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA,
+ RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA,
+ RtemsTaskReqRestart_Post_Restarting_NA,
+ RtemsTaskReqRestart_Post_Terminating_NA,
+ RtemsTaskReqRestart_Post_Protected_NA,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA,
+ RtemsTaskReqRestart_Post_FatalError_NA,
+ RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA,
+ RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA,
+ RtemsTaskReqRestart_Post_Restarting_NA,
+ RtemsTaskReqRestart_Post_Terminating_NA,
+ RtemsTaskReqRestart_Post_Protected_NA,
+ RtemsTaskReqRestart_Post_RestartExtensions_NA,
+ RtemsTaskReqRestart_Post_TerminateExtensions_NA },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA,
+ RtemsTaskReqRestart_Post_FatalError_NA,
+ RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA,
+ RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA,
+ RtemsTaskReqRestart_Post_Restarting_NA,
+ RtemsTaskReqRestart_Post_Terminating_NA,
+ RtemsTaskReqRestart_Post_Protected_NA,
+ RtemsTaskReqRestart_Post_RestartExtensions_NA,
+ RtemsTaskReqRestart_Post_TerminateExtensions_NA },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA,
+ RtemsTaskReqRestart_Post_FatalError_NA,
+ RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA,
+ RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA,
+ RtemsTaskReqRestart_Post_Restarting_NA,
+ RtemsTaskReqRestart_Post_Terminating_NA,
+ RtemsTaskReqRestart_Post_Protected_NA,
+ RtemsTaskReqRestart_Post_RestartExtensions_NA,
+ RtemsTaskReqRestart_Post_TerminateExtensions_NA },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA,
+ RtemsTaskReqRestart_Post_FatalError_NA,
+ RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA,
+ RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA,
+ RtemsTaskReqRestart_Post_Restarting_NA,
+ RtemsTaskReqRestart_Post_Terminating_NA,
+ RtemsTaskReqRestart_Post_Protected_NA,
+ RtemsTaskReqRestart_Post_RestartExtensions_NA,
+ RtemsTaskReqRestart_Post_TerminateExtensions_NA },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA,
+ RtemsTaskReqRestart_Post_FatalError_NA,
+ RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA,
+ RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA,
+ RtemsTaskReqRestart_Post_Restarting_NA,
+ RtemsTaskReqRestart_Post_Terminating_NA,
+ RtemsTaskReqRestart_Post_Protected_NA,
+ RtemsTaskReqRestart_Post_RestartExtensions_NA,
+ RtemsTaskReqRestart_Post_TerminateExtensions_NA },
+ { 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0,
+ RtemsTaskReqRestart_Post_Status_IncStat,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Nop,
+ RtemsTaskReqRestart_Post_State_DormantSuspended,
+ RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_No,
+ RtemsTaskReqRestart_Post_Terminating_No,
+ RtemsTaskReqRestart_Post_Protected_No,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0,
+ RtemsTaskReqRestart_Post_Status_IncStat,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Nop,
+ RtemsTaskReqRestart_Post_State_Dormant,
+ RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_No,
+ RtemsTaskReqRestart_Post_Terminating_No,
+ RtemsTaskReqRestart_Post_Protected_No,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA,
+ RtemsTaskReqRestart_Post_FatalError_NA,
+ RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA,
+ RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA,
+ RtemsTaskReqRestart_Post_Restarting_NA,
+ RtemsTaskReqRestart_Post_Terminating_NA,
+ RtemsTaskReqRestart_Post_Protected_NA,
+ RtemsTaskReqRestart_Post_RestartExtensions_NA,
+ RtemsTaskReqRestart_Post_TerminateExtensions_NA },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA,
+ RtemsTaskReqRestart_Post_FatalError_NA,
+ RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA,
+ RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA,
+ RtemsTaskReqRestart_Post_Restarting_NA,
+ RtemsTaskReqRestart_Post_Terminating_NA,
+ RtemsTaskReqRestart_Post_Protected_NA,
+ RtemsTaskReqRestart_Post_RestartExtensions_NA,
+ RtemsTaskReqRestart_Post_TerminateExtensions_NA },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_NA,
+ RtemsTaskReqRestart_Post_FatalError_NA,
+ RtemsTaskReqRestart_Post_Argument_NA, RtemsTaskReqRestart_Post_State_NA,
+ RtemsTaskReqRestart_Post_Enqueued_NA, RtemsTaskReqRestart_Post_Timer_NA,
+ RtemsTaskReqRestart_Post_Restarting_NA,
+ RtemsTaskReqRestart_Post_Terminating_NA,
+ RtemsTaskReqRestart_Post_Protected_NA,
+ RtemsTaskReqRestart_Post_RestartExtensions_NA,
+ RtemsTaskReqRestart_Post_TerminateExtensions_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_Yes,
+ RtemsTaskReqRestart_Post_Protected_No,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_No,
+ RtemsTaskReqRestart_Post_Protected_No,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Set, RtemsTaskReqRestart_Post_State_Nop,
+ RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_No,
+ RtemsTaskReqRestart_Post_Protected_No,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Set, RtemsTaskReqRestart_Post_State_Nop,
+ RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_Yes,
+ RtemsTaskReqRestart_Post_Protected_No,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_Yes,
+ RtemsTaskReqRestart_Post_Protected_Yes,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Blocked,
+ RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_Yes,
+ RtemsTaskReqRestart_Post_Protected_Yes,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Blocked,
+ RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Active,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_Yes,
+ RtemsTaskReqRestart_Post_Protected_Yes,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Blocked,
+ RtemsTaskReqRestart_Post_Enqueued_Yes,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_Yes,
+ RtemsTaskReqRestart_Post_Protected_Yes,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Blocked,
+ RtemsTaskReqRestart_Post_Enqueued_Yes,
+ RtemsTaskReqRestart_Post_Timer_Active,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_Yes,
+ RtemsTaskReqRestart_Post_Protected_Yes,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_No,
+ RtemsTaskReqRestart_Post_Protected_Yes,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Blocked,
+ RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_No,
+ RtemsTaskReqRestart_Post_Protected_Yes,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Blocked,
+ RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Active,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_No,
+ RtemsTaskReqRestart_Post_Protected_Yes,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Blocked,
+ RtemsTaskReqRestart_Post_Enqueued_Yes,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_No,
+ RtemsTaskReqRestart_Post_Protected_Yes,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqRestart_Post_Status_Ok,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Blocked,
+ RtemsTaskReqRestart_Post_Enqueued_Yes,
+ RtemsTaskReqRestart_Post_Timer_Active,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_No,
+ RtemsTaskReqRestart_Post_Protected_Yes,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqRestart_Post_Status_NoReturn,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Zombie,
+ RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_Yes,
+ RtemsTaskReqRestart_Post_Protected_Yes,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Yes },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqRestart_Post_Status_NoReturn,
+ RtemsTaskReqRestart_Post_FatalError_Nop,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_No,
+ RtemsTaskReqRestart_Post_Terminating_No,
+ RtemsTaskReqRestart_Post_Protected_No,
+ RtemsTaskReqRestart_Post_RestartExtensions_Yes,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqRestart_Post_Status_NoReturn,
+ RtemsTaskReqRestart_Post_FatalError_Yes,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_Yes,
+ RtemsTaskReqRestart_Post_Protected_Yes,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqRestart_Post_Status_NoReturn,
+ RtemsTaskReqRestart_Post_FatalError_Yes,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_Yes,
+ RtemsTaskReqRestart_Post_Protected_No,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqRestart_Post_Status_NoReturn,
+ RtemsTaskReqRestart_Post_FatalError_Yes,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_No,
+ RtemsTaskReqRestart_Post_Protected_Yes,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqRestart_Post_Status_NoReturn,
+ RtemsTaskReqRestart_Post_FatalError_Yes,
+ RtemsTaskReqRestart_Post_Argument_Set,
+ RtemsTaskReqRestart_Post_State_Ready, RtemsTaskReqRestart_Post_Enqueued_No,
+ RtemsTaskReqRestart_Post_Timer_Inactive,
+ RtemsTaskReqRestart_Post_Restarting_Yes,
+ RtemsTaskReqRestart_Post_Terminating_No,
+ RtemsTaskReqRestart_Post_Protected_No,
+ RtemsTaskReqRestart_Post_RestartExtensions_Nop,
+ RtemsTaskReqRestart_Post_TerminateExtensions_Nop }
+};
+
+static const uint8_t
+RtemsTaskReqRestart_Map[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0,
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0,
+ 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0,
+ 3, 0, 3, 0, 3, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0,
+ 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0,
+ 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0,
+ 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0,
+ 3, 0, 3, 0, 3, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0,
+ 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0,
+ 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0,
+ 3, 0, 3, 0, 3, 0, 3, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3,
+ 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3,
+ 0, 3, 0, 3, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 3, 0, 3,
+ 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 3, 0, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 28, 26, 28, 26, 10, 10,
+ 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 0, 16, 0, 10, 0,
+ 10, 0, 17, 0, 17, 0, 18, 0, 18, 0, 19, 0, 19, 0, 20, 0, 20, 0, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 29, 26, 29, 26, 10,
+ 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 12, 0, 12, 0, 10,
+ 0, 10, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 30, 27, 30, 27,
+ 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 21, 0, 21, 0,
+ 10, 0, 10, 0, 22, 0, 22, 0, 23, 0, 23, 0, 24, 0, 24, 0, 25, 0, 25, 0, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 31, 27, 31,
+ 27, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 13, 0,
+ 13, 0, 10, 0, 10, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0,
+ 14, 0, 14, 0, 10, 0, 10, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0,
+ 14, 0, 28, 26, 28, 26, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 16, 0, 16, 0, 10, 0, 10, 0, 17, 0, 17, 0, 18, 0, 18, 0, 19, 0, 19,
+ 0, 20, 0, 20, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 29, 26, 29, 26, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 12, 0, 12, 0, 10, 0, 10, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0,
+ 12, 0, 12, 0, 12, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 30, 27, 30, 27, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 21, 0, 21, 0, 10, 0, 10, 0, 22, 0, 22, 0, 23, 0, 23, 0, 24,
+ 0, 24, 0, 25, 0, 25, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 31, 27, 31, 27, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 13, 0, 13, 0, 10, 0, 10, 0, 13, 0, 13, 0, 13, 0, 13, 0,
+ 13, 0, 13, 0, 13, 0, 13, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 28, 26, 28, 26, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 0, 16, 0, 10, 0, 10, 0, 17, 0, 17, 0, 18, 0,
+ 18, 0, 19, 0, 19, 0, 20, 0, 20, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 29, 26, 29, 26, 10, 10, 10, 10, 9, 9, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 12, 0, 12, 0, 10, 0, 10, 0, 12, 0, 12, 0,
+ 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 30, 27, 30, 27, 10, 10, 10, 10, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 21, 0, 21, 0, 10, 0, 10, 0, 22, 0, 22,
+ 0, 23, 0, 23, 0, 24, 0, 24, 0, 25, 0, 25, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 31, 27, 31, 27, 10, 10, 10, 10, 9, 9,
+ 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 13, 0, 13, 0, 10, 0, 10, 0, 13, 0,
+ 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 14, 0, 14, 0, 10, 0, 10, 0,
+ 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 28, 26, 28, 26, 10,
+ 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 16, 0, 16, 0, 10,
+ 0, 10, 0, 17, 0, 17, 0, 18, 0, 18, 0, 19, 0, 19, 0, 20, 0, 20, 0, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 29, 26, 29, 26,
+ 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 12, 0, 12, 0,
+ 10, 0, 10, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 30, 27, 30,
+ 27, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 21, 0,
+ 21, 0, 10, 0, 10, 0, 22, 0, 22, 0, 23, 0, 23, 0, 24, 0, 24, 0, 25, 0, 25, 0,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 31,
+ 27, 31, 27, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+ 13, 0, 13, 0, 10, 0, 10, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0,
+ 13, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 0, 7, 0, 7,
+ 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 0,
+ 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0,
+ 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 0, 7, 0, 7, 0,
+ 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0,
+ 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0,
+ 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0,
+ 7, 0, 7, 0, 7, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 8, 0,
+ 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 8, 0, 8, 0,
+ 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 8, 0,
+ 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0,
+ 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 8, 0, 8, 0, 8, 0,
+ 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 8, 0,
+ 8, 0, 8, 0, 8, 0, 8, 0, 8, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 16, 16, 16, 16, 10, 10, 10, 10, 17, 17, 17, 17, 18,
+ 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 16, 0, 16, 0, 10, 0, 10, 0, 17,
+ 0, 17, 0, 18, 0, 18, 0, 19, 0, 19, 0, 20, 0, 20, 0, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 12, 12, 12, 12, 10, 10, 10,
+ 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0,
+ 12, 0, 10, 0, 10, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0,
+ 15, 0, 15, 0, 10, 0, 10, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0,
+ 15, 0, 21, 21, 21, 21, 10, 10, 10, 10, 22, 22, 22, 22, 23, 23, 23, 23, 24,
+ 24, 24, 24, 25, 25, 25, 25, 21, 0, 21, 0, 10, 0, 10, 0, 22, 0, 22, 0, 23, 0,
+ 23, 0, 24, 0, 24, 0, 25, 0, 25, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 13, 13, 13, 13, 10, 10, 10, 10, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 13, 0, 10, 0, 10, 0,
+ 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 14, 0, 14, 0, 10, 0,
+ 10, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 16, 16, 16,
+ 16, 10, 10, 10, 10, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20,
+ 20, 20, 16, 0, 16, 0, 10, 0, 10, 0, 17, 0, 17, 0, 18, 0, 18, 0, 19, 0, 19, 0,
+ 20, 0, 20, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 12, 12, 12, 12, 10, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 0, 12, 0, 10, 0, 10, 0, 12, 0, 12, 0, 12, 0,
+ 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 15, 0, 15, 0, 10, 0, 10, 0, 15, 0, 15, 0,
+ 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 21, 21, 21, 21, 10, 10, 10, 10, 22,
+ 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 21, 0, 21, 0, 10,
+ 0, 10, 0, 22, 0, 22, 0, 23, 0, 23, 0, 24, 0, 24, 0, 25, 0, 25, 0, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 13, 13, 13, 13,
+ 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 0, 13, 0, 10, 0, 10, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13,
+ 0, 13, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 16, 16, 16, 16, 10, 10, 10, 10, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19,
+ 19, 19, 20, 20, 20, 20, 16, 0, 16, 0, 10, 0, 10, 0, 17, 0, 17, 0, 18, 0, 18,
+ 0, 19, 0, 19, 0, 20, 0, 20, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 12, 12, 12, 12, 10, 10, 10, 10, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 0, 12, 0, 10, 0, 10, 0,
+ 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 15, 0, 15, 0, 10, 0,
+ 10, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 21, 21, 21,
+ 21, 10, 10, 10, 10, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25,
+ 25, 25, 21, 0, 21, 0, 10, 0, 10, 0, 22, 0, 22, 0, 23, 0, 23, 0, 24, 0, 24, 0,
+ 25, 0, 25, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 13, 13, 13, 13, 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 0, 13, 0, 10, 0, 10, 0, 13, 0, 13, 0, 13, 0,
+ 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 14, 0, 14, 0, 10, 0, 10, 0, 14, 0, 14, 0,
+ 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 14, 0, 16, 16, 16, 16, 10, 10, 10, 10, 17,
+ 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 16, 0, 16, 0, 10,
+ 0, 10, 0, 17, 0, 17, 0, 18, 0, 18, 0, 19, 0, 19, 0, 20, 0, 20, 0, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 12, 12, 12, 12,
+ 10, 10, 10, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 0, 12, 0, 10, 0, 10, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12, 0, 12,
+ 0, 12, 0, 15, 0, 15, 0, 10, 0, 10, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15,
+ 0, 15, 0, 15, 0, 21, 21, 21, 21, 10, 10, 10, 10, 22, 22, 22, 22, 23, 23, 23,
+ 23, 24, 24, 24, 24, 25, 25, 25, 25, 21, 0, 21, 0, 10, 0, 10, 0, 22, 0, 22, 0,
+ 23, 0, 23, 0, 24, 0, 24, 0, 25, 0, 25, 0, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 13, 13, 13, 13, 10, 10, 10, 10, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 0, 13, 0, 10, 0,
+ 10, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 13, 0, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6
+};
+
+static size_t RtemsTaskReqRestart_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqRestart_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsTaskReqRestart_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqRestart_Fixture = {
+ .setup = RtemsTaskReqRestart_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqRestart_Teardown_Wrap,
+ .scope = RtemsTaskReqRestart_Scope,
+ .initial_context = &RtemsTaskReqRestart_Instance
+};
+
+static inline RtemsTaskReqRestart_Entry RtemsTaskReqRestart_PopEntry(
+ RtemsTaskReqRestart_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqRestart_Entries[
+ RtemsTaskReqRestart_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqRestart_SetPreConditionStates(
+ RtemsTaskReqRestart_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+
+ if ( ctx->Map.entry.Pre_Dormant_NA ) {
+ ctx->Map.pcs[ 1 ] = RtemsTaskReqRestart_Pre_Dormant_NA;
+ } else {
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Suspended_NA ) {
+ ctx->Map.pcs[ 2 ] = RtemsTaskReqRestart_Pre_Suspended_NA;
+ } else {
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Restarting_NA ) {
+ ctx->Map.pcs[ 3 ] = RtemsTaskReqRestart_Pre_Restarting_NA;
+ } else {
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Terminating_NA ) {
+ ctx->Map.pcs[ 4 ] = RtemsTaskReqRestart_Pre_Terminating_NA;
+ } else {
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Protected_NA ) {
+ ctx->Map.pcs[ 5 ] = RtemsTaskReqRestart_Pre_Protected_NA;
+ } else {
+ ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
+ }
+
+ ctx->Map.pcs[ 6 ] = ctx->Map.pci[ 6 ];
+
+ if ( ctx->Map.entry.Pre_State_NA ) {
+ ctx->Map.pcs[ 7 ] = RtemsTaskReqRestart_Pre_State_NA;
+ } else {
+ ctx->Map.pcs[ 7 ] = ctx->Map.pci[ 7 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Timer_NA ) {
+ ctx->Map.pcs[ 8 ] = RtemsTaskReqRestart_Pre_Timer_NA;
+ } else {
+ ctx->Map.pcs[ 8 ] = ctx->Map.pci[ 8 ];
+ }
+
+ if ( ctx->Map.entry.Pre_RealPriority_NA ) {
+ ctx->Map.pcs[ 9 ] = RtemsTaskReqRestart_Pre_RealPriority_NA;
+ } else {
+ ctx->Map.pcs[ 9 ] = ctx->Map.pci[ 9 ];
+ }
+
+ ctx->Map.pcs[ 10 ] = ctx->Map.pci[ 10 ];
+}
+
+static void RtemsTaskReqRestart_TestVariant( RtemsTaskReqRestart_Context *ctx )
+{
+ RtemsTaskReqRestart_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqRestart_Pre_Dormant_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqRestart_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTaskReqRestart_Pre_Restarting_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsTaskReqRestart_Pre_Terminating_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsTaskReqRestart_Pre_Protected_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsTaskReqRestart_Pre_Context_Prepare( ctx, ctx->Map.pcs[ 6 ] );
+ RtemsTaskReqRestart_Pre_State_Prepare( ctx, ctx->Map.pcs[ 7 ] );
+ RtemsTaskReqRestart_Pre_Timer_Prepare( ctx, ctx->Map.pcs[ 8 ] );
+ RtemsTaskReqRestart_Pre_RealPriority_Prepare( ctx, ctx->Map.pcs[ 9 ] );
+ RtemsTaskReqRestart_Pre_ThreadDispatch_Prepare( ctx, ctx->Map.pcs[ 10 ] );
+ RtemsTaskReqRestart_Action( ctx );
+ RtemsTaskReqRestart_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsTaskReqRestart_Post_FatalError_Check(
+ ctx,
+ ctx->Map.entry.Post_FatalError
+ );
+ RtemsTaskReqRestart_Post_Argument_Check( ctx, ctx->Map.entry.Post_Argument );
+ RtemsTaskReqRestart_Post_State_Check( ctx, ctx->Map.entry.Post_State );
+ RtemsTaskReqRestart_Post_Enqueued_Check( ctx, ctx->Map.entry.Post_Enqueued );
+ RtemsTaskReqRestart_Post_Timer_Check( ctx, ctx->Map.entry.Post_Timer );
+ RtemsTaskReqRestart_Post_Restarting_Check(
+ ctx,
+ ctx->Map.entry.Post_Restarting
+ );
+ RtemsTaskReqRestart_Post_Terminating_Check(
+ ctx,
+ ctx->Map.entry.Post_Terminating
+ );
+ RtemsTaskReqRestart_Post_Protected_Check(
+ ctx,
+ ctx->Map.entry.Post_Protected
+ );
+ RtemsTaskReqRestart_Post_RestartExtensions_Check(
+ ctx,
+ ctx->Map.entry.Post_RestartExtensions
+ );
+ RtemsTaskReqRestart_Post_TerminateExtensions_Check(
+ ctx,
+ ctx->Map.entry.Post_TerminateExtensions
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqRestart( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTaskReqRestart, &RtemsTaskReqRestart_Fixture )
+{
+ RtemsTaskReqRestart_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsTaskReqRestart_Pre_Id_Invalid;
+ ctx->Map.pci[ 0 ] < RtemsTaskReqRestart_Pre_Id_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsTaskReqRestart_Pre_Dormant_Yes;
+ ctx->Map.pci[ 1 ] < RtemsTaskReqRestart_Pre_Dormant_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsTaskReqRestart_Pre_Suspended_Yes;
+ ctx->Map.pci[ 2 ] < RtemsTaskReqRestart_Pre_Suspended_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = RtemsTaskReqRestart_Pre_Restarting_Yes;
+ ctx->Map.pci[ 3 ] < RtemsTaskReqRestart_Pre_Restarting_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ for (
+ ctx->Map.pci[ 4 ] = RtemsTaskReqRestart_Pre_Terminating_Yes;
+ ctx->Map.pci[ 4 ] < RtemsTaskReqRestart_Pre_Terminating_NA;
+ ++ctx->Map.pci[ 4 ]
+ ) {
+ for (
+ ctx->Map.pci[ 5 ] = RtemsTaskReqRestart_Pre_Protected_Yes;
+ ctx->Map.pci[ 5 ] < RtemsTaskReqRestart_Pre_Protected_NA;
+ ++ctx->Map.pci[ 5 ]
+ ) {
+ for (
+ ctx->Map.pci[ 6 ] = RtemsTaskReqRestart_Pre_Context_Task;
+ ctx->Map.pci[ 6 ] < RtemsTaskReqRestart_Pre_Context_NA;
+ ++ctx->Map.pci[ 6 ]
+ ) {
+ for (
+ ctx->Map.pci[ 7 ] = RtemsTaskReqRestart_Pre_State_Ready;
+ ctx->Map.pci[ 7 ] < RtemsTaskReqRestart_Pre_State_NA;
+ ++ctx->Map.pci[ 7 ]
+ ) {
+ for (
+ ctx->Map.pci[ 8 ] = RtemsTaskReqRestart_Pre_Timer_Inactive;
+ ctx->Map.pci[ 8 ] < RtemsTaskReqRestart_Pre_Timer_NA;
+ ++ctx->Map.pci[ 8 ]
+ ) {
+ for (
+ ctx->Map.pci[ 9 ] = RtemsTaskReqRestart_Pre_RealPriority_Initial;
+ ctx->Map.pci[ 9 ] < RtemsTaskReqRestart_Pre_RealPriority_NA;
+ ++ctx->Map.pci[ 9 ]
+ ) {
+ for (
+ ctx->Map.pci[ 10 ] = RtemsTaskReqRestart_Pre_ThreadDispatch_Disabled;
+ ctx->Map.pci[ 10 ] < RtemsTaskReqRestart_Pre_ThreadDispatch_NA;
+ ++ctx->Map.pci[ 10 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqRestart_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsTaskReqRestart_SetPreConditionStates( ctx );
+ RtemsTaskReqRestart_Prepare( ctx );
+ RtemsTaskReqRestart_TestVariant( ctx );
+ RtemsTaskReqRestart_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-resume.c b/testsuites/validation/tc-task-resume.c
new file mode 100644
index 0000000000..d440b52bd5
--- /dev/null
+++ b/testsuites/validation/tc-task-resume.c
@@ -0,0 +1,411 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqResume
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqResume spec:/rtems/task/req/resume
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqResume_Pre_Id_Invalid,
+ RtemsTaskReqResume_Pre_Id_Task,
+ RtemsTaskReqResume_Pre_Id_NA
+} RtemsTaskReqResume_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqResume_Pre_Suspended_Yes,
+ RtemsTaskReqResume_Pre_Suspended_No,
+ RtemsTaskReqResume_Pre_Suspended_NA
+} RtemsTaskReqResume_Pre_Suspended;
+
+typedef enum {
+ RtemsTaskReqResume_Post_Status_Ok,
+ RtemsTaskReqResume_Post_Status_InvId,
+ RtemsTaskReqResume_Post_Status_IncStat,
+ RtemsTaskReqResume_Post_Status_NA
+} RtemsTaskReqResume_Post_Status;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Pre_Suspended_NA : 1;
+ uint8_t Post_Status : 2;
+} RtemsTaskReqResume_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/resume test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the identifier of a task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief If this member is true, then the worker is suspended before the
+ * rtems_task_resume() call.
+ */
+ bool suspend;
+
+ /**
+ * @brief This member contains the return value of the rtems_task_resume()
+ * call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 2 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqResume_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqResume_Context;
+
+static RtemsTaskReqResume_Context
+ RtemsTaskReqResume_Instance;
+
+static const char * const RtemsTaskReqResume_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqResume_PreDesc_Suspended[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqResume_PreDesc[] = {
+ RtemsTaskReqResume_PreDesc_Id,
+ RtemsTaskReqResume_PreDesc_Suspended,
+ NULL
+};
+
+static void Worker( rtems_task_argument arg )
+{
+ while ( true ) {
+ /* Do nothing */
+ }
+}
+
+static void RtemsTaskReqResume_Pre_Id_Prepare(
+ RtemsTaskReqResume_Context *ctx,
+ RtemsTaskReqResume_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqResume_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqResume_Pre_Id_Task: {
+ /*
+ * While the ``id`` parameter is associated with a task.
+ */
+ ctx->id = ctx->worker_id;
+ break;
+ }
+
+ case RtemsTaskReqResume_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqResume_Pre_Suspended_Prepare(
+ RtemsTaskReqResume_Context *ctx,
+ RtemsTaskReqResume_Pre_Suspended state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqResume_Pre_Suspended_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is suspended.
+ */
+ ctx->suspend = true;
+ break;
+ }
+
+ case RtemsTaskReqResume_Pre_Suspended_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not suspended.
+ */
+ ctx->suspend = false;
+ break;
+ }
+
+ case RtemsTaskReqResume_Pre_Suspended_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqResume_Post_Status_Check(
+ RtemsTaskReqResume_Context *ctx,
+ RtemsTaskReqResume_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqResume_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_resume() shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqResume_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_resume() shall be RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqResume_Post_Status_IncStat: {
+ /*
+ * The return status of rtems_task_resume() shall be
+ * RTEMS_INCORRECT_STATE.
+ */
+ T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
+ break;
+ }
+
+ case RtemsTaskReqResume_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqResume_Setup( RtemsTaskReqResume_Context *ctx )
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+static void RtemsTaskReqResume_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqResume_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqResume_Setup( ctx );
+}
+
+static void RtemsTaskReqResume_Teardown( RtemsTaskReqResume_Context *ctx )
+{
+ DeleteTask( ctx->worker_id );
+}
+
+static void RtemsTaskReqResume_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqResume_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqResume_Teardown( ctx );
+}
+
+static void RtemsTaskReqResume_Action( RtemsTaskReqResume_Context *ctx )
+{
+ if ( ctx->suspend ) {
+ SuspendTask( ctx->worker_id );
+ }
+
+ ctx->status = rtems_task_resume( ctx->id );
+
+ if ( ctx->suspend && ctx->status != RTEMS_SUCCESSFUL ) {
+ ResumeTask( ctx->worker_id );
+ }
+}
+
+static const RtemsTaskReqResume_Entry
+RtemsTaskReqResume_Entries[] = {
+ { 0, 0, 1, RtemsTaskReqResume_Post_Status_InvId },
+ { 0, 0, 0, RtemsTaskReqResume_Post_Status_Ok },
+ { 0, 0, 0, RtemsTaskReqResume_Post_Status_IncStat }
+};
+
+static const uint8_t
+RtemsTaskReqResume_Map[] = {
+ 0, 0, 1, 2
+};
+
+static size_t RtemsTaskReqResume_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqResume_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsTaskReqResume_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqResume_Fixture = {
+ .setup = RtemsTaskReqResume_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqResume_Teardown_Wrap,
+ .scope = RtemsTaskReqResume_Scope,
+ .initial_context = &RtemsTaskReqResume_Instance
+};
+
+static inline RtemsTaskReqResume_Entry RtemsTaskReqResume_PopEntry(
+ RtemsTaskReqResume_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqResume_Entries[
+ RtemsTaskReqResume_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqResume_SetPreConditionStates(
+ RtemsTaskReqResume_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+
+ if ( ctx->Map.entry.Pre_Suspended_NA ) {
+ ctx->Map.pcs[ 1 ] = RtemsTaskReqResume_Pre_Suspended_NA;
+ } else {
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ }
+}
+
+static void RtemsTaskReqResume_TestVariant( RtemsTaskReqResume_Context *ctx )
+{
+ RtemsTaskReqResume_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqResume_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqResume_Action( ctx );
+ RtemsTaskReqResume_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqResume( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTaskReqResume, &RtemsTaskReqResume_Fixture )
+{
+ RtemsTaskReqResume_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsTaskReqResume_Pre_Id_Invalid;
+ ctx->Map.pci[ 0 ] < RtemsTaskReqResume_Pre_Id_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsTaskReqResume_Pre_Suspended_Yes;
+ ctx->Map.pci[ 1 ] < RtemsTaskReqResume_Pre_Suspended_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqResume_PopEntry( ctx );
+ RtemsTaskReqResume_SetPreConditionStates( ctx );
+ RtemsTaskReqResume_TestVariant( ctx );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-set-affinity.c b/testsuites/validation/tc-task-set-affinity.c
new file mode 100644
index 0000000000..9502d009e1
--- /dev/null
+++ b/testsuites/validation/tc-task-set-affinity.c
@@ -0,0 +1,683 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqSetAffinity
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/test-scheduler.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqSetAffinity spec:/rtems/task/req/set-affinity
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ * @ingroup TestsuitesValidationOneCpu0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqSetAffinity_Pre_Id_Invalid,
+ RtemsTaskReqSetAffinity_Pre_Id_Task,
+ RtemsTaskReqSetAffinity_Pre_Id_NA
+} RtemsTaskReqSetAffinity_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqSetAffinity_Pre_CPUSetSize_Askew,
+ RtemsTaskReqSetAffinity_Pre_CPUSetSize_Normal,
+ RtemsTaskReqSetAffinity_Pre_CPUSetSize_Huge,
+ RtemsTaskReqSetAffinity_Pre_CPUSetSize_NA
+} RtemsTaskReqSetAffinity_Pre_CPUSetSize;
+
+typedef enum {
+ RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Supported,
+ RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Unsupported,
+ RtemsTaskReqSetAffinity_Pre_CPUSetOnline_NA
+} RtemsTaskReqSetAffinity_Pre_CPUSetOnline;
+
+typedef enum {
+ RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NotZero,
+ RtemsTaskReqSetAffinity_Pre_CPUSetHuge_Zero,
+ RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NA
+} RtemsTaskReqSetAffinity_Pre_CPUSetHuge;
+
+typedef enum {
+ RtemsTaskReqSetAffinity_Pre_CPUSet_Valid,
+ RtemsTaskReqSetAffinity_Pre_CPUSet_Null,
+ RtemsTaskReqSetAffinity_Pre_CPUSet_NA
+} RtemsTaskReqSetAffinity_Pre_CPUSet;
+
+typedef enum {
+ RtemsTaskReqSetAffinity_Post_Status_Ok,
+ RtemsTaskReqSetAffinity_Post_Status_InvAddr,
+ RtemsTaskReqSetAffinity_Post_Status_InvId,
+ RtemsTaskReqSetAffinity_Post_Status_InvNum,
+ RtemsTaskReqSetAffinity_Post_Status_NA
+} RtemsTaskReqSetAffinity_Post_Status;
+
+typedef enum {
+ RtemsTaskReqSetAffinity_Post_SetAffinity_Set,
+ RtemsTaskReqSetAffinity_Post_SetAffinity_Nop,
+ RtemsTaskReqSetAffinity_Post_SetAffinity_NA
+} RtemsTaskReqSetAffinity_Post_SetAffinity;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_CPUSetSize_NA : 1;
+ uint16_t Pre_CPUSetOnline_NA : 1;
+ uint16_t Pre_CPUSetHuge_NA : 1;
+ uint16_t Pre_CPUSet_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_SetAffinity : 2;
+} RtemsTaskReqSetAffinity_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/set-affinity test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides the scheduler operation records.
+ */
+ T_scheduler_log_2 scheduler_log;
+
+ /**
+ * @brief This member provides the object referenced by the ``cpuset``
+ * parameter.
+ */
+ cpu_set_t cpuset_obj[ 2 ];
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_task_set_affinity() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member specifies if the ``cpusetsize`` parameter value.
+ */
+ size_t cpusetsize;
+
+ /**
+ * @brief This member specifies if the ``cpuset`` parameter value.
+ */
+ cpu_set_t *cpuset;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 5 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 5 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqSetAffinity_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqSetAffinity_Context;
+
+static RtemsTaskReqSetAffinity_Context
+ RtemsTaskReqSetAffinity_Instance;
+
+static const char * const RtemsTaskReqSetAffinity_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSetSize[] = {
+ "Askew",
+ "Normal",
+ "Huge",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSetOnline[] = {
+ "Supported",
+ "Unsupported",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSetHuge[] = {
+ "NotZero",
+ "Zero",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetAffinity_PreDesc_CPUSet[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqSetAffinity_PreDesc[] = {
+ RtemsTaskReqSetAffinity_PreDesc_Id,
+ RtemsTaskReqSetAffinity_PreDesc_CPUSetSize,
+ RtemsTaskReqSetAffinity_PreDesc_CPUSetOnline,
+ RtemsTaskReqSetAffinity_PreDesc_CPUSetHuge,
+ RtemsTaskReqSetAffinity_PreDesc_CPUSet,
+ NULL
+};
+
+static void RtemsTaskReqSetAffinity_Pre_Id_Prepare(
+ RtemsTaskReqSetAffinity_Context *ctx,
+ RtemsTaskReqSetAffinity_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetAffinity_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_Id_Task: {
+ /*
+ * While the ``id`` parameter is associated with a task.
+ */
+ ctx->id = RTEMS_SELF;
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetAffinity_Pre_CPUSetSize_Prepare(
+ RtemsTaskReqSetAffinity_Context *ctx,
+ RtemsTaskReqSetAffinity_Pre_CPUSetSize state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetAffinity_Pre_CPUSetSize_Askew: {
+ /*
+ * While the ``cpusetsize`` parameter is not an integral multiple of the
+ * size of long.
+ */
+ ctx->cpusetsize = SIZE_MAX;
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_CPUSetSize_Normal: {
+ /*
+ * While the ``cpusetsize`` parameter is an integral multiple of the size
+ * of long, while the ``cpusetsize`` parameter is less than or equal to
+ * the maximum processor set size storable in the system.
+ */
+ ctx->cpusetsize = sizeof( ctx->cpuset_obj[ 0 ] );
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_CPUSetSize_Huge: {
+ /*
+ * While the ``cpusetsize`` parameter is an integral multiple of the size
+ * of long, while the ``cpusetsize`` parameter is greater than the
+ * maximum processor set size storable in the system.
+ */
+ ctx->cpusetsize = sizeof( ctx->cpuset_obj );
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_CPUSetSize_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Prepare(
+ RtemsTaskReqSetAffinity_Context *ctx,
+ RtemsTaskReqSetAffinity_Pre_CPUSetOnline state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Supported: {
+ /*
+ * While the intersection of the processor set specified by the
+ * ``cpusetsize`` and ``cpuset`` parameters and the set of online
+ * processors represents an affinity set supported by the home scheduler
+ * of the task specified by the ``id`` parameter at some point during the
+ * rtems_task_set_affinity() call.
+ */
+ /* Already prepared */
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Unsupported: {
+ /*
+ * While the intersection of the processor set specified by the
+ * ``cpusetsize`` and ``cpuset`` parameters and the set of online
+ * processors represents an affinity set not supported by the home
+ * scheduler of the task specified by the ``id`` parameter at some point
+ * during the rtems_task_set_affinity() call.
+ */
+ CPU_CLR( 0, &ctx->cpuset_obj[ 0 ] );
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_CPUSetOnline_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetAffinity_Pre_CPUSetHuge_Prepare(
+ RtemsTaskReqSetAffinity_Context *ctx,
+ RtemsTaskReqSetAffinity_Pre_CPUSetHuge state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NotZero: {
+ /*
+ * While the processor set specified by the ``cpusetsize`` and ``cpuset``
+ * parameters contains at least one processor which is not storable in a
+ * processor set supported by the system.
+ */
+ /* Already prepared */
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_CPUSetHuge_Zero: {
+ /*
+ * While the processor set specified by the ``cpusetsize`` and ``cpuset``
+ * parameters contains no processor which is not storable in a processor
+ * set supported by the system.
+ */
+ CPU_ZERO( &ctx->cpuset_obj[ 1 ] );
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetAffinity_Pre_CPUSet_Prepare(
+ RtemsTaskReqSetAffinity_Context *ctx,
+ RtemsTaskReqSetAffinity_Pre_CPUSet state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetAffinity_Pre_CPUSet_Valid: {
+ /*
+ * While the ``cpuset`` parameter references an object of type cpu_set_t.
+ */
+ ctx->cpuset = &ctx->cpuset_obj[ 0 ];
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_CPUSet_Null: {
+ /*
+ * While the ``cpuset`` parameter is equal to NULL.
+ */
+ ctx->cpuset = NULL;
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Pre_CPUSet_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetAffinity_Post_Status_Check(
+ RtemsTaskReqSetAffinity_Context *ctx,
+ RtemsTaskReqSetAffinity_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetAffinity_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_set_affinity() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_task_set_affinity() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_set_affinity() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Post_Status_InvNum: {
+ /*
+ * The return status of rtems_task_set_affinity() shall be
+ * RTEMS_INVALID_NUMBER.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NUMBER );
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetAffinity_Post_SetAffinity_Check(
+ RtemsTaskReqSetAffinity_Context *ctx,
+ RtemsTaskReqSetAffinity_Post_SetAffinity state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetAffinity_Post_SetAffinity_Set: {
+ /*
+ * The affinity set of the task specified by the ``id`` parameter shall
+ * be set with respect to the home scheduler of the task at some point
+ * during the rtems_task_set_affinity() call.
+ */
+ #if defined(RTEMS_SMP)
+ T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_SET_AFFINITY
+ );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].set_affinity.status,
+ STATUS_SUCCESSFUL
+ );
+ #else
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ #endif
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Post_SetAffinity_Nop: {
+ /*
+ * No task affinity shall be modified by the rtems_task_set_affinity()
+ * call.
+ */
+ #if defined(RTEMS_SMP)
+ if ( ctx->scheduler_log.header.recorded == 1 ) {
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_SET_AFFINITY
+ );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].set_affinity.status,
+ STATUS_INVALID_NUMBER
+ );
+ } else {
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ }
+ #else
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ #endif
+ break;
+ }
+
+ case RtemsTaskReqSetAffinity_Post_SetAffinity_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetAffinity_Prepare(
+ RtemsTaskReqSetAffinity_Context *ctx
+)
+{
+ CPU_FILL_S( sizeof( ctx->cpuset_obj ), &ctx->cpuset_obj[ 0 ] );
+}
+
+static void RtemsTaskReqSetAffinity_Action(
+ RtemsTaskReqSetAffinity_Context *ctx
+)
+{
+ T_scheduler_log *log;
+
+ log = T_scheduler_record_2( &ctx->scheduler_log );
+ T_null( log );
+
+ ctx->status = rtems_task_set_affinity(
+ ctx->id,
+ ctx->cpusetsize,
+ ctx->cpuset
+ );
+
+ log = T_scheduler_record( NULL );
+ T_eq_ptr( &log->header, &ctx->scheduler_log.header );
+}
+
+static const RtemsTaskReqSetAffinity_Entry
+RtemsTaskReqSetAffinity_Entries[] = {
+ { 0, 0, 0, 1, 1, 0, RtemsTaskReqSetAffinity_Post_Status_InvAddr,
+ RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
+ { 0, 0, 0, 1, 1, 0, RtemsTaskReqSetAffinity_Post_Status_InvId,
+ RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
+ { 0, 0, 0, 0, 1, 0, RtemsTaskReqSetAffinity_Post_Status_InvNum,
+ RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
+ { 0, 0, 0, 1, 0, 0, RtemsTaskReqSetAffinity_Post_Status_InvId,
+ RtemsTaskReqSetAffinity_Post_SetAffinity_Nop },
+ { 0, 0, 0, 0, 1, 0, RtemsTaskReqSetAffinity_Post_Status_Ok,
+ RtemsTaskReqSetAffinity_Post_SetAffinity_Set },
+ { 0, 0, 0, 0, 0, 0, RtemsTaskReqSetAffinity_Post_Status_Ok,
+ RtemsTaskReqSetAffinity_Post_SetAffinity_Set },
+ { 0, 0, 0, 0, 0, 0, RtemsTaskReqSetAffinity_Post_Status_InvNum,
+ RtemsTaskReqSetAffinity_Post_SetAffinity_Nop }
+};
+
+static const uint8_t
+RtemsTaskReqSetAffinity_Map[] = {
+ 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,
+ 2, 0, 2, 0, 2, 0, 4, 0, 4, 0, 2, 0, 2, 0, 5, 0, 5, 0, 6, 0, 6, 0
+};
+
+static size_t RtemsTaskReqSetAffinity_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqSetAffinity_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsTaskReqSetAffinity_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqSetAffinity_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsTaskReqSetAffinity_Scope,
+ .initial_context = &RtemsTaskReqSetAffinity_Instance
+};
+
+static inline RtemsTaskReqSetAffinity_Entry RtemsTaskReqSetAffinity_PopEntry(
+ RtemsTaskReqSetAffinity_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqSetAffinity_Entries[
+ RtemsTaskReqSetAffinity_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqSetAffinity_SetPreConditionStates(
+ RtemsTaskReqSetAffinity_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+
+ if ( ctx->Map.entry.Pre_CPUSetOnline_NA ) {
+ ctx->Map.pcs[ 2 ] = RtemsTaskReqSetAffinity_Pre_CPUSetOnline_NA;
+ } else {
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ }
+
+ if ( ctx->Map.entry.Pre_CPUSetHuge_NA ) {
+ ctx->Map.pcs[ 3 ] = RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NA;
+ } else {
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ }
+
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+}
+
+static void RtemsTaskReqSetAffinity_TestVariant(
+ RtemsTaskReqSetAffinity_Context *ctx
+)
+{
+ RtemsTaskReqSetAffinity_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqSetAffinity_Pre_CPUSetSize_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTaskReqSetAffinity_Pre_CPUSetHuge_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsTaskReqSetAffinity_Pre_CPUSet_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsTaskReqSetAffinity_Action( ctx );
+ RtemsTaskReqSetAffinity_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsTaskReqSetAffinity_Post_SetAffinity_Check(
+ ctx,
+ ctx->Map.entry.Post_SetAffinity
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqSetAffinity( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTaskReqSetAffinity,
+ &RtemsTaskReqSetAffinity_Fixture
+)
+{
+ RtemsTaskReqSetAffinity_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsTaskReqSetAffinity_Pre_Id_Invalid;
+ ctx->Map.pci[ 0 ] < RtemsTaskReqSetAffinity_Pre_Id_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsTaskReqSetAffinity_Pre_CPUSetSize_Askew;
+ ctx->Map.pci[ 1 ] < RtemsTaskReqSetAffinity_Pre_CPUSetSize_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsTaskReqSetAffinity_Pre_CPUSetOnline_Supported;
+ ctx->Map.pci[ 2 ] < RtemsTaskReqSetAffinity_Pre_CPUSetOnline_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NotZero;
+ ctx->Map.pci[ 3 ] < RtemsTaskReqSetAffinity_Pre_CPUSetHuge_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ for (
+ ctx->Map.pci[ 4 ] = RtemsTaskReqSetAffinity_Pre_CPUSet_Valid;
+ ctx->Map.pci[ 4 ] < RtemsTaskReqSetAffinity_Pre_CPUSet_NA;
+ ++ctx->Map.pci[ 4 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqSetAffinity_PopEntry( ctx );
+ RtemsTaskReqSetAffinity_SetPreConditionStates( ctx );
+ RtemsTaskReqSetAffinity_Prepare( ctx );
+ RtemsTaskReqSetAffinity_TestVariant( ctx );
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-set-priority.c b/testsuites/validation/tc-task-set-priority.c
new file mode 100644
index 0000000000..4094aaedfb
--- /dev/null
+++ b/testsuites/validation/tc-task-set-priority.c
@@ -0,0 +1,815 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqSetPriority
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqSetPriority spec:/rtems/task/req/set-priority
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ * @ingroup TestsuitesValidationOneCpu0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqSetPriority_Pre_Id_Invalid,
+ RtemsTaskReqSetPriority_Pre_Id_Task,
+ RtemsTaskReqSetPriority_Pre_Id_NA
+} RtemsTaskReqSetPriority_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqSetPriority_Pre_State_Dormant,
+ RtemsTaskReqSetPriority_Pre_State_Ready,
+ RtemsTaskReqSetPriority_Pre_State_Scheduled,
+ RtemsTaskReqSetPriority_Pre_State_Blocked,
+ RtemsTaskReqSetPriority_Pre_State_NA
+} RtemsTaskReqSetPriority_Pre_State;
+
+typedef enum {
+ RtemsTaskReqSetPriority_Pre_NewPriority_Current,
+ RtemsTaskReqSetPriority_Pre_NewPriority_Other,
+ RtemsTaskReqSetPriority_Pre_NewPriority_NA
+} RtemsTaskReqSetPriority_Pre_NewPriority;
+
+typedef enum {
+ RtemsTaskReqSetPriority_Pre_TaskPriority_High,
+ RtemsTaskReqSetPriority_Pre_TaskPriority_Equal,
+ RtemsTaskReqSetPriority_Pre_TaskPriority_Low,
+ RtemsTaskReqSetPriority_Pre_TaskPriority_Invalid,
+ RtemsTaskReqSetPriority_Pre_TaskPriority_NA
+} RtemsTaskReqSetPriority_Pre_TaskPriority;
+
+typedef enum {
+ RtemsTaskReqSetPriority_Pre_OldPriority_Valid,
+ RtemsTaskReqSetPriority_Pre_OldPriority_Null,
+ RtemsTaskReqSetPriority_Pre_OldPriority_NA
+} RtemsTaskReqSetPriority_Pre_OldPriority;
+
+typedef enum {
+ RtemsTaskReqSetPriority_Post_Status_Ok,
+ RtemsTaskReqSetPriority_Post_Status_InvAddr,
+ RtemsTaskReqSetPriority_Post_Status_InvId,
+ RtemsTaskReqSetPriority_Post_Status_InvPrio,
+ RtemsTaskReqSetPriority_Post_Status_NA
+} RtemsTaskReqSetPriority_Post_Status;
+
+typedef enum {
+ RtemsTaskReqSetPriority_Post_Priority_Set,
+ RtemsTaskReqSetPriority_Post_Priority_Nop,
+ RtemsTaskReqSetPriority_Post_Priority_NA
+} RtemsTaskReqSetPriority_Post_Priority;
+
+typedef enum {
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Set,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_NA
+} RtemsTaskReqSetPriority_Post_OldPriorityObj;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_State_NA : 1;
+ uint16_t Pre_NewPriority_NA : 1;
+ uint16_t Pre_TaskPriority_NA : 1;
+ uint16_t Pre_OldPriority_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_Priority : 2;
+ uint16_t Post_OldPriorityObj : 2;
+} RtemsTaskReqSetPriority_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/set-priority test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the worker task identifier.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief If this member is true, then the task shall be started.
+ */
+ bool started;
+
+ /**
+ * @brief If this member is true, then the task shall be blocked.
+ */
+ bool blocked;
+
+ /**
+ * @brief This member provides the object referenced by the ``old_priority``
+ * parameter.
+ */
+ rtems_task_priority old_priority_obj;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_task_set_priority() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member specifies if the ``new_priority`` parameter value.
+ */
+ rtems_task_priority new_priority;
+
+ /**
+ * @brief This member specifies if the ``old_priority`` parameter value.
+ */
+ rtems_task_priority *old_priority;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 5 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 5 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqSetPriority_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqSetPriority_Context;
+
+static RtemsTaskReqSetPriority_Context
+ RtemsTaskReqSetPriority_Instance;
+
+static const char * const RtemsTaskReqSetPriority_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetPriority_PreDesc_State[] = {
+ "Dormant",
+ "Ready",
+ "Scheduled",
+ "Blocked",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetPriority_PreDesc_NewPriority[] = {
+ "Current",
+ "Other",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetPriority_PreDesc_TaskPriority[] = {
+ "High",
+ "Equal",
+ "Low",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetPriority_PreDesc_OldPriority[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqSetPriority_PreDesc[] = {
+ RtemsTaskReqSetPriority_PreDesc_Id,
+ RtemsTaskReqSetPriority_PreDesc_State,
+ RtemsTaskReqSetPriority_PreDesc_NewPriority,
+ RtemsTaskReqSetPriority_PreDesc_TaskPriority,
+ RtemsTaskReqSetPriority_PreDesc_OldPriority,
+ NULL
+};
+
+static void Worker( rtems_task_argument arg )
+{
+ (void) ReceiveAnyEvents();
+ (void) ReceiveAnyEvents();
+}
+
+static void RtemsTaskReqSetPriority_Pre_Id_Prepare(
+ RtemsTaskReqSetPriority_Context *ctx,
+ RtemsTaskReqSetPriority_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetPriority_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_Id_Task: {
+ /*
+ * While the ``id`` parameter is associated with a task.
+ */
+ ctx->id = ctx->worker_id;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetPriority_Pre_State_Prepare(
+ RtemsTaskReqSetPriority_Context *ctx,
+ RtemsTaskReqSetPriority_Pre_State state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetPriority_Pre_State_Dormant: {
+ /*
+ * While the task specified by the ``id`` parameter is dormant.
+ */
+ ctx->started = false;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_State_Ready: {
+ /*
+ * While the task specified by the ``id`` parameter is ready.
+ */
+ ctx->started = true;
+ ctx->blocked = false;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_State_Scheduled: {
+ /*
+ * While the task specified by the ``id`` parameter is scheduled.
+ */
+ ctx->started = false;
+ ctx->id = rtems_task_self();
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_State_Blocked: {
+ /*
+ * While the task specified by the ``id`` parameter is blocked.
+ */
+ ctx->started = true;
+ ctx->blocked = true;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_State_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetPriority_Pre_NewPriority_Prepare(
+ RtemsTaskReqSetPriority_Context *ctx,
+ RtemsTaskReqSetPriority_Pre_NewPriority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetPriority_Pre_NewPriority_Current: {
+ /*
+ * While the value of the ``new_priority`` parameter is equal to
+ * RTEMS_CURRENT_PRIORITY.
+ */
+ ctx->new_priority = RTEMS_CURRENT_PRIORITY;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_NewPriority_Other: {
+ /*
+ * While the value of the ``new_priority`` parameter is not equal to
+ * RTEMS_CURRENT_PRIORITY.
+ */
+ ctx->new_priority = PRIO_NORMAL;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_NewPriority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetPriority_Pre_TaskPriority_Prepare(
+ RtemsTaskReqSetPriority_Context *ctx,
+ RtemsTaskReqSetPriority_Pre_TaskPriority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetPriority_Pre_TaskPriority_High: {
+ /*
+ * While the value of the ``new_priority`` parameter is a valid task
+ * priority with respect to the home scheduler of the task specified by
+ * the ``id`` parameter when the new priority is set, while the value of
+ * the ``new_priority`` parameter is higher than the task priority with
+ * respect to the home scheduler of the task specified by the ``id``
+ * parameter at time when the scheduler evaluates the new priority.
+ */
+ ctx->new_priority = PRIO_HIGH;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_TaskPriority_Equal: {
+ /*
+ * While the value of the ``new_priority`` parameter is a valid task
+ * priority with respect to the home scheduler of the task specified by
+ * the ``id`` parameter when the new priority is set, while the value of
+ * the ``new_priority`` parameter is equal to the task priority with
+ * respect to the home scheduler of the task specified by the ``id``
+ * parameter at time when the scheduler evaluates the new priority.
+ */
+ ctx->new_priority = PRIO_NORMAL;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_TaskPriority_Low: {
+ /*
+ * While the value of the ``new_priority`` parameter is a valid task
+ * priority with respect to the home scheduler of the task specified by
+ * the ``id`` parameter when the new priority is set, while the value of
+ * the ``new_priority`` parameter is lower than the task priority with
+ * respect to the home scheduler of the task specified by the ``id``
+ * parameter at time when the scheduler evaluates the new priority.
+ */
+ ctx->new_priority = PRIO_LOW;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_TaskPriority_Invalid: {
+ /*
+ * While the value of the ``new_priority`` parameter is an invalid task
+ * priority with respect to the home scheduler of the task specified by
+ * the ``id`` parameter when the new priority is evaluated.
+ */
+ ctx->new_priority = PRIO_INVALID;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_TaskPriority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetPriority_Pre_OldPriority_Prepare(
+ RtemsTaskReqSetPriority_Context *ctx,
+ RtemsTaskReqSetPriority_Pre_OldPriority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetPriority_Pre_OldPriority_Valid: {
+ /*
+ * While the ``old_priority`` parameter references an object of type
+ * rtems_task_priority.
+ */
+ ctx->old_priority = &ctx->old_priority_obj;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_OldPriority_Null: {
+ /*
+ * While the ``old_priority`` parameter is equal to NULL.
+ */
+ ctx->old_priority = NULL;
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Pre_OldPriority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetPriority_Post_Status_Check(
+ RtemsTaskReqSetPriority_Context *ctx,
+ RtemsTaskReqSetPriority_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetPriority_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_set_priority() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_task_set_priority() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_set_priority() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Post_Status_InvPrio: {
+ /*
+ * The return status of rtems_task_set_priority() shall be
+ * RTEMS_INVALID_PRIORITY.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_PRIORITY );
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetPriority_Post_Priority_Check(
+ RtemsTaskReqSetPriority_Context *ctx,
+ RtemsTaskReqSetPriority_Post_Priority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetPriority_Post_Priority_Set: {
+ /*
+ * The real priority of the task specified by the ``id`` parameter shall
+ * be set to the value specified by the ``new_priority`` parameter at
+ * some point during the rtems_task_set_priority() call.
+ */
+ T_eq_u32( GetPriority( ctx->id ), ctx->new_priority );
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Post_Priority_Nop: {
+ /*
+ * No real priority of a task shall be modified by the
+ * rtems_task_set_priority() call.
+ */
+ T_eq_u32( GetPriority( ctx->worker_id ), PRIO_NORMAL );
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Post_Priority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetPriority_Post_OldPriorityObj_Check(
+ RtemsTaskReqSetPriority_Context *ctx,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetPriority_Post_OldPriorityObj_Set: {
+ /*
+ * The value of the object referenced by the ``old_priority`` parameter
+ * shall be set after the return of the rtems_task_set_priority() call to
+ * the current priority of the task specified by the ``id`` parameter at
+ * some point during the call and before the real priority is modified by
+ * the call if it is modified by the call.
+ */
+ T_eq_u32( ctx->old_priority_obj, PRIO_NORMAL );
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop: {
+ /*
+ * Objects referenced by the ``old_priority`` parameter in past calls to
+ * rtems_task_set_priority() shall not be accessed by the
+ * rtems_task_set_priority() call.
+ */
+ T_eq_u32( ctx->old_priority_obj, PRIO_INVALID );
+ break;
+ }
+
+ case RtemsTaskReqSetPriority_Post_OldPriorityObj_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetPriority_Setup(
+ RtemsTaskReqSetPriority_Context *ctx
+)
+{
+ SetSelfPriority( PRIO_ULTRA_HIGH );
+}
+
+static void RtemsTaskReqSetPriority_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqSetPriority_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqSetPriority_Setup( ctx );
+}
+
+static void RtemsTaskReqSetPriority_Teardown(
+ RtemsTaskReqSetPriority_Context *ctx
+)
+{
+ RestoreRunnerPriority();
+}
+
+static void RtemsTaskReqSetPriority_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqSetPriority_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqSetPriority_Teardown( ctx );
+}
+
+static void RtemsTaskReqSetPriority_Prepare(
+ RtemsTaskReqSetPriority_Context *ctx
+)
+{
+ ctx->old_priority_obj = PRIO_INVALID;
+ ctx->worker_id = CreateTask( "WORK", PRIO_NORMAL );
+ ctx->started = false;
+ ctx->blocked = false;
+}
+
+static void RtemsTaskReqSetPriority_Action(
+ RtemsTaskReqSetPriority_Context *ctx
+)
+{
+ if ( ctx->started ) {
+ SetSelfPriority( PRIO_ULTRA_HIGH );
+ StartTask( ctx->worker_id, Worker, NULL );
+
+ if ( ctx->blocked ) {
+ SetSelfPriority( PRIO_ULTRA_LOW );
+ SetSelfPriority( PRIO_ULTRA_HIGH );
+ }
+ } else {
+ SetSelfPriority( PRIO_NORMAL );
+ }
+
+ ctx->status = rtems_task_set_priority(
+ ctx->id,
+ ctx->new_priority,
+ ctx->old_priority
+ );
+
+ if ( ctx->started ) {
+ SendEvents( ctx->worker_id, RTEMS_EVENT_0 );
+ SetSelfPriority( PRIO_ULTRA_LOW );
+ SetSelfPriority( PRIO_ULTRA_HIGH );
+ }
+}
+
+static void RtemsTaskReqSetPriority_Cleanup(
+ RtemsTaskReqSetPriority_Context *ctx
+)
+{
+ DeleteTask( ctx->worker_id );
+}
+
+static const RtemsTaskReqSetPriority_Entry
+RtemsTaskReqSetPriority_Entries[] = {
+ { 0, 0, 1, 0, 1, 0, RtemsTaskReqSetPriority_Post_Status_InvId,
+ RtemsTaskReqSetPriority_Post_Priority_Nop,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop },
+ { 0, 0, 1, 0, 1, 0, RtemsTaskReqSetPriority_Post_Status_InvAddr,
+ RtemsTaskReqSetPriority_Post_Priority_Nop,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop },
+ { 0, 0, 0, 0, 1, 0, RtemsTaskReqSetPriority_Post_Status_Ok,
+ RtemsTaskReqSetPriority_Post_Priority_Nop,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Set },
+ { 0, 0, 0, 0, 1, 0, RtemsTaskReqSetPriority_Post_Status_InvAddr,
+ RtemsTaskReqSetPriority_Post_Priority_Nop,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop },
+ { 0, 0, 0, 0, 0, 0, RtemsTaskReqSetPriority_Post_Status_InvAddr,
+ RtemsTaskReqSetPriority_Post_Priority_Nop,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Nop },
+ { 0, 0, 0, 0, 0, 0, RtemsTaskReqSetPriority_Post_Status_Ok,
+ RtemsTaskReqSetPriority_Post_Priority_Set,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Set },
+ { 0, 0, 0, 0, 0, 0, RtemsTaskReqSetPriority_Post_Status_InvPrio,
+ RtemsTaskReqSetPriority_Post_Priority_Nop,
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Set }
+};
+
+static const uint8_t
+RtemsTaskReqSetPriority_Map[] = {
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2, 3, 2, 3, 2, 3, 2, 3, 5, 4, 5, 4, 5, 4,
+ 6, 4, 2, 3, 2, 3, 2, 3, 2, 3, 5, 4, 5, 4, 5, 4, 6, 4, 2, 3, 2, 3, 2, 3, 2, 3,
+ 5, 4, 5, 4, 5, 4, 6, 4, 2, 3, 2, 3, 2, 3, 2, 3, 5, 4, 5, 4, 5, 4, 6, 4
+};
+
+static size_t RtemsTaskReqSetPriority_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqSetPriority_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsTaskReqSetPriority_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqSetPriority_Fixture = {
+ .setup = RtemsTaskReqSetPriority_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqSetPriority_Teardown_Wrap,
+ .scope = RtemsTaskReqSetPriority_Scope,
+ .initial_context = &RtemsTaskReqSetPriority_Instance
+};
+
+static inline RtemsTaskReqSetPriority_Entry RtemsTaskReqSetPriority_PopEntry(
+ RtemsTaskReqSetPriority_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqSetPriority_Entries[
+ RtemsTaskReqSetPriority_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqSetPriority_SetPreConditionStates(
+ RtemsTaskReqSetPriority_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+
+ if ( ctx->Map.entry.Pre_State_NA ) {
+ ctx->Map.pcs[ 1 ] = RtemsTaskReqSetPriority_Pre_State_NA;
+ } else {
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ }
+
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+
+ if ( ctx->Map.entry.Pre_TaskPriority_NA ) {
+ ctx->Map.pcs[ 3 ] = RtemsTaskReqSetPriority_Pre_TaskPriority_NA;
+ } else {
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ }
+
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+}
+
+static void RtemsTaskReqSetPriority_TestVariant(
+ RtemsTaskReqSetPriority_Context *ctx
+)
+{
+ RtemsTaskReqSetPriority_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqSetPriority_Pre_State_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqSetPriority_Pre_NewPriority_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTaskReqSetPriority_Pre_TaskPriority_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsTaskReqSetPriority_Pre_OldPriority_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsTaskReqSetPriority_Action( ctx );
+ RtemsTaskReqSetPriority_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsTaskReqSetPriority_Post_Priority_Check(
+ ctx,
+ ctx->Map.entry.Post_Priority
+ );
+ RtemsTaskReqSetPriority_Post_OldPriorityObj_Check(
+ ctx,
+ ctx->Map.entry.Post_OldPriorityObj
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqSetPriority( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTaskReqSetPriority,
+ &RtemsTaskReqSetPriority_Fixture
+)
+{
+ RtemsTaskReqSetPriority_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsTaskReqSetPriority_Pre_Id_Invalid;
+ ctx->Map.pci[ 0 ] < RtemsTaskReqSetPriority_Pre_Id_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsTaskReqSetPriority_Pre_State_Dormant;
+ ctx->Map.pci[ 1 ] < RtemsTaskReqSetPriority_Pre_State_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsTaskReqSetPriority_Pre_NewPriority_Current;
+ ctx->Map.pci[ 2 ] < RtemsTaskReqSetPriority_Pre_NewPriority_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = RtemsTaskReqSetPriority_Pre_TaskPriority_High;
+ ctx->Map.pci[ 3 ] < RtemsTaskReqSetPriority_Pre_TaskPriority_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ for (
+ ctx->Map.pci[ 4 ] = RtemsTaskReqSetPriority_Pre_OldPriority_Valid;
+ ctx->Map.pci[ 4 ] < RtemsTaskReqSetPriority_Pre_OldPriority_NA;
+ ++ctx->Map.pci[ 4 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqSetPriority_PopEntry( ctx );
+ RtemsTaskReqSetPriority_SetPreConditionStates( ctx );
+ RtemsTaskReqSetPriority_Prepare( ctx );
+ RtemsTaskReqSetPriority_TestVariant( ctx );
+ RtemsTaskReqSetPriority_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-set-scheduler.c b/testsuites/validation/tc-task-set-scheduler.c
new file mode 100644
index 0000000000..174aa55736
--- /dev/null
+++ b/testsuites/validation/tc-task-set-scheduler.c
@@ -0,0 +1,1491 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqSetScheduler
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/score/threadimpl.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqSetScheduler spec:/rtems/task/req/set-scheduler
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_TaskId_Task,
+ RtemsTaskReqSetScheduler_Pre_TaskId_Invalid,
+ RtemsTaskReqSetScheduler_Pre_TaskId_NA
+} RtemsTaskReqSetScheduler_Pre_TaskId;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_Scheduler_Home,
+ RtemsTaskReqSetScheduler_Pre_Scheduler_Other,
+ RtemsTaskReqSetScheduler_Pre_Scheduler_NA
+} RtemsTaskReqSetScheduler_Pre_Scheduler;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_Yes,
+ RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_No,
+ RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_NA
+} RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_SchedulerId_Scheduler,
+ RtemsTaskReqSetScheduler_Pre_SchedulerId_Invalid,
+ RtemsTaskReqSetScheduler_Pre_SchedulerId_NA
+} RtemsTaskReqSetScheduler_Pre_SchedulerId;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_Priority_Valid,
+ RtemsTaskReqSetScheduler_Pre_Priority_Invalid,
+ RtemsTaskReqSetScheduler_Pre_Priority_NA
+} RtemsTaskReqSetScheduler_Pre_Priority;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_HomePriority_Real,
+ RtemsTaskReqSetScheduler_Pre_HomePriority_More,
+ RtemsTaskReqSetScheduler_Pre_HomePriority_NA
+} RtemsTaskReqSetScheduler_Pre_HomePriority;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_EligiblePriorities_OnlyOne,
+ RtemsTaskReqSetScheduler_Pre_EligiblePriorities_More,
+ RtemsTaskReqSetScheduler_Pre_EligiblePriorities_NA
+} RtemsTaskReqSetScheduler_Pre_EligiblePriorities;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_Pinned_Yes,
+ RtemsTaskReqSetScheduler_Pre_Pinned_No,
+ RtemsTaskReqSetScheduler_Pre_Pinned_NA
+} RtemsTaskReqSetScheduler_Pre_Pinned;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_TaskState_Ready,
+ RtemsTaskReqSetScheduler_Pre_TaskState_Blocked,
+ RtemsTaskReqSetScheduler_Pre_TaskState_Enqueued,
+ RtemsTaskReqSetScheduler_Pre_TaskState_NA
+} RtemsTaskReqSetScheduler_Pre_TaskState;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Pre_AffinitySupported_Yes,
+ RtemsTaskReqSetScheduler_Pre_AffinitySupported_No,
+ RtemsTaskReqSetScheduler_Pre_AffinitySupported_NA
+} RtemsTaskReqSetScheduler_Pre_AffinitySupported;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Post_Status_Ok,
+ RtemsTaskReqSetScheduler_Post_Status_InvAddr,
+ RtemsTaskReqSetScheduler_Post_Status_InvId,
+ RtemsTaskReqSetScheduler_Post_Status_InvPrio,
+ RtemsTaskReqSetScheduler_Post_Status_InUse,
+ RtemsTaskReqSetScheduler_Post_Status_Unsat,
+ RtemsTaskReqSetScheduler_Post_Status_NA
+} RtemsTaskReqSetScheduler_Post_Status;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Post_Scheduler_Set,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA
+} RtemsTaskReqSetScheduler_Post_Scheduler;
+
+typedef enum {
+ RtemsTaskReqSetScheduler_Post_Priority_Set,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_NA
+} RtemsTaskReqSetScheduler_Post_Priority;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_TaskId_NA : 1;
+ uint32_t Pre_Scheduler_NA : 1;
+ uint32_t Pre_SchedulerHasCPU_NA : 1;
+ uint32_t Pre_SchedulerId_NA : 1;
+ uint32_t Pre_Priority_NA : 1;
+ uint32_t Pre_HomePriority_NA : 1;
+ uint32_t Pre_EligiblePriorities_NA : 1;
+ uint32_t Pre_Pinned_NA : 1;
+ uint32_t Pre_TaskState_NA : 1;
+ uint32_t Pre_AffinitySupported_NA : 1;
+ uint32_t Post_Status : 3;
+ uint32_t Post_Scheduler : 2;
+ uint32_t Post_Priority : 2;
+} RtemsTaskReqSetScheduler_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/set-scheduler test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the runner task identifier.
+ */
+ rtems_id runner_id;
+
+ /**
+ * @brief This member contains the scheduler A identifier.
+ */
+ rtems_id scheduler_a_id;
+
+ /**
+ * @brief This member contains the scheduler B identifier.
+ */
+ rtems_id scheduler_b_id;
+
+ /**
+ * @brief This member contains the scheduler D identifier.
+ */
+ rtems_id scheduler_d_id;
+
+ /**
+ * @brief This member contains the worker task identifiers.
+ */
+ rtems_id worker_id[ 3 ];
+
+ /**
+ * @brief This member contains the mutex identifiers.
+ */
+ rtems_id mutex_id[ 2 ];
+
+ /**
+ * @brief If this member is true, then the task shall have an additional
+ * priority for the home scheduler.
+ */
+ bool additional_home_priority;
+
+ /**
+ * @brief If this member is true, then the task shall have a second eligible
+ * scheduler.
+ */
+ bool second_eligible_scheduler;
+
+ /**
+ * @brief If this member is true, then the task shall be pinned to a
+ * processor.
+ */
+ bool pinned;
+
+ /**
+ * @brief If this member is true, then the task shall be blocked.
+ */
+ bool blocked;
+
+ /**
+ * @brief If this member is true, then the task shall be enqueued on a thread
+ * queue.
+ */
+ bool enqueued;
+
+ /**
+ * @brief This member specifies the scheduler identifier to set.
+ */
+ rtems_id scheduler_to_set_id;
+
+ /**
+ * @brief If this member is true, then the affinity of the task shall be
+ * supported by the scheduler.
+ */
+ bool affinity_supported;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_task_set_scheduler() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``task_id`` parameter value.
+ */
+ rtems_id task_id;
+
+ /**
+ * @brief This member specifies if the ``scheduler_id`` parameter value.
+ */
+ rtems_id scheduler_id;
+
+ /**
+ * @brief This member specifies if the ``priority`` parameter value.
+ */
+ rtems_task_priority priority;
+
+ /**
+ * @brief This member contains the identifier of the new scheduler.
+ */
+ rtems_id new_scheduler;
+
+ /**
+ * @brief This member contains the new priorities of the task.
+ */
+ rtems_task_priority new_priority[ 2 ];
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 10 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 10 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqSetScheduler_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqSetScheduler_Context;
+
+static RtemsTaskReqSetScheduler_Context
+ RtemsTaskReqSetScheduler_Instance;
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_TaskId[] = {
+ "Task",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_Scheduler[] = {
+ "Home",
+ "Other",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_SchedulerHasCPU[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_SchedulerId[] = {
+ "Scheduler",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_Priority[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_HomePriority[] = {
+ "Real",
+ "More",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_EligiblePriorities[] = {
+ "OnlyOne",
+ "More",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_Pinned[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_TaskState[] = {
+ "Ready",
+ "Blocked",
+ "Enqueued",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSetScheduler_PreDesc_AffinitySupported[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqSetScheduler_PreDesc[] = {
+ RtemsTaskReqSetScheduler_PreDesc_TaskId,
+ RtemsTaskReqSetScheduler_PreDesc_Scheduler,
+ RtemsTaskReqSetScheduler_PreDesc_SchedulerHasCPU,
+ RtemsTaskReqSetScheduler_PreDesc_SchedulerId,
+ RtemsTaskReqSetScheduler_PreDesc_Priority,
+ RtemsTaskReqSetScheduler_PreDesc_HomePriority,
+ RtemsTaskReqSetScheduler_PreDesc_EligiblePriorities,
+ RtemsTaskReqSetScheduler_PreDesc_Pinned,
+ RtemsTaskReqSetScheduler_PreDesc_TaskState,
+ RtemsTaskReqSetScheduler_PreDesc_AffinitySupported,
+ NULL
+};
+
+typedef RtemsTaskReqSetScheduler_Context Context;
+
+#define EVENT_OBTAIN_MUTEX_A RTEMS_EVENT_0
+
+#define EVENT_RELEASE_MUTEX_A RTEMS_EVENT_1
+
+#define EVENT_OBTAIN_MUTEX_B RTEMS_EVENT_2
+
+#define EVENT_RELEASE_MUTEX_B RTEMS_EVENT_3
+
+#define EVENT_PIN RTEMS_EVENT_4
+
+#define EVENT_UNPIN RTEMS_EVENT_5
+
+#define EVENT_SET_LOW_PRIO RTEMS_EVENT_6
+
+#define EVENT_RUNNER_SYNC_0 RTEMS_EVENT_7
+
+#define EVENT_RUNNER_SYNC_1 RTEMS_EVENT_8
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+ Thread_Control *executing;
+
+ ctx = (Context *) arg;
+ executing = _Thread_Get_executing();
+
+ while ( true ) {
+ rtems_event_set events;
+
+ events = ReceiveAnyEvents();
+
+ if ( ( events & EVENT_RUNNER_SYNC_0 ) != 0 ) {
+ SendEvents( ctx->runner_id, EVENT_RUNNER_SYNC_0 );
+ }
+
+ if ( ( events & EVENT_OBTAIN_MUTEX_A ) != 0 ) {
+ ObtainMutex( ctx->mutex_id[ 0 ] );
+ }
+
+ if ( ( events & EVENT_RELEASE_MUTEX_A ) != 0 ) {
+ ReleaseMutex( ctx->mutex_id[ 0 ] );
+ }
+
+ if ( ( events & EVENT_OBTAIN_MUTEX_B ) != 0 ) {
+ ObtainMutex( ctx->mutex_id[ 1 ] );
+ }
+
+ if ( ( events & EVENT_RELEASE_MUTEX_B ) != 0 ) {
+ ReleaseMutex( ctx->mutex_id[ 1 ] );
+ }
+
+ if ( ( events & EVENT_PIN ) != 0 ) {
+ _Thread_Pin( executing );
+ }
+
+ if ( ( events & EVENT_UNPIN ) != 0 ) {
+ _Thread_Unpin( executing, _Per_CPU_Get_snapshot() );
+ }
+
+ if ( ( events & EVENT_SET_LOW_PRIO ) != 0 ) {
+ SetSelfPriority( PRIO_LOW );
+ }
+
+ if ( ( events & EVENT_RUNNER_SYNC_1 ) != 0 ) {
+ SendEvents( ctx->runner_id, EVENT_RUNNER_SYNC_1 );
+ }
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_TaskId_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_TaskId state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_TaskId_Task: {
+ /*
+ * While the ``task_id`` parameter is associated with a task.
+ */
+ ctx->task_id = ctx->worker_id[ 0 ];
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_TaskId_Invalid: {
+ /*
+ * While the ``task_id`` parameter is not associated with a task.
+ */
+ ctx->task_id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_TaskId_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_Scheduler_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_Scheduler state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_Scheduler_Home: {
+ /*
+ * While the scheduler specified by the ``scheduler_id`` parameter is the
+ * home scheduler of the task specified by the ``task_id`` parameter.
+ */
+ ctx->scheduler_to_set_id = ctx->scheduler_a_id;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_Scheduler_Other: {
+ /*
+ * While the scheduler specified by the ``scheduler_id`` parameter is not
+ * the home scheduler of the task specified by the ``task_id`` parameter.
+ */
+ ctx->scheduler_to_set_id = ctx->scheduler_b_id;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_Scheduler_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_Yes: {
+ /*
+ * While the scheduler specified by the ``scheduler_id`` parameter owns
+ * at least one processor.
+ */
+ /* Already set by Scheduler pre-condition */
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_No: {
+ /*
+ * While the scheduler specified by the ``scheduler_id`` parameter owns
+ * no processor.
+ */
+ ctx->scheduler_to_set_id = ctx->scheduler_d_id;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_SchedulerId_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_SchedulerId state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_SchedulerId_Scheduler: {
+ /*
+ * While the ``scheduler_id`` parameter is associated with a scheduler.
+ */
+ ctx->scheduler_id = ctx->scheduler_to_set_id;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_SchedulerId_Invalid: {
+ /*
+ * While the ``scheduler_id`` parameter is not associated with a
+ * scheduler.
+ */
+ ctx->scheduler_id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_SchedulerId_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_Priority_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_Priority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_Priority_Valid: {
+ /*
+ * While the task priority specified by the ``priority`` parameter is
+ * valid with respect to the scheduler specified by the ``scheduler_id``
+ * parameter.
+ */
+ ctx->priority = PRIO_VERY_LOW;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_Priority_Invalid: {
+ /*
+ * While the task priority specified by the ``priority`` parameter is
+ * invalid with respect to the scheduler specified by the
+ * ``scheduler_id`` parameter.
+ */
+ ctx->priority = PRIO_INVALID;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_Priority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_HomePriority_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_HomePriority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_HomePriority_Real: {
+ /*
+ * While the current priority of the task specified by the ``task_id``
+ * parameter consists only of the real priority.
+ */
+ ctx->additional_home_priority = false;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_HomePriority_More: {
+ /*
+ * While the current priority of the task specified by the ``task_id``
+ * parameter consists of more than the real priority.
+ */
+ ctx->additional_home_priority = true;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_HomePriority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_EligiblePriorities_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_EligiblePriorities state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_EligiblePriorities_OnlyOne: {
+ /*
+ * While the set of eligible priorities of the task specified by the
+ * ``task_id`` parameter consists of exactly the current priority.
+ */
+ ctx->second_eligible_scheduler = false;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_EligiblePriorities_More: {
+ /*
+ * While the set of eligible priorities of the task specified by the
+ * ``task_id`` parameter consists of more than the current priority.
+ */
+ ctx->second_eligible_scheduler = true;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_EligiblePriorities_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_Pinned_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_Pinned state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_Pinned_Yes: {
+ /*
+ * While the task specified by the ``task_id`` parameter is pinned.
+ */
+ ctx->pinned = true;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_Pinned_No: {
+ /*
+ * While the task specified by the ``task_id`` parameter is not pinned.
+ */
+ ctx->pinned = false;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_Pinned_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_TaskState_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_TaskState state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_TaskState_Ready: {
+ /*
+ * While the task specified by the ``task_id`` parameter is ready.
+ */
+ ctx->blocked = false;
+ ctx->enqueued = false;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_TaskState_Blocked: {
+ /*
+ * While the task specified by the ``task_id`` parameter is blocked,
+ * while the task specified by the ``task_id`` parameter is not enqueued
+ * on a wait queue.
+ */
+ ctx->blocked = true;
+ ctx->enqueued = false;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_TaskState_Enqueued: {
+ /*
+ * While the task specified by the ``task_id`` parameter is blocked,
+ * while the task specified by the ``task_id`` parameter is enqueued on a
+ * wait queue.
+ */
+ ctx->blocked = true;
+ ctx->enqueued = true;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_TaskState_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Pre_AffinitySupported_Prepare(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Pre_AffinitySupported state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Pre_AffinitySupported_Yes: {
+ /*
+ * While the affinity set of the task specified by the ``task_id``
+ * parameter is supported by the scheduler specified by the
+ * ``scheduler_id`` parameter.
+ */
+ ctx->affinity_supported = true;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_AffinitySupported_No: {
+ /*
+ * While the affinity set of the task specified by the ``task_id``
+ * parameter is not supported by the scheduler specified by the
+ * ``scheduler_id`` parameter.
+ */
+ ctx->affinity_supported = false;
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Pre_AffinitySupported_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Post_Status_Check(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_set_scheduler() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_task_set_scheduler() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_set_scheduler() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Status_InvPrio: {
+ /*
+ * The return status of rtems_task_set_scheduler() shall be
+ * RTEMS_INVALID_PRIORITY.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_PRIORITY );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Status_InUse: {
+ /*
+ * The return status of rtems_task_set_scheduler() shall be
+ * RTEMS_RESOURCE_IN_USE.
+ */
+ T_rsc( ctx->status, RTEMS_RESOURCE_IN_USE );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Status_Unsat: {
+ /*
+ * The return status of rtems_task_set_scheduler() shall be
+ * RTEMS_UNSATISFIED.
+ */
+ T_rsc( ctx->status, RTEMS_UNSATISFIED );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Post_Scheduler_Check(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Post_Scheduler state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Post_Scheduler_Set: {
+ /*
+ * The home scheduler of the task specified by the ``task_id`` parameter
+ * shall be set to the scheduler specified by the ``scheduler_id``
+ * parameter at some point during the rtems_task_set_scheduler() call.
+ */
+ T_eq_u32( ctx->new_scheduler, ctx->scheduler_to_set_id );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Scheduler_Nop: {
+ /*
+ * No home scheduler of a task shall be modified by the
+ * rtems_task_set_scheduler() call.
+ */
+ T_eq_u32( ctx->new_scheduler, ctx->scheduler_a_id );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Scheduler_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Post_Priority_Check(
+ RtemsTaskReqSetScheduler_Context *ctx,
+ RtemsTaskReqSetScheduler_Post_Priority state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSetScheduler_Post_Priority_Set: {
+ /*
+ * The real priority of the task specified by the ``task_id`` parameter
+ * shall be set to the priority specified by the ``priority`` parameter
+ * at some point during the rtems_task_set_scheduler() call.
+ */
+ if ( ctx->scheduler_to_set_id == ctx->scheduler_a_id ) {
+ T_eq_u32( ctx->new_priority[ 0 ], PRIO_VERY_LOW );
+ T_eq_u32( ctx->new_priority[ 1 ], PRIO_INVALID );
+ } else {
+ T_eq_u32( ctx->new_priority[ 0 ], PRIO_INVALID );
+ T_eq_u32( ctx->new_priority[ 1 ], PRIO_VERY_LOW );
+ }
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Priority_Nop: {
+ /*
+ * No task priority shall be modified by the rtems_task_set_scheduler()
+ * call.
+ */
+ if ( ctx->blocked ) {
+ T_eq_u32( ctx->new_priority[ 0 ], PRIO_HIGH );
+ } else {
+ T_eq_u32( ctx->new_priority[ 0 ], PRIO_LOW );
+ }
+
+ T_eq_u32( ctx->new_priority[ 1 ], PRIO_INVALID );
+ break;
+ }
+
+ case RtemsTaskReqSetScheduler_Post_Priority_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSetScheduler_Setup(
+ RtemsTaskReqSetScheduler_Context *ctx
+)
+{
+ rtems_status_code sc;
+ size_t i;
+
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->runner_id = rtems_task_self();
+ SetSelfPriority( PRIO_NORMAL );
+
+ sc = rtems_scheduler_ident(
+ TEST_SCHEDULER_A_NAME,
+ &ctx->scheduler_a_id
+ );
+ T_rsc_success( sc );
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->mutex_id ); ++i ) {
+ ctx->mutex_id[ i ] = CreateMutex();
+ }
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->worker_id ); ++i ) {
+ ctx->worker_id[ i ] = CreateTask( "WORK", PRIO_HIGH - i );
+ StartTask( ctx->worker_id[ i ], Worker, ctx );
+ }
+
+ #if defined(RTEMS_SMP)
+ sc = rtems_scheduler_ident( TEST_SCHEDULER_B_NAME, &ctx->scheduler_b_id );
+ T_rsc_success( sc );
+
+ sc = rtems_scheduler_ident( TEST_SCHEDULER_D_NAME, &ctx->scheduler_d_id );
+ T_rsc_success( sc );
+
+ SetScheduler( ctx->worker_id[ 2 ], ctx->scheduler_b_id, PRIO_NORMAL );
+ #else
+ ctx->scheduler_b_id = INVALID_ID;
+ #endif
+}
+
+static void RtemsTaskReqSetScheduler_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqSetScheduler_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqSetScheduler_Setup( ctx );
+}
+
+static void RtemsTaskReqSetScheduler_Teardown(
+ RtemsTaskReqSetScheduler_Context *ctx
+)
+{
+ size_t i;
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->worker_id ); ++i ) {
+ DeleteTask( ctx->worker_id[ i ] );
+ }
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->mutex_id ); ++i ) {
+ DeleteMutex( ctx->mutex_id[ i ] );
+ }
+
+ RestoreRunnerPriority();
+}
+
+static void RtemsTaskReqSetScheduler_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqSetScheduler_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqSetScheduler_Teardown( ctx );
+}
+
+static void RtemsTaskReqSetScheduler_Action(
+ RtemsTaskReqSetScheduler_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ if ( ctx->additional_home_priority || ctx->second_eligible_scheduler ) {
+ SendEvents( ctx->worker_id[ 0 ], EVENT_OBTAIN_MUTEX_A );
+
+ if ( ctx->additional_home_priority ) {
+ SendEvents( ctx->worker_id[ 1 ], EVENT_OBTAIN_MUTEX_A );
+ }
+
+ if ( ctx->second_eligible_scheduler ) {
+ SendEvents(
+ ctx->worker_id[ 2 ],
+ EVENT_RUNNER_SYNC_0 | EVENT_OBTAIN_MUTEX_A
+ );
+ ReceiveAllEvents( EVENT_RUNNER_SYNC_0 );
+ WaitForExecutionStop( ctx->worker_id[ 2 ] );
+ }
+ }
+
+ if ( ctx->blocked && ctx->enqueued ) {
+ ObtainMutex( ctx->mutex_id[ 1 ] );
+ SendEvents( ctx->worker_id[ 0 ], EVENT_OBTAIN_MUTEX_B );
+ }
+
+ if ( !ctx->affinity_supported ) {
+ SetAffinityOne( ctx->worker_id[ 0 ], 0 );
+ }
+
+ if ( ctx->pinned ) {
+ SendEvents( ctx->worker_id[ 0 ], EVENT_PIN );
+ }
+
+ if ( !ctx->blocked ) {
+ SendEvents( ctx->worker_id[ 0 ], EVENT_SET_LOW_PRIO );
+ }
+
+ ctx->status = rtems_task_set_scheduler(
+ ctx->task_id,
+ ctx->scheduler_id,
+ ctx->priority
+ );
+
+ ctx->new_scheduler = GetScheduler( ctx->worker_id[ 0 ] );
+
+ if ( ctx->pinned ) {
+ SendEvents( ctx->worker_id[ 0 ], EVENT_UNPIN );
+ }
+
+ if ( !ctx->affinity_supported ) {
+ SetAffinityAll( ctx->worker_id[ 0 ] );
+ }
+
+ if ( ctx->blocked && ctx->enqueued ) {
+ ReleaseMutex( ctx->mutex_id[ 1 ] );
+ SendEvents( ctx->worker_id[ 0 ], EVENT_RELEASE_MUTEX_B );
+ }
+
+ if ( ctx->additional_home_priority || ctx->second_eligible_scheduler ) {
+ SendEvents( ctx->worker_id[ 0 ], EVENT_RELEASE_MUTEX_A );
+
+ if ( ctx->additional_home_priority ) {
+ SendEvents( ctx->worker_id[ 1 ], EVENT_RELEASE_MUTEX_A );
+ }
+
+ if ( ctx->second_eligible_scheduler ) {
+ SendEvents(
+ ctx->worker_id[ 2 ],
+ EVENT_RELEASE_MUTEX_A | EVENT_RUNNER_SYNC_1
+ );
+ ReceiveAllEvents( EVENT_RUNNER_SYNC_1 );
+ }
+ }
+
+ sc = rtems_task_get_priority(
+ ctx->worker_id[ 0 ],
+ ctx->scheduler_a_id,
+ &ctx->new_priority[ 0 ]
+ );
+
+ if ( sc == RTEMS_NOT_DEFINED ) {
+ ctx->new_priority[ 0 ] = PRIO_INVALID;
+ } else {
+ T_rsc_success( sc );
+ }
+
+ #if defined(RTEMS_SMP)
+ sc = rtems_task_get_priority(
+ ctx->worker_id[ 0 ],
+ ctx->scheduler_b_id,
+ &ctx->new_priority[ 1 ]
+ );
+
+ if ( sc == RTEMS_NOT_DEFINED ) {
+ ctx->new_priority[ 1 ] = PRIO_INVALID;
+ } else {
+ T_rsc_success( sc );
+ }
+ #else
+ ctx->new_priority[ 1 ] = PRIO_INVALID;
+ #endif
+
+ if ( ctx->status == RTEMS_SUCCESSFUL ) {
+ SetScheduler( ctx->worker_id[ 0 ], ctx->scheduler_a_id, PRIO_HIGH );
+ } else if ( !ctx->blocked ) {
+ SetPriority( ctx->worker_id[ 0 ], PRIO_HIGH );
+ }
+}
+
+static const RtemsTaskReqSetScheduler_Entry
+RtemsTaskReqSetScheduler_Entries[] = {
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#else
+ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1,
+ RtemsTaskReqSetScheduler_Post_Status_InvId,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#else
+ { 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ RtemsTaskReqSetScheduler_Post_Status_InvId,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+#endif
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqSetScheduler_Post_Status_InvPrio,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
+ RtemsTaskReqSetScheduler_Post_Status_InvId,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
+ RtemsTaskReqSetScheduler_Post_Status_InvPrio,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqSetScheduler_Post_Status_InUse,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+#endif
+ { 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1,
+ RtemsTaskReqSetScheduler_Post_Status_InvId,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+ { 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ RtemsTaskReqSetScheduler_Post_Status_InvId,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqSetScheduler_Post_Status_InvPrio,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqSetScheduler_Post_Status_Unsat,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+#endif
+ { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
+ RtemsTaskReqSetScheduler_Post_Status_InvId,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0,
+ RtemsTaskReqSetScheduler_Post_Status_InvPrio,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTaskReqSetScheduler_Post_Status_InUse,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Nop,
+ RtemsTaskReqSetScheduler_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_Ok,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Set,
+ RtemsTaskReqSetScheduler_Post_Priority_Set },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_NA,
+ RtemsTaskReqSetScheduler_Post_Scheduler_NA,
+ RtemsTaskReqSetScheduler_Post_Priority_NA }
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTaskReqSetScheduler_Post_Status_Ok,
+ RtemsTaskReqSetScheduler_Post_Scheduler_Set,
+ RtemsTaskReqSetScheduler_Post_Priority_Set }
+#endif
+};
+
+static const uint8_t
+RtemsTaskReqSetScheduler_Map[] = {
+ 7, 0, 7, 0, 7, 0, 15, 3, 15, 3, 14, 3, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7,
+ 0, 7, 0, 7, 0, 14, 3, 14, 3, 14, 3, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 7, 0, 4, 0,
+ 4, 0, 4, 0, 10, 3, 10, 3, 10, 3, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4,
+ 0, 4, 0, 10, 3, 10, 3, 10, 3, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, 0, 1, 0, 1, 0,
+ 1, 0, 8, 3, 8, 3, 8, 3, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0,
+ 8, 3, 8, 3, 8, 3, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 8, 3,
+ 8, 3, 8, 3, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 8, 3, 8, 3,
+ 8, 3, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7,
+ 7, 7, 7, 7, 16, 11, 16, 11, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7, 7, 7, 7, 7, 11, 11, 11, 11, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 0, 5, 0,
+ 5, 0, 12, 3, 12, 3, 12, 3, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5,
+ 0, 12, 3, 12, 3, 12, 3, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 5, 0, 6, 0, 6, 0, 6, 0,
+ 13, 3, 13, 3, 13, 3, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0,
+ 13, 3, 13, 3, 13, 3, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 6, 0, 2, 0, 2, 0, 2, 0, 9,
+ 3, 9, 3, 9, 3, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 9, 3, 9,
+ 3, 9, 3, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 9, 3, 9, 3, 9,
+ 3, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 9, 3, 9, 3, 9, 3, 2,
+ 0, 2, 0, 2, 0, 2, 0, 2, 0, 2, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
+};
+
+static size_t RtemsTaskReqSetScheduler_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqSetScheduler_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsTaskReqSetScheduler_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqSetScheduler_Fixture = {
+ .setup = RtemsTaskReqSetScheduler_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqSetScheduler_Teardown_Wrap,
+ .scope = RtemsTaskReqSetScheduler_Scope,
+ .initial_context = &RtemsTaskReqSetScheduler_Instance
+};
+
+static inline RtemsTaskReqSetScheduler_Entry RtemsTaskReqSetScheduler_PopEntry(
+ RtemsTaskReqSetScheduler_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqSetScheduler_Entries[
+ RtemsTaskReqSetScheduler_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqSetScheduler_SetPreConditionStates(
+ RtemsTaskReqSetScheduler_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+
+ if ( ctx->Map.entry.Pre_Scheduler_NA ) {
+ ctx->Map.pcs[ 1 ] = RtemsTaskReqSetScheduler_Pre_Scheduler_NA;
+ } else {
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ }
+
+ if ( ctx->Map.entry.Pre_SchedulerHasCPU_NA ) {
+ ctx->Map.pcs[ 2 ] = RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_NA;
+ } else {
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ }
+
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+
+ if ( ctx->Map.entry.Pre_Priority_NA ) {
+ ctx->Map.pcs[ 4 ] = RtemsTaskReqSetScheduler_Pre_Priority_NA;
+ } else {
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+ }
+
+ if ( ctx->Map.entry.Pre_HomePriority_NA ) {
+ ctx->Map.pcs[ 5 ] = RtemsTaskReqSetScheduler_Pre_HomePriority_NA;
+ } else {
+ ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
+ }
+
+ if ( ctx->Map.entry.Pre_EligiblePriorities_NA ) {
+ ctx->Map.pcs[ 6 ] = RtemsTaskReqSetScheduler_Pre_EligiblePriorities_NA;
+ } else {
+ ctx->Map.pcs[ 6 ] = ctx->Map.pci[ 6 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Pinned_NA ) {
+ ctx->Map.pcs[ 7 ] = RtemsTaskReqSetScheduler_Pre_Pinned_NA;
+ } else {
+ ctx->Map.pcs[ 7 ] = ctx->Map.pci[ 7 ];
+ }
+
+ if ( ctx->Map.entry.Pre_TaskState_NA ) {
+ ctx->Map.pcs[ 8 ] = RtemsTaskReqSetScheduler_Pre_TaskState_NA;
+ } else {
+ ctx->Map.pcs[ 8 ] = ctx->Map.pci[ 8 ];
+ }
+
+ if ( ctx->Map.entry.Pre_AffinitySupported_NA ) {
+ ctx->Map.pcs[ 9 ] = RtemsTaskReqSetScheduler_Pre_AffinitySupported_NA;
+ } else {
+ ctx->Map.pcs[ 9 ] = ctx->Map.pci[ 9 ];
+ }
+}
+
+static void RtemsTaskReqSetScheduler_TestVariant(
+ RtemsTaskReqSetScheduler_Context *ctx
+)
+{
+ RtemsTaskReqSetScheduler_Pre_TaskId_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqSetScheduler_Pre_Scheduler_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_Prepare(
+ ctx,
+ ctx->Map.pcs[ 2 ]
+ );
+ RtemsTaskReqSetScheduler_Pre_SchedulerId_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsTaskReqSetScheduler_Pre_Priority_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsTaskReqSetScheduler_Pre_HomePriority_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsTaskReqSetScheduler_Pre_EligiblePriorities_Prepare(
+ ctx,
+ ctx->Map.pcs[ 6 ]
+ );
+ RtemsTaskReqSetScheduler_Pre_Pinned_Prepare( ctx, ctx->Map.pcs[ 7 ] );
+ RtemsTaskReqSetScheduler_Pre_TaskState_Prepare( ctx, ctx->Map.pcs[ 8 ] );
+ RtemsTaskReqSetScheduler_Pre_AffinitySupported_Prepare(
+ ctx,
+ ctx->Map.pcs[ 9 ]
+ );
+ RtemsTaskReqSetScheduler_Action( ctx );
+ RtemsTaskReqSetScheduler_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ RtemsTaskReqSetScheduler_Post_Scheduler_Check(
+ ctx,
+ ctx->Map.entry.Post_Scheduler
+ );
+ RtemsTaskReqSetScheduler_Post_Priority_Check(
+ ctx,
+ ctx->Map.entry.Post_Priority
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqSetScheduler( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTaskReqSetScheduler,
+ &RtemsTaskReqSetScheduler_Fixture
+)
+{
+ RtemsTaskReqSetScheduler_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsTaskReqSetScheduler_Pre_TaskId_Task;
+ ctx->Map.pci[ 0 ] < RtemsTaskReqSetScheduler_Pre_TaskId_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsTaskReqSetScheduler_Pre_Scheduler_Home;
+ ctx->Map.pci[ 1 ] < RtemsTaskReqSetScheduler_Pre_Scheduler_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_Yes;
+ ctx->Map.pci[ 2 ] < RtemsTaskReqSetScheduler_Pre_SchedulerHasCPU_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = RtemsTaskReqSetScheduler_Pre_SchedulerId_Scheduler;
+ ctx->Map.pci[ 3 ] < RtemsTaskReqSetScheduler_Pre_SchedulerId_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ for (
+ ctx->Map.pci[ 4 ] = RtemsTaskReqSetScheduler_Pre_Priority_Valid;
+ ctx->Map.pci[ 4 ] < RtemsTaskReqSetScheduler_Pre_Priority_NA;
+ ++ctx->Map.pci[ 4 ]
+ ) {
+ for (
+ ctx->Map.pci[ 5 ] = RtemsTaskReqSetScheduler_Pre_HomePriority_Real;
+ ctx->Map.pci[ 5 ] < RtemsTaskReqSetScheduler_Pre_HomePriority_NA;
+ ++ctx->Map.pci[ 5 ]
+ ) {
+ for (
+ ctx->Map.pci[ 6 ] = RtemsTaskReqSetScheduler_Pre_EligiblePriorities_OnlyOne;
+ ctx->Map.pci[ 6 ] < RtemsTaskReqSetScheduler_Pre_EligiblePriorities_NA;
+ ++ctx->Map.pci[ 6 ]
+ ) {
+ for (
+ ctx->Map.pci[ 7 ] = RtemsTaskReqSetScheduler_Pre_Pinned_Yes;
+ ctx->Map.pci[ 7 ] < RtemsTaskReqSetScheduler_Pre_Pinned_NA;
+ ++ctx->Map.pci[ 7 ]
+ ) {
+ for (
+ ctx->Map.pci[ 8 ] = RtemsTaskReqSetScheduler_Pre_TaskState_Ready;
+ ctx->Map.pci[ 8 ] < RtemsTaskReqSetScheduler_Pre_TaskState_NA;
+ ++ctx->Map.pci[ 8 ]
+ ) {
+ for (
+ ctx->Map.pci[ 9 ] = RtemsTaskReqSetScheduler_Pre_AffinitySupported_Yes;
+ ctx->Map.pci[ 9 ] < RtemsTaskReqSetScheduler_Pre_AffinitySupported_NA;
+ ++ctx->Map.pci[ 9 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqSetScheduler_PopEntry(
+ ctx
+ );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsTaskReqSetScheduler_SetPreConditionStates( ctx );
+ RtemsTaskReqSetScheduler_TestVariant( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-smp.c b/testsuites/validation/tc-task-smp.c
new file mode 100644
index 0000000000..9bfdc4fd73
--- /dev/null
+++ b/testsuites/validation/tc-task-smp.c
@@ -0,0 +1,146 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskValSmp
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskValSmp spec:/rtems/task/val/smp
+ *
+ * @ingroup TestsuitesValidationSmpOnly0
+ *
+ * @brief This test case collection provides SMP-specific validation test cases
+ * for requirements of the @ref RTEMSAPIClassicTasks.
+ *
+ * This test case performs the following actions:
+ *
+ * - Validate the home scheduler of tasks created by rtems_task_create() and
+ * constructed by rtems_task_construct() on scheduler B.
+ *
+ * - Move runner from scheduler A to B.
+ *
+ * - Create a task. Check that the home scheduler of the created task is
+ * scheduler B.
+ *
+ * - Construct a task. Check that the home scheduler of the constructed task
+ * is scheduler B.
+ *
+ * - Restore runner scheduler.
+ *
+ * @{
+ */
+
+/**
+ * @brief Validate the home scheduler of tasks created by rtems_task_create()
+ * and constructed by rtems_task_construct() on scheduler B.
+ */
+static void RtemsTaskValSmp_Action_0( void )
+{
+ rtems_status_code sc;
+ rtems_status_code id;
+
+ /*
+ * Move runner from scheduler A to B.
+ */
+ T_step_eq_u32( 0, GetSelfScheduler(), SCHEDULER_A_ID );
+ SetSelfScheduler( SCHEDULER_B_ID, 1 );
+
+ /*
+ * Create a task. Check that the home scheduler of the created task is
+ * scheduler B.
+ */
+ sc = rtems_task_create(
+ OBJECT_NAME,
+ 1,
+ TEST_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &id
+ );
+ T_step_rsc_success( 1, sc );
+
+ T_step_eq_u32( 2, GetScheduler( id ), SCHEDULER_B_ID );
+ DeleteTask( id );
+
+ /*
+ * Construct a task. Check that the home scheduler of the constructed task
+ * is scheduler B.
+ */
+ sc = rtems_task_construct( &DefaultTaskConfig, &id );
+ T_step_rsc_success( 3, sc );
+
+ T_step_eq_u32( 4, GetScheduler( id ), SCHEDULER_B_ID );
+ DeleteTask( id );
+
+ /*
+ * Restore runner scheduler.
+ */
+ RestoreRunnerScheduler();
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskValSmp( void )
+ */
+T_TEST_CASE( RtemsTaskValSmp )
+{
+ T_plan( 5 );
+
+ RtemsTaskValSmp_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-start.c b/testsuites/validation/tc-task-start.c
new file mode 100644
index 0000000000..235d9f0827
--- /dev/null
+++ b/testsuites/validation/tc-task-start.c
@@ -0,0 +1,859 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqStart
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/test-scheduler.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqStart spec:/rtems/task/req/start
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqStart_Pre_Id_Invalid,
+ RtemsTaskReqStart_Pre_Id_Task,
+ RtemsTaskReqStart_Pre_Id_NA
+} RtemsTaskReqStart_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqStart_Pre_EntryPoint_Valid,
+ RtemsTaskReqStart_Pre_EntryPoint_Null,
+ RtemsTaskReqStart_Pre_EntryPoint_NA
+} RtemsTaskReqStart_Pre_EntryPoint;
+
+typedef enum {
+ RtemsTaskReqStart_Pre_Argument_Pointer,
+ RtemsTaskReqStart_Pre_Argument_Number,
+ RtemsTaskReqStart_Pre_Argument_NA
+} RtemsTaskReqStart_Pre_Argument;
+
+typedef enum {
+ RtemsTaskReqStart_Pre_Dormant_Yes,
+ RtemsTaskReqStart_Pre_Dormant_No,
+ RtemsTaskReqStart_Pre_Dormant_NA
+} RtemsTaskReqStart_Pre_Dormant;
+
+typedef enum {
+ RtemsTaskReqStart_Pre_Suspended_Yes,
+ RtemsTaskReqStart_Pre_Suspended_No,
+ RtemsTaskReqStart_Pre_Suspended_NA
+} RtemsTaskReqStart_Pre_Suspended;
+
+typedef enum {
+ RtemsTaskReqStart_Post_Status_Ok,
+ RtemsTaskReqStart_Post_Status_InvAddr,
+ RtemsTaskReqStart_Post_Status_InvId,
+ RtemsTaskReqStart_Post_Status_IncStat,
+ RtemsTaskReqStart_Post_Status_NA
+} RtemsTaskReqStart_Post_Status;
+
+typedef enum {
+ RtemsTaskReqStart_Post_EntryPoint_Set,
+ RtemsTaskReqStart_Post_EntryPoint_Nop,
+ RtemsTaskReqStart_Post_EntryPoint_NA
+} RtemsTaskReqStart_Post_EntryPoint;
+
+typedef enum {
+ RtemsTaskReqStart_Post_Argument_Set,
+ RtemsTaskReqStart_Post_Argument_Nop,
+ RtemsTaskReqStart_Post_Argument_NA
+} RtemsTaskReqStart_Post_Argument;
+
+typedef enum {
+ RtemsTaskReqStart_Post_Unblock_Yes,
+ RtemsTaskReqStart_Post_Unblock_Nop,
+ RtemsTaskReqStart_Post_Unblock_NA
+} RtemsTaskReqStart_Post_Unblock;
+
+typedef enum {
+ RtemsTaskReqStart_Post_StartExtensions_Yes,
+ RtemsTaskReqStart_Post_StartExtensions_Nop,
+ RtemsTaskReqStart_Post_StartExtensions_NA
+} RtemsTaskReqStart_Post_StartExtensions;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_Id_NA : 1;
+ uint32_t Pre_EntryPoint_NA : 1;
+ uint32_t Pre_Argument_NA : 1;
+ uint32_t Pre_Dormant_NA : 1;
+ uint32_t Pre_Suspended_NA : 1;
+ uint32_t Post_Status : 3;
+ uint32_t Post_EntryPoint : 2;
+ uint32_t Post_Argument : 2;
+ uint32_t Post_Unblock : 2;
+ uint32_t Post_StartExtensions : 2;
+} RtemsTaskReqStart_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/start test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides the scheduler operation records.
+ */
+ T_scheduler_log_2 scheduler_log;
+
+ /**
+ * @brief This member contains the identifier of a task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member contains the identifier of the test user extensions.
+ */
+ rtems_id extension_id;
+
+ /**
+ * @brief This member contains the count of thread start extension calls.
+ */
+ uint32_t start_extension_calls;
+
+ /**
+ * @brief This member contains the actual argument passed to the entry point.
+ */
+ rtems_task_argument actual_argument;
+
+ /**
+ * @brief This member contains the entry point counter.
+ */
+ uint32_t counter;
+
+ /**
+ * @brief If this member is true, then the worker is started before the
+ * rtems_task_start() call.
+ */
+ bool start;
+
+ /**
+ * @brief If this member is true, then the worker is suspended before the
+ * rtems_task_start() call.
+ */
+ bool suspend;
+
+ /**
+ * @brief This member contains the return value of the rtems_task_start()
+ * call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ /**
+ * @brief This member specifies if the ``entry_point`` parameter value.
+ */
+ rtems_task_entry entry_point;
+
+ /**
+ * @brief This member specifies if the ``argument`` parameter value.
+ */
+ rtems_task_argument argument;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 5 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 5 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqStart_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqStart_Context;
+
+static RtemsTaskReqStart_Context
+ RtemsTaskReqStart_Instance;
+
+static const char * const RtemsTaskReqStart_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqStart_PreDesc_EntryPoint[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsTaskReqStart_PreDesc_Argument[] = {
+ "Pointer",
+ "Number",
+ "NA"
+};
+
+static const char * const RtemsTaskReqStart_PreDesc_Dormant[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqStart_PreDesc_Suspended[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqStart_PreDesc[] = {
+ RtemsTaskReqStart_PreDesc_Id,
+ RtemsTaskReqStart_PreDesc_EntryPoint,
+ RtemsTaskReqStart_PreDesc_Argument,
+ RtemsTaskReqStart_PreDesc_Dormant,
+ RtemsTaskReqStart_PreDesc_Suspended,
+ NULL
+};
+
+typedef RtemsTaskReqStart_Context Context;
+
+static void WorkerA( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = &RtemsTaskReqStart_Instance;
+
+ while ( true ) {
+ ctx->actual_argument += arg;
+ ++ctx->counter;
+ Yield();
+ }
+}
+
+static void WorkerB( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = &RtemsTaskReqStart_Instance;
+
+ while ( true ) {
+ ctx->actual_argument += arg;
+ Yield();
+ }
+}
+
+static void ThreadStart( rtems_tcb *executing, rtems_tcb *started )
+{
+ (void) executing;
+ (void) started;
+
+ ++RtemsTaskReqStart_Instance.start_extension_calls;
+}
+
+static const rtems_extensions_table extensions = {
+ .thread_start = ThreadStart
+};
+
+static void RtemsTaskReqStart_Pre_Id_Prepare(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_Id_Task: {
+ /*
+ * While the ``id`` parameter is associated with a task.
+ */
+ ctx->id = ctx->worker_id;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Pre_EntryPoint_Prepare(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Pre_EntryPoint state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Pre_EntryPoint_Valid: {
+ /*
+ * While the task entry point specified by the ``entry_point`` parameter
+ * is valid.
+ */
+ ctx->entry_point = WorkerA;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_EntryPoint_Null: {
+ /*
+ * While the task entry point specified by the ``entry_point`` parameter
+ * is equal to NULL.
+ */
+ ctx->entry_point = NULL;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_EntryPoint_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Pre_Argument_Prepare(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Pre_Argument state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Pre_Argument_Pointer: {
+ /*
+ * While the entry point argument specified by the ``argument`` parameter
+ * is a pointer.
+ */
+ ctx->argument = (rtems_task_argument) ctx;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_Argument_Number: {
+ /*
+ * While the entry point argument specified by the ``argument`` parameter
+ * is a 32-bit number.
+ */
+ ctx->argument = UINT32_C( 0x87654321 );
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_Argument_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Pre_Dormant_Prepare(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Pre_Dormant state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Pre_Dormant_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is dormant.
+ */
+ ctx->start = false;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_Dormant_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not dormant.
+ */
+ ctx->start = true;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_Dormant_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Pre_Suspended_Prepare(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Pre_Suspended state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Pre_Suspended_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is suspended.
+ */
+ ctx->suspend = true;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_Suspended_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not suspended.
+ */
+ ctx->suspend = false;
+ break;
+ }
+
+ case RtemsTaskReqStart_Pre_Suspended_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Post_Status_Check(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_start() shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_task_start() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_start() shall be RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_Status_IncStat: {
+ /*
+ * The return status of rtems_task_start() shall be
+ * RTEMS_INCORRECT_STATE.
+ */
+ T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Post_EntryPoint_Check(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Post_EntryPoint state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Post_EntryPoint_Set: {
+ /*
+ * The entry point of the task specified by the ``id`` parameter shall be
+ * set to the function specified by the ``entry_point`` parameter before
+ * the task is unblocked by the rtems_task_start() call.
+ */
+ T_eq_u32( ctx->counter, 1 );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_EntryPoint_Nop: {
+ /*
+ * No entry point of a task shall be modified by the rtems_task_start()
+ * call.
+ */
+ T_eq_u32( ctx->counter, 0 );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_EntryPoint_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Post_Argument_Check(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Post_Argument state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Post_Argument_Set: {
+ /*
+ * The entry point argument of the task specified by the ``id`` parameter
+ * shall be set to the value specified by the ``argument`` parameter
+ * before the task is unblocked by the rtems_task_start() call.
+ */
+ T_eq_u32( ctx->actual_argument, ctx->argument );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_Argument_Nop: {
+ /*
+ * No entry point argument of a task shall be modified by the
+ * rtems_task_start() call.
+ */
+ T_eq_u32( ctx->actual_argument, 0 );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_Argument_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Post_Unblock_Check(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Post_Unblock state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Post_Unblock_Yes: {
+ /*
+ * The task specified by the ``id`` parameter shall be unblocked by the
+ * rtems_task_start() call.
+ */
+ T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_UNBLOCK
+ );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_Unblock_Nop: {
+ /*
+ * No task shall be unblocked by the rtems_task_start() call.
+ */
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_Unblock_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Post_StartExtensions_Check(
+ RtemsTaskReqStart_Context *ctx,
+ RtemsTaskReqStart_Post_StartExtensions state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStart_Post_StartExtensions_Yes: {
+ /*
+ * The thread start user extensions shall be invoked by the
+ * rtems_task_start() call.
+ */
+ T_eq_u32( ctx->start_extension_calls, 1 );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_StartExtensions_Nop: {
+ /*
+ * The thread start user extensions shall not be invoked by the
+ * rtems_task_start() call.
+ */
+ T_eq_u32( ctx->start_extension_calls, 0 );
+ break;
+ }
+
+ case RtemsTaskReqStart_Post_StartExtensions_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStart_Setup( RtemsTaskReqStart_Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_extension_create(
+ rtems_build_name( 'T', 'E', 'S', 'T' ),
+ &extensions,
+ &ctx->extension_id
+ );
+ T_rsc_success( sc );
+}
+
+static void RtemsTaskReqStart_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqStart_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqStart_Setup( ctx );
+}
+
+static void RtemsTaskReqStart_Teardown( RtemsTaskReqStart_Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_extension_delete( ctx->extension_id );
+ T_rsc_success( sc );
+}
+
+static void RtemsTaskReqStart_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqStart_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqStart_Teardown( ctx );
+}
+
+static void RtemsTaskReqStart_Prepare( RtemsTaskReqStart_Context *ctx )
+{
+ ctx->actual_argument = 0;
+ ctx->counter = 0;
+ ctx->worker_id = CreateTask( "WORK", PRIO_DEFAULT );
+}
+
+static void RtemsTaskReqStart_Action( RtemsTaskReqStart_Context *ctx )
+{
+ T_scheduler_log *log;
+
+ if ( ctx->start ) {
+ StartTask( ctx->worker_id, WorkerB, 0 );
+ }
+
+ if ( ctx->suspend ) {
+ SuspendTask( ctx->worker_id );
+ }
+
+ ctx->start_extension_calls = 0;
+
+ log = T_scheduler_record_2( &ctx->scheduler_log );
+ T_null( log );
+
+ ctx->status = rtems_task_start( ctx->id, ctx->entry_point, ctx->argument );
+
+ log = T_scheduler_record( NULL );
+ T_eq_ptr( &log->header, &ctx->scheduler_log.header );
+
+ Yield();
+}
+
+static void RtemsTaskReqStart_Cleanup( RtemsTaskReqStart_Context *ctx )
+{
+ DeleteTask( ctx->worker_id );
+}
+
+static const RtemsTaskReqStart_Entry
+RtemsTaskReqStart_Entries[] = {
+ { 0, 0, 0, 0, 0, 0, RtemsTaskReqStart_Post_Status_InvAddr,
+ RtemsTaskReqStart_Post_EntryPoint_Nop, RtemsTaskReqStart_Post_Argument_Nop,
+ RtemsTaskReqStart_Post_Unblock_Nop,
+ RtemsTaskReqStart_Post_StartExtensions_Nop },
+ { 0, 0, 0, 0, 1, 1, RtemsTaskReqStart_Post_Status_InvId,
+ RtemsTaskReqStart_Post_EntryPoint_Nop, RtemsTaskReqStart_Post_Argument_Nop,
+ RtemsTaskReqStart_Post_Unblock_Nop,
+ RtemsTaskReqStart_Post_StartExtensions_Nop },
+ { 0, 0, 0, 0, 0, 0, RtemsTaskReqStart_Post_Status_Ok,
+ RtemsTaskReqStart_Post_EntryPoint_Set, RtemsTaskReqStart_Post_Argument_Set,
+ RtemsTaskReqStart_Post_Unblock_Yes,
+ RtemsTaskReqStart_Post_StartExtensions_Yes },
+ { 0, 0, 0, 0, 0, 0, RtemsTaskReqStart_Post_Status_IncStat,
+ RtemsTaskReqStart_Post_EntryPoint_Nop, RtemsTaskReqStart_Post_Argument_Nop,
+ RtemsTaskReqStart_Post_Unblock_Nop,
+ RtemsTaskReqStart_Post_StartExtensions_Nop }
+};
+
+static const uint8_t
+RtemsTaskReqStart_Map[] = {
+ 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 3, 3, 2, 2, 3, 3, 0, 0,
+ 0, 0, 0, 0, 0, 0
+};
+
+static size_t RtemsTaskReqStart_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqStart_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsTaskReqStart_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqStart_Fixture = {
+ .setup = RtemsTaskReqStart_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqStart_Teardown_Wrap,
+ .scope = RtemsTaskReqStart_Scope,
+ .initial_context = &RtemsTaskReqStart_Instance
+};
+
+static inline RtemsTaskReqStart_Entry RtemsTaskReqStart_PopEntry(
+ RtemsTaskReqStart_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqStart_Entries[
+ RtemsTaskReqStart_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqStart_SetPreConditionStates(
+ RtemsTaskReqStart_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+
+ if ( ctx->Map.entry.Pre_Dormant_NA ) {
+ ctx->Map.pcs[ 3 ] = RtemsTaskReqStart_Pre_Dormant_NA;
+ } else {
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Suspended_NA ) {
+ ctx->Map.pcs[ 4 ] = RtemsTaskReqStart_Pre_Suspended_NA;
+ } else {
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+ }
+}
+
+static void RtemsTaskReqStart_TestVariant( RtemsTaskReqStart_Context *ctx )
+{
+ RtemsTaskReqStart_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqStart_Pre_EntryPoint_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqStart_Pre_Argument_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTaskReqStart_Pre_Dormant_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsTaskReqStart_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsTaskReqStart_Action( ctx );
+ RtemsTaskReqStart_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsTaskReqStart_Post_EntryPoint_Check(
+ ctx,
+ ctx->Map.entry.Post_EntryPoint
+ );
+ RtemsTaskReqStart_Post_Argument_Check( ctx, ctx->Map.entry.Post_Argument );
+ RtemsTaskReqStart_Post_Unblock_Check( ctx, ctx->Map.entry.Post_Unblock );
+ RtemsTaskReqStart_Post_StartExtensions_Check(
+ ctx,
+ ctx->Map.entry.Post_StartExtensions
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqStart( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTaskReqStart, &RtemsTaskReqStart_Fixture )
+{
+ RtemsTaskReqStart_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsTaskReqStart_Pre_Id_Invalid;
+ ctx->Map.pci[ 0 ] < RtemsTaskReqStart_Pre_Id_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsTaskReqStart_Pre_EntryPoint_Valid;
+ ctx->Map.pci[ 1 ] < RtemsTaskReqStart_Pre_EntryPoint_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsTaskReqStart_Pre_Argument_Pointer;
+ ctx->Map.pci[ 2 ] < RtemsTaskReqStart_Pre_Argument_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = RtemsTaskReqStart_Pre_Dormant_Yes;
+ ctx->Map.pci[ 3 ] < RtemsTaskReqStart_Pre_Dormant_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ for (
+ ctx->Map.pci[ 4 ] = RtemsTaskReqStart_Pre_Suspended_Yes;
+ ctx->Map.pci[ 4 ] < RtemsTaskReqStart_Pre_Suspended_NA;
+ ++ctx->Map.pci[ 4 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqStart_PopEntry( ctx );
+ RtemsTaskReqStart_SetPreConditionStates( ctx );
+ RtemsTaskReqStart_Prepare( ctx );
+ RtemsTaskReqStart_TestVariant( ctx );
+ RtemsTaskReqStart_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-storage-size.c b/testsuites/validation/tc-task-storage-size.c
new file mode 100644
index 0000000000..29ac53c237
--- /dev/null
+++ b/testsuites/validation/tc-task-storage-size.c
@@ -0,0 +1,427 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqStorageSize
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqStorageSize spec:/rtems/task/req/storage-size
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqStorageSize_Pre_Id_Invalid,
+ RtemsTaskReqStorageSize_Pre_Id_Task,
+ RtemsTaskReqStorageSize_Pre_Id_NA
+} RtemsTaskReqStorageSize_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqStorageSize_Pre_Suspended_Yes,
+ RtemsTaskReqStorageSize_Pre_Suspended_No,
+ RtemsTaskReqStorageSize_Pre_Suspended_NA
+} RtemsTaskReqStorageSize_Pre_Suspended;
+
+typedef enum {
+ RtemsTaskReqStorageSize_Post_Status_Ok,
+ RtemsTaskReqStorageSize_Post_Status_InvId,
+ RtemsTaskReqStorageSize_Post_Status_AlrdySus,
+ RtemsTaskReqStorageSize_Post_Status_NA
+} RtemsTaskReqStorageSize_Post_Status;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Pre_Suspended_NA : 1;
+ uint8_t Post_Status : 2;
+} RtemsTaskReqStorageSize_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/storage-size test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the identifier of a task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief If this member is true, then the worker is suspended before the
+ * rtems_task_suspend() call.
+ */
+ bool suspend;
+
+ /**
+ * @brief This member contains the return value of the rtems_task_suspend()
+ * call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 2 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqStorageSize_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqStorageSize_Context;
+
+static RtemsTaskReqStorageSize_Context
+ RtemsTaskReqStorageSize_Instance;
+
+static const char * const RtemsTaskReqStorageSize_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqStorageSize_PreDesc_Suspended[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqStorageSize_PreDesc[] = {
+ RtemsTaskReqStorageSize_PreDesc_Id,
+ RtemsTaskReqStorageSize_PreDesc_Suspended,
+ NULL
+};
+
+static void Worker( rtems_task_argument arg )
+{
+ while ( true ) {
+ /* Do nothing */
+ }
+}
+
+static void RtemsTaskReqStorageSize_Pre_Id_Prepare(
+ RtemsTaskReqStorageSize_Context *ctx,
+ RtemsTaskReqStorageSize_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStorageSize_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqStorageSize_Pre_Id_Task: {
+ /*
+ * While the ``id`` parameter is associated with a task.
+ */
+ ctx->id = ctx->worker_id;
+ break;
+ }
+
+ case RtemsTaskReqStorageSize_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStorageSize_Pre_Suspended_Prepare(
+ RtemsTaskReqStorageSize_Context *ctx,
+ RtemsTaskReqStorageSize_Pre_Suspended state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStorageSize_Pre_Suspended_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is suspended.
+ */
+ ctx->suspend = true;
+ break;
+ }
+
+ case RtemsTaskReqStorageSize_Pre_Suspended_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not suspended.
+ */
+ ctx->suspend = false;
+ break;
+ }
+
+ case RtemsTaskReqStorageSize_Pre_Suspended_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStorageSize_Post_Status_Check(
+ RtemsTaskReqStorageSize_Context *ctx,
+ RtemsTaskReqStorageSize_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqStorageSize_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_suspend() shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqStorageSize_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_suspend() shall be RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqStorageSize_Post_Status_AlrdySus: {
+ /*
+ * The return status of rtems_task_suspend() shall be
+ * RTEMS_ALREADY_SUSPENDED.
+ */
+ T_rsc( ctx->status, RTEMS_ALREADY_SUSPENDED );
+ break;
+ }
+
+ case RtemsTaskReqStorageSize_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqStorageSize_Setup(
+ RtemsTaskReqStorageSize_Context *ctx
+)
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+static void RtemsTaskReqStorageSize_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqStorageSize_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqStorageSize_Setup( ctx );
+}
+
+static void RtemsTaskReqStorageSize_Teardown(
+ RtemsTaskReqStorageSize_Context *ctx
+)
+{
+ DeleteTask( ctx->worker_id );
+}
+
+static void RtemsTaskReqStorageSize_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqStorageSize_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqStorageSize_Teardown( ctx );
+}
+
+static void RtemsTaskReqStorageSize_Action(
+ RtemsTaskReqStorageSize_Context *ctx
+)
+{
+ if ( ctx->suspend ) {
+ SuspendTask( ctx->worker_id );
+ }
+
+ ctx->status = rtems_task_suspend( ctx->id );
+
+ if ( ctx->suspend ) {
+ ResumeTask( ctx->worker_id );
+ }
+}
+
+static const RtemsTaskReqStorageSize_Entry
+RtemsTaskReqStorageSize_Entries[] = {
+ { 0, 0, 1, RtemsTaskReqStorageSize_Post_Status_InvId },
+ { 0, 0, 0, RtemsTaskReqStorageSize_Post_Status_AlrdySus },
+ { 0, 0, 0, RtemsTaskReqStorageSize_Post_Status_Ok }
+};
+
+static const uint8_t
+RtemsTaskReqStorageSize_Map[] = {
+ 0, 0, 1, 2
+};
+
+static size_t RtemsTaskReqStorageSize_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqStorageSize_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsTaskReqStorageSize_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqStorageSize_Fixture = {
+ .setup = RtemsTaskReqStorageSize_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqStorageSize_Teardown_Wrap,
+ .scope = RtemsTaskReqStorageSize_Scope,
+ .initial_context = &RtemsTaskReqStorageSize_Instance
+};
+
+static inline RtemsTaskReqStorageSize_Entry RtemsTaskReqStorageSize_PopEntry(
+ RtemsTaskReqStorageSize_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqStorageSize_Entries[
+ RtemsTaskReqStorageSize_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqStorageSize_SetPreConditionStates(
+ RtemsTaskReqStorageSize_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+
+ if ( ctx->Map.entry.Pre_Suspended_NA ) {
+ ctx->Map.pcs[ 1 ] = RtemsTaskReqStorageSize_Pre_Suspended_NA;
+ } else {
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ }
+}
+
+static void RtemsTaskReqStorageSize_TestVariant(
+ RtemsTaskReqStorageSize_Context *ctx
+)
+{
+ RtemsTaskReqStorageSize_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqStorageSize_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqStorageSize_Action( ctx );
+ RtemsTaskReqStorageSize_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqStorageSize( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTaskReqStorageSize,
+ &RtemsTaskReqStorageSize_Fixture
+)
+{
+ RtemsTaskReqStorageSize_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsTaskReqStorageSize_Pre_Id_Invalid;
+ ctx->Map.pci[ 0 ] < RtemsTaskReqStorageSize_Pre_Id_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsTaskReqStorageSize_Pre_Suspended_Yes;
+ ctx->Map.pci[ 1 ] < RtemsTaskReqStorageSize_Pre_Suspended_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqStorageSize_PopEntry( ctx );
+ RtemsTaskReqStorageSize_SetPreConditionStates( ctx );
+ RtemsTaskReqStorageSize_TestVariant( ctx );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-suspend.c b/testsuites/validation/tc-task-suspend.c
new file mode 100644
index 0000000000..123e223fb9
--- /dev/null
+++ b/testsuites/validation/tc-task-suspend.c
@@ -0,0 +1,411 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqSuspend
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqSuspend spec:/rtems/task/req/suspend
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqSuspend_Pre_Id_Invalid,
+ RtemsTaskReqSuspend_Pre_Id_Task,
+ RtemsTaskReqSuspend_Pre_Id_NA
+} RtemsTaskReqSuspend_Pre_Id;
+
+typedef enum {
+ RtemsTaskReqSuspend_Pre_Suspended_Yes,
+ RtemsTaskReqSuspend_Pre_Suspended_No,
+ RtemsTaskReqSuspend_Pre_Suspended_NA
+} RtemsTaskReqSuspend_Pre_Suspended;
+
+typedef enum {
+ RtemsTaskReqSuspend_Post_Status_Ok,
+ RtemsTaskReqSuspend_Post_Status_InvId,
+ RtemsTaskReqSuspend_Post_Status_AlrdySus,
+ RtemsTaskReqSuspend_Post_Status_NA
+} RtemsTaskReqSuspend_Post_Status;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Pre_Suspended_NA : 1;
+ uint8_t Post_Status : 2;
+} RtemsTaskReqSuspend_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/suspend test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the identifier of a task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief If this member is true, then the worker is suspended before the
+ * rtems_task_suspend() call.
+ */
+ bool suspend;
+
+ /**
+ * @brief This member contains the return value of the rtems_task_suspend()
+ * call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies if the ``id`` parameter value.
+ */
+ rtems_id id;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 2 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqSuspend_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqSuspend_Context;
+
+static RtemsTaskReqSuspend_Context
+ RtemsTaskReqSuspend_Instance;
+
+static const char * const RtemsTaskReqSuspend_PreDesc_Id[] = {
+ "Invalid",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsTaskReqSuspend_PreDesc_Suspended[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqSuspend_PreDesc[] = {
+ RtemsTaskReqSuspend_PreDesc_Id,
+ RtemsTaskReqSuspend_PreDesc_Suspended,
+ NULL
+};
+
+static void Worker( rtems_task_argument arg )
+{
+ while ( true ) {
+ /* Do nothing */
+ }
+}
+
+static void RtemsTaskReqSuspend_Pre_Id_Prepare(
+ RtemsTaskReqSuspend_Context *ctx,
+ RtemsTaskReqSuspend_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSuspend_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is not associated with a task.
+ */
+ ctx->id = INVALID_ID;
+ break;
+ }
+
+ case RtemsTaskReqSuspend_Pre_Id_Task: {
+ /*
+ * While the ``id`` parameter is associated with a task.
+ */
+ ctx->id = ctx->worker_id;
+ break;
+ }
+
+ case RtemsTaskReqSuspend_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSuspend_Pre_Suspended_Prepare(
+ RtemsTaskReqSuspend_Context *ctx,
+ RtemsTaskReqSuspend_Pre_Suspended state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSuspend_Pre_Suspended_Yes: {
+ /*
+ * While the task specified by the ``id`` parameter is suspended.
+ */
+ ctx->suspend = true;
+ break;
+ }
+
+ case RtemsTaskReqSuspend_Pre_Suspended_No: {
+ /*
+ * While the task specified by the ``id`` parameter is not suspended.
+ */
+ ctx->suspend = false;
+ break;
+ }
+
+ case RtemsTaskReqSuspend_Pre_Suspended_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSuspend_Post_Status_Check(
+ RtemsTaskReqSuspend_Context *ctx,
+ RtemsTaskReqSuspend_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqSuspend_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_suspend() shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqSuspend_Post_Status_InvId: {
+ /*
+ * The return status of rtems_task_suspend() shall be RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTaskReqSuspend_Post_Status_AlrdySus: {
+ /*
+ * The return status of rtems_task_suspend() shall be
+ * RTEMS_ALREADY_SUSPENDED.
+ */
+ T_rsc( ctx->status, RTEMS_ALREADY_SUSPENDED );
+ break;
+ }
+
+ case RtemsTaskReqSuspend_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqSuspend_Setup( RtemsTaskReqSuspend_Context *ctx )
+{
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+static void RtemsTaskReqSuspend_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqSuspend_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqSuspend_Setup( ctx );
+}
+
+static void RtemsTaskReqSuspend_Teardown( RtemsTaskReqSuspend_Context *ctx )
+{
+ DeleteTask( ctx->worker_id );
+}
+
+static void RtemsTaskReqSuspend_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqSuspend_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqSuspend_Teardown( ctx );
+}
+
+static void RtemsTaskReqSuspend_Action( RtemsTaskReqSuspend_Context *ctx )
+{
+ if ( ctx->suspend ) {
+ SuspendTask( ctx->worker_id );
+ }
+
+ ctx->status = rtems_task_suspend( ctx->id );
+
+ if ( ctx->suspend ) {
+ ResumeTask( ctx->worker_id );
+ }
+}
+
+static const RtemsTaskReqSuspend_Entry
+RtemsTaskReqSuspend_Entries[] = {
+ { 0, 0, 1, RtemsTaskReqSuspend_Post_Status_InvId },
+ { 0, 0, 0, RtemsTaskReqSuspend_Post_Status_AlrdySus },
+ { 0, 0, 0, RtemsTaskReqSuspend_Post_Status_Ok }
+};
+
+static const uint8_t
+RtemsTaskReqSuspend_Map[] = {
+ 0, 0, 1, 2
+};
+
+static size_t RtemsTaskReqSuspend_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqSuspend_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsTaskReqSuspend_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqSuspend_Fixture = {
+ .setup = RtemsTaskReqSuspend_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqSuspend_Teardown_Wrap,
+ .scope = RtemsTaskReqSuspend_Scope,
+ .initial_context = &RtemsTaskReqSuspend_Instance
+};
+
+static inline RtemsTaskReqSuspend_Entry RtemsTaskReqSuspend_PopEntry(
+ RtemsTaskReqSuspend_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqSuspend_Entries[
+ RtemsTaskReqSuspend_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqSuspend_SetPreConditionStates(
+ RtemsTaskReqSuspend_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+
+ if ( ctx->Map.entry.Pre_Suspended_NA ) {
+ ctx->Map.pcs[ 1 ] = RtemsTaskReqSuspend_Pre_Suspended_NA;
+ } else {
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ }
+}
+
+static void RtemsTaskReqSuspend_TestVariant( RtemsTaskReqSuspend_Context *ctx )
+{
+ RtemsTaskReqSuspend_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqSuspend_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqSuspend_Action( ctx );
+ RtemsTaskReqSuspend_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqSuspend( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTaskReqSuspend, &RtemsTaskReqSuspend_Fixture )
+{
+ RtemsTaskReqSuspend_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsTaskReqSuspend_Pre_Id_Invalid;
+ ctx->Map.pci[ 0 ] < RtemsTaskReqSuspend_Pre_Id_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsTaskReqSuspend_Pre_Suspended_Yes;
+ ctx->Map.pci[ 1 ] < RtemsTaskReqSuspend_Pre_Suspended_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqSuspend_PopEntry( ctx );
+ RtemsTaskReqSuspend_SetPreConditionStates( ctx );
+ RtemsTaskReqSuspend_TestVariant( ctx );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-wake-after.c b/testsuites/validation/tc-task-wake-after.c
new file mode 100644
index 0000000000..ba12d21c85
--- /dev/null
+++ b/testsuites/validation/tc-task-wake-after.c
@@ -0,0 +1,574 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqWakeAfter
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/test-scheduler.h>
+#include <rtems/score/threaddispatch.h>
+#include <rtems/score/timecounter.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqWakeAfter spec:/rtems/task/req/wake-after
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ * @ingroup TestsuitesValidationOneCpu0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqWakeAfter_Pre_Ticks_Yield,
+ RtemsTaskReqWakeAfter_Pre_Ticks_Interval,
+ RtemsTaskReqWakeAfter_Pre_Ticks_NA
+} RtemsTaskReqWakeAfter_Pre_Ticks;
+
+typedef enum {
+ RtemsTaskReqWakeAfter_Pre_Suspended_Yes,
+ RtemsTaskReqWakeAfter_Pre_Suspended_No,
+ RtemsTaskReqWakeAfter_Pre_Suspended_NA
+} RtemsTaskReqWakeAfter_Pre_Suspended;
+
+typedef enum {
+ RtemsTaskReqWakeAfter_Post_Status_Ok,
+ RtemsTaskReqWakeAfter_Post_Status_NA
+} RtemsTaskReqWakeAfter_Post_Status;
+
+typedef enum {
+ RtemsTaskReqWakeAfter_Post_Timer_Inactive,
+ RtemsTaskReqWakeAfter_Post_Timer_Ticks,
+ RtemsTaskReqWakeAfter_Post_Timer_NA
+} RtemsTaskReqWakeAfter_Post_Timer;
+
+typedef enum {
+ RtemsTaskReqWakeAfter_Post_Expire_Relative,
+ RtemsTaskReqWakeAfter_Post_Expire_NA
+} RtemsTaskReqWakeAfter_Post_Expire;
+
+typedef enum {
+ RtemsTaskReqWakeAfter_Post_Scheduler_Block,
+ RtemsTaskReqWakeAfter_Post_Scheduler_Yield,
+ RtemsTaskReqWakeAfter_Post_Scheduler_Nop,
+ RtemsTaskReqWakeAfter_Post_Scheduler_NA
+} RtemsTaskReqWakeAfter_Post_Scheduler;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Ticks_NA : 1;
+ uint16_t Pre_Suspended_NA : 1;
+ uint16_t Post_Status : 1;
+ uint16_t Post_Timer : 2;
+ uint16_t Post_Expire : 1;
+ uint16_t Post_Scheduler : 2;
+} RtemsTaskReqWakeAfter_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/wake-after test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides the scheduler operation records.
+ */
+ T_scheduler_log_4 scheduler_log;
+
+ /**
+ * @brief This member contains the clock tick value before the
+ * rtems_task_wake_after() call.
+ */
+ uint64_t now;
+
+ /**
+ * @brief This member contains the worker task identifier.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief If this member is true, then the worker shall be suspended during
+ * the rtems_task_wake_after() call.
+ */
+ bool suspended;
+
+ /**
+ * @brief This member contains the timer information of the worker task.
+ */
+ TaskTimerInfo timer_info;
+
+ /**
+ * @brief This member contains the return value of the
+ * rtems_task_wake_after() call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies the ``ticks`` parameter value.
+ */
+ rtems_interval ticks;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqWakeAfter_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqWakeAfter_Context;
+
+static RtemsTaskReqWakeAfter_Context
+ RtemsTaskReqWakeAfter_Instance;
+
+static const char * const RtemsTaskReqWakeAfter_PreDesc_Ticks[] = {
+ "Yield",
+ "Interval",
+ "NA"
+};
+
+static const char * const RtemsTaskReqWakeAfter_PreDesc_Suspended[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqWakeAfter_PreDesc[] = {
+ RtemsTaskReqWakeAfter_PreDesc_Ticks,
+ RtemsTaskReqWakeAfter_PreDesc_Suspended,
+ NULL
+};
+
+typedef RtemsTaskReqWakeAfter_Context Context;
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ while ( true ) {
+ T_scheduler_log *log;
+
+ SuspendSelf();
+
+ ctx->now = rtems_clock_get_ticks_since_boot();
+
+ if ( ctx->suspended ) {
+ Per_CPU_Control *cpu_self;
+
+ /*
+ * The rtems_task_wake_after() disables thread dispatching to carry out
+ * its operations. While thread dispatching is disabled, when an
+ * interrupt suspends the calling task, the suspended task executes
+ * until it enables thread dispatching. We simulate this situation
+ * with the code below. Where the system was built with SMP support
+ * enabled, other processors may suspend an executing task in parallel.
+ * This case is also simulated by the code below.
+ */
+ cpu_self = _Thread_Dispatch_disable();
+ SuspendSelf();
+ cpu_self->dispatch_necessary = false;
+ _Thread_Dispatch_enable( cpu_self );
+ }
+
+ log = T_scheduler_record_4( &ctx->scheduler_log );
+ T_null( log );
+
+ ctx->status = rtems_task_wake_after( ctx->ticks );
+
+ (void) T_scheduler_record( NULL );
+ }
+}
+
+static void RtemsTaskReqWakeAfter_Pre_Ticks_Prepare(
+ RtemsTaskReqWakeAfter_Context *ctx,
+ RtemsTaskReqWakeAfter_Pre_Ticks state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqWakeAfter_Pre_Ticks_Yield: {
+ /*
+ * While the ``ticks`` parameter is equal to RTEMS_YIELD_PROCESSOR.
+ */
+ ctx->ticks = RTEMS_YIELD_PROCESSOR;
+ break;
+ }
+
+ case RtemsTaskReqWakeAfter_Pre_Ticks_Interval: {
+ /*
+ * While the ``ticks`` parameter is not equal to RTEMS_YIELD_PROCESSOR.
+ */
+ ctx->ticks = UINT32_MAX;
+ break;
+ }
+
+ case RtemsTaskReqWakeAfter_Pre_Ticks_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqWakeAfter_Pre_Suspended_Prepare(
+ RtemsTaskReqWakeAfter_Context *ctx,
+ RtemsTaskReqWakeAfter_Pre_Suspended state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqWakeAfter_Pre_Suspended_Yes: {
+ /*
+ * While the calling task is suspended.
+ */
+ ctx->suspended = true;
+ break;
+ }
+
+ case RtemsTaskReqWakeAfter_Pre_Suspended_No: {
+ /*
+ * While the calling task is not suspended.
+ */
+ ctx->suspended = false;
+ break;
+ }
+
+ case RtemsTaskReqWakeAfter_Pre_Suspended_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqWakeAfter_Post_Status_Check(
+ RtemsTaskReqWakeAfter_Context *ctx,
+ RtemsTaskReqWakeAfter_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqWakeAfter_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_wake_after() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqWakeAfter_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqWakeAfter_Post_Timer_Check(
+ RtemsTaskReqWakeAfter_Context *ctx,
+ RtemsTaskReqWakeAfter_Post_Timer state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqWakeAfter_Post_Timer_Inactive: {
+ /*
+ * The timer of the calling task shall be inactive.
+ */
+ T_eq_int( ctx->timer_info.state, TASK_TIMER_INACTIVE );
+ break;
+ }
+
+ case RtemsTaskReqWakeAfter_Post_Timer_Ticks: {
+ /*
+ * The timer of the calling task shall be active using the clock tick.
+ */
+ T_eq_int( ctx->timer_info.state, TASK_TIMER_TICKS );
+ break;
+ }
+
+ case RtemsTaskReqWakeAfter_Post_Timer_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqWakeAfter_Post_Expire_Check(
+ RtemsTaskReqWakeAfter_Context *ctx,
+ RtemsTaskReqWakeAfter_Post_Expire state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqWakeAfter_Post_Expire_Relative: {
+ /*
+ * The timer of the calling task shall expire at the time point specified
+ * by the sum of the current clock tick and the interval specified by the
+ * ``ticks`` parameter.
+ */
+ T_eq_u64( ctx->timer_info.expire_ticks, ctx->now + UINT32_MAX );
+ break;
+ }
+
+ case RtemsTaskReqWakeAfter_Post_Expire_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqWakeAfter_Post_Scheduler_Check(
+ RtemsTaskReqWakeAfter_Context *ctx,
+ RtemsTaskReqWakeAfter_Post_Scheduler state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqWakeAfter_Post_Scheduler_Block: {
+ /*
+ * The calling task shall be blocked by the scheduler exactly once by the
+ * rtems_task_wake_after() call.
+ */
+ T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_BLOCK
+ );
+ break;
+ }
+
+ case RtemsTaskReqWakeAfter_Post_Scheduler_Yield: {
+ /*
+ * The calling task shall yield by the scheduler exactly once by the
+ * rtems_task_wake_after() call.
+ */
+ T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_YIELD
+ );
+ break;
+ }
+
+ case RtemsTaskReqWakeAfter_Post_Scheduler_Nop: {
+ /*
+ * The calling task shall not carry out a scheduler operation through the
+ * rtems_task_wake_after() call.
+ */
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ break;
+ }
+
+ case RtemsTaskReqWakeAfter_Post_Scheduler_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqWakeAfter_Setup( RtemsTaskReqWakeAfter_Context *ctx )
+{
+ SetSelfPriority( PRIO_NORMAL );
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+static void RtemsTaskReqWakeAfter_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqWakeAfter_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqWakeAfter_Setup( ctx );
+}
+
+static void RtemsTaskReqWakeAfter_Teardown(
+ RtemsTaskReqWakeAfter_Context *ctx
+)
+{
+ DeleteTask( ctx->worker_id );
+ RestoreRunnerPriority();
+}
+
+static void RtemsTaskReqWakeAfter_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqWakeAfter_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqWakeAfter_Teardown( ctx );
+}
+
+static void RtemsTaskReqWakeAfter_Prepare( RtemsTaskReqWakeAfter_Context *ctx )
+{
+ ctx->status = RTEMS_NOT_IMPLEMENTED;
+}
+
+static void RtemsTaskReqWakeAfter_Action( RtemsTaskReqWakeAfter_Context *ctx )
+{
+ ResumeTask( ctx->worker_id );
+ (void) T_scheduler_record( NULL );
+ GetTaskTimerInfo( ctx->worker_id, &ctx->timer_info );
+
+ if ( ctx->suspended ) {
+ ResumeTask( ctx->worker_id );
+ }
+
+ FinalClockTick();
+}
+
+static const RtemsTaskReqWakeAfter_Entry
+RtemsTaskReqWakeAfter_Entries[] = {
+ { 0, 0, 0, RtemsTaskReqWakeAfter_Post_Status_Ok,
+ RtemsTaskReqWakeAfter_Post_Timer_Inactive,
+ RtemsTaskReqWakeAfter_Post_Expire_NA,
+ RtemsTaskReqWakeAfter_Post_Scheduler_Nop },
+ { 0, 0, 0, RtemsTaskReqWakeAfter_Post_Status_Ok,
+ RtemsTaskReqWakeAfter_Post_Timer_Inactive,
+ RtemsTaskReqWakeAfter_Post_Expire_NA,
+ RtemsTaskReqWakeAfter_Post_Scheduler_Yield },
+ { 0, 0, 0, RtemsTaskReqWakeAfter_Post_Status_Ok,
+ RtemsTaskReqWakeAfter_Post_Timer_Ticks,
+ RtemsTaskReqWakeAfter_Post_Expire_Relative,
+ RtemsTaskReqWakeAfter_Post_Scheduler_Nop },
+ { 0, 0, 0, RtemsTaskReqWakeAfter_Post_Status_Ok,
+ RtemsTaskReqWakeAfter_Post_Timer_Ticks,
+ RtemsTaskReqWakeAfter_Post_Expire_Relative,
+ RtemsTaskReqWakeAfter_Post_Scheduler_Block }
+};
+
+static const uint8_t
+RtemsTaskReqWakeAfter_Map[] = {
+ 0, 1, 2, 3
+};
+
+static size_t RtemsTaskReqWakeAfter_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqWakeAfter_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsTaskReqWakeAfter_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqWakeAfter_Fixture = {
+ .setup = RtemsTaskReqWakeAfter_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqWakeAfter_Teardown_Wrap,
+ .scope = RtemsTaskReqWakeAfter_Scope,
+ .initial_context = &RtemsTaskReqWakeAfter_Instance
+};
+
+static inline RtemsTaskReqWakeAfter_Entry RtemsTaskReqWakeAfter_PopEntry(
+ RtemsTaskReqWakeAfter_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqWakeAfter_Entries[
+ RtemsTaskReqWakeAfter_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqWakeAfter_TestVariant(
+ RtemsTaskReqWakeAfter_Context *ctx
+)
+{
+ RtemsTaskReqWakeAfter_Pre_Ticks_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqWakeAfter_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqWakeAfter_Action( ctx );
+ RtemsTaskReqWakeAfter_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsTaskReqWakeAfter_Post_Timer_Check( ctx, ctx->Map.entry.Post_Timer );
+ RtemsTaskReqWakeAfter_Post_Expire_Check( ctx, ctx->Map.entry.Post_Expire );
+ RtemsTaskReqWakeAfter_Post_Scheduler_Check(
+ ctx,
+ ctx->Map.entry.Post_Scheduler
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqWakeAfter( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTaskReqWakeAfter, &RtemsTaskReqWakeAfter_Fixture )
+{
+ RtemsTaskReqWakeAfter_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsTaskReqWakeAfter_Pre_Ticks_Yield;
+ ctx->Map.pcs[ 0 ] < RtemsTaskReqWakeAfter_Pre_Ticks_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsTaskReqWakeAfter_Pre_Suspended_Yes;
+ ctx->Map.pcs[ 1 ] < RtemsTaskReqWakeAfter_Pre_Suspended_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqWakeAfter_PopEntry( ctx );
+ RtemsTaskReqWakeAfter_Prepare( ctx );
+ RtemsTaskReqWakeAfter_TestVariant( ctx );
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task-wake-when.c b/testsuites/validation/tc-task-wake-when.c
new file mode 100644
index 0000000000..bb31fded26
--- /dev/null
+++ b/testsuites/validation/tc-task-wake-when.c
@@ -0,0 +1,665 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskReqWakeWhen
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+#include <rtems/test-scheduler.h>
+#include <rtems/score/timecounter.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskReqWakeWhen spec:/rtems/task/req/wake-when
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTaskReqWakeWhen_Pre_TODSet_Yes,
+ RtemsTaskReqWakeWhen_Pre_TODSet_No,
+ RtemsTaskReqWakeWhen_Pre_TODSet_NA
+} RtemsTaskReqWakeWhen_Pre_TODSet;
+
+typedef enum {
+ RtemsTaskReqWakeWhen_Pre_TOD_Valid,
+ RtemsTaskReqWakeWhen_Pre_TOD_Null,
+ RtemsTaskReqWakeWhen_Pre_TOD_NA
+} RtemsTaskReqWakeWhen_Pre_TOD;
+
+typedef enum {
+ RtemsTaskReqWakeWhen_Pre_TODObj_Future,
+ RtemsTaskReqWakeWhen_Pre_TODObj_PastOrNow,
+ RtemsTaskReqWakeWhen_Pre_TODObj_Invalid,
+ RtemsTaskReqWakeWhen_Pre_TODObj_NA
+} RtemsTaskReqWakeWhen_Pre_TODObj;
+
+typedef enum {
+ RtemsTaskReqWakeWhen_Post_Status_Ok,
+ RtemsTaskReqWakeWhen_Post_Status_NotDef,
+ RtemsTaskReqWakeWhen_Post_Status_InvAddr,
+ RtemsTaskReqWakeWhen_Post_Status_InvClock,
+ RtemsTaskReqWakeWhen_Post_Status_NA
+} RtemsTaskReqWakeWhen_Post_Status;
+
+typedef enum {
+ RtemsTaskReqWakeWhen_Post_Timer_Inactive,
+ RtemsTaskReqWakeWhen_Post_Timer_Realtime,
+ RtemsTaskReqWakeWhen_Post_Timer_NA
+} RtemsTaskReqWakeWhen_Post_Timer;
+
+typedef enum {
+ RtemsTaskReqWakeWhen_Post_Expire_Absolute,
+ RtemsTaskReqWakeWhen_Post_Expire_NA
+} RtemsTaskReqWakeWhen_Post_Expire;
+
+typedef enum {
+ RtemsTaskReqWakeWhen_Post_Scheduler_Block,
+ RtemsTaskReqWakeWhen_Post_Scheduler_Nop,
+ RtemsTaskReqWakeWhen_Post_Scheduler_NA
+} RtemsTaskReqWakeWhen_Post_Scheduler;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_TODSet_NA : 1;
+ uint16_t Pre_TOD_NA : 1;
+ uint16_t Pre_TODObj_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_Timer : 2;
+ uint16_t Post_Expire : 1;
+ uint16_t Post_Scheduler : 2;
+} RtemsTaskReqWakeWhen_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/task/req/wake-when test case.
+ */
+typedef struct {
+ /**
+ * @brief This member provides the scheduler operation records.
+ */
+ T_scheduler_log_4 scheduler_log;
+
+ /**
+ * @brief This member contains the CLOCK_REALTIME value before the
+ * rtems_task_wake_when() call.
+ */
+ struct timespec now;
+
+ /**
+ * @brief This member contains the worker task identifier.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member contains the timer information of the worker task.
+ */
+ TaskTimerInfo timer_info;
+
+ /**
+ * @brief This member provides the object referenced by the ``time_buffer``
+ * parameter.
+ */
+ rtems_time_of_day tod_obj;
+
+ /**
+ * @brief This member contains the return value of the rtems_task_wake_when()
+ * call.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member specifies the ``time_buffer`` parameter value.
+ */
+ const rtems_time_of_day *tod;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 3 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTaskReqWakeWhen_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTaskReqWakeWhen_Context;
+
+static RtemsTaskReqWakeWhen_Context
+ RtemsTaskReqWakeWhen_Instance;
+
+static const char * const RtemsTaskReqWakeWhen_PreDesc_TODSet[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTaskReqWakeWhen_PreDesc_TOD[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsTaskReqWakeWhen_PreDesc_TODObj[] = {
+ "Future",
+ "PastOrNow",
+ "Invalid",
+ "NA"
+};
+
+static const char * const * const RtemsTaskReqWakeWhen_PreDesc[] = {
+ RtemsTaskReqWakeWhen_PreDesc_TODSet,
+ RtemsTaskReqWakeWhen_PreDesc_TOD,
+ RtemsTaskReqWakeWhen_PreDesc_TODObj,
+ NULL
+};
+
+typedef RtemsTaskReqWakeWhen_Context Context;
+
+static void SetTOD( rtems_time_of_day *tod, uint32_t year )
+{
+ memset( tod, 0, sizeof( *tod ) );
+ tod->year = year;
+ tod->month = 1;
+ tod->day = 1;
+}
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ while ( true ) {
+ T_scheduler_log *log;
+
+ SuspendSelf();
+
+ log = T_scheduler_record_4( &ctx->scheduler_log );
+ T_null( log );
+
+ _Timecounter_Getnanotime( &ctx->now );
+
+ ctx->status = rtems_task_wake_when( ctx->tod );
+
+ (void) T_scheduler_record( NULL );
+ }
+}
+
+static void RtemsTaskReqWakeWhen_Pre_TODSet_Prepare(
+ RtemsTaskReqWakeWhen_Context *ctx,
+ RtemsTaskReqWakeWhen_Pre_TODSet state
+)
+{
+ rtems_status_code sc;
+ rtems_time_of_day tod;
+
+ switch ( state ) {
+ case RtemsTaskReqWakeWhen_Pre_TODSet_Yes: {
+ /*
+ * While the CLOCK_REALTIME was set at least once.
+ */
+ SetTOD( &tod, 2000 );
+ sc = rtems_clock_set( &tod );
+ T_rsc_success( sc );
+ break;
+ }
+
+ case RtemsTaskReqWakeWhen_Pre_TODSet_No: {
+ /*
+ * While the CLOCK_REALTIME was never set.
+ */
+ UnsetClock();
+ break;
+ }
+
+ case RtemsTaskReqWakeWhen_Pre_TODSet_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqWakeWhen_Pre_TOD_Prepare(
+ RtemsTaskReqWakeWhen_Context *ctx,
+ RtemsTaskReqWakeWhen_Pre_TOD state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqWakeWhen_Pre_TOD_Valid: {
+ /*
+ * While the ``time_buffer`` parameter references an object of type
+ * rtems_time_of_day.
+ */
+ ctx->tod = &ctx->tod_obj;
+ break;
+ }
+
+ case RtemsTaskReqWakeWhen_Pre_TOD_Null: {
+ /*
+ * While the ``time_buffer`` parameter is equal to NULL.
+ */
+ ctx->tod = NULL;
+ break;
+ }
+
+ case RtemsTaskReqWakeWhen_Pre_TOD_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqWakeWhen_Pre_TODObj_Prepare(
+ RtemsTaskReqWakeWhen_Context *ctx,
+ RtemsTaskReqWakeWhen_Pre_TODObj state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqWakeWhen_Pre_TODObj_Future: {
+ /*
+ * While the object referenced by the ``time_buffer`` parameter specifies
+ * a valid time of day in the future.
+ */
+ SetTOD( &ctx->tod_obj, 2010 );
+ break;
+ }
+
+ case RtemsTaskReqWakeWhen_Pre_TODObj_PastOrNow: {
+ /*
+ * While the object referenced by the ``time_buffer`` parameter specifies
+ * a valid time of day in the past or at the time of the
+ * rtems_task_wake_when() call.
+ */
+ SetTOD( &ctx->tod_obj, 1990 );
+ break;
+ }
+
+ case RtemsTaskReqWakeWhen_Pre_TODObj_Invalid: {
+ /*
+ * While the object referenced by the ``time_buffer`` parameter specifies
+ * an invalid time of day.
+ */
+ memset( &ctx->tod_obj, 0xff, sizeof( ctx->tod_obj ) );
+ break;
+ }
+
+ case RtemsTaskReqWakeWhen_Pre_TODObj_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqWakeWhen_Post_Status_Check(
+ RtemsTaskReqWakeWhen_Context *ctx,
+ RtemsTaskReqWakeWhen_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqWakeWhen_Post_Status_Ok: {
+ /*
+ * The return status of rtems_task_wake_when() shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTaskReqWakeWhen_Post_Status_NotDef: {
+ /*
+ * The return status of rtems_task_wake_when() shall be
+ * RTEMS_NOT_DEFINED.
+ */
+ T_rsc( ctx->status, RTEMS_NOT_DEFINED );
+ break;
+ }
+
+ case RtemsTaskReqWakeWhen_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_task_wake_when() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTaskReqWakeWhen_Post_Status_InvClock: {
+ /*
+ * The return status of rtems_task_wake_when() shall be
+ * RTEMS_INVALID_CLOCK.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_CLOCK );
+ break;
+ }
+
+ case RtemsTaskReqWakeWhen_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqWakeWhen_Post_Timer_Check(
+ RtemsTaskReqWakeWhen_Context *ctx,
+ RtemsTaskReqWakeWhen_Post_Timer state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqWakeWhen_Post_Timer_Inactive: {
+ /*
+ * The timer of the calling task shall be inactive.
+ */
+ T_eq_int( ctx->timer_info.state, TASK_TIMER_INACTIVE );
+ break;
+ }
+
+ case RtemsTaskReqWakeWhen_Post_Timer_Realtime: {
+ /*
+ * The timer of the calling task shall be active using the
+ * CLOCK_REALTIME.
+ */
+ T_eq_int( ctx->timer_info.state, TASK_TIMER_REALTIME );
+ break;
+ }
+
+ case RtemsTaskReqWakeWhen_Post_Timer_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqWakeWhen_Post_Expire_Check(
+ RtemsTaskReqWakeWhen_Context *ctx,
+ RtemsTaskReqWakeWhen_Post_Expire state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqWakeWhen_Post_Expire_Absolute: {
+ /*
+ * The timer of the calling task shall expire at the time point specified
+ * by the ``time_buffer`` parameter.
+ */
+ T_eq_i64( ctx->timer_info.expire_timespec.tv_sec, 1262304000 );
+ T_eq_long( ctx->timer_info.expire_timespec.tv_nsec, 0 );
+ break;
+ }
+
+ case RtemsTaskReqWakeWhen_Post_Expire_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqWakeWhen_Post_Scheduler_Check(
+ RtemsTaskReqWakeWhen_Context *ctx,
+ RtemsTaskReqWakeWhen_Post_Scheduler state
+)
+{
+ switch ( state ) {
+ case RtemsTaskReqWakeWhen_Post_Scheduler_Block: {
+ /*
+ * The calling task shall be blocked by the scheduler exactly once by the
+ * rtems_task_wake_when() call.
+ */
+ T_eq_sz( ctx->scheduler_log.header.recorded, 1 );
+ T_eq_int(
+ ctx->scheduler_log.events[ 0 ].operation,
+ T_SCHEDULER_BLOCK
+ );
+ break;
+ }
+
+ case RtemsTaskReqWakeWhen_Post_Scheduler_Nop: {
+ /*
+ * The calling task shall not be altered by the scheduler by the
+ * rtems_task_wake_when() call.
+ */
+ T_eq_sz( ctx->scheduler_log.header.recorded, 0 );
+ break;
+ }
+
+ case RtemsTaskReqWakeWhen_Post_Scheduler_NA:
+ break;
+ }
+}
+
+static void RtemsTaskReqWakeWhen_Setup( RtemsTaskReqWakeWhen_Context *ctx )
+{
+ SetSelfPriority( PRIO_NORMAL );
+ ctx->worker_id = CreateTask( "WORK", PRIO_HIGH );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+static void RtemsTaskReqWakeWhen_Setup_Wrap( void *arg )
+{
+ RtemsTaskReqWakeWhen_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqWakeWhen_Setup( ctx );
+}
+
+static void RtemsTaskReqWakeWhen_Teardown( RtemsTaskReqWakeWhen_Context *ctx )
+{
+ DeleteTask( ctx->worker_id );
+ RestoreRunnerPriority();
+}
+
+static void RtemsTaskReqWakeWhen_Teardown_Wrap( void *arg )
+{
+ RtemsTaskReqWakeWhen_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTaskReqWakeWhen_Teardown( ctx );
+}
+
+static void RtemsTaskReqWakeWhen_Prepare( RtemsTaskReqWakeWhen_Context *ctx )
+{
+ ctx->status = RTEMS_NOT_IMPLEMENTED;
+}
+
+static void RtemsTaskReqWakeWhen_Action( RtemsTaskReqWakeWhen_Context *ctx )
+{
+ ResumeTask( ctx->worker_id );
+ (void) T_scheduler_record( NULL );
+ GetTaskTimerInfo( ctx->worker_id, &ctx->timer_info );
+ FinalClockTick();
+}
+
+static const RtemsTaskReqWakeWhen_Entry
+RtemsTaskReqWakeWhen_Entries[] = {
+ { 0, 0, 0, 1, RtemsTaskReqWakeWhen_Post_Status_InvAddr,
+ RtemsTaskReqWakeWhen_Post_Timer_Inactive,
+ RtemsTaskReqWakeWhen_Post_Expire_NA,
+ RtemsTaskReqWakeWhen_Post_Scheduler_Nop },
+ { 0, 0, 0, 0, RtemsTaskReqWakeWhen_Post_Status_NotDef,
+ RtemsTaskReqWakeWhen_Post_Timer_Inactive,
+ RtemsTaskReqWakeWhen_Post_Expire_NA,
+ RtemsTaskReqWakeWhen_Post_Scheduler_Nop },
+ { 0, 0, 0, 1, RtemsTaskReqWakeWhen_Post_Status_NotDef,
+ RtemsTaskReqWakeWhen_Post_Timer_Inactive,
+ RtemsTaskReqWakeWhen_Post_Expire_NA,
+ RtemsTaskReqWakeWhen_Post_Scheduler_Nop },
+ { 0, 0, 0, 0, RtemsTaskReqWakeWhen_Post_Status_InvClock,
+ RtemsTaskReqWakeWhen_Post_Timer_Inactive,
+ RtemsTaskReqWakeWhen_Post_Expire_NA,
+ RtemsTaskReqWakeWhen_Post_Scheduler_Nop },
+ { 0, 0, 0, 0, RtemsTaskReqWakeWhen_Post_Status_Ok,
+ RtemsTaskReqWakeWhen_Post_Timer_Realtime,
+ RtemsTaskReqWakeWhen_Post_Expire_Absolute,
+ RtemsTaskReqWakeWhen_Post_Scheduler_Block }
+};
+
+static const uint8_t
+RtemsTaskReqWakeWhen_Map[] = {
+ 4, 3, 3, 0, 0, 0, 1, 1, 1, 2, 2, 2
+};
+
+static size_t RtemsTaskReqWakeWhen_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTaskReqWakeWhen_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsTaskReqWakeWhen_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTaskReqWakeWhen_Fixture = {
+ .setup = RtemsTaskReqWakeWhen_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTaskReqWakeWhen_Teardown_Wrap,
+ .scope = RtemsTaskReqWakeWhen_Scope,
+ .initial_context = &RtemsTaskReqWakeWhen_Instance
+};
+
+static inline RtemsTaskReqWakeWhen_Entry RtemsTaskReqWakeWhen_PopEntry(
+ RtemsTaskReqWakeWhen_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTaskReqWakeWhen_Entries[
+ RtemsTaskReqWakeWhen_Map[ index ]
+ ];
+}
+
+static void RtemsTaskReqWakeWhen_SetPreConditionStates(
+ RtemsTaskReqWakeWhen_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+
+ if ( ctx->Map.entry.Pre_TODObj_NA ) {
+ ctx->Map.pcs[ 2 ] = RtemsTaskReqWakeWhen_Pre_TODObj_NA;
+ } else {
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ }
+}
+
+static void RtemsTaskReqWakeWhen_TestVariant(
+ RtemsTaskReqWakeWhen_Context *ctx
+)
+{
+ RtemsTaskReqWakeWhen_Pre_TODSet_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTaskReqWakeWhen_Pre_TOD_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTaskReqWakeWhen_Pre_TODObj_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTaskReqWakeWhen_Action( ctx );
+ RtemsTaskReqWakeWhen_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsTaskReqWakeWhen_Post_Timer_Check( ctx, ctx->Map.entry.Post_Timer );
+ RtemsTaskReqWakeWhen_Post_Expire_Check( ctx, ctx->Map.entry.Post_Expire );
+ RtemsTaskReqWakeWhen_Post_Scheduler_Check(
+ ctx,
+ ctx->Map.entry.Post_Scheduler
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskReqWakeWhen( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTaskReqWakeWhen, &RtemsTaskReqWakeWhen_Fixture )
+{
+ RtemsTaskReqWakeWhen_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsTaskReqWakeWhen_Pre_TODSet_Yes;
+ ctx->Map.pci[ 0 ] < RtemsTaskReqWakeWhen_Pre_TODSet_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsTaskReqWakeWhen_Pre_TOD_Valid;
+ ctx->Map.pci[ 1 ] < RtemsTaskReqWakeWhen_Pre_TOD_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsTaskReqWakeWhen_Pre_TODObj_Future;
+ ctx->Map.pci[ 2 ] < RtemsTaskReqWakeWhen_Pre_TODObj_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ ctx->Map.entry = RtemsTaskReqWakeWhen_PopEntry( ctx );
+ RtemsTaskReqWakeWhen_SetPreConditionStates( ctx );
+ RtemsTaskReqWakeWhen_Prepare( ctx );
+ RtemsTaskReqWakeWhen_TestVariant( ctx );
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-task.c b/testsuites/validation/tc-task.c
new file mode 100644
index 0000000000..5ab96445ed
--- /dev/null
+++ b/testsuites/validation/tc-task.c
@@ -0,0 +1,355 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTaskValTask
+ */
+
+/*
+ * Copyright (C) 2021, 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+#include <rtems/score/apimutex.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTaskValTask spec:/rtems/task/val/task
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief This test case collection provides validation test cases for
+ * requirements of the @ref RTEMSAPIClassicTasks.
+ *
+ * This test case performs the following actions:
+ *
+ * - Call rtems_task_self() check the returned value.
+ *
+ * - Check that the returned value is equal to the object identifier of the
+ * calling task.
+ *
+ * - Call rtems_task_iterate() with a visitor which always returns false.
+ *
+ * - Check that the all counter is equal to the count of tasks. Check that
+ * the calling task was visited exacly once. Firstly, this shows that
+ * rtems_task_iterate() used the parameters specified by ``visitor`` and
+ * ``arg``. Secondly, this shows that the iteration was done over all
+ * tasks.
+ *
+ * - Check that the object alloctor mutex was not owned before and after the
+ * call. Check that the object alloctor mutex was owned during the
+ * iteration.
+ *
+ * - Call rtems_task_iterate() with a visitor which returns true.
+ *
+ * - Check that the all counter is equal to one. This shows that the
+ * iteration stops when the visitor returns true.
+ *
+ * - Assert that RTEMS_TASK_STORAGE_ALIGNMENT is a constant expression which
+ * evaluates to the expected value.
+ *
+ * - Assert that RTEMS_NO_PRIORITY is a constant expression which evaluates to
+ * the expected value.
+ *
+ * - Assert that RTEMS_MINIMUM_STACK_SIZE is a constant expression which
+ * evaluates to the expected value.
+ *
+ * - Assert that RTEMS_CONFIGURED_MINIMUM_STACK_SIZE is a constant expression
+ * which evaluates to the expected value.
+ *
+ * - Assert that RTEMS_MINIMUM_PRIORITY is a constant expression which
+ * evaluates to the expected value.
+ *
+ * - Validate RTEMS_SELF using a sample directive call.
+ *
+ * - Check that rtems_task_is_suspended() returns the expected status if
+ * called with a task identifier parameter of RTEMS_SELF.
+ *
+ * - Validate the home scheduler of tasks created by rtems_task_create() and
+ * constructed by rtems_task_construct().
+ *
+ * - Create a task. Check that the home scheduler of the created task is
+ * scheduler A.
+ *
+ * - Construct a task. Check that the home scheduler of the constructed task
+ * is scheduler A.
+ *
+ * @{
+ */
+
+typedef struct {
+ bool owner_before;
+ bool owner_in_visitor;
+ bool owner_after;
+ uint32_t counter_all;
+ uint32_t counter_self;
+ bool done;
+} TaskIterateContext;
+
+static bool TaskVisitor( rtems_tcb *tcb, void *arg )
+{
+ TaskIterateContext *ctx;
+
+ ctx = arg;
+ ++ctx->counter_all;
+
+ if ( rtems_task_self() == tcb->Object.id ) {
+ ++ctx->counter_self;
+ }
+
+ ctx->owner_in_visitor = _RTEMS_Allocator_is_owner();
+
+ return ctx->done;
+}
+
+/**
+ * @brief Call rtems_task_self() check the returned value.
+ */
+static void RtemsTaskValTask_Action_0( void )
+{
+ rtems_id id;
+
+ id = rtems_task_self();
+
+ /*
+ * Check that the returned value is equal to the object identifier of the
+ * calling task.
+ */
+ T_step_eq_u32( 0, id, 0x0a010001 );
+}
+
+/**
+ * @brief Call rtems_task_iterate() with a visitor which always returns false.
+ */
+static void RtemsTaskValTask_Action_1( void )
+{
+ TaskIterateContext ctx;
+ uint32_t task_count;
+
+ task_count = rtems_scheduler_get_processor_maximum();
+
+ if ( task_count > 4 ) {
+ task_count = 4;
+ }
+
+ ++task_count;
+
+ memset( &ctx, 0, sizeof( ctx ) );
+ ctx.owner_before = _RTEMS_Allocator_is_owner();
+ rtems_task_iterate( TaskVisitor, &ctx );
+ ctx.owner_after = _RTEMS_Allocator_is_owner();
+
+ /*
+ * Check that the all counter is equal to the count of tasks. Check that the
+ * calling task was visited exacly once. Firstly, this shows that
+ * rtems_task_iterate() used the parameters specified by ``visitor`` and
+ * ``arg``. Secondly, this shows that the iteration was done over all tasks.
+ */
+ T_step_eq_u32( 1, ctx.counter_all, task_count );
+ T_step_eq_u32( 2, ctx.counter_self, 1 );
+
+ /*
+ * Check that the object alloctor mutex was not owned before and after the
+ * call. Check that the object alloctor mutex was owned during the
+ * iteration.
+ */
+ T_step_false( 3, ctx.owner_before );
+ T_step_true( 4, ctx.owner_in_visitor );
+ T_step_false( 5, ctx.owner_after );
+}
+
+/**
+ * @brief Call rtems_task_iterate() with a visitor which returns true.
+ */
+static void RtemsTaskValTask_Action_2( void )
+{
+ TaskIterateContext ctx;
+
+ memset( &ctx, 0, sizeof( ctx ) );
+ ctx.done = true;
+ rtems_task_iterate( TaskVisitor, &ctx );
+
+ /*
+ * Check that the all counter is equal to one. This shows that the iteration
+ * stops when the visitor returns true.
+ */
+ T_step_eq_u32( 6, ctx.counter_all, 1 );
+}
+
+/**
+ * @brief Assert that RTEMS_TASK_STORAGE_ALIGNMENT is a constant expression
+ * which evaluates to the expected value.
+ */
+static void RtemsTaskValTask_Action_3( void )
+{
+ RTEMS_STATIC_ASSERT(
+ RTEMS_TASK_STORAGE_ALIGNMENT == CPU_STACK_ALIGNMENT,
+ STORAGE_ALIGNMENT
+ );
+}
+
+/**
+ * @brief Assert that RTEMS_NO_PRIORITY is a constant expression which
+ * evaluates to the expected value.
+ */
+static void RtemsTaskValTask_Action_4( void )
+{
+ RTEMS_STATIC_ASSERT(
+ RTEMS_NO_PRIORITY == RTEMS_CURRENT_PRIORITY,
+ NO_PRIORITY
+ );
+}
+
+/**
+ * @brief Assert that RTEMS_MINIMUM_STACK_SIZE is a constant expression which
+ * evaluates to the expected value.
+ */
+static void RtemsTaskValTask_Action_5( void )
+{
+ RTEMS_STATIC_ASSERT(
+ RTEMS_MINIMUM_STACK_SIZE == STACK_MINIMUM_SIZE,
+ MINIMUM_STACK_SIZE
+ );
+}
+
+/**
+ * @brief Assert that RTEMS_CONFIGURED_MINIMUM_STACK_SIZE is a constant
+ * expression which evaluates to the expected value.
+ */
+static void RtemsTaskValTask_Action_6( void )
+{
+ RTEMS_STATIC_ASSERT(
+ RTEMS_CONFIGURED_MINIMUM_STACK_SIZE == 0,
+ CONFIGURED_MINIMUM_STACK_SIZE
+ );
+}
+
+/**
+ * @brief Assert that RTEMS_MINIMUM_PRIORITY is a constant expression which
+ * evaluates to the expected value.
+ */
+static void RtemsTaskValTask_Action_7( void )
+{
+ RTEMS_STATIC_ASSERT( RTEMS_MINIMUM_PRIORITY == 1, MINIMUM_PRIORITY );
+}
+
+/**
+ * @brief Validate RTEMS_SELF using a sample directive call.
+ */
+static void RtemsTaskValTask_Action_8( void )
+{
+ rtems_status_code sc;
+
+ /*
+ * Check that rtems_task_is_suspended() returns the expected status if called
+ * with a task identifier parameter of RTEMS_SELF.
+ */
+ sc = rtems_task_is_suspended( RTEMS_SELF );
+ T_step_rsc_success( 7, sc );
+}
+
+/**
+ * @brief Validate the home scheduler of tasks created by rtems_task_create()
+ * and constructed by rtems_task_construct().
+ */
+static void RtemsTaskValTask_Action_9( void )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ /*
+ * Create a task. Check that the home scheduler of the created task is
+ * scheduler A.
+ */
+ sc = rtems_task_create(
+ OBJECT_NAME,
+ 1,
+ TEST_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ &id
+ );
+ T_step_rsc_success( 8, sc );
+
+ T_step_eq_u32( 9, GetScheduler( id ), SCHEDULER_A_ID );
+ DeleteTask( id );
+
+ /*
+ * Construct a task. Check that the home scheduler of the constructed task
+ * is scheduler A.
+ */
+ sc = rtems_task_construct( &DefaultTaskConfig, &id );
+ T_step_rsc_success( 10, sc );
+
+ T_step_eq_u32( 11, GetScheduler( id ), SCHEDULER_A_ID );
+ DeleteTask( id );
+}
+
+/**
+ * @fn void T_case_body_RtemsTaskValTask( void )
+ */
+T_TEST_CASE( RtemsTaskValTask )
+{
+ T_plan( 12 );
+
+ RtemsTaskValTask_Action_0();
+ RtemsTaskValTask_Action_1();
+ RtemsTaskValTask_Action_2();
+ RtemsTaskValTask_Action_3();
+ RtemsTaskValTask_Action_4();
+ RtemsTaskValTask_Action_5();
+ RtemsTaskValTask_Action_6();
+ RtemsTaskValTask_Action_7();
+ RtemsTaskValTask_Action_8();
+ RtemsTaskValTask_Action_9();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-terminate.c b/testsuites/validation/tc-terminate.c
new file mode 100644
index 0000000000..b533092c19
--- /dev/null
+++ b/testsuites/validation/tc-terminate.c
@@ -0,0 +1,446 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreInterrValTerminate
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <bsp.h>
+#include <setjmp.h>
+#include <string.h>
+#include <rtems/bspIo.h>
+#include <rtems/test-info.h>
+#include <rtems/score/atomic.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/sysstate.h>
+
+#include "tc-userext.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreInterrValTerminate spec:/score/interr/val/terminate
+ *
+ * @ingroup TestsuitesTerminate
+ *
+ * @brief Tests system termination procedure.
+ *
+ * This test case performs the following actions:
+ *
+ * - Create five dynamic extensions. Call the system termination procedure.
+ * Delete three dynamic extension during the fatal extension invocation.
+ * Delete the two remaining dynamic extensions.
+ *
+ * - Where the system was built with SMP support enabled, check that a
+ * shutdown request was issued.
+ *
+ * - Delete the dynamic extension sets.
+ *
+ * - Check that the fatal extensions were invoked with the expected source.
+ *
+ * - Check that the fatal extensions were invoked with the expected always
+ * set to false argument.
+ *
+ * - Check that the fatal extensions were invoked with the expected code.
+ *
+ * - Check that the fatal extensions were invoked in forward order.
+ *
+ * - Check that the fatal extension in the deleted extension set was not
+ * invoked.
+ *
+ * - Check that the system state is terminated.
+ *
+ * - Check that the system was halted with the expected fatal source.
+ *
+ * - Check that the system was halted with the expected fatal code.
+ *
+ * - Check that the system was finally halted.
+ *
+ * @{
+ */
+
+typedef struct {
+ unsigned int counter;
+ rtems_fatal_source source;
+ bool always_set_to_false;
+ rtems_fatal_code code;
+} FatalInfo;
+
+static Atomic_Uint counter;
+
+static FatalInfo info[ 7 ];
+
+static bool test_case_active;
+
+static const rtems_extensions_table bsp = BSP_INITIAL_EXTENSION;
+
+static jmp_buf before_terminate;
+
+static unsigned int halt_counter;
+
+static rtems_fatal_source halt_source;
+
+static rtems_fatal_code halt_code;
+
+static rtems_id extension_ids[ 7 ];
+
+static unsigned int GetCounter( void )
+{
+ return _Atomic_Fetch_add_uint( &counter, 1, ATOMIC_ORDER_RELAXED ) + 1;
+}
+
+void __real__CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr code );
+
+void __wrap__CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr code );
+
+void __wrap__CPU_Fatal_halt( uint32_t source, CPU_Uint32ptr code )
+{
+ if ( test_case_active ) {
+ halt_counter = GetCounter();
+ halt_source = source;
+ halt_code = code;
+ longjmp( before_terminate, 1 );
+ } else {
+#if defined(RTEMS_GCOV_COVERAGE)
+ rtems_test_gcov_dump_info();
+#endif
+ __real__CPU_Fatal_halt( source, code );
+ }
+}
+
+static void FatalExtension(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code,
+ size_t index
+)
+{
+ if ( test_case_active ) {
+ info[ index ].counter = GetCounter();
+ info[ index ].source = source;
+ info[ index ].always_set_to_false = always_set_to_false;
+ info[ index ].code = code;
+ } else {
+ ( *bsp.fatal )( source, always_set_to_false, code );
+ }
+}
+
+void FatalExtension0(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code
+)
+{
+ FatalExtension( source, always_set_to_false, code, 0 );
+}
+
+void FatalExtension1(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code
+)
+{
+ FatalExtension( source, always_set_to_false, code, 1 );
+}
+
+static void FatalExtension2(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code
+)
+{
+ rtems_status_code sc;
+
+ FatalExtension( source, always_set_to_false, code, 2 );
+
+ sc = rtems_extension_delete( extension_ids[ 3 ] );
+ T_quiet_rsc_success( sc );
+}
+
+static void FatalExtension3(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code
+)
+{
+ FatalExtension( source, always_set_to_false, code, 3 );
+}
+
+static void FatalExtension4(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code
+)
+{
+ FatalExtension( source, always_set_to_false, code, 4 );
+}
+
+static void FatalExtension5(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code
+)
+{
+ rtems_status_code sc;
+
+ FatalExtension( source, always_set_to_false, code, 5 );
+
+ sc = rtems_extension_delete( extension_ids[ 5 ] );
+ T_quiet_rsc_success( sc );
+}
+
+static void FatalExtension6(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code
+)
+{
+ rtems_status_code sc;
+
+ FatalExtension( source, always_set_to_false, code, 6 );
+
+ sc = rtems_extension_delete( extension_ids[ 4 ] );
+ T_quiet_rsc_success( sc );
+}
+
+/**
+ * @brief Create five dynamic extensions. Call the system termination
+ * procedure. Delete three dynamic extension during the fatal extension
+ * invocation. Delete the two remaining dynamic extensions.
+ */
+static void ScoreInterrValTerminate_Action_0( void )
+{
+ rtems_status_code sc;
+ rtems_extensions_table table;
+ bool shutdown_ok;
+
+ #if defined(RTEMS_SMP)
+ shutdown_ok =
+ ( _Per_CPU_Get_state( _Per_CPU_Get_snapshot() ) == PER_CPU_STATE_UP );
+ #else
+ shutdown_ok = true;
+ #endif
+
+ memset( &table, 0, sizeof( table ) );
+
+ table.fatal = FatalExtension2;
+ sc = rtems_extension_create(
+ rtems_build_name( ' ', ' ', ' ', '2' ),
+ &table,
+ &extension_ids[ 2 ]
+ );
+ T_step_rsc_success( 0, sc );
+
+ table.fatal = FatalExtension3;
+ sc = rtems_extension_create(
+ rtems_build_name( ' ', ' ', ' ', '3' ),
+ &table,
+ &extension_ids[ 3 ]
+ );
+ T_step_rsc_success( 1, sc );
+
+ table.fatal = FatalExtension4;
+ sc = rtems_extension_create(
+ rtems_build_name( ' ', ' ', ' ', '4' ),
+ &table,
+ &extension_ids[ 4 ]
+ );
+ T_step_rsc_success( 2, sc );
+
+ table.fatal = FatalExtension5;
+ sc = rtems_extension_create(
+ rtems_build_name( ' ', ' ', ' ', '5' ),
+ &table,
+ &extension_ids[ 5 ]
+ );
+ T_step_rsc_success( 3, sc );
+
+ table.fatal = FatalExtension6;
+ sc = rtems_extension_create(
+ rtems_build_name( ' ', ' ', ' ', '6' ),
+ &table,
+ &extension_ids[ 6 ]
+ );
+ T_step_rsc_success( 4, sc );
+
+ test_case_active = true;
+
+ if ( setjmp( before_terminate ) == 0 ) {
+ _Terminate( RTEMS_FATAL_SOURCE_APPLICATION, 123456 );
+ }
+
+ test_case_active = false;
+
+ /*
+ * Where the system was built with SMP support enabled, check that a shutdown
+ * request was issued.
+ */
+ #if defined(RTEMS_SMP)
+ shutdown_ok = ( shutdown_ok && _ISR_Get_level() != 0 &&
+ _Per_CPU_Get_state( _Per_CPU_Get() ) == PER_CPU_STATE_SHUTDOWN );
+ _ISR_Set_level( 0 );
+ #endif
+ T_step_true( 5, shutdown_ok );
+
+ /*
+ * Delete the dynamic extension sets.
+ */
+ sc = rtems_extension_delete( extension_ids[ 2 ] );
+ T_step_rsc_success( 6, sc );
+
+ sc = rtems_extension_delete( extension_ids[ 6 ] );
+ T_step_rsc_success( 7, sc );
+
+ /*
+ * Check that the fatal extensions were invoked with the expected source.
+ */
+ T_step_eq_int(
+ 8,
+ info[ 0 ].source,
+ RTEMS_FATAL_SOURCE_APPLICATION
+ );
+ T_step_eq_int(
+ 9,
+ info[ 1 ].source,
+ RTEMS_FATAL_SOURCE_APPLICATION
+ );
+ T_step_eq_int(
+ 10,
+ info[ 2 ].source,
+ RTEMS_FATAL_SOURCE_APPLICATION
+ );
+ T_step_eq_int(
+ 11,
+ info[ 4 ].source,
+ RTEMS_FATAL_SOURCE_APPLICATION
+ );
+ T_step_eq_int(
+ 12,
+ info[ 5 ].source,
+ RTEMS_FATAL_SOURCE_APPLICATION
+ );
+ T_step_eq_int(
+ 13,
+ info[ 6 ].source,
+ RTEMS_FATAL_SOURCE_APPLICATION
+ );
+
+ /*
+ * Check that the fatal extensions were invoked with the expected always set
+ * to false argument.
+ */
+ T_step_false( 14, info[ 0 ].always_set_to_false );
+ T_step_false( 15, info[ 1 ].always_set_to_false );
+ T_step_false( 16, info[ 2 ].always_set_to_false );
+ T_step_false( 17, info[ 4 ].always_set_to_false );
+ T_step_false( 18, info[ 5 ].always_set_to_false );
+ T_step_false( 19, info[ 6 ].always_set_to_false );
+
+ /*
+ * Check that the fatal extensions were invoked with the expected code.
+ */
+ T_step_eq_ulong( 20, info[ 0 ].code, 123456 );
+ T_step_eq_ulong( 21, info[ 1 ].code, 123456 );
+ T_step_eq_ulong( 22, info[ 2 ].code, 123456 );
+ T_step_eq_ulong( 23, info[ 4 ].code, 123456 );
+ T_step_eq_ulong( 24, info[ 5 ].code, 123456 );
+ T_step_eq_ulong( 25, info[ 6 ].code, 123456 );
+
+ /*
+ * Check that the fatal extensions were invoked in forward order.
+ */
+ T_step_eq_uint( 26, info[ 0 ].counter, 1 );
+ T_step_eq_uint( 27, info[ 1 ].counter, 2 );
+ T_step_eq_uint( 28, info[ 2 ].counter, 3 );
+ T_step_eq_uint( 29, info[ 4 ].counter, 4 );
+ T_step_eq_uint( 30, info[ 5 ].counter, 5 );
+ T_step_eq_uint( 31, info[ 6 ].counter, 6 );
+
+ /*
+ * Check that the fatal extension in the deleted extension set was not
+ * invoked.
+ */
+ T_step_eq_int( 32, info[ 3 ].source, 0 );
+ T_step_false( 33, info[ 3 ].always_set_to_false );
+ T_step_eq_ulong( 34, info[ 3 ].code, 0 );
+ T_step_eq_uint( 35, info[ 3 ].counter, 0 );
+
+ /*
+ * Check that the system state is terminated.
+ */
+ T_step_eq_int( 36, _System_state_Get(), SYSTEM_STATE_TERMINATED );
+
+ /*
+ * Check that the system was halted with the expected fatal source.
+ */
+ T_step_eq_int( 37, halt_source, RTEMS_FATAL_SOURCE_APPLICATION );
+
+ /*
+ * Check that the system was halted with the expected fatal code.
+ */
+ T_step_eq_ulong( 38, halt_code, 123456 );
+
+ /*
+ * Check that the system was finally halted.
+ */
+ T_step_eq_uint( 39, counter, 7 );
+}
+
+/**
+ * @fn void T_case_body_ScoreInterrValTerminate( void )
+ */
+T_TEST_CASE( ScoreInterrValTerminate )
+{
+ T_plan( 40 );
+
+ ScoreInterrValTerminate_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-thread-idle-body-no-return.c b/testsuites/validation/tc-thread-idle-body-no-return.c
new file mode 100644
index 0000000000..19c86dad99
--- /dev/null
+++ b/testsuites/validation/tc-thread-idle-body-no-return.c
@@ -0,0 +1,205 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreThreadValIdleBodyNoReturn
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <bsp.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreThreadValIdleBodyNoReturn \
+ * spec:/score/thread/val/idle-body-no-return
+ *
+ * @ingroup TestsuitesValidation0
+ *
+ * @brief Tests thread idle body behaviour.
+ *
+ * This test case performs the following actions:
+ *
+ * - Create threads which execute an thread idle body. Check that the thread
+ * idle body does not return. If it would return, then an
+ * INTERNAL_ERROR_THREAD_EXITTED fatal error would occur.
+ *
+ * - Check that the CPU port thread idle body does not return.
+ *
+ * - Where the BSP provides an idle thread body, check that it does not
+ * return.
+ *
+ * - Clean up all used resources.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/score/thread/val/idle-body-no-return test
+ * case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a counter.
+ */
+ uint32_t counter;
+} ScoreThreadValIdleBodyNoReturn_Context;
+
+static ScoreThreadValIdleBodyNoReturn_Context
+ ScoreThreadValIdleBodyNoReturn_Instance;
+
+typedef ScoreThreadValIdleBodyNoReturn_Context Context;
+
+static void CheckIdleBody( Context *ctx, rtems_task_entry entry )
+{
+ rtems_id id;
+ rtems_interval interval;
+ rtems_status_code sc;
+
+ ctx->counter = 0;
+ id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( id, entry, ctx );
+
+ /*
+ * With optimization disabled, coverage enabled, SMP enabled and a slow
+ * target, things may take some time.
+ */
+ interval = 1;
+ while ( ctx->counter == 0 && interval <= 1024 ) {
+
+ sc = rtems_task_wake_after( interval );
+ T_rsc_success( sc );
+
+ interval *= 2;
+ }
+
+ sc = rtems_task_wake_after( interval );
+ T_rsc_success( sc );
+
+ T_eq_u32( ctx->counter, 1 );
+ DeleteTask( id );
+}
+
+static void CPUThreadIdleBody( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+ ++ctx->counter;
+
+ (void) _CPU_Thread_Idle_body( 0 );
+}
+
+#if defined(BSP_IDLE_TASK_BODY)
+static void BSPIdleTaskBody( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+ ++ctx->counter;
+
+ (void) BSP_IDLE_TASK_BODY( 0 );
+}
+#endif
+
+static T_fixture ScoreThreadValIdleBodyNoReturn_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &ScoreThreadValIdleBodyNoReturn_Instance
+};
+
+/**
+ * @brief Create threads which execute an thread idle body. Check that the
+ * thread idle body does not return. If it would return, then an
+ * INTERNAL_ERROR_THREAD_EXITTED fatal error would occur.
+ */
+static void ScoreThreadValIdleBodyNoReturn_Action_0(
+ ScoreThreadValIdleBodyNoReturn_Context *ctx
+)
+{
+ SetSelfPriority( PRIO_NORMAL );
+
+ /*
+ * Check that the CPU port thread idle body does not return.
+ */
+ CheckIdleBody( ctx, CPUThreadIdleBody );
+
+ /*
+ * Where the BSP provides an idle thread body, check that it does not return.
+ */
+ #if defined(BSP_IDLE_TASK_BODY)
+ CheckIdleBody( ctx, BSPIdleTaskBody );
+ #endif
+
+ /*
+ * Clean up all used resources.
+ */
+ RestoreRunnerPriority();
+}
+
+/**
+ * @fn void T_case_body_ScoreThreadValIdleBodyNoReturn( void )
+ */
+T_TEST_CASE_FIXTURE(
+ ScoreThreadValIdleBodyNoReturn,
+ &ScoreThreadValIdleBodyNoReturn_Fixture
+)
+{
+ ScoreThreadValIdleBodyNoReturn_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ ScoreThreadValIdleBodyNoReturn_Action_0( ctx );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-timecounter-get-smp.c b/testsuites/validation/tc-timecounter-get-smp.c
new file mode 100644
index 0000000000..d8c9f598dd
--- /dev/null
+++ b/testsuites/validation/tc-timecounter-get-smp.c
@@ -0,0 +1,740 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTimecounterValGetSmp
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/counter.h>
+#include <rtems/timecounter.h>
+#include <rtems/score/smpbarrier.h>
+#include <rtems/score/threaddispatch.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTimecounterValGetSmp spec:/score/timecounter/val/get-smp
+ *
+ * @ingroup TestsuitesValidationTimecounterSmp0
+ *
+ * @brief Tests directives to get a time value.
+ *
+ * This test case performs the following actions:
+ *
+ * - Install timecounter of different quality levels and frequencies.
+ *
+ * - Call the rtems_clock_get_realtime() directive and let it observe a
+ * generation number of zero as well as a generation number change.
+ *
+ * - Call the rtems_clock_get_realtime_bintime() directive and let it observe
+ * a generation number of zero as well as a generation number change.
+ *
+ * - Call the rtems_clock_get_realtime_timeval() directive and let it observe
+ * a generation number of zero as well as a generation number change.
+ *
+ * - Call the rtems_clock_get_monotonic() directive and let it observe a
+ * generation number of zero as well as a generation number change.
+ *
+ * - Call the rtems_clock_get_monotonic_bintime() directive and let it
+ * observe a generation number of zero as well as a generation number
+ * change.
+ *
+ * - Call the rtems_clock_get_monotonic_sbintime() directive and let it
+ * observe a generation number of zero as well as a generation number
+ * change.
+ *
+ * - Call the rtems_clock_get_monotonic_timeval() directive and let it
+ * observe a generation number of zero as well as a generation number
+ * change.
+ *
+ * - Delete the synchronous worker task. Reinitialize the barrier and
+ * barrier states. Start the zero worker task.
+ *
+ * - Call the rtems_clock_get_realtime_coarse() directive and try to let it
+ * observe a generation number of zero.
+ *
+ * - Call the rtems_clock_get_realtime_coarse_bintime() directive and try to
+ * let it observe a generation number of zero.
+ *
+ * - Call the rtems_clock_get_realtime_coarse_timeval() directive and try to
+ * let it observe a generation number of zero.
+ *
+ * - Call the rtems_clock_get_monotonic_coarse() directive and try to let it
+ * observe a generation number of zero.
+ *
+ * - Call the rtems_clock_get_monotonic_coarse_bintime() directive and try to
+ * let it observe a generation number of zero.
+ *
+ * - Call the rtems_clock_get_monotonic_coarse_timeval() directive and try to
+ * let it observe a generation number of zero.
+ *
+ * - Call the rtems_clock_get_boot_time() directive and try to let it observe
+ * a generation number of zero.
+ *
+ * - Call the rtems_clock_get_boot_time_bintime() directive and try to let it
+ * observe a generation number of zero.
+ *
+ * - Call the rtems_clock_get_boot_time_timeval() directive and try to let it
+ * observe a generation number of zero.
+ *
+ * - Delete the zero worker task. Reinitialize the barrier and barrier
+ * states. Start the change worker task.
+ *
+ * - Call the rtems_clock_get_realtime_coarse() directive and try to let it
+ * observe a changing generation number.
+ *
+ * - Call the rtems_clock_get_realtime_coarse_bintime() directive and try to
+ * let it observe a changing generation number.
+ *
+ * - Call the rtems_clock_get_realtime_coarse_timeval() directive and try to
+ * let it observe a changing generation number.
+ *
+ * - Call the rtems_clock_get_monotonic_coarse() directive and try to let it
+ * observe a changing generation number.
+ *
+ * - Call the rtems_clock_get_monotonic_coarse_bintime() directive and try to
+ * let it observe a changing generation number.
+ *
+ * - Call the rtems_clock_get_monotonic_coarse_timeval() directive and try to
+ * let it observe a changing generation number.
+ *
+ * - Call the rtems_clock_get_boot_time() directive and try to let it observe
+ * a changing generation number.
+ *
+ * - Call the rtems_clock_get_boot_time_bintime() directive and try to let it
+ * observe a changing generation number.
+ *
+ * - Call the rtems_clock_get_boot_time_timeval() directive and try to let it
+ * observe a changing generation number.
+ *
+ * - Delete the change worker task.
+ *
+ * @{
+ */
+
+typedef struct {
+ struct timecounter base;
+ Atomic_Ulong counter;
+ Atomic_Uint *generation_0;
+ Atomic_Uint *generation_1;
+ SMP_barrier_Control barrier;
+ SMP_barrier_State barrier_state[ 2 ];
+} Timecounter;
+
+static Timecounter test_timecounter;
+
+static uint32_t GetTimecount( struct timecounter *base )
+{
+ Timecounter *tc;
+
+ tc = (Timecounter *) base;
+
+ return (uint32_t) _Atomic_Fetch_add_ulong(
+ &tc->counter,
+ 1,
+ ATOMIC_ORDER_RELAXED
+ );
+}
+
+static uint32_t GetTimecountBarrier( struct timecounter *base )
+{
+ Timecounter *tc;
+
+ tc = (Timecounter *) base;
+
+ /* C0, C1, C2 */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 );
+
+ /* D0, D1, D2 */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 );
+
+ return GetTimecount( &tc->base );
+}
+
+static uint32_t GetCounter( const Timecounter *tc )
+{
+ return (uint32_t) _Atomic_Load_ulong(
+ &tc->counter,
+ ATOMIC_ORDER_RELAXED
+ );
+}
+
+static void SetCounter( Timecounter *tc, uint32_t counter )
+{
+ _Atomic_Store_ulong(
+ &tc->counter,
+ counter,
+ ATOMIC_ORDER_RELAXED
+ );
+}
+
+static void CallTimecounterTick( void )
+{
+ Per_CPU_Control *cpu_self;
+
+ cpu_self = _Thread_Dispatch_disable();
+ rtems_timecounter_tick();
+ _Thread_Dispatch_enable( cpu_self );
+}
+
+static void SetGeneration( Timecounter *tc, unsigned int generation )
+{
+ _Atomic_Store_uint( tc->generation_0, generation, ATOMIC_ORDER_RELAXED );
+ _Atomic_Store_uint( tc->generation_1, generation, ATOMIC_ORDER_RELAXED );
+}
+
+static void PrepareSynchronousWork( Timecounter *tc )
+{
+ /* A */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 );
+
+ SetCounter( tc, 0 );
+
+ /* B */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 );
+}
+
+static void CleanupSynchronousWork( Timecounter *tc )
+{
+ /* E */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 );
+
+ T_eq_u32( GetCounter( tc ), 3 );
+}
+
+static void SynchronousWorker( rtems_task_argument arg )
+{
+ Timecounter *tc;
+
+ tc = (Timecounter *) arg;
+
+ while ( true ) {
+ /* A */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 );
+
+ SetGeneration( tc, 0 );
+
+ /* B */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 );
+
+ /* C0 */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 );
+
+ SetGeneration( tc, 1 );
+
+ /* D0 */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 );
+
+ /* C1 */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 );
+
+ SetGeneration( tc, 2 );
+
+ /* D1 */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 );
+
+ /* C2 */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 );
+
+ /* D2 */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 );
+
+ /* E */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 );
+ }
+}
+
+static void PrepareZeroWork( Timecounter *tc )
+{
+ /* F */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 );
+
+ SetCounter( tc, 0 );
+
+ /* G */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 );
+}
+
+static void CleanupZeroWork( Timecounter *tc )
+{
+ /* H */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 );
+
+ T_eq_u32( GetCounter( tc ), 0 );
+}
+
+static void ZeroWorker( rtems_task_argument arg )
+{
+ Timecounter *tc;
+
+ tc = (Timecounter *) arg;
+
+ while ( true ) {
+ /* F */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 );
+
+ SetGeneration( tc, 0 );
+
+ /* G */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 );
+
+ rtems_counter_delay_nanoseconds( 10000000 );
+ SetGeneration( tc, 1 );
+
+ /* H */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 );
+ }
+}
+
+static void PrepareChangeWork( Timecounter *tc )
+{
+ /* F */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 );
+
+ SetCounter( tc, 0 );
+
+ /* G */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 );
+}
+
+static void CleanupChangeWork( Timecounter *tc )
+{
+ /* H */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 0 ], 2 );
+
+ T_eq_u32( GetCounter( tc ), 0 );
+}
+
+static void ChangeWorker( rtems_task_argument arg )
+{
+ Timecounter *tc;
+
+ tc = (Timecounter *) arg;
+
+ while ( true ) {
+ unsigned int i;
+
+ /* F */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 );
+
+ /* G */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 );
+
+ for ( i = 1; i < 1000; ++i ) {
+ SetGeneration( tc, i );
+ }
+
+ /* H */
+ _SMP_barrier_Wait( &tc->barrier, &tc->barrier_state[ 1 ], 2 );
+ }
+}
+
+/* This definition must be identical to the one in kern_tc.c */
+struct timehands {
+ struct timecounter *th_counter;
+ int64_t th_adjustment;
+ uint64_t th_scale;
+ uint32_t th_large_delta;
+ uint32_t th_offset_count;
+ struct bintime th_offset;
+ struct bintime th_bintime;
+ struct timeval th_microtime;
+ struct timespec th_nanotime;
+ struct bintime th_boottime;
+ Atomic_Uint th_generation;
+ struct timehands *th_next;
+};
+
+static void NtpUpdateSecond( int64_t *adjustment, time_t *newsec )
+{
+ Timecounter *tc;
+ struct timehands *th;
+
+ tc = &test_timecounter;
+ th = RTEMS_CONTAINER_OF( adjustment, struct timehands, th_adjustment );
+ T_assert_eq_ptr( th, th->th_next->th_next );
+ tc->generation_0 = &th->th_generation;
+ tc->generation_1 = &th->th_next->th_generation;
+}
+
+/**
+ * @brief Install timecounter of different quality levels and frequencies.
+ */
+static void ScoreTimecounterValGetSmp_Action_0( void )
+{
+ Timecounter *tc;
+ rtems_id worker_id;
+ struct bintime bt;
+ sbintime_t sbt;
+ struct timespec ts;
+ struct timeval tv;
+ unsigned int i;
+
+ tc = &test_timecounter;
+ tc->base.tc_get_timecount = GetTimecount;
+ tc->base.tc_counter_mask = 0xffffffff;
+ tc->base.tc_frequency = 0x10000000;
+ tc->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ rtems_timecounter_install( &tc->base );
+
+ SetCounter( tc, tc->base.tc_frequency );
+ _Timecounter_Set_NTP_update_second( NtpUpdateSecond );
+ CallTimecounterTick();
+ _Timecounter_Set_NTP_update_second( NULL );
+
+ T_assert_not_null( tc->generation_0 );
+ T_assert_not_null( tc->generation_1 );
+
+ _SMP_barrier_Control_initialize( &tc->barrier );
+ _SMP_barrier_State_initialize( &tc->barrier_state[ 0 ] );
+ _SMP_barrier_State_initialize( &tc->barrier_state[ 1 ] );
+
+ worker_id = CreateTask( "WORK", PRIO_NORMAL );
+ SetScheduler( worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+ StartTask( worker_id, SynchronousWorker, tc );
+
+ tc->base.tc_get_timecount = GetTimecountBarrier;
+
+ /*
+ * Call the rtems_clock_get_realtime() directive and let it observe a
+ * generation number of zero as well as a generation number change.
+ */
+ PrepareSynchronousWork( tc );
+ rtems_clock_get_realtime( &ts );
+ T_eq_i64( ts.tv_sec, 567993616 );
+ T_eq_long( ts.tv_nsec, 7 );
+ CleanupSynchronousWork( tc );
+
+ /*
+ * Call the rtems_clock_get_realtime_bintime() directive and let it observe a
+ * generation number of zero as well as a generation number change.
+ */
+ PrepareSynchronousWork( tc );
+ rtems_clock_get_realtime_bintime( &bt );
+ T_eq_i64( bt.sec, 567993616 );
+ T_eq_u64( bt.frac, 137438953472 );
+ CleanupSynchronousWork( tc );
+
+ /*
+ * Call the rtems_clock_get_realtime_timeval() directive and let it observe a
+ * generation number of zero as well as a generation number change.
+ */
+ PrepareSynchronousWork( tc );
+ rtems_clock_get_realtime_timeval( &tv );
+ T_eq_i64( tv.tv_sec, 567993616 );
+ T_eq_long( tv.tv_usec, 0 );
+ CleanupSynchronousWork( tc );
+
+ /*
+ * Call the rtems_clock_get_monotonic() directive and let it observe a
+ * generation number of zero as well as a generation number change.
+ */
+ PrepareSynchronousWork( tc );
+ rtems_clock_get_monotonic( &ts );
+ T_eq_i64( ts.tv_sec, 17 );
+ T_eq_long( ts.tv_nsec, 7 );
+ CleanupSynchronousWork( tc );
+
+ /*
+ * Call the rtems_clock_get_monotonic_bintime() directive and let it observe
+ * a generation number of zero as well as a generation number change.
+ */
+ PrepareSynchronousWork( tc );
+ rtems_clock_get_monotonic_bintime( &bt );
+ T_eq_i64( bt.sec, 17 );
+ T_eq_u64( bt.frac, 137438953472 );
+ CleanupSynchronousWork( tc );
+
+ /*
+ * Call the rtems_clock_get_monotonic_sbintime() directive and let it observe
+ * a generation number of zero as well as a generation number change.
+ */
+ PrepareSynchronousWork( tc );
+ sbt = rtems_clock_get_monotonic_sbintime();
+ T_eq_i64( sbt, 73014444064 );
+ CleanupSynchronousWork( tc );
+
+ /*
+ * Call the rtems_clock_get_monotonic_timeval() directive and let it observe
+ * a generation number of zero as well as a generation number change.
+ */
+ PrepareSynchronousWork( tc );
+ rtems_clock_get_monotonic_timeval( &tv );
+ T_eq_i64( tv.tv_sec, 17 );
+ T_eq_long( tv.tv_usec, 0 );
+ CleanupSynchronousWork( tc );
+
+ /*
+ * Delete the synchronous worker task. Reinitialize the barrier and barrier
+ * states. Start the zero worker task.
+ */
+ tc->base.tc_get_timecount = GetTimecount;
+ DeleteTask( worker_id );
+
+ _SMP_barrier_Control_initialize( &tc->barrier );
+ _SMP_barrier_State_initialize( &tc->barrier_state[ 0 ] );
+ _SMP_barrier_State_initialize( &tc->barrier_state[ 1 ] );
+
+ worker_id = CreateTask( "WORK", PRIO_NORMAL );
+ SetScheduler( worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+ StartTask( worker_id, ZeroWorker, tc );
+
+ /*
+ * Call the rtems_clock_get_realtime_coarse() directive and try to let it
+ * observe a generation number of zero.
+ */
+ PrepareZeroWork( tc );
+ rtems_clock_get_realtime_coarse( &ts );
+ CleanupZeroWork( tc );
+
+ /*
+ * Call the rtems_clock_get_realtime_coarse_bintime() directive and try to
+ * let it observe a generation number of zero.
+ */
+ PrepareZeroWork( tc );
+ rtems_clock_get_realtime_coarse_bintime( &bt );
+ CleanupZeroWork( tc );
+
+ /*
+ * Call the rtems_clock_get_realtime_coarse_timeval() directive and try to
+ * let it observe a generation number of zero.
+ */
+ PrepareZeroWork( tc );
+ rtems_clock_get_realtime_coarse_timeval( &tv );
+ CleanupZeroWork( tc );
+
+ /*
+ * Call the rtems_clock_get_monotonic_coarse() directive and try to let it
+ * observe a generation number of zero.
+ */
+ PrepareZeroWork( tc );
+ rtems_clock_get_monotonic_coarse( &ts );
+ CleanupZeroWork( tc );
+
+ /*
+ * Call the rtems_clock_get_monotonic_coarse_bintime() directive and try to
+ * let it observe a generation number of zero.
+ */
+ PrepareZeroWork( tc );
+ rtems_clock_get_monotonic_coarse_bintime( &bt );
+ CleanupZeroWork( tc );
+
+ /*
+ * Call the rtems_clock_get_monotonic_coarse_timeval() directive and try to
+ * let it observe a generation number of zero.
+ */
+ PrepareZeroWork( tc );
+ rtems_clock_get_monotonic_coarse_timeval( &tv );
+ CleanupZeroWork( tc );
+
+ /*
+ * Call the rtems_clock_get_boot_time() directive and try to let it observe a
+ * generation number of zero.
+ */
+ PrepareZeroWork( tc );
+ rtems_clock_get_boot_time( &ts );
+ CleanupZeroWork( tc );
+
+ /*
+ * Call the rtems_clock_get_boot_time_bintime() directive and try to let it
+ * observe a generation number of zero.
+ */
+ PrepareZeroWork( tc );
+ rtems_clock_get_boot_time_bintime( &bt );
+ CleanupZeroWork( tc );
+
+ /*
+ * Call the rtems_clock_get_boot_time_timeval() directive and try to let it
+ * observe a generation number of zero.
+ */
+ PrepareZeroWork( tc );
+ rtems_clock_get_boot_time_timeval( &tv );
+ CleanupZeroWork( tc );
+
+ /*
+ * Delete the zero worker task. Reinitialize the barrier and barrier states.
+ * Start the change worker task.
+ */
+ DeleteTask( worker_id );
+
+ _SMP_barrier_Control_initialize( &tc->barrier );
+ _SMP_barrier_State_initialize( &tc->barrier_state[ 0 ] );
+ _SMP_barrier_State_initialize( &tc->barrier_state[ 1 ] );
+
+ worker_id = CreateTask( "WORK", PRIO_NORMAL );
+ SetScheduler( worker_id, SCHEDULER_B_ID, PRIO_NORMAL );
+ StartTask( worker_id, ChangeWorker, tc );
+
+ /*
+ * Call the rtems_clock_get_realtime_coarse() directive and try to let it
+ * observe a changing generation number.
+ */
+ PrepareChangeWork( tc );
+
+ for ( i = 0; i < 100; ++i ) {
+ rtems_clock_get_realtime_coarse( &ts );
+ }
+
+ CleanupChangeWork( tc );
+
+ /*
+ * Call the rtems_clock_get_realtime_coarse_bintime() directive and try to
+ * let it observe a changing generation number.
+ */
+ PrepareChangeWork( tc );
+
+ for ( i = 0; i < 100; ++i ) {
+ rtems_clock_get_realtime_coarse_bintime( &bt );
+ }
+
+ CleanupChangeWork( tc );
+
+ /*
+ * Call the rtems_clock_get_realtime_coarse_timeval() directive and try to
+ * let it observe a changing generation number.
+ */
+ PrepareChangeWork( tc );
+
+ for ( i = 0; i < 100; ++i ) {
+ rtems_clock_get_realtime_coarse_timeval( &tv );
+ }
+
+ CleanupChangeWork( tc );
+
+ /*
+ * Call the rtems_clock_get_monotonic_coarse() directive and try to let it
+ * observe a changing generation number.
+ */
+ PrepareChangeWork( tc );
+
+ for ( i = 0; i < 100; ++i ) {
+ rtems_clock_get_monotonic_coarse( &ts );
+ }
+
+ CleanupChangeWork( tc );
+
+ /*
+ * Call the rtems_clock_get_monotonic_coarse_bintime() directive and try to
+ * let it observe a changing generation number.
+ */
+ PrepareChangeWork( tc );
+
+ for ( i = 0; i < 100; ++i ) {
+ rtems_clock_get_monotonic_coarse_bintime( &bt );
+ }
+
+ CleanupChangeWork( tc );
+
+ /*
+ * Call the rtems_clock_get_monotonic_coarse_timeval() directive and try to
+ * let it observe a changing generation number.
+ */
+ PrepareChangeWork( tc );
+
+ for ( i = 0; i < 100; ++i ) {
+ rtems_clock_get_monotonic_coarse_timeval( &tv );
+ }
+
+ CleanupChangeWork( tc );
+
+ /*
+ * Call the rtems_clock_get_boot_time() directive and try to let it observe a
+ * changing generation number.
+ */
+ PrepareChangeWork( tc );
+
+ for ( i = 0; i < 100; ++i ) {
+ rtems_clock_get_boot_time( &ts );
+ }
+
+ CleanupChangeWork( tc );
+
+ /*
+ * Call the rtems_clock_get_boot_time_bintime() directive and try to let it
+ * observe a changing generation number.
+ */
+ PrepareChangeWork( tc );
+
+ for ( i = 0; i < 100; ++i ) {
+ rtems_clock_get_boot_time_bintime( &bt );
+ }
+
+ CleanupChangeWork( tc );
+
+ /*
+ * Call the rtems_clock_get_boot_time_timeval() directive and try to let it
+ * observe a changing generation number.
+ */
+ PrepareChangeWork( tc );
+
+ for ( i = 0; i < 100; ++i ) {
+ rtems_clock_get_boot_time_timeval( &tv );
+ }
+
+ CleanupChangeWork( tc );
+
+ /*
+ * Delete the change worker task.
+ */
+ DeleteTask( worker_id );
+}
+
+/**
+ * @fn void T_case_body_ScoreTimecounterValGetSmp( void )
+ */
+T_TEST_CASE( ScoreTimecounterValGetSmp )
+{
+ ScoreTimecounterValGetSmp_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-timecounter-get.c b/testsuites/validation/tc-timecounter-get.c
new file mode 100644
index 0000000000..cd2464399e
--- /dev/null
+++ b/testsuites/validation/tc-timecounter-get.c
@@ -0,0 +1,574 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTimecounterValGet
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/counter.h>
+#include <rtems/timecounter.h>
+#include <rtems/score/timecounterimpl.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTimecounterValGet spec:/score/timecounter/val/get
+ *
+ * @ingroup TestsuitesValidationTimecounter1
+ *
+ * @brief Tests directives to get a time value.
+ *
+ * This test case performs the following actions:
+ *
+ * - Install a timecounter which can be used to perform interrut tests for the
+ * get time directives.
+ *
+ * - Try to interrupt the rtems_clock_get_realtime() directive to provoke a
+ * change in the timehand generation number.
+ *
+ * - Try to interrupt the rtems_clock_get_realtime_bintime() directive to
+ * provoke a change in the timehand generation number.
+ *
+ * - Try to interrupt the rtems_clock_get_realtime_timeval() directive to
+ * provoke a change in the timehand generation number.
+ *
+ * - Try to interrupt the rtems_clock_get_monotonic() directive to provoke a
+ * change in the timehand generation number.
+ *
+ * - Try to interrupt the rtems_clock_get_monotonic_bintime() directive to
+ * provoke a change in the timehand generation number.
+ *
+ * - Try to interrupt the rtems_clock_get_monotonic_sbintime() directive to
+ * provoke a change in the timehand generation number.
+ *
+ * - Try to interrupt the rtems_clock_get_monotonic_timeval() directive to
+ * provoke a change in the timehand generation number.
+ *
+ * - Prepare for the coarse get time directives.
+ *
+ * - Try to interrupt the rtems_clock_get_realtime_coarse() directive to
+ * provoke a change in the timehand generation number.
+ *
+ * - Try to interrupt the rtems_clock_get_realtime_coarse_bintime() directive
+ * to provoke a change in the timehand generation number.
+ *
+ * - Try to interrupt the rtems_clock_get_realtime_coarse_timeval() directive
+ * to provoke a change in the timehand generation number.
+ *
+ * - Try to interrupt the rtems_clock_get_monotonic_coarse() directive to
+ * provoke a change in the timehand generation number.
+ *
+ * - Try to interrupt the rtems_clock_get_monotonic_coarse_bintime()
+ * directive to provoke a change in the timehand generation number.
+ *
+ * - Try to interrupt the rtems_clock_get_monotonic_coarse_timeval()
+ * directive to provoke a change in the timehand generation number.
+ *
+ * - Try to interrupt the rtems_clock_get_boot_time() directive to provoke a
+ * change in the timehand generation number.
+ *
+ * - Try to interrupt the rtems_clock_get_boot_time_bintime() directive to
+ * provoke a change in the timehand generation number.
+ *
+ * - Try to interrupt the rtems_clock_get_boot_time_timeval() directive to
+ * provoke a change in the timehand generation number.
+ *
+ * @{
+ */
+
+typedef enum {
+ STATE_EARLY,
+ STATE_GET_TIMECOUNT_BEFORE,
+ STATE_GET_TIMECOUNT_BUSY,
+ STATE_GET_TIMECOUNT_DONE,
+ STATE_GET_TIMECOUNT_AFTER
+} State;
+
+typedef struct {
+ struct timecounter base;
+ State state;
+ uint_fast32_t busy;
+ struct bintime tod;
+} Timecounter;
+
+static Timecounter test_timecounter;
+
+static uint32_t GetTimecount( struct timecounter *base )
+{
+ Timecounter *tc;
+
+ tc = (Timecounter *) base;
+
+ if (
+ tc->state == STATE_GET_TIMECOUNT_BEFORE &&
+ !rtems_interrupt_is_in_progress()
+ ) {
+ tc->state = STATE_GET_TIMECOUNT_BUSY;
+ T_busy( tc->busy );
+ tc->state = STATE_GET_TIMECOUNT_DONE;
+ }
+
+ return rtems_counter_read();
+}
+
+static void InterruptPrepare( void *arg )
+{
+ Timecounter *tc;
+
+ tc = (Timecounter *) arg;
+ tc->state = STATE_EARLY;
+}
+
+static void ActionRealtime( void *arg )
+{
+ Timecounter *tc;
+ struct timespec ts;
+
+ tc = (Timecounter *) arg;
+ tc->state = STATE_GET_TIMECOUNT_BEFORE;
+ rtems_clock_get_realtime( &ts );
+ tc->state = STATE_GET_TIMECOUNT_AFTER;
+}
+
+static void ActionRealtimeBintime( void *arg )
+{
+ Timecounter *tc;
+ struct bintime bt;
+
+ tc = (Timecounter *) arg;
+ tc->state = STATE_GET_TIMECOUNT_BEFORE;
+ rtems_clock_get_realtime_bintime( &bt );
+ tc->state = STATE_GET_TIMECOUNT_AFTER;
+}
+
+static void ActionRealtimeTimeval( void *arg )
+{
+ Timecounter *tc;
+ struct timeval tv;
+
+ tc = (Timecounter *) arg;
+ tc->state = STATE_GET_TIMECOUNT_BEFORE;
+ rtems_clock_get_realtime_timeval( &tv );
+ tc->state = STATE_GET_TIMECOUNT_AFTER;
+}
+
+static void ActionMonotonic( void *arg )
+{
+ Timecounter *tc;
+ struct timespec ts;
+
+ tc = (Timecounter *) arg;
+ tc->state = STATE_GET_TIMECOUNT_BEFORE;
+ rtems_clock_get_monotonic( &ts );
+ tc->state = STATE_GET_TIMECOUNT_AFTER;
+}
+
+static void ActionMonotonicBintime( void *arg )
+{
+ Timecounter *tc;
+ struct bintime bt;
+
+ tc = (Timecounter *) arg;
+ tc->state = STATE_GET_TIMECOUNT_BEFORE;
+ rtems_clock_get_monotonic_bintime( &bt );
+ tc->state = STATE_GET_TIMECOUNT_AFTER;
+}
+
+static void ActionMonotonicSbintime( void *arg )
+{
+ Timecounter *tc;
+
+ tc = (Timecounter *) arg;
+ tc->state = STATE_GET_TIMECOUNT_BEFORE;
+ (void) rtems_clock_get_monotonic_sbintime();
+ tc->state = STATE_GET_TIMECOUNT_AFTER;
+}
+
+static void ActionMonotonicTimeval( void *arg )
+{
+ Timecounter *tc;
+ struct timeval tv;
+
+ tc = (Timecounter *) arg;
+ tc->state = STATE_GET_TIMECOUNT_BEFORE;
+ rtems_clock_get_monotonic_timeval( &tv );
+ tc->state = STATE_GET_TIMECOUNT_AFTER;
+}
+
+static void ActionCoarseRealtime( void *arg )
+{
+ Timecounter *tc;
+ struct timespec ts;
+
+ tc = (Timecounter *) arg;
+ tc->state = STATE_GET_TIMECOUNT_BEFORE;
+ rtems_clock_get_realtime_coarse( &ts );
+ tc->state = STATE_GET_TIMECOUNT_AFTER;
+}
+
+static void ActionCoarseRealtimeBintime( void *arg )
+{
+ Timecounter *tc;
+ struct bintime bt;
+
+ tc = (Timecounter *) arg;
+ tc->state = STATE_GET_TIMECOUNT_BEFORE;
+ rtems_clock_get_realtime_coarse_bintime( &bt );
+ tc->state = STATE_GET_TIMECOUNT_AFTER;
+}
+
+static void ActionCoarseRealtimeTimeval( void *arg )
+{
+ Timecounter *tc;
+ struct timeval tv;
+
+ tc = (Timecounter *) arg;
+ tc->state = STATE_GET_TIMECOUNT_BEFORE;
+ rtems_clock_get_realtime_coarse_timeval( &tv );
+ tc->state = STATE_GET_TIMECOUNT_AFTER;
+}
+
+static void ActionCoarseMonotonic( void *arg )
+{
+ Timecounter *tc;
+ struct timespec ts;
+
+ tc = (Timecounter *) arg;
+ tc->state = STATE_GET_TIMECOUNT_BEFORE;
+ rtems_clock_get_monotonic_coarse( &ts );
+ tc->state = STATE_GET_TIMECOUNT_AFTER;
+}
+
+static void ActionCoarseMonotonicBintime( void *arg )
+{
+ Timecounter *tc;
+ struct bintime bt;
+
+ tc = (Timecounter *) arg;
+ tc->state = STATE_GET_TIMECOUNT_BEFORE;
+ rtems_clock_get_monotonic_coarse_bintime( &bt );
+ tc->state = STATE_GET_TIMECOUNT_AFTER;
+}
+
+static void ActionCoarseMonotonicTimeval( void *arg )
+{
+ Timecounter *tc;
+ struct timeval tv;
+
+ tc = (Timecounter *) arg;
+ tc->state = STATE_GET_TIMECOUNT_BEFORE;
+ rtems_clock_get_monotonic_coarse_timeval( &tv );
+ tc->state = STATE_GET_TIMECOUNT_AFTER;
+}
+
+static void ActionBootTime( void *arg )
+{
+ Timecounter *tc;
+ struct timespec ts;
+
+ tc = (Timecounter *) arg;
+ tc->state = STATE_GET_TIMECOUNT_BEFORE;
+ rtems_clock_get_boot_time( &ts );
+ tc->state = STATE_GET_TIMECOUNT_AFTER;
+}
+
+static void ActionBootTimeBintime( void *arg )
+{
+ Timecounter *tc;
+ struct bintime bt;
+
+ tc = (Timecounter *) arg;
+ tc->state = STATE_GET_TIMECOUNT_BEFORE;
+ rtems_clock_get_boot_time_bintime( &bt );
+ tc->state = STATE_GET_TIMECOUNT_AFTER;
+}
+
+static void ActionBootTimeTimeval( void *arg )
+{
+ Timecounter *tc;
+ struct timeval tv;
+
+ tc = (Timecounter *) arg;
+ tc->state = STATE_GET_TIMECOUNT_BEFORE;
+ rtems_clock_get_boot_time_timeval( &tv );
+ tc->state = STATE_GET_TIMECOUNT_AFTER;
+}
+
+static void CallTimcounterWindupTwice( const Timecounter *tc )
+{
+ ISR_lock_Context lock_context;
+
+ /*
+ * Make sure that tc_windup() was called at least twice to increment the
+ * generation number for * both timehands.
+ */
+
+ _Timecounter_Acquire( &lock_context );
+ _Timecounter_Set_clock( &tc->tod, &lock_context );
+
+ _Timecounter_Acquire( &lock_context );
+ _Timecounter_Set_clock( &tc->tod, &lock_context );
+}
+
+static T_interrupt_test_state Interrupt( void *arg )
+{
+ Timecounter *tc;
+ State state;
+
+ tc = (Timecounter *) arg;
+ state = tc->state;
+
+ if ( state == STATE_EARLY || state == STATE_GET_TIMECOUNT_BEFORE ) {
+ return T_INTERRUPT_TEST_EARLY;
+ }
+
+ if ( state == STATE_GET_TIMECOUNT_BUSY ) {
+ CallTimcounterWindupTwice( tc );
+
+ return T_INTERRUPT_TEST_DONE;
+ }
+
+ return T_INTERRUPT_TEST_LATE;
+}
+
+static T_interrupt_test_state InterruptCoarse( void *arg )
+{
+ Timecounter *tc;
+ State state;
+
+ tc = (Timecounter *) arg;
+ state = tc->state;
+
+ if ( state == STATE_EARLY ) {
+ return T_INTERRUPT_TEST_EARLY;
+ }
+
+ if ( state == STATE_GET_TIMECOUNT_BEFORE ) {
+ CallTimcounterWindupTwice( tc );
+
+ return T_INTERRUPT_TEST_DONE;
+ }
+
+ return T_INTERRUPT_TEST_LATE;
+}
+
+static bool InterruptTest(
+ const T_interrupt_test_config *config,
+ void *arg,
+ uint32_t iterations
+)
+{
+ uint32_t i;
+ bool ok;
+
+ ok = false;
+
+ for ( i = 0; i < iterations; ++i ) {
+ T_interrupt_test_state test_state;
+
+ test_state = T_interrupt_test( config, arg );
+ ok = ok || test_state == T_INTERRUPT_TEST_DONE;
+ }
+
+ return ok;
+}
+
+/**
+ * @brief Install a timecounter which can be used to perform interrut tests for
+ * the get time directives.
+ */
+static void ScoreTimecounterValGet_Action_0( void )
+{
+ T_interrupt_test_config config = {
+ .prepare = InterruptPrepare,
+ .interrupt = Interrupt,
+ .max_iteration_count = 10000
+ };
+ Timecounter *tc;
+
+ tc = &test_timecounter;
+ tc->base.tc_get_timecount = GetTimecount;
+ tc->base.tc_counter_mask = 0xffffffff;
+ tc->base.tc_frequency = rtems_counter_frequency();
+ tc->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER + 1;
+ tc->busy = T_get_one_clock_tick_busy() / 10;
+ rtems_clock_get_realtime_bintime( &tc->tod );
+ rtems_timecounter_install( &tc->base );
+
+ /*
+ * Try to interrupt the rtems_clock_get_realtime() directive to provoke a
+ * change in the timehand generation number.
+ */
+ config.action = ActionRealtime;
+ T_true( InterruptTest( &config, tc, 1 ) );
+
+ /*
+ * Try to interrupt the rtems_clock_get_realtime_bintime() directive to
+ * provoke a change in the timehand generation number.
+ */
+ config.action = ActionRealtimeBintime;
+ T_true( InterruptTest( &config, tc, 1 ) );
+
+ /*
+ * Try to interrupt the rtems_clock_get_realtime_timeval() directive to
+ * provoke a change in the timehand generation number.
+ */
+ config.action = ActionRealtimeTimeval;
+ T_true( InterruptTest( &config, tc, 1 ) );
+
+ /*
+ * Try to interrupt the rtems_clock_get_monotonic() directive to provoke a
+ * change in the timehand generation number.
+ */
+ config.action = ActionMonotonic;
+ T_true( InterruptTest( &config, tc, 1 ) );
+
+ /*
+ * Try to interrupt the rtems_clock_get_monotonic_bintime() directive to
+ * provoke a change in the timehand generation number.
+ */
+ config.action = ActionMonotonicBintime;
+ T_true( InterruptTest( &config, tc, 1 ) );
+
+ /*
+ * Try to interrupt the rtems_clock_get_monotonic_sbintime() directive to
+ * provoke a change in the timehand generation number.
+ */
+ config.action = ActionMonotonicSbintime;
+ T_true( InterruptTest( &config, tc, 1 ) );
+
+ /*
+ * Try to interrupt the rtems_clock_get_monotonic_timeval() directive to
+ * provoke a change in the timehand generation number.
+ */
+ config.action = ActionMonotonicTimeval;
+ T_true( InterruptTest( &config, tc, 1 ) );
+
+ /*
+ * Prepare for the coarse get time directives.
+ */
+ config.interrupt = InterruptCoarse;
+
+ /*
+ * Try to interrupt the rtems_clock_get_realtime_coarse() directive to
+ * provoke a change in the timehand generation number.
+ */
+ config.action = ActionCoarseRealtime;
+ T_true( InterruptTest( &config, tc, 10 ) );
+
+ /*
+ * Try to interrupt the rtems_clock_get_realtime_coarse_bintime() directive
+ * to provoke a change in the timehand generation number.
+ */
+ config.action = ActionCoarseRealtimeBintime;
+ T_true( InterruptTest( &config, tc, 10 ) );
+
+ /*
+ * Try to interrupt the rtems_clock_get_realtime_coarse_timeval() directive
+ * to provoke a change in the timehand generation number.
+ */
+ config.action = ActionCoarseRealtimeTimeval;
+ T_true( InterruptTest( &config, tc, 10 ) );
+
+ /*
+ * Try to interrupt the rtems_clock_get_monotonic_coarse() directive to
+ * provoke a change in the timehand generation number.
+ */
+ config.action = ActionCoarseMonotonic;
+ T_true( InterruptTest( &config, tc, 10 ) );
+
+ /*
+ * Try to interrupt the rtems_clock_get_monotonic_coarse_bintime() directive
+ * to provoke a change in the timehand generation number.
+ */
+ config.action = ActionCoarseMonotonicBintime;
+ T_true( InterruptTest( &config, tc, 10 ) );
+
+ /*
+ * Try to interrupt the rtems_clock_get_monotonic_coarse_timeval() directive
+ * to provoke a change in the timehand generation number.
+ */
+ config.action = ActionCoarseMonotonicTimeval;
+ T_true( InterruptTest( &config, tc, 10 ) );
+
+ /*
+ * Try to interrupt the rtems_clock_get_boot_time() directive to provoke a
+ * change in the timehand generation number.
+ */
+ config.action = ActionBootTime;
+ T_true( InterruptTest( &config, tc, 10 ) );
+
+ /*
+ * Try to interrupt the rtems_clock_get_boot_time_bintime() directive to
+ * provoke a change in the timehand generation number.
+ */
+ config.action = ActionBootTimeBintime;
+ T_true( InterruptTest( &config, tc, 10 ) );
+
+ /*
+ * Try to interrupt the rtems_clock_get_boot_time_timeval() directive to
+ * provoke a change in the timehand generation number.
+ */
+ config.action = ActionBootTimeTimeval;
+ T_true( InterruptTest( &config, tc, 10 ) );
+}
+
+/**
+ * @fn void T_case_body_ScoreTimecounterValGet( void )
+ */
+T_TEST_CASE( ScoreTimecounterValGet )
+{
+ ScoreTimecounterValGet_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-timecounter-install.c b/testsuites/validation/tc-timecounter-install.c
new file mode 100644
index 0000000000..14babc5b94
--- /dev/null
+++ b/testsuites/validation/tc-timecounter-install.c
@@ -0,0 +1,1133 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTimecounterValInstall
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/timecounter.h>
+#include <rtems/score/atomic.h>
+#include <rtems/score/threaddispatch.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTimecounterValInstall spec:/score/timecounter/val/install
+ *
+ * @ingroup TestsuitesValidationTimecounter0
+ *
+ * @brief Tests timecounter installation related functions and directives of
+ * the Clock Manager.
+ *
+ * This test case performs the following actions:
+ *
+ * - Call the simple timecounter tick service with a zero delta and offset.
+ * This will lead to an overflow to zero of the timehand generation. It
+ * shall not change the initial clock values.
+ *
+ * - Call the directives to get the initial value of CLOCK_REALTIME and the
+ * initial boot time.
+ *
+ * - Check the initial CLOCK_REALTIME in seconds and nanoseconds format.
+ *
+ * - Check that CLOCK_REALTIME is frozen in seconds and nanoseconds format.
+ *
+ * - Check the initial CLOCK_REALTIME in coarse resolution in seconds and
+ * nanoseconds format.
+ *
+ * - Check that CLOCK_REALTIME is frozen in coarse resolution in seconds and
+ * nanoseconds format.
+ *
+ * - Check the initial CLOCK_REALTIME in binary time format.
+ *
+ * - Check that CLOCK_REALTIME is frozen in binary time format.
+ *
+ * - Check the initial CLOCK_REALTIME in coarse resolution in binary time
+ * format.
+ *
+ * - Check that CLOCK_REALTIME is frozen in coarse resolution in binary time
+ * format.
+ *
+ * - Check the initial CLOCK_REALTIME in seconds and microseconds format.
+ *
+ * - Check that CLOCK_REALTIME is frozen in seconds and microseconds format.
+ *
+ * - Check the initial CLOCK_REALTIME in coarse resolution in seconds and
+ * microseconds format.
+ *
+ * - Check that CLOCK_REALTIME is frozen in coarse resolution in seconds and
+ * microseconds format.
+ *
+ * - Check the initial boot time in seconds and nanoseconds format.
+ *
+ * - Check the initial boot time in binary time format.
+ *
+ * - Check the initial boot time in seconds and microseconds format.
+ *
+ * - Call the directives to get the initial value of CLOCK_MONOTONIC and the
+ * initial boot time.
+ *
+ * - Check the initial CLOCK_MONOTONIC in seconds and nanoseconds format.
+ *
+ * - Check that CLOCK_MONOTONIC is frozen in seconds and nanoseconds format.
+ *
+ * - Check the initial CLOCK_MONOTONIC in coarse resolution in seconds and
+ * nanoseconds format.
+ *
+ * - Check that CLOCK_MONOTONIC is frozen in coarse resolution in seconds and
+ * nanoseconds format.
+ *
+ * - Check the initial CLOCK_MONOTONIC in binary time format.
+ *
+ * - Check that CLOCK_MONOTONIC is frozen in binary time format.
+ *
+ * - Check the initial CLOCK_MONOTONIC in coarse resolution in binary time
+ * format.
+ *
+ * - Check that CLOCK_MONOTONIC is frozen in coarse resolution in binary time
+ * format.
+ *
+ * - Check the initial CLOCK_MONOTONIC in signed binary time format.
+ *
+ * - Check that CLOCK_MONOTONIC is frozen in signed binary time format.
+ *
+ * - Check the initial CLOCK_MONOTONIC in seconds and microseconds format.
+ *
+ * - Check that CLOCK_MONOTONIC is frozen in seconds and microseconds format.
+ *
+ * - Check the initial CLOCK_MONOTONIC in coarse resolution in seconds and
+ * microseconds format.
+ *
+ * - Check that CLOCK_MONOTONIC is frozen in coarse resolution in seconds and
+ * microseconds format.
+ *
+ * - Install timecounter of different quality levels and frequencies.
+ *
+ * - Install a timecounter with a high quality level and normal frequency.
+ * Check that it was installed.
+ *
+ * - Install a timecounter with a high quality level and low frequency. Check
+ * that it was not installed.
+ *
+ * - Install a timecounter with a high quality level and high frequency.
+ * Check that it was installed.
+ *
+ * - Install a timecounter with a low quality level. Check that it was not
+ * installed.
+ *
+ * - Call the directives to get the time in the highest resolution available to
+ * the system.
+ *
+ * - Check that the timecounter was used by rtems_clock_get_realtime().
+ *
+ * - Check that the timecounter was used by
+ * rtems_clock_get_realtime_bintime().
+ *
+ * - Check that the timecounter was used by
+ * rtems_clock_get_realtime_timeval().
+ *
+ * - Check that the timecounter was used by rtems_clock_get_monotonic().
+ *
+ * - Check that the timecounter was used by
+ * rtems_clock_get_monotonic_bintime().
+ *
+ * - Check that the timecounter was used by
+ * rtems_clock_get_monotonic_sbintime().
+ *
+ * - Check that the timecounter was used by
+ * rtems_clock_get_monotonic_timeval().
+ *
+ * - Call the directives to get the time in a coarse resolution.
+ *
+ * - Check that the timecounter was not used by
+ * rtems_clock_get_realtime_coarse().
+ *
+ * - Check that the timecounter was not used by
+ * rtems_clock_get_realtime_coarse_bintime().
+ *
+ * - Check that the timecounter was not used by
+ * rtems_clock_get_realtime_coarse_timeval().
+ *
+ * - Check that the timecounter was not used by
+ * rtems_clock_get_monotonic_coarse().
+ *
+ * - Check that the timecounter was not used by
+ * rtems_clock_get_monotonic_coarse_bintime().
+ *
+ * - Check that the timecounter was not used by
+ * rtems_clock_get_monotonic_coarse_timeval().
+ *
+ * - Check that the timecounter was not used by rtems_clock_get_boot_time().
+ *
+ * - Check that the timecounter was not used by
+ * rtems_clock_get_boot_time_bintime().
+ *
+ * - Check that the timecounter was not used by
+ * rtems_clock_get_boot_time_timeval().
+ *
+ * - Call the directives to get the time in the highest resolution available to
+ * the system.
+ *
+ * - Prepare the timecounter to get a large time difference. Check that
+ * rtems_clock_get_realtime() returns the correct time.
+ *
+ * - Prepare the timecounter to get a large time difference. Check that
+ * rtems_clock_get_realtime_bintime() returns the correct time.
+ *
+ * - Prepare the timecounter to get a large time difference. Check that
+ * rtems_clock_get_realtime_timeval() returns the correct time.
+ *
+ * - Prepare the timecounter to get a large time difference. Check that
+ * rtems_clock_get_monotonic() returns the correct time.
+ *
+ * - Prepare the timecounter to get a large time difference. Check that
+ * rtems_clock_get_monotonic_bintime() returns the correct time.
+ *
+ * - Prepare the timecounter to get a large time difference. Check that
+ * rtems_clock_get_monotonic_sbintime() returns the correct time.
+ *
+ * - Prepare the timecounter to get a large time difference. Check that
+ * rtems_clock_get_monotonic_timeval() returns the correct time.
+ *
+ * - Update the oldest timehand after a large time interval.
+ *
+ * - Call the simple timecounter tick service with non-zero delta and offset
+ * parameter values so that exactly one second passed.
+ *
+ * - Check that exactly one second passed due to the simple clock tick
+ * service.
+ *
+ * - Install a very high quality timecounter with a low frequency to test the
+ * NTP support.
+ *
+ * - Let the seconds value of CLOCK_REALTIME not change. Check that the NTP
+ * update second handler is not called.
+ *
+ * - Let the seconds value of CLOCK_REALTIME change by one. Check that the
+ * NTP update second handler is called exactly once.
+ *
+ * - Let the seconds value of CLOCK_REALTIME change by 200. Check that the
+ * NTP update second handler is called exactly 200 times.
+ *
+ * - Let the seconds value of CLOCK_REALTIME change by 201. Check that the
+ * NTP update second handler is called exactly twice.
+ *
+ * - Let the seconds value of CLOCK_REALTIME change by one. Check that the
+ * NTP update second handler is incremented the CLOCK_REALTIME by one
+ * second.
+ *
+ * - Let the seconds value of CLOCK_REALTIME change by one. Check that the
+ * NTP update second handler is decremented the CLOCK_REALTIME by one
+ * second.
+ *
+ * - Let the seconds value of CLOCK_REALTIME change by one. Check that the
+ * NTP update second handler increased the timecounter frequency.
+ *
+ * - Let the seconds value of CLOCK_REALTIME change by one. Check that the
+ * NTP update second handler decreased the timecounter frequency.
+ *
+ * @{
+ */
+
+typedef struct {
+ struct timecounter base;
+ Atomic_Ulong counter;
+} Timecounter;
+
+static Timecounter high_quality_low_frequency;
+
+static Timecounter high_quality_normal_frequency;
+
+static Timecounter high_quality_high_frequency;
+
+static Timecounter low_quality;
+
+static Timecounter very_high_quality;
+
+static uint32_t ntp_counter;
+
+static uint32_t GetTimecount( struct timecounter *base )
+{
+ Timecounter *tc;
+
+ tc = (Timecounter *) base;
+
+ return (uint32_t) _Atomic_Fetch_add_ulong(
+ &tc->counter,
+ 1,
+ ATOMIC_ORDER_RELAXED
+ );
+}
+
+static uint32_t GetCounter( const Timecounter *tc )
+{
+ return (uint32_t) _Atomic_Load_ulong(
+ &tc->counter,
+ ATOMIC_ORDER_RELAXED
+ );
+}
+
+static void SetCounter( Timecounter *tc, uint32_t counter )
+{
+ _Atomic_Store_ulong(
+ &tc->counter,
+ counter,
+ ATOMIC_ORDER_RELAXED
+ );
+}
+
+static void NtpUpdateCounter( int64_t *adjustment, time_t *newsec )
+{
+ (void) newsec;
+ T_eq_i64( *adjustment, 0 );
+ ++ntp_counter;
+}
+
+static void NtpUpdateSecondIncrement( int64_t *adjustment, time_t *newsec )
+{
+ (void) adjustment;
+ ++(*newsec);
+}
+
+static void NtpUpdateSecondDecrement( int64_t *adjustment, time_t *newsec )
+{
+ (void) adjustment;
+ --(*newsec);
+}
+
+static void NtpUpdateAdjustmentFaster( int64_t *adjustment, time_t *newsec )
+{
+ *adjustment = ( (int64_t) 5000 ) << 32;
+ (void) newsec;
+}
+
+static void NtpUpdateAdjustmentSlower( int64_t *adjustment, time_t *newsec )
+{
+ *adjustment = -( (int64_t) 5000 ) << 32;
+ (void) newsec;
+}
+
+static void CallTimecounterTick( void )
+{
+ Per_CPU_Control *cpu_self;
+
+ cpu_self = _Thread_Dispatch_disable();
+ rtems_timecounter_tick();
+ _Thread_Dispatch_enable( cpu_self );
+}
+
+/**
+ * @brief Call the simple timecounter tick service with a zero delta and
+ * offset. This will lead to an overflow to zero of the timehand generation.
+ * It shall not change the initial clock values.
+ */
+static void ScoreTimecounterValInstall_Action_0( void )
+{
+ ISR_lock_Context lock_context;
+
+ _Timecounter_Acquire( &lock_context );
+ _Timecounter_Tick_simple( 0, 0, &lock_context );
+}
+
+/**
+ * @brief Call the directives to get the initial value of CLOCK_REALTIME and
+ * the initial boot time.
+ */
+static void ScoreTimecounterValInstall_Action_1( void )
+{
+ struct bintime bt;
+ struct timespec ts;
+ struct timeval tv;
+
+ /*
+ * Check the initial CLOCK_REALTIME in seconds and nanoseconds format.
+ */
+ rtems_clock_get_realtime( &ts );
+ T_eq_i64( ts.tv_sec, 567993600 );
+ T_eq_u64( ts.tv_nsec, 0 );
+
+ /*
+ * Check that CLOCK_REALTIME is frozen in seconds and nanoseconds format.
+ */
+ rtems_clock_get_realtime( &ts );
+ T_eq_i64( ts.tv_sec, 567993600 );
+ T_eq_u64( ts.tv_nsec, 0 );
+
+ /*
+ * Check the initial CLOCK_REALTIME in coarse resolution in seconds and
+ * nanoseconds format.
+ */
+ rtems_clock_get_realtime_coarse( &ts );
+ T_eq_i64( ts.tv_sec, 567993600 );
+ T_eq_u64( ts.tv_nsec, 0 );
+
+ /*
+ * Check that CLOCK_REALTIME is frozen in coarse resolution in seconds and
+ * nanoseconds format.
+ */
+ rtems_clock_get_realtime_coarse( &ts );
+ T_eq_i64( ts.tv_sec, 567993600 );
+ T_eq_u64( ts.tv_nsec, 0 );
+
+ /*
+ * Check the initial CLOCK_REALTIME in binary time format.
+ */
+ rtems_clock_get_realtime_bintime( &bt );
+ T_eq_i64( bt.sec, 567993600 );
+ T_eq_u64( bt.frac, 0 );
+
+ /*
+ * Check that CLOCK_REALTIME is frozen in binary time format.
+ */
+ rtems_clock_get_realtime_bintime( &bt );
+ T_eq_i64( bt.sec, 567993600 );
+ T_eq_u64( bt.frac, 0 );
+
+ /*
+ * Check the initial CLOCK_REALTIME in coarse resolution in binary time
+ * format.
+ */
+ rtems_clock_get_realtime_coarse_bintime( &bt );
+ T_eq_i64( bt.sec, 567993600 );
+ T_eq_u64( bt.frac, 0 );
+
+ /*
+ * Check that CLOCK_REALTIME is frozen in coarse resolution in binary time
+ * format.
+ */
+ rtems_clock_get_realtime_coarse_bintime( &bt );
+ T_eq_i64( bt.sec, 567993600 );
+ T_eq_u64( bt.frac, 0 );
+
+ /*
+ * Check the initial CLOCK_REALTIME in seconds and microseconds format.
+ */
+ rtems_clock_get_realtime_timeval( &tv );
+ T_eq_i64( tv.tv_sec, 567993600 );
+ T_eq_long( tv.tv_usec, 0 );
+
+ /*
+ * Check that CLOCK_REALTIME is frozen in seconds and microseconds format.
+ */
+ rtems_clock_get_realtime_timeval( &tv );
+ T_eq_i64( tv.tv_sec, 567993600 );
+ T_eq_long( tv.tv_usec, 0 );
+
+ /*
+ * Check the initial CLOCK_REALTIME in coarse resolution in seconds and
+ * microseconds format.
+ */
+ rtems_clock_get_realtime_coarse_timeval( &tv );
+ T_eq_i64( tv.tv_sec, 567993600 );
+ T_eq_long( tv.tv_usec, 0 );
+
+ /*
+ * Check that CLOCK_REALTIME is frozen in coarse resolution in seconds and
+ * microseconds format.
+ */
+ rtems_clock_get_realtime_coarse_timeval( &tv );
+ T_eq_i64( tv.tv_sec, 567993600 );
+ T_eq_long( tv.tv_usec, 0 );
+
+ /*
+ * Check the initial boot time in seconds and nanoseconds format.
+ */
+ rtems_clock_get_boot_time( &ts );
+ T_eq_i64( ts.tv_sec, 567993599 );
+ T_eq_u64( ts.tv_nsec, 0 );
+
+ /*
+ * Check the initial boot time in binary time format.
+ */
+ rtems_clock_get_boot_time_bintime( &bt );
+ T_eq_i64( bt.sec, 567993599 );
+ T_eq_u64( bt.frac, 0 );
+
+ /*
+ * Check the initial boot time in seconds and microseconds format.
+ */
+ rtems_clock_get_boot_time_timeval( &tv );
+ T_eq_i64( tv.tv_sec, 567993599 );
+ T_eq_long( tv.tv_usec, 0 );
+}
+
+/**
+ * @brief Call the directives to get the initial value of CLOCK_MONOTONIC and
+ * the initial boot time.
+ */
+static void ScoreTimecounterValInstall_Action_2( void )
+{
+ struct bintime bt;
+ sbintime_t sb;
+ struct timespec ts;
+ struct timeval tv;
+
+ /*
+ * Check the initial CLOCK_MONOTONIC in seconds and nanoseconds format.
+ */
+ rtems_clock_get_monotonic( &ts );
+ T_eq_i64( ts.tv_sec, 1 );
+ T_eq_u64( ts.tv_nsec, 0 );
+
+ /*
+ * Check that CLOCK_MONOTONIC is frozen in seconds and nanoseconds format.
+ */
+ rtems_clock_get_monotonic( &ts );
+ T_eq_i64( ts.tv_sec, 1 );
+ T_eq_u64( ts.tv_nsec, 0 );
+
+ /*
+ * Check the initial CLOCK_MONOTONIC in coarse resolution in seconds and
+ * nanoseconds format.
+ */
+ rtems_clock_get_monotonic_coarse( &ts );
+ T_eq_i64( ts.tv_sec, 1 );
+ T_eq_u64( ts.tv_nsec, 0 );
+
+ /*
+ * Check that CLOCK_MONOTONIC is frozen in coarse resolution in seconds and
+ * nanoseconds format.
+ */
+ rtems_clock_get_monotonic_coarse( &ts );
+ T_eq_i64( ts.tv_sec, 1 );
+ T_eq_u64( ts.tv_nsec, 0 );
+
+ /*
+ * Check the initial CLOCK_MONOTONIC in binary time format.
+ */
+ rtems_clock_get_monotonic_bintime( &bt );
+ T_eq_i64( bt.sec, 1 );
+ T_eq_u64( bt.frac, 0 );
+
+ /*
+ * Check that CLOCK_MONOTONIC is frozen in binary time format.
+ */
+ rtems_clock_get_monotonic_bintime( &bt );
+ T_eq_i64( bt.sec, 1 );
+ T_eq_u64( bt.frac, 0 );
+
+ /*
+ * Check the initial CLOCK_MONOTONIC in coarse resolution in binary time
+ * format.
+ */
+ rtems_clock_get_monotonic_coarse_bintime( &bt );
+ T_eq_i64( bt.sec, 1 );
+ T_eq_u64( bt.frac, 0 );
+
+ /*
+ * Check that CLOCK_MONOTONIC is frozen in coarse resolution in binary time
+ * format.
+ */
+ rtems_clock_get_monotonic_coarse_bintime( &bt );
+ T_eq_i64( bt.sec, 1 );
+ T_eq_u64( bt.frac, 0 );
+
+ /*
+ * Check the initial CLOCK_MONOTONIC in signed binary time format.
+ */
+ sb = rtems_clock_get_monotonic_sbintime();
+ T_eq_i64( sb, SBT_1S );
+
+ /*
+ * Check that CLOCK_MONOTONIC is frozen in signed binary time format.
+ */
+ sb = rtems_clock_get_monotonic_sbintime();
+ T_eq_i64( sb, SBT_1S );
+
+ /*
+ * Check the initial CLOCK_MONOTONIC in seconds and microseconds format.
+ */
+ rtems_clock_get_monotonic_timeval( &tv );
+ T_eq_i64( tv.tv_sec, 1 );
+ T_eq_long( tv.tv_usec, 0 );
+
+ /*
+ * Check that CLOCK_MONOTONIC is frozen in seconds and microseconds format.
+ */
+ rtems_clock_get_monotonic_timeval( &tv );
+ T_eq_i64( tv.tv_sec, 1 );
+ T_eq_long( tv.tv_usec, 0 );
+
+ /*
+ * Check the initial CLOCK_MONOTONIC in coarse resolution in seconds and
+ * microseconds format.
+ */
+ rtems_clock_get_monotonic_coarse_timeval( &tv );
+ T_eq_i64( tv.tv_sec, 1 );
+ T_eq_long( tv.tv_usec, 0 );
+
+ /*
+ * Check that CLOCK_MONOTONIC is frozen in coarse resolution in seconds and
+ * microseconds format.
+ */
+ rtems_clock_get_monotonic_coarse_timeval( &tv );
+ T_eq_i64( tv.tv_sec, 1 );
+ T_eq_long( tv.tv_usec, 0 );
+}
+
+/**
+ * @brief Install timecounter of different quality levels and frequencies.
+ */
+static void ScoreTimecounterValInstall_Action_3( void )
+{
+ Timecounter *hqlf;
+ Timecounter *hqnf;
+ Timecounter *hqhf;
+ Timecounter *lq;
+ sbintime_t sb;
+
+ hqlf = &high_quality_low_frequency;
+ hqnf = &high_quality_normal_frequency;
+ hqhf = &high_quality_high_frequency;
+ lq = &low_quality;
+
+ /*
+ * Install a timecounter with a high quality level and normal frequency.
+ * Check that it was installed.
+ */
+ hqnf->base.tc_get_timecount = GetTimecount;
+ hqnf->base.tc_counter_mask = 0xffffffff;
+ hqnf->base.tc_frequency = 0x20000000;
+ hqnf->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER + 1;
+ rtems_timecounter_install( &hqnf->base );
+
+ T_eq_u32( GetCounter( hqnf ), 1 );
+
+ sb = rtems_clock_get_monotonic_sbintime();
+ T_eq_u32( GetCounter( hqnf ), 2 );
+ T_eq_i64( sb, SBT_1S + 8 );
+
+ /*
+ * Install a timecounter with a high quality level and low frequency. Check
+ * that it was not installed.
+ */
+ hqlf->base.tc_get_timecount = GetTimecount;
+ hqlf->base.tc_counter_mask = 0xffffffff;
+ hqlf->base.tc_frequency = 0x10000000;
+ hqlf->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER + 1;
+ rtems_timecounter_install( &hqlf->base );
+
+ T_eq_u32( GetCounter( hqlf ), 0 );
+ T_eq_u32( GetCounter( hqnf ), 2 );
+
+ sb = rtems_clock_get_monotonic_sbintime();
+ T_eq_u32( GetCounter( hqlf ), 0 );
+ T_eq_u32( GetCounter( hqnf ), 3 );
+ T_eq_i64( sb, SBT_1S + 16 );
+
+ /*
+ * Install a timecounter with a high quality level and high frequency. Check
+ * that it was installed.
+ */
+ hqhf->base.tc_get_timecount = GetTimecount;
+ hqhf->base.tc_counter_mask = 0xffffffff;
+ hqhf->base.tc_frequency = 0x40000000;
+ hqhf->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER + 1;
+ rtems_timecounter_install( &hqhf->base );
+
+ T_eq_u32( GetCounter( hqlf ), 0 );
+ T_eq_u32( GetCounter( hqnf ), 4 );
+ T_eq_u32( GetCounter( hqhf ), 1 );
+
+ sb = rtems_clock_get_monotonic_sbintime();
+ T_eq_u32( GetCounter( hqlf ), 0 );
+ T_eq_u32( GetCounter( hqnf ), 4 );
+ T_eq_u32( GetCounter( hqhf ), 2 );
+ T_eq_i64( sb, SBT_1S + 28 );
+
+ /*
+ * Install a timecounter with a low quality level. Check that it was not
+ * installed.
+ */
+ lq->base.tc_get_timecount = GetTimecount;
+ lq->base.tc_counter_mask = 0xffffffff;
+ lq->base.tc_frequency = 0x80000000;
+ lq->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER;
+ rtems_timecounter_install( &lq->base );
+
+ T_eq_u32( GetCounter( hqlf ), 0 );
+ T_eq_u32( GetCounter( hqnf ), 4 );
+ T_eq_u32( GetCounter( hqhf ), 2 );
+ T_eq_u32( GetCounter( lq ), 0 );
+
+ sb = rtems_clock_get_monotonic_sbintime();
+ T_eq_u32( GetCounter( hqlf ), 0 );
+ T_eq_u32( GetCounter( hqnf ), 4 );
+ T_eq_u32( GetCounter( hqhf ), 3 );
+ T_eq_u32( GetCounter( lq ), 0 );
+ T_eq_i64( sb, SBT_1S + 32 );
+}
+
+/**
+ * @brief Call the directives to get the time in the highest resolution
+ * available to the system.
+ */
+static void ScoreTimecounterValInstall_Action_4( void )
+{
+ Timecounter *tc;
+ uint32_t counter;
+ struct bintime bt;
+ struct timespec ts;
+ struct timeval tv;
+
+ tc = &high_quality_high_frequency;
+ counter = GetCounter( tc );
+
+ /*
+ * Check that the timecounter was used by rtems_clock_get_realtime().
+ */
+ rtems_clock_get_realtime( &ts );
+ T_eq_u32( GetCounter( tc ), counter + 1 );
+
+ /*
+ * Check that the timecounter was used by rtems_clock_get_realtime_bintime().
+ */
+ rtems_clock_get_realtime_bintime( &bt );
+ T_eq_u32( GetCounter( tc ), counter + 2 );
+
+ /*
+ * Check that the timecounter was used by rtems_clock_get_realtime_timeval().
+ */
+ rtems_clock_get_realtime_timeval( &tv );
+ T_eq_u32( GetCounter( tc ), counter + 3 );
+
+ /*
+ * Check that the timecounter was used by rtems_clock_get_monotonic().
+ */
+ rtems_clock_get_monotonic( &ts );
+ T_eq_u32( GetCounter( tc ), counter + 4 );
+
+ /*
+ * Check that the timecounter was used by
+ * rtems_clock_get_monotonic_bintime().
+ */
+ rtems_clock_get_monotonic_bintime( &bt );
+ T_eq_u32( GetCounter( tc ), counter + 5 );
+
+ /*
+ * Check that the timecounter was used by
+ * rtems_clock_get_monotonic_sbintime().
+ */
+ (void) rtems_clock_get_monotonic_sbintime();
+ T_eq_u32( GetCounter( tc ), counter + 6 );
+
+ /*
+ * Check that the timecounter was used by
+ * rtems_clock_get_monotonic_timeval().
+ */
+ rtems_clock_get_monotonic_timeval( &tv );
+ T_eq_u32( GetCounter( tc ), counter + 7 );
+}
+
+/**
+ * @brief Call the directives to get the time in a coarse resolution.
+ */
+static void ScoreTimecounterValInstall_Action_5( void )
+{
+ Timecounter *tc;
+ uint32_t counter;
+ struct bintime bt;
+ struct timespec ts;
+ struct timeval tv;
+
+ tc = &high_quality_high_frequency;
+ counter = GetCounter( tc );
+
+ /*
+ * Check that the timecounter was not used by
+ * rtems_clock_get_realtime_coarse().
+ */
+ rtems_clock_get_realtime_coarse( &ts );
+ T_eq_u32( GetCounter( tc ), counter );
+
+ /*
+ * Check that the timecounter was not used by
+ * rtems_clock_get_realtime_coarse_bintime().
+ */
+ rtems_clock_get_realtime_coarse_bintime( &bt );
+ T_eq_u32( GetCounter( tc ), counter );
+
+ /*
+ * Check that the timecounter was not used by
+ * rtems_clock_get_realtime_coarse_timeval().
+ */
+ rtems_clock_get_realtime_coarse_timeval( &tv );
+ T_eq_u32( GetCounter( tc ), counter );
+
+ /*
+ * Check that the timecounter was not used by
+ * rtems_clock_get_monotonic_coarse().
+ */
+ rtems_clock_get_monotonic_coarse( &ts );
+ T_eq_u32( GetCounter( tc ), counter );
+
+ /*
+ * Check that the timecounter was not used by
+ * rtems_clock_get_monotonic_coarse_bintime().
+ */
+ rtems_clock_get_monotonic_coarse_bintime( &bt );
+ T_eq_u32( GetCounter( tc ), counter );
+
+ /*
+ * Check that the timecounter was not used by
+ * rtems_clock_get_monotonic_coarse_timeval().
+ */
+ rtems_clock_get_monotonic_coarse_timeval( &tv );
+ T_eq_u32( GetCounter( tc ), counter );
+
+ /*
+ * Check that the timecounter was not used by rtems_clock_get_boot_time().
+ */
+ rtems_clock_get_boot_time( &ts );
+ T_eq_u32( GetCounter( tc ), counter );
+
+ /*
+ * Check that the timecounter was not used by
+ * rtems_clock_get_boot_time_bintime().
+ */
+ rtems_clock_get_boot_time_bintime( &bt );
+ T_eq_u32( GetCounter( tc ), counter );
+
+ /*
+ * Check that the timecounter was not used by
+ * rtems_clock_get_boot_time_timeval().
+ */
+ rtems_clock_get_boot_time_timeval( &tv );
+ T_eq_u32( GetCounter( tc ), counter );
+}
+
+/**
+ * @brief Call the directives to get the time in the highest resolution
+ * available to the system.
+ */
+static void ScoreTimecounterValInstall_Action_6( void )
+{
+ Timecounter *tc;
+ uint32_t counter;
+ struct bintime bt;
+ sbintime_t sb;
+ struct timespec ts;
+ struct timeval tv;
+
+ tc = &high_quality_high_frequency;
+ counter = 3 * tc->base.tc_frequency + 123456789;
+
+ /*
+ * Prepare the timecounter to get a large time difference. Check that
+ * rtems_clock_get_realtime() returns the correct time.
+ */
+ SetCounter( tc, counter );
+ rtems_clock_get_realtime( &ts );
+ T_eq_i64( ts.tv_sec, 567993603 );
+ T_eq_u64( ts.tv_nsec, 114978100 );
+
+ /*
+ * Prepare the timecounter to get a large time difference. Check that
+ * rtems_clock_get_realtime_bintime() returns the correct time.
+ */
+ SetCounter( tc, counter );
+ rtems_clock_get_realtime_bintime( &bt );
+ T_eq_i64( bt.sec, 567993603 );
+ T_eq_u64( bt.frac, 2120971587975905280 );
+
+ /*
+ * Prepare the timecounter to get a large time difference. Check that
+ * rtems_clock_get_realtime_timeval() returns the correct time.
+ */
+ SetCounter( tc, counter );
+ rtems_clock_get_realtime_timeval( &tv );
+ T_eq_i64( tv.tv_sec, 567993603 );
+ T_eq_long( tv.tv_usec, 114978 );
+
+ /*
+ * Prepare the timecounter to get a large time difference. Check that
+ * rtems_clock_get_monotonic() returns the correct time.
+ */
+ SetCounter( tc, counter );
+ rtems_clock_get_monotonic( &ts );
+ T_eq_i64( ts.tv_sec, 4 );
+ T_eq_u64( ts.tv_nsec, 114978100 );
+
+ /*
+ * Prepare the timecounter to get a large time difference. Check that
+ * rtems_clock_get_monotonic_bintime() returns the correct time.
+ */
+ SetCounter( tc, counter );
+ rtems_clock_get_monotonic_bintime( &bt );
+ T_eq_i64( bt.sec, 4 );
+ T_eq_u64( bt.frac, 2120971587975905280 );
+
+ /*
+ * Prepare the timecounter to get a large time difference. Check that
+ * rtems_clock_get_monotonic_sbintime() returns the correct time.
+ */
+ SetCounter( tc, counter );
+ sb = rtems_clock_get_monotonic_sbintime();
+ T_eq_i64( sb, 17673696364 );
+
+ /*
+ * Prepare the timecounter to get a large time difference. Check that
+ * rtems_clock_get_monotonic_timeval() returns the correct time.
+ */
+ SetCounter( tc, counter );
+ rtems_clock_get_monotonic_timeval( &tv );
+ T_eq_i64( tv.tv_sec, 4 );
+ T_eq_long( tv.tv_usec, 114978 );
+}
+
+/**
+ * @brief Update the oldest timehand after a large time interval.
+ */
+static void ScoreTimecounterValInstall_Action_7( void )
+{
+ Timecounter *tc;
+ struct bintime bt;
+
+ tc = &high_quality_high_frequency;
+
+ SetCounter( tc, 0 );
+ rtems_clock_get_realtime_bintime( &bt );
+ T_eq_i64( bt.sec, 567993600 );
+ T_eq_u64( bt.frac, 103079215104 );
+
+ SetCounter( tc, 2 * tc->base.tc_frequency );
+ CallTimecounterTick();
+
+ SetCounter( tc, 2 * tc->base.tc_frequency );
+ rtems_clock_get_realtime_bintime( &bt );
+ T_eq_i64( bt.sec, 567993602 );
+ T_eq_u64( bt.frac, 103079215104 );
+}
+
+/**
+ * @brief Call the simple timecounter tick service with non-zero delta and
+ * offset parameter values so that exactly one second passed.
+ */
+static void ScoreTimecounterValInstall_Action_8( void )
+{
+ ISR_lock_Context lock_context;
+ Timecounter *tc;
+ struct bintime bt;
+
+ tc = &high_quality_high_frequency;
+
+ _Timecounter_Acquire( &lock_context );
+ _Timecounter_Tick_simple(
+ tc->base.tc_frequency / 2,
+ GetCounter( tc ) - tc->base.tc_frequency / 2,
+ &lock_context
+ );
+
+ /*
+ * Check that exactly one second passed due to the simple clock tick service.
+ */
+ rtems_clock_get_realtime_bintime( &bt );
+ T_eq_i64( bt.sec, 567993603 );
+ T_eq_u64( bt.frac, 103079215104 );
+}
+
+/**
+ * @brief Install a very high quality timecounter with a low frequency to test
+ * the NTP support.
+ */
+static void ScoreTimecounterValInstall_Action_9( void )
+{
+ Timecounter *tc;
+ struct bintime bt;
+
+ tc = &very_high_quality;
+ tc->base.tc_get_timecount = GetTimecount;
+ tc->base.tc_counter_mask = 0xffffffff;
+ tc->base.tc_frequency = 0x01000000;
+ tc->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER + 2;
+ rtems_timecounter_install( &tc->base );
+
+ T_eq_u32( GetCounter( tc ), 1 );
+
+ rtems_clock_get_realtime_bintime( &bt );
+ T_eq_i64( bt.sec, 567993603 );
+ T_eq_u64( bt.frac, 1219770712064 );
+
+ /*
+ * Let the seconds value of CLOCK_REALTIME not change. Check that the NTP
+ * update second handler is not called.
+ */
+ _Timecounter_Set_NTP_update_second( NtpUpdateCounter );
+ SetCounter( tc, tc->base.tc_frequency / 2 );
+ CallTimecounterTick();
+ _Timecounter_Set_NTP_update_second( NULL );
+
+ T_eq_u32( ntp_counter, 0 );
+
+ rtems_clock_get_realtime_bintime( &bt );
+ T_eq_i64( bt.sec, 567993603 );
+ T_eq_u64( bt.frac, UINT64_C( 9223373256625487872 ) );
+
+ /*
+ * Let the seconds value of CLOCK_REALTIME change by one. Check that the NTP
+ * update second handler is called exactly once.
+ */
+ _Timecounter_Set_NTP_update_second( NtpUpdateCounter );
+ SetCounter( tc, tc->base.tc_frequency );
+ CallTimecounterTick();
+ _Timecounter_Set_NTP_update_second( NULL );
+
+ T_eq_u32( ntp_counter, 1 );
+
+ rtems_clock_get_realtime_bintime( &bt );
+ T_eq_i64( bt.sec, 567993604 );
+ T_eq_u64( bt.frac, 1219770712064 );
+
+ /*
+ * Let the seconds value of CLOCK_REALTIME change by 200. Check that the NTP
+ * update second handler is called exactly 200 times.
+ */
+ _Timecounter_Set_NTP_update_second( NtpUpdateCounter );
+ SetCounter( tc, 201 * tc->base.tc_frequency );
+ CallTimecounterTick();
+ _Timecounter_Set_NTP_update_second( NULL );
+
+ T_eq_u32( ntp_counter, 201 );
+
+ rtems_clock_get_realtime_bintime( &bt );
+ T_eq_i64( bt.sec, 567993804 );
+ T_eq_u64( bt.frac, 1219770712064 );
+
+ /*
+ * Let the seconds value of CLOCK_REALTIME change by 201. Check that the NTP
+ * update second handler is called exactly twice.
+ */
+ _Timecounter_Set_NTP_update_second( NtpUpdateCounter );
+ SetCounter( tc, 402 * tc->base.tc_frequency );
+ CallTimecounterTick();
+ _Timecounter_Set_NTP_update_second( NULL );
+
+ T_eq_u32( ntp_counter, 203 );
+
+ rtems_clock_get_realtime_bintime( &bt );
+ T_eq_i64( bt.sec, 567994005 );
+ T_eq_u64( bt.frac, 1219770712064 );
+
+ /*
+ * Let the seconds value of CLOCK_REALTIME change by one. Check that the NTP
+ * update second handler is incremented the CLOCK_REALTIME by one second.
+ */
+ _Timecounter_Set_NTP_update_second( NtpUpdateSecondIncrement );
+ SetCounter( tc, 403 * tc->base.tc_frequency );
+ CallTimecounterTick();
+ _Timecounter_Set_NTP_update_second( NULL );
+
+ rtems_clock_get_realtime_bintime( &bt );
+ T_eq_i64( bt.sec, 567994007 );
+ T_eq_u64( bt.frac, 1219770712064 );
+
+ /*
+ * Let the seconds value of CLOCK_REALTIME change by one. Check that the NTP
+ * update second handler is decremented the CLOCK_REALTIME by one second.
+ */
+ _Timecounter_Set_NTP_update_second( NtpUpdateSecondDecrement );
+ SetCounter( tc, 404 * tc->base.tc_frequency );
+ CallTimecounterTick();
+ _Timecounter_Set_NTP_update_second( NULL );
+
+ rtems_clock_get_realtime_bintime( &bt );
+ T_eq_i64( bt.sec, 567994007 );
+ T_eq_u64( bt.frac, 1219770712064 );
+
+ /*
+ * Let the seconds value of CLOCK_REALTIME change by one. Check that the NTP
+ * update second handler increased the timecounter frequency.
+ */
+ _Timecounter_Set_NTP_update_second( NtpUpdateAdjustmentFaster );
+ SetCounter( tc, 405 * tc->base.tc_frequency );
+ CallTimecounterTick();
+ _Timecounter_Set_NTP_update_second( NULL );
+
+ SetCounter( tc, 406 * tc->base.tc_frequency );
+ rtems_clock_get_realtime_bintime( &bt );
+ T_eq_i64( bt.sec, 567994009 );
+ T_eq_u64( bt.frac, 92353004044288 );
+
+ /*
+ * Let the seconds value of CLOCK_REALTIME change by one. Check that the NTP
+ * update second handler decreased the timecounter frequency.
+ */
+ _Timecounter_Set_NTP_update_second( NtpUpdateAdjustmentSlower );
+ SetCounter( tc, 407 * tc->base.tc_frequency );
+ CallTimecounterTick();
+ _Timecounter_Set_NTP_update_second( NULL );
+
+ SetCounter( tc, 408 * tc->base.tc_frequency );
+ rtems_clock_get_realtime_bintime( &bt );
+ T_eq_i64( bt.sec, 567994011 );
+ T_eq_u64( bt.frac, 92353004044288 );
+}
+
+/**
+ * @fn void T_case_body_ScoreTimecounterValInstall( void )
+ */
+T_TEST_CASE( ScoreTimecounterValInstall )
+{
+ ScoreTimecounterValInstall_Action_0();
+ ScoreTimecounterValInstall_Action_1();
+ ScoreTimecounterValInstall_Action_2();
+ ScoreTimecounterValInstall_Action_3();
+ ScoreTimecounterValInstall_Action_4();
+ ScoreTimecounterValInstall_Action_5();
+ ScoreTimecounterValInstall_Action_6();
+ ScoreTimecounterValInstall_Action_7();
+ ScoreTimecounterValInstall_Action_8();
+ ScoreTimecounterValInstall_Action_9();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-timer-cancel.c b/testsuites/validation/tc-timer-cancel.c
new file mode 100644
index 0000000000..3030045e9c
--- /dev/null
+++ b/testsuites/validation/tc-timer-cancel.c
@@ -0,0 +1,813 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTimerReqCancel
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTimerReqCancel spec:/rtems/timer/req/cancel
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTimerReqCancel_Pre_Id_Valid,
+ RtemsTimerReqCancel_Pre_Id_Invalid,
+ RtemsTimerReqCancel_Pre_Id_NA
+} RtemsTimerReqCancel_Pre_Id;
+
+typedef enum {
+ RtemsTimerReqCancel_Pre_Context_None,
+ RtemsTimerReqCancel_Pre_Context_Interrupt,
+ RtemsTimerReqCancel_Pre_Context_Server,
+ RtemsTimerReqCancel_Pre_Context_NA
+} RtemsTimerReqCancel_Pre_Context;
+
+typedef enum {
+ RtemsTimerReqCancel_Pre_Clock_None,
+ RtemsTimerReqCancel_Pre_Clock_Ticks,
+ RtemsTimerReqCancel_Pre_Clock_Realtime,
+ RtemsTimerReqCancel_Pre_Clock_NA
+} RtemsTimerReqCancel_Pre_Clock;
+
+typedef enum {
+ RtemsTimerReqCancel_Pre_State_Inactive,
+ RtemsTimerReqCancel_Pre_State_Scheduled,
+ RtemsTimerReqCancel_Pre_State_Pending,
+ RtemsTimerReqCancel_Pre_State_NA
+} RtemsTimerReqCancel_Pre_State;
+
+typedef enum {
+ RtemsTimerReqCancel_Post_Status_Ok,
+ RtemsTimerReqCancel_Post_Status_InvId,
+ RtemsTimerReqCancel_Post_Status_NA
+} RtemsTimerReqCancel_Post_Status;
+
+typedef enum {
+ RtemsTimerReqCancel_Post_Context_None,
+ RtemsTimerReqCancel_Post_Context_Interrupt,
+ RtemsTimerReqCancel_Post_Context_Server,
+ RtemsTimerReqCancel_Post_Context_Nop,
+ RtemsTimerReqCancel_Post_Context_NA
+} RtemsTimerReqCancel_Post_Context;
+
+typedef enum {
+ RtemsTimerReqCancel_Post_Clock_None,
+ RtemsTimerReqCancel_Post_Clock_Ticks,
+ RtemsTimerReqCancel_Post_Clock_Realtime,
+ RtemsTimerReqCancel_Post_Clock_Nop,
+ RtemsTimerReqCancel_Post_Clock_NA
+} RtemsTimerReqCancel_Post_Clock;
+
+typedef enum {
+ RtemsTimerReqCancel_Post_State_Inactive,
+ RtemsTimerReqCancel_Post_State_Nop,
+ RtemsTimerReqCancel_Post_State_NA
+} RtemsTimerReqCancel_Post_State;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_Context_NA : 1;
+ uint16_t Pre_Clock_NA : 1;
+ uint16_t Pre_State_NA : 1;
+ uint16_t Post_Status : 2;
+ uint16_t Post_Context : 3;
+ uint16_t Post_Clock : 3;
+ uint16_t Post_State : 2;
+} RtemsTimerReqCancel_Entry;
+
+typedef enum {
+ PRE_NONE = 0,
+ PRE_INTERRUPT = 1,
+ PRE_SERVER = 2
+} PreConditionContext;
+
+/**
+ * @brief Test context for spec:/rtems/timer/req/cancel test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a valid id of a timer.
+ */
+ rtems_id timer_id;
+
+ /**
+ * @brief This member specifies the ``id`` parameter for the action.
+ */
+ rtems_id id_param;
+
+ /**
+ * @brief This member contains the return status of the action.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member contains the counter for invocations of the Timer
+ * Service Routine.
+ */
+ int invocations;
+
+ /**
+ * @brief This member specifies which pre-condition context (none, interrupt
+ * context, server context) must be created before the cancel action gets
+ * executed.
+ */
+ PreConditionContext pre_cond_contex;
+
+ /**
+ * @brief This member stores RTEMS internal clock and context settings of the
+ * timer before the execution of the test action.
+ */
+ Timer_Classes pre_class;
+
+ /**
+ * @brief This member stores the state of the timer before the execution of
+ * the test action.
+ */
+ Timer_States pre_state;
+
+ /**
+ * @brief This member stores the state of the timer after the execution of
+ * the test action.
+ */
+ Timer_States post_state;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 4 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTimerReqCancel_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTimerReqCancel_Context;
+
+static RtemsTimerReqCancel_Context
+ RtemsTimerReqCancel_Instance;
+
+static const char * const RtemsTimerReqCancel_PreDesc_Id[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTimerReqCancel_PreDesc_Context[] = {
+ "None",
+ "Interrupt",
+ "Server",
+ "NA"
+};
+
+static const char * const RtemsTimerReqCancel_PreDesc_Clock[] = {
+ "None",
+ "Ticks",
+ "Realtime",
+ "NA"
+};
+
+static const char * const RtemsTimerReqCancel_PreDesc_State[] = {
+ "Inactive",
+ "Scheduled",
+ "Pending",
+ "NA"
+};
+
+static const char * const * const RtemsTimerReqCancel_PreDesc[] = {
+ RtemsTimerReqCancel_PreDesc_Id,
+ RtemsTimerReqCancel_PreDesc_Context,
+ RtemsTimerReqCancel_PreDesc_Clock,
+ RtemsTimerReqCancel_PreDesc_State,
+ NULL
+};
+
+static const rtems_time_of_day tod_now = { 2000, 1, 1, 0, 0, 0, 0 };
+static const rtems_time_of_day tod_schedule = { 2000, 1, 1, 1, 0, 0, 0 };
+static const rtems_time_of_day tod_fire = { 2000, 1, 2, 0, 0, 0, 0 };
+
+static void TriggerTimer( void )
+{
+ /* Fire the timer service routine for ticks and realtime clock */
+ int i;
+ for ( i = 0; i < 5; i++ ) {
+ ClockTick();
+ }
+ T_rsc_success( rtems_clock_set( &tod_fire ) );
+}
+
+static void TimerServiceRoutine(
+ rtems_id timer_id,
+ void *user_data
+)
+{
+ RtemsTimerReqCancel_Context *ctx = user_data;
+ ++( ctx->invocations );
+}
+
+static void RtemsTimerReqCancel_Pre_Id_Prepare(
+ RtemsTimerReqCancel_Context *ctx,
+ RtemsTimerReqCancel_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqCancel_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter is valid.
+ */
+ ctx->id_param = ctx->timer_id;
+ break;
+ }
+
+ case RtemsTimerReqCancel_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is invalid.
+ */
+ ctx->id_param = RTEMS_ID_NONE;
+ break;
+ }
+
+ case RtemsTimerReqCancel_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqCancel_Pre_Context_Prepare(
+ RtemsTimerReqCancel_Context *ctx,
+ RtemsTimerReqCancel_Pre_Context state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqCancel_Pre_Context_None: {
+ /*
+ * While the Timer Service Routine has never been scheduled since
+ * creation of the timer. See also none.
+ */
+ ctx->pre_cond_contex = PRE_NONE;
+ break;
+ }
+
+ case RtemsTimerReqCancel_Pre_Context_Interrupt: {
+ /*
+ * While the timer is in interrupt context.
+ */
+ ctx->pre_cond_contex = PRE_INTERRUPT;
+ break;
+ }
+
+ case RtemsTimerReqCancel_Pre_Context_Server: {
+ /*
+ * While the timer is in server context.
+ */
+ ctx->pre_cond_contex = PRE_SERVER;
+ break;
+ }
+
+ case RtemsTimerReqCancel_Pre_Context_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqCancel_Pre_Clock_Prepare(
+ RtemsTimerReqCancel_Context *ctx,
+ RtemsTimerReqCancel_Pre_Clock state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqCancel_Pre_Clock_None: {
+ /*
+ * While the timer has never been scheduled since creation of the timer.
+ */
+ T_eq_int( ctx->pre_cond_contex, PRE_NONE );
+ break;
+ }
+
+ case RtemsTimerReqCancel_Pre_Clock_Ticks: {
+ /*
+ * While the clock used to determine when the timer will fire is the
+ * ticks based clock.
+ */
+ rtems_status_code status;
+
+ if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
+ status = rtems_timer_fire_after(
+ ctx->timer_id,
+ 1,
+ TimerServiceRoutine,
+ ctx
+ );
+ } else {
+ status = rtems_timer_server_fire_after(
+ ctx->timer_id,
+ 1,
+ TimerServiceRoutine,
+ ctx
+ );
+ }
+ T_rsc_success( status );
+ break;
+ }
+
+ case RtemsTimerReqCancel_Pre_Clock_Realtime: {
+ /*
+ * While the clock used to determine when the timer will fire is the
+ * realtime clock.
+ */
+ rtems_status_code status;
+
+ if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
+ status = rtems_timer_fire_when(
+ ctx->timer_id,
+ &tod_schedule,
+ TimerServiceRoutine,
+ ctx
+ );
+ } else {
+ status = rtems_timer_server_fire_when(
+ ctx->timer_id,
+ &tod_schedule,
+ TimerServiceRoutine,
+ ctx
+ );
+ }
+ T_rsc_success( status );
+ break;
+ }
+
+ case RtemsTimerReqCancel_Pre_Clock_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqCancel_Pre_State_Prepare(
+ RtemsTimerReqCancel_Context *ctx,
+ RtemsTimerReqCancel_Pre_State state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqCancel_Pre_State_Inactive: {
+ /*
+ * While the timer is in inactive state.
+ */
+ TriggerTimer();
+ T_eq_int(
+ ctx->invocations,
+ ( ctx->pre_cond_contex == PRE_NONE ) ? 0 : 1
+ );
+ ctx->invocations = 0;
+ ctx->pre_state = TIMER_INACTIVE;
+ break;
+ }
+
+ case RtemsTimerReqCancel_Pre_State_Scheduled: {
+ /*
+ * While the timer is in scheduled state.
+ */
+ /* The timer was already scheduled in the "Clock" pre-conditions. */
+ ctx->pre_state = TIMER_SCHEDULED;
+ break;
+ }
+
+ case RtemsTimerReqCancel_Pre_State_Pending: {
+ /*
+ * While the timer is in pending state.
+ */
+ T_rsc_success( rtems_task_suspend( GetTimerServerTaskId() ) );
+ TriggerTimer();
+ T_eq_int( ctx->invocations, 0 );
+ ctx->pre_state = TIMER_PENDING;
+ break;
+ }
+
+ case RtemsTimerReqCancel_Pre_State_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqCancel_Post_Status_Check(
+ RtemsTimerReqCancel_Context *ctx,
+ RtemsTimerReqCancel_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqCancel_Post_Status_Ok: {
+ /*
+ * The return status of rtems_timer_cancel() shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTimerReqCancel_Post_Status_InvId: {
+ /*
+ * The return status of rtems_timer_cancel() shall be RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTimerReqCancel_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqCancel_Post_Context_Check(
+ RtemsTimerReqCancel_Context *ctx,
+ RtemsTimerReqCancel_Post_Context state
+)
+{
+ Timer_Classes class;
+ class = GetTimerClass( ctx->timer_id );
+
+ switch ( state ) {
+ case RtemsTimerReqCancel_Post_Context_None: {
+ /*
+ * The timer shall have never been scheduled. See also none.
+ */
+ T_eq_int( class, TIMER_DORMANT );
+ break;
+ }
+
+ case RtemsTimerReqCancel_Post_Context_Interrupt: {
+ /*
+ * The timer shall be in interrupt context.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, 0 );
+ break;
+ }
+
+ case RtemsTimerReqCancel_Post_Context_Server: {
+ /*
+ * The timer shall be in server context.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, TIMER_CLASS_BIT_ON_TASK );
+ break;
+ }
+
+ case RtemsTimerReqCancel_Post_Context_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past call to
+ * rtems_timer_cancel() shall not be accessed by the rtems_timer_cancel()
+ * call. See also Nop.
+ */
+ T_eq_int( class, ctx->pre_class );
+ break;
+ }
+
+ case RtemsTimerReqCancel_Post_Context_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqCancel_Post_Clock_Check(
+ RtemsTimerReqCancel_Context *ctx,
+ RtemsTimerReqCancel_Post_Clock state
+)
+{
+ Timer_Classes class;
+ class = GetTimerClass( ctx->timer_id );
+
+ switch ( state ) {
+ case RtemsTimerReqCancel_Post_Clock_None: {
+ /*
+ * The timer shall have never been scheduled.
+ */
+ T_eq_int( class, TIMER_DORMANT );
+ break;
+ }
+
+ case RtemsTimerReqCancel_Post_Clock_Ticks: {
+ /*
+ * The timer shall use the ticks based clock.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_TIME_OF_DAY, 0 );
+ break;
+ }
+
+ case RtemsTimerReqCancel_Post_Clock_Realtime: {
+ /*
+ * The timer shall use the realtime clock.
+ */
+ T_eq_int(
+ class & TIMER_CLASS_BIT_TIME_OF_DAY,
+ TIMER_CLASS_BIT_TIME_OF_DAY
+ );
+ break;
+ }
+
+ case RtemsTimerReqCancel_Post_Clock_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past call to
+ * rtems_timer_cancel() shall not be accessed by the rtems_timer_cancel()
+ * call.
+ */
+ T_eq_int( class, ctx->pre_class );
+ break;
+ }
+
+ case RtemsTimerReqCancel_Post_Clock_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqCancel_Post_State_Check(
+ RtemsTimerReqCancel_Context *ctx,
+ RtemsTimerReqCancel_Post_State state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqCancel_Post_State_Inactive: {
+ /*
+ * The timer shall be in inactive state.
+ */
+ /* Try to fire the timer service routine - which should not fire. */
+ TriggerTimer();
+ T_eq_int( ctx->invocations, 0 );
+ break;
+ }
+
+ case RtemsTimerReqCancel_Post_State_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past call to
+ * rtems_timer_cancel() shall not be accessed by the rtems_timer_cancel()
+ * call.
+ */
+ T_eq_int( ctx->post_state, ctx->pre_state );
+ break;
+ }
+
+ case RtemsTimerReqCancel_Post_State_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqCancel_Setup( RtemsTimerReqCancel_Context *ctx )
+{
+ rtems_status_code status;
+ status = rtems_timer_initiate_server(
+ RTEMS_TIMER_SERVER_DEFAULT_PRIORITY,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_ATTRIBUTES
+ );
+ T_rsc_success( status );
+}
+
+static void RtemsTimerReqCancel_Setup_Wrap( void *arg )
+{
+ RtemsTimerReqCancel_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTimerReqCancel_Setup( ctx );
+}
+
+/**
+ * @brief Make sure the timer server is not running and the realtime clock is
+ * not set after this test.
+ */
+static void RtemsTimerReqCancel_Teardown( RtemsTimerReqCancel_Context *ctx )
+{
+ DeleteTimerServer();
+ UnsetClock();
+}
+
+static void RtemsTimerReqCancel_Teardown_Wrap( void *arg )
+{
+ RtemsTimerReqCancel_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTimerReqCancel_Teardown( ctx );
+}
+
+static void RtemsTimerReqCancel_Prepare( RtemsTimerReqCancel_Context *ctx )
+{
+ rtems_status_code status;
+ status = rtems_timer_create(
+ rtems_build_name( 'T', 'I', 'M', 'E' ),
+ &ctx->timer_id
+ );
+ T_rsc_success( status );
+
+ ctx->invocations = 0;
+ T_rsc_success( rtems_clock_set( &tod_now ) );
+}
+
+static void RtemsTimerReqCancel_Action( RtemsTimerReqCancel_Context *ctx )
+{
+ ctx->pre_class = GetTimerClass( ctx->timer_id );
+ ctx->status = rtems_timer_cancel( ctx->id_param );
+ ctx->post_state = GetTimerState( ctx->timer_id );
+ /* Ignoring return status: the timer server task may be suspended or not. */
+ rtems_task_resume( GetTimerServerTaskId() );
+}
+
+static void RtemsTimerReqCancel_Cleanup( RtemsTimerReqCancel_Context *ctx )
+{
+ T_rsc_success( rtems_timer_delete( ctx->timer_id ) );
+}
+
+static const RtemsTimerReqCancel_Entry
+RtemsTimerReqCancel_Entries[] = {
+ { 1, 0, 0, 0, 0, RtemsTimerReqCancel_Post_Status_NA,
+ RtemsTimerReqCancel_Post_Context_NA, RtemsTimerReqCancel_Post_Clock_NA,
+ RtemsTimerReqCancel_Post_State_NA },
+ { 0, 0, 0, 0, 0, RtemsTimerReqCancel_Post_Status_InvId,
+ RtemsTimerReqCancel_Post_Context_Nop, RtemsTimerReqCancel_Post_Clock_Nop,
+ RtemsTimerReqCancel_Post_State_Nop },
+ { 0, 0, 0, 0, 0, RtemsTimerReqCancel_Post_Status_Ok,
+ RtemsTimerReqCancel_Post_Context_Server,
+ RtemsTimerReqCancel_Post_Clock_Ticks,
+ RtemsTimerReqCancel_Post_State_Inactive },
+ { 0, 0, 0, 0, 0, RtemsTimerReqCancel_Post_Status_Ok,
+ RtemsTimerReqCancel_Post_Context_Server,
+ RtemsTimerReqCancel_Post_Clock_Realtime,
+ RtemsTimerReqCancel_Post_State_Inactive },
+ { 0, 0, 0, 0, 0, RtemsTimerReqCancel_Post_Status_Ok,
+ RtemsTimerReqCancel_Post_Context_Interrupt,
+ RtemsTimerReqCancel_Post_Clock_Ticks,
+ RtemsTimerReqCancel_Post_State_Inactive },
+ { 0, 0, 0, 0, 0, RtemsTimerReqCancel_Post_Status_Ok,
+ RtemsTimerReqCancel_Post_Context_Interrupt,
+ RtemsTimerReqCancel_Post_Clock_Realtime,
+ RtemsTimerReqCancel_Post_State_Inactive },
+ { 0, 0, 0, 0, 0, RtemsTimerReqCancel_Post_Status_Ok,
+ RtemsTimerReqCancel_Post_Context_None, RtemsTimerReqCancel_Post_Clock_None,
+ RtemsTimerReqCancel_Post_State_Inactive }
+};
+
+static const uint8_t
+RtemsTimerReqCancel_Map[] = {
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 5, 5, 0, 0, 0, 0, 2, 2, 2, 3, 3,
+ 3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+ 1, 1
+};
+
+static size_t RtemsTimerReqCancel_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTimerReqCancel_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsTimerReqCancel_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTimerReqCancel_Fixture = {
+ .setup = RtemsTimerReqCancel_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTimerReqCancel_Teardown_Wrap,
+ .scope = RtemsTimerReqCancel_Scope,
+ .initial_context = &RtemsTimerReqCancel_Instance
+};
+
+static inline RtemsTimerReqCancel_Entry RtemsTimerReqCancel_PopEntry(
+ RtemsTimerReqCancel_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTimerReqCancel_Entries[
+ RtemsTimerReqCancel_Map[ index ]
+ ];
+}
+
+static void RtemsTimerReqCancel_TestVariant( RtemsTimerReqCancel_Context *ctx )
+{
+ RtemsTimerReqCancel_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTimerReqCancel_Pre_Context_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTimerReqCancel_Pre_Clock_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTimerReqCancel_Pre_State_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsTimerReqCancel_Action( ctx );
+ RtemsTimerReqCancel_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsTimerReqCancel_Post_Context_Check( ctx, ctx->Map.entry.Post_Context );
+ RtemsTimerReqCancel_Post_Clock_Check( ctx, ctx->Map.entry.Post_Clock );
+ RtemsTimerReqCancel_Post_State_Check( ctx, ctx->Map.entry.Post_State );
+}
+
+/**
+ * @fn void T_case_body_RtemsTimerReqCancel( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTimerReqCancel, &RtemsTimerReqCancel_Fixture )
+{
+ RtemsTimerReqCancel_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsTimerReqCancel_Pre_Id_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsTimerReqCancel_Pre_Id_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsTimerReqCancel_Pre_Context_None;
+ ctx->Map.pcs[ 1 ] < RtemsTimerReqCancel_Pre_Context_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsTimerReqCancel_Pre_Clock_None;
+ ctx->Map.pcs[ 2 ] < RtemsTimerReqCancel_Pre_Clock_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsTimerReqCancel_Pre_State_Inactive;
+ ctx->Map.pcs[ 3 ] < RtemsTimerReqCancel_Pre_State_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ ctx->Map.entry = RtemsTimerReqCancel_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsTimerReqCancel_Prepare( ctx );
+ RtemsTimerReqCancel_TestVariant( ctx );
+ RtemsTimerReqCancel_Cleanup( ctx );
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-timer-create.c b/testsuites/validation/tc-timer-create.c
new file mode 100644
index 0000000000..416f5401d0
--- /dev/null
+++ b/testsuites/validation/tc-timer-create.c
@@ -0,0 +1,535 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTimerReqCreate
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTimerReqCreate spec:/rtems/timer/req/create
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTimerReqCreate_Pre_Name_Valid,
+ RtemsTimerReqCreate_Pre_Name_Invalid,
+ RtemsTimerReqCreate_Pre_Name_NA
+} RtemsTimerReqCreate_Pre_Name;
+
+typedef enum {
+ RtemsTimerReqCreate_Pre_Id_Valid,
+ RtemsTimerReqCreate_Pre_Id_Null,
+ RtemsTimerReqCreate_Pre_Id_NA
+} RtemsTimerReqCreate_Pre_Id;
+
+typedef enum {
+ RtemsTimerReqCreate_Pre_Free_Yes,
+ RtemsTimerReqCreate_Pre_Free_No,
+ RtemsTimerReqCreate_Pre_Free_NA
+} RtemsTimerReqCreate_Pre_Free;
+
+typedef enum {
+ RtemsTimerReqCreate_Post_Status_Ok,
+ RtemsTimerReqCreate_Post_Status_InvName,
+ RtemsTimerReqCreate_Post_Status_InvAddr,
+ RtemsTimerReqCreate_Post_Status_TooMany,
+ RtemsTimerReqCreate_Post_Status_NA
+} RtemsTimerReqCreate_Post_Status;
+
+typedef enum {
+ RtemsTimerReqCreate_Post_Name_Valid,
+ RtemsTimerReqCreate_Post_Name_Invalid,
+ RtemsTimerReqCreate_Post_Name_NA
+} RtemsTimerReqCreate_Post_Name;
+
+typedef enum {
+ RtemsTimerReqCreate_Post_IdVar_Set,
+ RtemsTimerReqCreate_Post_IdVar_Nop,
+ RtemsTimerReqCreate_Post_IdVar_NA
+} RtemsTimerReqCreate_Post_IdVar;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Name_NA : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_Free_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_Name : 2;
+ uint16_t Post_IdVar : 2;
+} RtemsTimerReqCreate_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/timer/req/create test case.
+ */
+typedef struct {
+ /**
+ * @brief This member is used by the T_seize_objects() and
+ * T_surrender_objects() support functions.
+ */
+ void *seized_objects;
+
+ /**
+ * @brief This member may contain the object identifier returned by
+ * rtems_timer_create().
+ */
+ rtems_id id_value;
+
+ /**
+ * @brief This member specifies the ``name`` parameter for the action.
+ */
+ rtems_name name;
+
+ /**
+ * @brief This member specifies the ``id`` parameter for the action.
+ */
+ rtems_id *id;
+
+ /**
+ * @brief This member contains the return status of the action.
+ */
+ rtems_status_code status;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTimerReqCreate_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTimerReqCreate_Context;
+
+static RtemsTimerReqCreate_Context
+ RtemsTimerReqCreate_Instance;
+
+static const char * const RtemsTimerReqCreate_PreDesc_Name[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTimerReqCreate_PreDesc_Id[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsTimerReqCreate_PreDesc_Free[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsTimerReqCreate_PreDesc[] = {
+ RtemsTimerReqCreate_PreDesc_Name,
+ RtemsTimerReqCreate_PreDesc_Id,
+ RtemsTimerReqCreate_PreDesc_Free,
+ NULL
+};
+
+#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+static rtems_status_code Create( void *arg, uint32_t *id )
+{
+ return rtems_timer_create( rtems_build_name( 'S', 'I', 'Z', 'E' ), id );
+}
+
+static void RtemsTimerReqCreate_Pre_Name_Prepare(
+ RtemsTimerReqCreate_Context *ctx,
+ RtemsTimerReqCreate_Pre_Name state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqCreate_Pre_Name_Valid: {
+ /*
+ * While the ``name`` parameter is valid.
+ */
+ ctx->name = NAME;
+ break;
+ }
+
+ case RtemsTimerReqCreate_Pre_Name_Invalid: {
+ /*
+ * While the ``name`` parameter is invalid.
+ */
+ ctx->name = 0;
+ break;
+ }
+
+ case RtemsTimerReqCreate_Pre_Name_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqCreate_Pre_Id_Prepare(
+ RtemsTimerReqCreate_Context *ctx,
+ RtemsTimerReqCreate_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqCreate_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter references an object of type rtems_id.
+ */
+ ctx->id = &ctx->id_value;
+ break;
+ }
+
+ case RtemsTimerReqCreate_Pre_Id_Null: {
+ /*
+ * While the ``id`` parameter is NULL.
+ */
+ ctx->id = NULL;
+ break;
+ }
+
+ case RtemsTimerReqCreate_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqCreate_Pre_Free_Prepare(
+ RtemsTimerReqCreate_Context *ctx,
+ RtemsTimerReqCreate_Pre_Free state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqCreate_Pre_Free_Yes: {
+ /*
+ * While the system has at least one inactive timer object available.
+ */
+ /* Ensured by the test suite configuration */
+ break;
+ }
+
+ case RtemsTimerReqCreate_Pre_Free_No: {
+ /*
+ * While the system has no inactive timer object available.
+ */
+ ctx->seized_objects = T_seize_objects( Create, NULL );
+ break;
+ }
+
+ case RtemsTimerReqCreate_Pre_Free_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqCreate_Post_Status_Check(
+ RtemsTimerReqCreate_Context *ctx,
+ RtemsTimerReqCreate_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqCreate_Post_Status_Ok: {
+ /*
+ * The return status of rtems_timer_create() shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTimerReqCreate_Post_Status_InvName: {
+ /*
+ * The return status of rtems_timer_create() shall be RTEMS_INVALID_NAME.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsTimerReqCreate_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_timer_create() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTimerReqCreate_Post_Status_TooMany: {
+ /*
+ * The return status of rtems_timer_create() shall be RTEMS_TOO_MANY.
+ */
+ T_rsc( ctx->status, RTEMS_TOO_MANY );
+ break;
+ }
+
+ case RtemsTimerReqCreate_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqCreate_Post_Name_Check(
+ RtemsTimerReqCreate_Context *ctx,
+ RtemsTimerReqCreate_Post_Name state
+)
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ switch ( state ) {
+ case RtemsTimerReqCreate_Post_Name_Valid: {
+ /*
+ * The unique object name shall identify the timer created by the
+ * rtems_timer_create() call.
+ */
+ id = 0;
+ sc = rtems_timer_ident( NAME, &id );
+ T_rsc_success( sc );
+ T_eq_u32( id, ctx->id_value );
+ break;
+ }
+
+ case RtemsTimerReqCreate_Post_Name_Invalid: {
+ /*
+ * The unique object name shall not identify a timer.
+ */
+ sc = rtems_timer_ident( NAME, &id );
+ T_rsc( sc, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsTimerReqCreate_Post_Name_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqCreate_Post_IdVar_Check(
+ RtemsTimerReqCreate_Context *ctx,
+ RtemsTimerReqCreate_Post_IdVar state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqCreate_Post_IdVar_Set: {
+ /*
+ * The value of the object referenced by the ``id`` parameter shall be
+ * set to the object identifier of the created timer after the return of
+ * the rtems_timer_create() call.
+ */
+ T_eq_ptr( ctx->id, &ctx->id_value );
+ T_ne_u32( ctx->id_value, INVALID_ID );
+ break;
+ }
+
+ case RtemsTimerReqCreate_Post_IdVar_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past calls to
+ * rtems_timer_create() shall not be accessed by the rtems_timer_create()
+ * call.
+ */
+ T_eq_u32( ctx->id_value, INVALID_ID );
+ break;
+ }
+
+ case RtemsTimerReqCreate_Post_IdVar_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqCreate_Setup( RtemsTimerReqCreate_Context *ctx )
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->id_value = INVALID_ID;
+}
+
+static void RtemsTimerReqCreate_Setup_Wrap( void *arg )
+{
+ RtemsTimerReqCreate_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTimerReqCreate_Setup( ctx );
+}
+
+static void RtemsTimerReqCreate_Action( RtemsTimerReqCreate_Context *ctx )
+{
+ ctx->status = rtems_timer_create( ctx->name, ctx->id );
+}
+
+static void RtemsTimerReqCreate_Cleanup( RtemsTimerReqCreate_Context *ctx )
+{
+ if ( ctx->id_value != INVALID_ID ) {
+ rtems_status_code sc;
+
+ sc = rtems_timer_delete( ctx->id_value );
+ T_rsc_success( sc );
+
+ ctx->id_value = INVALID_ID;
+ }
+
+ T_surrender_objects( &ctx->seized_objects, rtems_timer_delete );
+}
+
+static const RtemsTimerReqCreate_Entry
+RtemsTimerReqCreate_Entries[] = {
+ { 0, 0, 0, 0, RtemsTimerReqCreate_Post_Status_InvName,
+ RtemsTimerReqCreate_Post_Name_Invalid, RtemsTimerReqCreate_Post_IdVar_Nop },
+ { 0, 0, 0, 0, RtemsTimerReqCreate_Post_Status_InvAddr,
+ RtemsTimerReqCreate_Post_Name_Invalid, RtemsTimerReqCreate_Post_IdVar_Nop },
+ { 0, 0, 0, 0, RtemsTimerReqCreate_Post_Status_Ok,
+ RtemsTimerReqCreate_Post_Name_Valid, RtemsTimerReqCreate_Post_IdVar_Set },
+ { 0, 0, 0, 0, RtemsTimerReqCreate_Post_Status_TooMany,
+ RtemsTimerReqCreate_Post_Name_Invalid, RtemsTimerReqCreate_Post_IdVar_Nop }
+};
+
+static const uint8_t
+RtemsTimerReqCreate_Map[] = {
+ 2, 3, 1, 1, 0, 0, 0, 0
+};
+
+static size_t RtemsTimerReqCreate_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTimerReqCreate_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsTimerReqCreate_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTimerReqCreate_Fixture = {
+ .setup = RtemsTimerReqCreate_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsTimerReqCreate_Scope,
+ .initial_context = &RtemsTimerReqCreate_Instance
+};
+
+static inline RtemsTimerReqCreate_Entry RtemsTimerReqCreate_PopEntry(
+ RtemsTimerReqCreate_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTimerReqCreate_Entries[
+ RtemsTimerReqCreate_Map[ index ]
+ ];
+}
+
+static void RtemsTimerReqCreate_TestVariant( RtemsTimerReqCreate_Context *ctx )
+{
+ RtemsTimerReqCreate_Pre_Name_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTimerReqCreate_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTimerReqCreate_Pre_Free_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTimerReqCreate_Action( ctx );
+ RtemsTimerReqCreate_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsTimerReqCreate_Post_Name_Check( ctx, ctx->Map.entry.Post_Name );
+ RtemsTimerReqCreate_Post_IdVar_Check( ctx, ctx->Map.entry.Post_IdVar );
+}
+
+/**
+ * @fn void T_case_body_RtemsTimerReqCreate( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTimerReqCreate, &RtemsTimerReqCreate_Fixture )
+{
+ RtemsTimerReqCreate_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsTimerReqCreate_Pre_Name_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsTimerReqCreate_Pre_Name_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsTimerReqCreate_Pre_Id_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsTimerReqCreate_Pre_Id_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsTimerReqCreate_Pre_Free_Yes;
+ ctx->Map.pcs[ 2 ] < RtemsTimerReqCreate_Pre_Free_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ ctx->Map.entry = RtemsTimerReqCreate_PopEntry( ctx );
+ RtemsTimerReqCreate_TestVariant( ctx );
+ RtemsTimerReqCreate_Cleanup( ctx );
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-timer-delete.c b/testsuites/validation/tc-timer-delete.c
new file mode 100644
index 0000000000..84999c5ae7
--- /dev/null
+++ b/testsuites/validation/tc-timer-delete.c
@@ -0,0 +1,362 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTimerReqDelete
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTimerReqDelete spec:/rtems/timer/req/delete
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTimerReqDelete_Pre_Id_NoObj,
+ RtemsTimerReqDelete_Pre_Id_Timer,
+ RtemsTimerReqDelete_Pre_Id_NA
+} RtemsTimerReqDelete_Pre_Id;
+
+typedef enum {
+ RtemsTimerReqDelete_Post_Status_Ok,
+ RtemsTimerReqDelete_Post_Status_InvId,
+ RtemsTimerReqDelete_Post_Status_NA
+} RtemsTimerReqDelete_Post_Status;
+
+typedef enum {
+ RtemsTimerReqDelete_Post_Name_Valid,
+ RtemsTimerReqDelete_Post_Name_Invalid,
+ RtemsTimerReqDelete_Post_Name_NA
+} RtemsTimerReqDelete_Post_Name;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Post_Status : 2;
+ uint8_t Post_Name : 2;
+} RtemsTimerReqDelete_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/timer/req/delete test case.
+ */
+typedef struct {
+ rtems_id timer_id;
+
+ rtems_id id;
+
+ rtems_status_code status;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTimerReqDelete_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTimerReqDelete_Context;
+
+static RtemsTimerReqDelete_Context
+ RtemsTimerReqDelete_Instance;
+
+static const char * const RtemsTimerReqDelete_PreDesc_Id[] = {
+ "NoObj",
+ "Timer",
+ "NA"
+};
+
+static const char * const * const RtemsTimerReqDelete_PreDesc[] = {
+ RtemsTimerReqDelete_PreDesc_Id,
+ NULL
+};
+
+#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+static void RtemsTimerReqDelete_Pre_Id_Prepare(
+ RtemsTimerReqDelete_Context *ctx,
+ RtemsTimerReqDelete_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqDelete_Pre_Id_NoObj: {
+ /*
+ * While the ``id`` parameter is not associated with a timer.
+ */
+ ctx->id = 0;
+ break;
+ }
+
+ case RtemsTimerReqDelete_Pre_Id_Timer: {
+ /*
+ * While the ``id`` parameter is associated with a timer.
+ */
+ ctx->id = ctx->timer_id;
+ break;
+ }
+
+ case RtemsTimerReqDelete_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqDelete_Post_Status_Check(
+ RtemsTimerReqDelete_Context *ctx,
+ RtemsTimerReqDelete_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqDelete_Post_Status_Ok: {
+ /*
+ * The return status of rtems_timer_delete() shall be RTEMS_SUCCESSFUL.
+ */
+ ctx->timer_id = 0;
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTimerReqDelete_Post_Status_InvId: {
+ /*
+ * The return status of rtems_timer_delete() shall be RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTimerReqDelete_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqDelete_Post_Name_Check(
+ RtemsTimerReqDelete_Context *ctx,
+ RtemsTimerReqDelete_Post_Name state
+)
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ switch ( state ) {
+ case RtemsTimerReqDelete_Post_Name_Valid: {
+ /*
+ * The unique object name shall identify a timer.
+ */
+ id = 0;
+ sc = rtems_timer_ident( NAME, &id );
+ T_rsc_success( sc );
+ T_eq_u32( id, ctx->timer_id );
+ break;
+ }
+
+ case RtemsTimerReqDelete_Post_Name_Invalid: {
+ /*
+ * The unique object name shall not identify a timer.
+ */
+ sc = rtems_timer_ident( NAME, &id );
+ T_rsc( sc, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsTimerReqDelete_Post_Name_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqDelete_Setup( RtemsTimerReqDelete_Context *ctx )
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+}
+
+static void RtemsTimerReqDelete_Setup_Wrap( void *arg )
+{
+ RtemsTimerReqDelete_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTimerReqDelete_Setup( ctx );
+}
+
+static void RtemsTimerReqDelete_Teardown( RtemsTimerReqDelete_Context *ctx )
+{
+ if ( ctx->timer_id != 0 ) {
+ rtems_status_code sc;
+
+ sc = rtems_timer_delete( ctx->timer_id );
+ T_rsc_success( sc );
+ }
+}
+
+static void RtemsTimerReqDelete_Teardown_Wrap( void *arg )
+{
+ RtemsTimerReqDelete_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTimerReqDelete_Teardown( ctx );
+}
+
+static void RtemsTimerReqDelete_Prepare( RtemsTimerReqDelete_Context *ctx )
+{
+ if ( ctx->timer_id == 0 ) {
+ rtems_status_code sc;
+
+ sc = rtems_timer_create( NAME, &ctx->timer_id );
+ T_rsc_success( sc );
+ }
+}
+
+static void RtemsTimerReqDelete_Action( RtemsTimerReqDelete_Context *ctx )
+{
+ ctx->status = rtems_timer_delete( ctx->id );
+}
+
+static const RtemsTimerReqDelete_Entry
+RtemsTimerReqDelete_Entries[] = {
+ { 0, 0, RtemsTimerReqDelete_Post_Status_InvId,
+ RtemsTimerReqDelete_Post_Name_Valid },
+ { 0, 0, RtemsTimerReqDelete_Post_Status_Ok,
+ RtemsTimerReqDelete_Post_Name_Invalid }
+};
+
+static const uint8_t
+RtemsTimerReqDelete_Map[] = {
+ 0, 1
+};
+
+static size_t RtemsTimerReqDelete_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTimerReqDelete_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsTimerReqDelete_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTimerReqDelete_Fixture = {
+ .setup = RtemsTimerReqDelete_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTimerReqDelete_Teardown_Wrap,
+ .scope = RtemsTimerReqDelete_Scope,
+ .initial_context = &RtemsTimerReqDelete_Instance
+};
+
+static inline RtemsTimerReqDelete_Entry RtemsTimerReqDelete_PopEntry(
+ RtemsTimerReqDelete_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTimerReqDelete_Entries[
+ RtemsTimerReqDelete_Map[ index ]
+ ];
+}
+
+static void RtemsTimerReqDelete_TestVariant( RtemsTimerReqDelete_Context *ctx )
+{
+ RtemsTimerReqDelete_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTimerReqDelete_Action( ctx );
+ RtemsTimerReqDelete_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsTimerReqDelete_Post_Name_Check( ctx, ctx->Map.entry.Post_Name );
+}
+
+/**
+ * @fn void T_case_body_RtemsTimerReqDelete( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTimerReqDelete, &RtemsTimerReqDelete_Fixture )
+{
+ RtemsTimerReqDelete_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsTimerReqDelete_Pre_Id_NoObj;
+ ctx->Map.pcs[ 0 ] < RtemsTimerReqDelete_Pre_Id_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = RtemsTimerReqDelete_PopEntry( ctx );
+ RtemsTimerReqDelete_Prepare( ctx );
+ RtemsTimerReqDelete_TestVariant( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-timer-fire-after.c b/testsuites/validation/tc-timer-fire-after.c
new file mode 100644
index 0000000000..27c27523cb
--- /dev/null
+++ b/testsuites/validation/tc-timer-fire-after.c
@@ -0,0 +1,1161 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTimerReqFireAfter
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTimerReqFireAfter spec:/rtems/timer/req/fire-after
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTimerReqFireAfter_Pre_Ticks_Valid,
+ RtemsTimerReqFireAfter_Pre_Ticks_Is0,
+ RtemsTimerReqFireAfter_Pre_Ticks_NA
+} RtemsTimerReqFireAfter_Pre_Ticks;
+
+typedef enum {
+ RtemsTimerReqFireAfter_Pre_Routine_Valid,
+ RtemsTimerReqFireAfter_Pre_Routine_Null,
+ RtemsTimerReqFireAfter_Pre_Routine_NA
+} RtemsTimerReqFireAfter_Pre_Routine;
+
+typedef enum {
+ RtemsTimerReqFireAfter_Pre_Id_Valid,
+ RtemsTimerReqFireAfter_Pre_Id_Invalid,
+ RtemsTimerReqFireAfter_Pre_Id_NA
+} RtemsTimerReqFireAfter_Pre_Id;
+
+typedef enum {
+ RtemsTimerReqFireAfter_Pre_Context_None,
+ RtemsTimerReqFireAfter_Pre_Context_Interrupt,
+ RtemsTimerReqFireAfter_Pre_Context_Server,
+ RtemsTimerReqFireAfter_Pre_Context_NA
+} RtemsTimerReqFireAfter_Pre_Context;
+
+typedef enum {
+ RtemsTimerReqFireAfter_Pre_Clock_None,
+ RtemsTimerReqFireAfter_Pre_Clock_Ticks,
+ RtemsTimerReqFireAfter_Pre_Clock_Realtime,
+ RtemsTimerReqFireAfter_Pre_Clock_NA
+} RtemsTimerReqFireAfter_Pre_Clock;
+
+typedef enum {
+ RtemsTimerReqFireAfter_Pre_State_Inactive,
+ RtemsTimerReqFireAfter_Pre_State_Scheduled,
+ RtemsTimerReqFireAfter_Pre_State_Pending,
+ RtemsTimerReqFireAfter_Pre_State_NA
+} RtemsTimerReqFireAfter_Pre_State;
+
+typedef enum {
+ RtemsTimerReqFireAfter_Post_Status_Ok,
+ RtemsTimerReqFireAfter_Post_Status_InvId,
+ RtemsTimerReqFireAfter_Post_Status_InvAddr,
+ RtemsTimerReqFireAfter_Post_Status_InvNum,
+ RtemsTimerReqFireAfter_Post_Status_NA
+} RtemsTimerReqFireAfter_Post_Status;
+
+typedef enum {
+ RtemsTimerReqFireAfter_Post_Context_None,
+ RtemsTimerReqFireAfter_Post_Context_Interrupt,
+ RtemsTimerReqFireAfter_Post_Context_Server,
+ RtemsTimerReqFireAfter_Post_Context_Nop,
+ RtemsTimerReqFireAfter_Post_Context_NA
+} RtemsTimerReqFireAfter_Post_Context;
+
+typedef enum {
+ RtemsTimerReqFireAfter_Post_Clock_None,
+ RtemsTimerReqFireAfter_Post_Clock_Ticks,
+ RtemsTimerReqFireAfter_Post_Clock_Realtime,
+ RtemsTimerReqFireAfter_Post_Clock_Nop,
+ RtemsTimerReqFireAfter_Post_Clock_NA
+} RtemsTimerReqFireAfter_Post_Clock;
+
+typedef enum {
+ RtemsTimerReqFireAfter_Post_State_Scheduled,
+ RtemsTimerReqFireAfter_Post_State_Nop,
+ RtemsTimerReqFireAfter_Post_State_NA
+} RtemsTimerReqFireAfter_Post_State;
+
+typedef enum {
+ RtemsTimerReqFireAfter_Post_Interval_Param,
+ RtemsTimerReqFireAfter_Post_Interval_Nop,
+ RtemsTimerReqFireAfter_Post_Interval_NA
+} RtemsTimerReqFireAfter_Post_Interval;
+
+typedef enum {
+ RtemsTimerReqFireAfter_Post_Routine_Param,
+ RtemsTimerReqFireAfter_Post_Routine_Nop,
+ RtemsTimerReqFireAfter_Post_Routine_NA
+} RtemsTimerReqFireAfter_Post_Routine;
+
+typedef enum {
+ RtemsTimerReqFireAfter_Post_UserData_Param,
+ RtemsTimerReqFireAfter_Post_UserData_Nop,
+ RtemsTimerReqFireAfter_Post_UserData_NA
+} RtemsTimerReqFireAfter_Post_UserData;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_Ticks_NA : 1;
+ uint32_t Pre_Routine_NA : 1;
+ uint32_t Pre_Id_NA : 1;
+ uint32_t Pre_Context_NA : 1;
+ uint32_t Pre_Clock_NA : 1;
+ uint32_t Pre_State_NA : 1;
+ uint32_t Post_Status : 3;
+ uint32_t Post_Context : 3;
+ uint32_t Post_Clock : 3;
+ uint32_t Post_State : 2;
+ uint32_t Post_Interval : 2;
+ uint32_t Post_Routine : 2;
+ uint32_t Post_UserData : 2;
+} RtemsTimerReqFireAfter_Entry;
+
+typedef enum {
+ PRE_NONE = 0,
+ PRE_INTERRUPT = 1,
+ PRE_SERVER = 2
+} PreConditionContext;
+
+typedef enum {
+ SCHEDULE_NONE = 0,
+ SCHEDULE_SOON = 1,
+ SCHEDULE_LATER = 2,
+ SCHEDULE_MAX = 5
+} Scheduling_Ticks;
+
+/**
+ * @brief Test context for spec:/rtems/timer/req/fire-after test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a valid id of a timer.
+ */
+ rtems_id timer_id;
+
+ /**
+ * @brief This member specifies the ``id`` parameter for the action.
+ */
+ rtems_id id_param;
+
+ /**
+ * @brief This member specifies the ``ticks`` parameter for the action.
+ */
+ rtems_interval ticks_param;
+
+ /**
+ * @brief This member specifies the ``routine`` parameter for the action.
+ */
+ rtems_timer_service_routine_entry routine_param;
+
+ /**
+ * @brief This member contains the returned status code of the action.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member contains a counter for invocations of the Timer Service
+ * Routine.
+ */
+ int invocations;
+
+ /**
+ * @brief Function TriggerTimer() is used to figure out how many ticks (see
+ * tick) are needed till the Timer Service Routine gets executed. This
+ * member contains the number of ticks needed to fire the Timer Service
+ * Routine.
+ */
+ Scheduling_Ticks ticks_till_fire;
+
+ /**
+ * @brief This member contains the user data given to the Timer Service
+ * Routine when called.
+ */
+ void *routine_user_data;
+
+ /**
+ * @brief This member specifies which pre-condition context (none, interrupt
+ * context, server context) must be created before the
+ * rtems_timer_fire_after() action gets executed.
+ */
+ PreConditionContext pre_cond_contex;
+
+ /**
+ * @brief This member stores internal clock and context settings of the timer
+ * before the execution of the test action.
+ */
+ Timer_Classes pre_class;
+
+ /**
+ * @brief This member stores the state of the timer before the execution of
+ * the test action.
+ */
+ Timer_States pre_state;
+
+ /**
+ * @brief This member stores the state of the timer after the execution of
+ * the test action.
+ */
+ Timer_States post_state;
+
+ /**
+ * @brief This member stores the scheduling data of the timer before the
+ * execution of the test action.
+ */
+ Timer_Scheduling_Data pre_scheduling_data;
+
+ /**
+ * @brief This member stores the scheduling data of the timer after the
+ * execution of the test action.
+ */
+ Timer_Scheduling_Data post_scheduling_data;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 6 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTimerReqFireAfter_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTimerReqFireAfter_Context;
+
+static RtemsTimerReqFireAfter_Context
+ RtemsTimerReqFireAfter_Instance;
+
+static const char * const RtemsTimerReqFireAfter_PreDesc_Ticks[] = {
+ "Valid",
+ "Is0",
+ "NA"
+};
+
+static const char * const RtemsTimerReqFireAfter_PreDesc_Routine[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsTimerReqFireAfter_PreDesc_Id[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTimerReqFireAfter_PreDesc_Context[] = {
+ "None",
+ "Interrupt",
+ "Server",
+ "NA"
+};
+
+static const char * const RtemsTimerReqFireAfter_PreDesc_Clock[] = {
+ "None",
+ "Ticks",
+ "Realtime",
+ "NA"
+};
+
+static const char * const RtemsTimerReqFireAfter_PreDesc_State[] = {
+ "Inactive",
+ "Scheduled",
+ "Pending",
+ "NA"
+};
+
+static const char * const * const RtemsTimerReqFireAfter_PreDesc[] = {
+ RtemsTimerReqFireAfter_PreDesc_Ticks,
+ RtemsTimerReqFireAfter_PreDesc_Routine,
+ RtemsTimerReqFireAfter_PreDesc_Id,
+ RtemsTimerReqFireAfter_PreDesc_Context,
+ RtemsTimerReqFireAfter_PreDesc_Clock,
+ RtemsTimerReqFireAfter_PreDesc_State,
+ NULL
+};
+
+static const rtems_time_of_day tod_now = { 2000, 1, 1, 0, 0, 0, 0 };
+static const rtems_time_of_day tod_schedule = { 2000, 1, 1, 1, 0, 0, 0 };
+static const rtems_time_of_day tod_fire = { 2000, 1, 2, 0, 0, 0, 0 };
+
+static Scheduling_Ticks TriggerTimer( const RtemsTimerReqFireAfter_Context *ctx )
+{
+ int ticks_fired = SCHEDULE_NONE;
+ int invocations_old = ctx->invocations;
+
+ /* Fire the timer service routine for ticks and realtime clock */
+ int i;
+ for ( i = 1; i <= SCHEDULE_MAX; ++i ) {
+ ClockTick();
+ if ( ctx->invocations > invocations_old ) {
+ ticks_fired = i;
+ break;
+ }
+ }
+
+ T_rsc_success( rtems_clock_set( &tod_fire ) );
+
+ return ticks_fired;
+}
+
+static void TimerServiceRoutine(
+ rtems_id timer_id,
+ void *user_data
+)
+{
+ RtemsTimerReqFireAfter_Context *ctx = user_data;
+ ++( ctx->invocations );
+ ctx->routine_user_data = user_data;
+}
+
+static void RtemsTimerReqFireAfter_Pre_Ticks_Prepare(
+ RtemsTimerReqFireAfter_Context *ctx,
+ RtemsTimerReqFireAfter_Pre_Ticks state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireAfter_Pre_Ticks_Valid: {
+ /*
+ * While the ``ticks`` parameter is a positive (greater 0) number.
+ */
+ ctx->ticks_param = SCHEDULE_LATER;
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Pre_Ticks_Is0: {
+ /*
+ * While the ``ticks`` parameter is 0.
+ */
+ ctx->ticks_param = 0;
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Pre_Ticks_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireAfter_Pre_Routine_Prepare(
+ RtemsTimerReqFireAfter_Context *ctx,
+ RtemsTimerReqFireAfter_Pre_Routine state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireAfter_Pre_Routine_Valid: {
+ /*
+ * While the ``routine`` parameter references an object of type
+ * rtems_timer_service_routine_entry.
+ */
+ ctx->routine_param = TimerServiceRoutine;
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Pre_Routine_Null: {
+ /*
+ * While the ``routine`` parameter is NULL..
+ */
+ ctx->routine_param = NULL;
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Pre_Routine_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireAfter_Pre_Id_Prepare(
+ RtemsTimerReqFireAfter_Context *ctx,
+ RtemsTimerReqFireAfter_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireAfter_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter is valid.
+ */
+ ctx->id_param = ctx->timer_id;
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is invalid.
+ */
+ ctx->id_param = RTEMS_ID_NONE;
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireAfter_Pre_Context_Prepare(
+ RtemsTimerReqFireAfter_Context *ctx,
+ RtemsTimerReqFireAfter_Pre_Context state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireAfter_Pre_Context_None: {
+ /*
+ * While the Timer Service Routine has never been scheduled since
+ * creation of the timer. See also none.
+ */
+ ctx->pre_cond_contex = PRE_NONE;
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Pre_Context_Interrupt: {
+ /*
+ * While the timer is in interrupt context.
+ */
+ ctx->pre_cond_contex = PRE_INTERRUPT;
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Pre_Context_Server: {
+ /*
+ * While the timer is in server context.
+ */
+ ctx->pre_cond_contex = PRE_SERVER;
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Pre_Context_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireAfter_Pre_Clock_Prepare(
+ RtemsTimerReqFireAfter_Context *ctx,
+ RtemsTimerReqFireAfter_Pre_Clock state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireAfter_Pre_Clock_None: {
+ /*
+ * While the timer has never been scheduled since creation of the timer.
+ */
+ T_eq_int( ctx->pre_cond_contex, PRE_NONE );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Pre_Clock_Ticks: {
+ /*
+ * While the clock used to determine when the timer will fire is the
+ * ticks based clock.
+ */
+ rtems_status_code status;
+
+ if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
+ status = rtems_timer_fire_after(
+ ctx->timer_id,
+ SCHEDULE_SOON,
+ TimerServiceRoutine,
+ ctx
+ );
+ } else {
+ status = rtems_timer_server_fire_after(
+ ctx->timer_id,
+ SCHEDULE_SOON,
+ TimerServiceRoutine,
+ ctx
+ );
+ }
+ T_rsc_success( status );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Pre_Clock_Realtime: {
+ /*
+ * While the clock used to determine when the timer will fire is the
+ * realtime clock.
+ */
+ rtems_status_code status;
+
+ if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
+ status = rtems_timer_fire_when(
+ ctx->timer_id,
+ &tod_schedule,
+ TimerServiceRoutine,
+ ctx
+ );
+ } else {
+ status = rtems_timer_server_fire_when(
+ ctx->timer_id,
+ &tod_schedule,
+ TimerServiceRoutine,
+ ctx
+ );
+ }
+ T_rsc_success( status );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Pre_Clock_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireAfter_Pre_State_Prepare(
+ RtemsTimerReqFireAfter_Context *ctx,
+ RtemsTimerReqFireAfter_Pre_State state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireAfter_Pre_State_Inactive: {
+ /*
+ * While the timer is in inactive state.
+ */
+ TriggerTimer( ctx );
+ T_eq_int(
+ ctx->invocations,
+ ( ctx->pre_cond_contex == PRE_NONE ) ? 0 : 1
+ );
+ ctx->invocations = 0;
+ ctx->pre_state = TIMER_INACTIVE;
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Pre_State_Scheduled: {
+ /*
+ * While the timer is in scheduled state.
+ */
+ /* The timer was already scheduled in the "Clock" pre-conditions. */
+ ctx->pre_state = TIMER_SCHEDULED;
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Pre_State_Pending: {
+ /*
+ * While the timer is in pending state.
+ */
+ T_rsc_success( rtems_task_suspend( GetTimerServerTaskId() ) );
+ TriggerTimer( ctx );
+ T_eq_int( ctx->invocations, 0 );
+ ctx->pre_state = TIMER_PENDING;
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Pre_State_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireAfter_Post_Status_Check(
+ RtemsTimerReqFireAfter_Context *ctx,
+ RtemsTimerReqFireAfter_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireAfter_Post_Status_Ok: {
+ /*
+ * The return status of rtems_timer_fire_after() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_Status_InvId: {
+ /*
+ * The return status of rtems_timer_fire_after() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_timer_fire_after() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_Status_InvNum: {
+ /*
+ * The return status of rtems_timer_fire_after() shall be
+ * RTEMS_INVALID_NUMBER.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NUMBER );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireAfter_Post_Context_Check(
+ RtemsTimerReqFireAfter_Context *ctx,
+ RtemsTimerReqFireAfter_Post_Context state
+)
+{
+ Timer_Classes class;
+ class = GetTimerClass( ctx->timer_id );
+
+ switch ( state ) {
+ case RtemsTimerReqFireAfter_Post_Context_None: {
+ /*
+ * The timer shall have never been scheduled. See also none.
+ */
+ T_eq_int( class, TIMER_DORMANT );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_Context_Interrupt: {
+ /*
+ * The timer shall be in interrupt context.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, 0 );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_Context_Server: {
+ /*
+ * The timer shall be in server context.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, TIMER_CLASS_BIT_ON_TASK );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_Context_Nop: {
+ /*
+ * Objects referenced by the parameters in the past call to
+ * rtems_timer_fire_after() shall not be accessed by the
+ * rtems_timer_fire_after() call. See also Nop.
+ */
+ T_eq_int( class, ctx->pre_class );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_Context_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireAfter_Post_Clock_Check(
+ RtemsTimerReqFireAfter_Context *ctx,
+ RtemsTimerReqFireAfter_Post_Clock state
+)
+{
+ Timer_Classes class;
+ class = GetTimerClass( ctx->timer_id );
+
+ switch ( state ) {
+ case RtemsTimerReqFireAfter_Post_Clock_None: {
+ /*
+ * The timer shall have never been scheduled.
+ */
+ T_eq_int( class, TIMER_DORMANT );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_Clock_Ticks: {
+ /*
+ * The timer shall use the ticks based clock.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_TIME_OF_DAY, 0 );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_Clock_Realtime: {
+ /*
+ * The timer shall use the realtime clock.
+ */
+ T_eq_int(
+ class & TIMER_CLASS_BIT_TIME_OF_DAY,
+ TIMER_CLASS_BIT_TIME_OF_DAY
+ );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_Clock_Nop: {
+ /*
+ * Objects referenced by the parameters in the past call to
+ * rtems_timer_fire_after() shall not be accessed by the
+ * rtems_timer_fire_after() call.
+ */
+ T_eq_int( class, ctx->pre_class );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_Clock_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireAfter_Post_State_Check(
+ RtemsTimerReqFireAfter_Context *ctx,
+ RtemsTimerReqFireAfter_Post_State state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireAfter_Post_State_Scheduled: {
+ /*
+ * The timer shall be in scheduled state.
+ */
+ ctx->ticks_till_fire = TriggerTimer( ctx );
+ T_eq_int( ctx->invocations, 1 );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_State_Nop: {
+ /*
+ * Objects referenced by the parameters in the past call to
+ * rtems_timer_fire_after() shall not be accessed by the
+ * rtems_timer_fire_after() call.
+ */
+ T_eq_int( ctx->post_state, ctx->pre_state );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_State_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireAfter_Post_Interval_Check(
+ RtemsTimerReqFireAfter_Context *ctx,
+ RtemsTimerReqFireAfter_Post_Interval state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireAfter_Post_Interval_Param: {
+ /*
+ * The Timer Service Routine shall be invoked the number of ticks (see
+ * tick), which are provided by the ``ticks`` parameter in the past call
+ * to rtems_timer_fire_after(), after a point in time during the
+ * execution of the rtems_timer_fire_after() call.
+ */
+ T_eq_int( ctx->ticks_till_fire, ctx->ticks_param );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_Interval_Nop: {
+ /*
+ * If and when the Timer Service Routine will be invoked shall not be
+ * changed by the past call to rtems_timer_fire_after().
+ */
+ /*
+ * Whether the timer is scheduled has already been tested by the
+ * "Nop" "State" post-condition above.
+ */
+ T_eq_u32(
+ ctx->post_scheduling_data.interval,
+ ctx->pre_scheduling_data.interval
+ );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_Interval_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireAfter_Post_Routine_Check(
+ RtemsTimerReqFireAfter_Context *ctx,
+ RtemsTimerReqFireAfter_Post_Routine state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireAfter_Post_Routine_Param: {
+ /*
+ * The function reference used to invoke the Timer Service Routine when
+ * the timer will fire shall be the one provided by the ``routine``
+ * parameter in the past call to rtems_timer_fire_after().
+ */
+ T_eq_int( ctx->invocations, 1 );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_Routine_Nop: {
+ /*
+ * The function reference used for any invocation of the Timer Service
+ * Routine shall not be changed by the past call to
+ * rtems_timer_fire_after().
+ */
+ T_eq_ptr(
+ ctx->post_scheduling_data.routine,
+ ctx->pre_scheduling_data.routine
+ );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_Routine_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireAfter_Post_UserData_Check(
+ RtemsTimerReqFireAfter_Context *ctx,
+ RtemsTimerReqFireAfter_Post_UserData state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireAfter_Post_UserData_Param: {
+ /*
+ * The user data argument for invoking the Timer Service Routine when the
+ * timer will fire shall be the one provided by the ``user_data``
+ * parameter in the past call to rtems_timer_fire_after().
+ */
+ T_eq_ptr( ctx->routine_user_data, ctx );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_UserData_Nop: {
+ /*
+ * The user data argument used for any invocation of the Timer Service
+ * Routine shall not be changed by the past call to
+ * rtems_timer_fire_after().
+ */
+ T_eq_ptr(
+ ctx->post_scheduling_data.user_data,
+ ctx->pre_scheduling_data.user_data
+ );
+ break;
+ }
+
+ case RtemsTimerReqFireAfter_Post_UserData_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireAfter_Setup( RtemsTimerReqFireAfter_Context *ctx )
+{
+ rtems_status_code status;
+ status = rtems_timer_initiate_server(
+ RTEMS_TIMER_SERVER_DEFAULT_PRIORITY,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_ATTRIBUTES
+ );
+ T_rsc_success( status );
+}
+
+static void RtemsTimerReqFireAfter_Setup_Wrap( void *arg )
+{
+ RtemsTimerReqFireAfter_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTimerReqFireAfter_Setup( ctx );
+}
+
+/**
+ * @brief Make sure the timer server is not running and the realtime clock is
+ * not set after this test.
+ */
+static void RtemsTimerReqFireAfter_Teardown(
+ RtemsTimerReqFireAfter_Context *ctx
+)
+{
+ DeleteTimerServer();
+ UnsetClock();
+}
+
+static void RtemsTimerReqFireAfter_Teardown_Wrap( void *arg )
+{
+ RtemsTimerReqFireAfter_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTimerReqFireAfter_Teardown( ctx );
+}
+
+static void RtemsTimerReqFireAfter_Prepare(
+ RtemsTimerReqFireAfter_Context *ctx
+)
+{
+ rtems_status_code status;
+ status = rtems_timer_create(
+ rtems_build_name( 'T', 'I', 'M', 'E' ),
+ &ctx->timer_id
+ );
+ T_rsc_success( status );
+
+ ctx->invocations = 0;
+ ctx->ticks_till_fire = SCHEDULE_NONE;
+ ctx->routine_user_data = NULL;
+ T_rsc_success( rtems_clock_set( &tod_now ) );
+}
+
+static void RtemsTimerReqFireAfter_Action(
+ RtemsTimerReqFireAfter_Context *ctx
+)
+{
+ GetTimerSchedulingData( ctx->timer_id, &ctx->pre_scheduling_data );
+ ctx->pre_class = GetTimerClass( ctx->timer_id );
+ ctx->status = rtems_timer_fire_after(
+ ctx->id_param,
+ ctx->ticks_param,
+ ctx->routine_param,
+ ctx
+ );
+ ctx->post_state = GetTimerState( ctx->timer_id );
+ GetTimerSchedulingData( ctx->timer_id, &ctx->post_scheduling_data );
+ /* Ignoring return status: the timer server task may be suspended or not. */
+ rtems_task_resume( GetTimerServerTaskId() );
+}
+
+static void RtemsTimerReqFireAfter_Cleanup(
+ RtemsTimerReqFireAfter_Context *ctx
+)
+{
+ T_rsc_success( rtems_timer_delete( ctx->timer_id ) );
+}
+
+static const RtemsTimerReqFireAfter_Entry
+RtemsTimerReqFireAfter_Entries[] = {
+ { 1, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireAfter_Post_Status_NA,
+ RtemsTimerReqFireAfter_Post_Context_NA,
+ RtemsTimerReqFireAfter_Post_Clock_NA, RtemsTimerReqFireAfter_Post_State_NA,
+ RtemsTimerReqFireAfter_Post_Interval_NA,
+ RtemsTimerReqFireAfter_Post_Routine_NA,
+ RtemsTimerReqFireAfter_Post_UserData_NA },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireAfter_Post_Status_InvNum,
+ RtemsTimerReqFireAfter_Post_Context_Nop,
+ RtemsTimerReqFireAfter_Post_Clock_Nop,
+ RtemsTimerReqFireAfter_Post_State_Nop,
+ RtemsTimerReqFireAfter_Post_Interval_Nop,
+ RtemsTimerReqFireAfter_Post_Routine_Nop,
+ RtemsTimerReqFireAfter_Post_UserData_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireAfter_Post_Status_InvAddr,
+ RtemsTimerReqFireAfter_Post_Context_Nop,
+ RtemsTimerReqFireAfter_Post_Clock_Nop,
+ RtemsTimerReqFireAfter_Post_State_Nop,
+ RtemsTimerReqFireAfter_Post_Interval_Nop,
+ RtemsTimerReqFireAfter_Post_Routine_Nop,
+ RtemsTimerReqFireAfter_Post_UserData_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireAfter_Post_Status_Ok,
+ RtemsTimerReqFireAfter_Post_Context_Interrupt,
+ RtemsTimerReqFireAfter_Post_Clock_Ticks,
+ RtemsTimerReqFireAfter_Post_State_Scheduled,
+ RtemsTimerReqFireAfter_Post_Interval_Param,
+ RtemsTimerReqFireAfter_Post_Routine_Param,
+ RtemsTimerReqFireAfter_Post_UserData_Param },
+ { 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireAfter_Post_Status_InvId,
+ RtemsTimerReqFireAfter_Post_Context_Nop,
+ RtemsTimerReqFireAfter_Post_Clock_Nop,
+ RtemsTimerReqFireAfter_Post_State_Nop,
+ RtemsTimerReqFireAfter_Post_Interval_Nop,
+ RtemsTimerReqFireAfter_Post_Routine_Nop,
+ RtemsTimerReqFireAfter_Post_UserData_Nop }
+};
+
+static const uint8_t
+RtemsTimerReqFireAfter_Map[] = {
+ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 0, 3, 3, 3, 3, 3,
+ 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4,
+ 4, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0, 2, 2, 2,
+ 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0, 2, 2,
+ 2, 2, 2, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1
+};
+
+static size_t RtemsTimerReqFireAfter_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTimerReqFireAfter_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsTimerReqFireAfter_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTimerReqFireAfter_Fixture = {
+ .setup = RtemsTimerReqFireAfter_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTimerReqFireAfter_Teardown_Wrap,
+ .scope = RtemsTimerReqFireAfter_Scope,
+ .initial_context = &RtemsTimerReqFireAfter_Instance
+};
+
+static inline RtemsTimerReqFireAfter_Entry RtemsTimerReqFireAfter_PopEntry(
+ RtemsTimerReqFireAfter_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTimerReqFireAfter_Entries[
+ RtemsTimerReqFireAfter_Map[ index ]
+ ];
+}
+
+static void RtemsTimerReqFireAfter_TestVariant(
+ RtemsTimerReqFireAfter_Context *ctx
+)
+{
+ RtemsTimerReqFireAfter_Pre_Ticks_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTimerReqFireAfter_Pre_Routine_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTimerReqFireAfter_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTimerReqFireAfter_Pre_Context_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsTimerReqFireAfter_Pre_Clock_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsTimerReqFireAfter_Pre_State_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsTimerReqFireAfter_Action( ctx );
+ RtemsTimerReqFireAfter_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsTimerReqFireAfter_Post_Context_Check(
+ ctx,
+ ctx->Map.entry.Post_Context
+ );
+ RtemsTimerReqFireAfter_Post_Clock_Check( ctx, ctx->Map.entry.Post_Clock );
+ RtemsTimerReqFireAfter_Post_State_Check( ctx, ctx->Map.entry.Post_State );
+ RtemsTimerReqFireAfter_Post_Interval_Check(
+ ctx,
+ ctx->Map.entry.Post_Interval
+ );
+ RtemsTimerReqFireAfter_Post_Routine_Check(
+ ctx,
+ ctx->Map.entry.Post_Routine
+ );
+ RtemsTimerReqFireAfter_Post_UserData_Check(
+ ctx,
+ ctx->Map.entry.Post_UserData
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsTimerReqFireAfter( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTimerReqFireAfter, &RtemsTimerReqFireAfter_Fixture )
+{
+ RtemsTimerReqFireAfter_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsTimerReqFireAfter_Pre_Ticks_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsTimerReqFireAfter_Pre_Ticks_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsTimerReqFireAfter_Pre_Routine_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsTimerReqFireAfter_Pre_Routine_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsTimerReqFireAfter_Pre_Id_Valid;
+ ctx->Map.pcs[ 2 ] < RtemsTimerReqFireAfter_Pre_Id_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsTimerReqFireAfter_Pre_Context_None;
+ ctx->Map.pcs[ 3 ] < RtemsTimerReqFireAfter_Pre_Context_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = RtemsTimerReqFireAfter_Pre_Clock_None;
+ ctx->Map.pcs[ 4 ] < RtemsTimerReqFireAfter_Pre_Clock_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 5 ] = RtemsTimerReqFireAfter_Pre_State_Inactive;
+ ctx->Map.pcs[ 5 ] < RtemsTimerReqFireAfter_Pre_State_NA;
+ ++ctx->Map.pcs[ 5 ]
+ ) {
+ ctx->Map.entry = RtemsTimerReqFireAfter_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsTimerReqFireAfter_Prepare( ctx );
+ RtemsTimerReqFireAfter_TestVariant( ctx );
+ RtemsTimerReqFireAfter_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-timer-fire-when.c b/testsuites/validation/tc-timer-fire-when.c
new file mode 100644
index 0000000000..92bd505a41
--- /dev/null
+++ b/testsuites/validation/tc-timer-fire-when.c
@@ -0,0 +1,1286 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTimerReqFireWhen
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTimerReqFireWhen spec:/rtems/timer/req/fire-when
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTimerReqFireWhen_Pre_RtClock_Set,
+ RtemsTimerReqFireWhen_Pre_RtClock_Unset,
+ RtemsTimerReqFireWhen_Pre_RtClock_NA
+} RtemsTimerReqFireWhen_Pre_RtClock;
+
+typedef enum {
+ RtemsTimerReqFireWhen_Pre_Routine_Valid,
+ RtemsTimerReqFireWhen_Pre_Routine_Null,
+ RtemsTimerReqFireWhen_Pre_Routine_NA
+} RtemsTimerReqFireWhen_Pre_Routine;
+
+typedef enum {
+ RtemsTimerReqFireWhen_Pre_WallTime_Valid,
+ RtemsTimerReqFireWhen_Pre_WallTime_Invalid,
+ RtemsTimerReqFireWhen_Pre_WallTime_Past,
+ RtemsTimerReqFireWhen_Pre_WallTime_Null,
+ RtemsTimerReqFireWhen_Pre_WallTime_NA
+} RtemsTimerReqFireWhen_Pre_WallTime;
+
+typedef enum {
+ RtemsTimerReqFireWhen_Pre_Id_Valid,
+ RtemsTimerReqFireWhen_Pre_Id_Invalid,
+ RtemsTimerReqFireWhen_Pre_Id_NA
+} RtemsTimerReqFireWhen_Pre_Id;
+
+typedef enum {
+ RtemsTimerReqFireWhen_Pre_Context_None,
+ RtemsTimerReqFireWhen_Pre_Context_Interrupt,
+ RtemsTimerReqFireWhen_Pre_Context_Server,
+ RtemsTimerReqFireWhen_Pre_Context_NA
+} RtemsTimerReqFireWhen_Pre_Context;
+
+typedef enum {
+ RtemsTimerReqFireWhen_Pre_Clock_None,
+ RtemsTimerReqFireWhen_Pre_Clock_Ticks,
+ RtemsTimerReqFireWhen_Pre_Clock_Realtime,
+ RtemsTimerReqFireWhen_Pre_Clock_NA
+} RtemsTimerReqFireWhen_Pre_Clock;
+
+typedef enum {
+ RtemsTimerReqFireWhen_Pre_State_Inactive,
+ RtemsTimerReqFireWhen_Pre_State_Scheduled,
+ RtemsTimerReqFireWhen_Pre_State_Pending,
+ RtemsTimerReqFireWhen_Pre_State_NA
+} RtemsTimerReqFireWhen_Pre_State;
+
+typedef enum {
+ RtemsTimerReqFireWhen_Post_Status_Ok,
+ RtemsTimerReqFireWhen_Post_Status_NotDef,
+ RtemsTimerReqFireWhen_Post_Status_InvId,
+ RtemsTimerReqFireWhen_Post_Status_InvAddr,
+ RtemsTimerReqFireWhen_Post_Status_InvClock,
+ RtemsTimerReqFireWhen_Post_Status_NA
+} RtemsTimerReqFireWhen_Post_Status;
+
+typedef enum {
+ RtemsTimerReqFireWhen_Post_Context_None,
+ RtemsTimerReqFireWhen_Post_Context_Interrupt,
+ RtemsTimerReqFireWhen_Post_Context_Server,
+ RtemsTimerReqFireWhen_Post_Context_Nop,
+ RtemsTimerReqFireWhen_Post_Context_NA
+} RtemsTimerReqFireWhen_Post_Context;
+
+typedef enum {
+ RtemsTimerReqFireWhen_Post_Clock_None,
+ RtemsTimerReqFireWhen_Post_Clock_Ticks,
+ RtemsTimerReqFireWhen_Post_Clock_Realtime,
+ RtemsTimerReqFireWhen_Post_Clock_Nop,
+ RtemsTimerReqFireWhen_Post_Clock_NA
+} RtemsTimerReqFireWhen_Post_Clock;
+
+typedef enum {
+ RtemsTimerReqFireWhen_Post_State_Scheduled,
+ RtemsTimerReqFireWhen_Post_State_Nop,
+ RtemsTimerReqFireWhen_Post_State_NA
+} RtemsTimerReqFireWhen_Post_State;
+
+typedef enum {
+ RtemsTimerReqFireWhen_Post_WallTime_Param,
+ RtemsTimerReqFireWhen_Post_WallTime_Nop,
+ RtemsTimerReqFireWhen_Post_WallTime_NA
+} RtemsTimerReqFireWhen_Post_WallTime;
+
+typedef enum {
+ RtemsTimerReqFireWhen_Post_Routine_Param,
+ RtemsTimerReqFireWhen_Post_Routine_Nop,
+ RtemsTimerReqFireWhen_Post_Routine_NA
+} RtemsTimerReqFireWhen_Post_Routine;
+
+typedef enum {
+ RtemsTimerReqFireWhen_Post_UserData_Param,
+ RtemsTimerReqFireWhen_Post_UserData_Nop,
+ RtemsTimerReqFireWhen_Post_UserData_NA
+} RtemsTimerReqFireWhen_Post_UserData;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_RtClock_NA : 1;
+ uint32_t Pre_Routine_NA : 1;
+ uint32_t Pre_WallTime_NA : 1;
+ uint32_t Pre_Id_NA : 1;
+ uint32_t Pre_Context_NA : 1;
+ uint32_t Pre_Clock_NA : 1;
+ uint32_t Pre_State_NA : 1;
+ uint32_t Post_Status : 3;
+ uint32_t Post_Context : 3;
+ uint32_t Post_Clock : 3;
+ uint32_t Post_State : 2;
+ uint32_t Post_WallTime : 2;
+ uint32_t Post_Routine : 2;
+ uint32_t Post_UserData : 2;
+} RtemsTimerReqFireWhen_Entry;
+
+typedef enum {
+ PRE_NONE = 0,
+ PRE_INTERRUPT = 1,
+ PRE_SERVER = 2
+} PreConditionContext;
+
+typedef enum {
+ SCHEDULE_NONE = 0,
+ SCHEDULE_SOON = 1,
+ SCHEDULE_MAX = 5
+} Scheduling_Ticks;
+
+/**
+ * @brief Test context for spec:/rtems/timer/req/fire-when test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a valid id of a timer.
+ */
+ rtems_id timer_id;
+
+ /**
+ * @brief This member specifies the ``id`` parameter for the action.
+ */
+ rtems_id id_param;
+
+ /**
+ * @brief This member specifies the ``wall_time`` parameter for the action.
+ */
+ const rtems_time_of_day *wall_time_param;
+
+ /**
+ * @brief This member specifies the ``routine`` parameter for the action.
+ */
+ rtems_timer_service_routine_entry routine_param;
+
+ /**
+ * @brief This member contains the returned status code of the action.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member contains a counter of invocations of the Timer Service
+ * Routine.
+ */
+ int invocations;
+
+ /**
+ * @brief Function TriggerTimer() is used to figure out when the Timer
+ * Service Routine gets executed. This member contains the time-of-day when
+ * the Timer Service Routine fires (see fire).
+ */
+ rtems_time_of_day tod_till_fire;
+
+ /**
+ * @brief This member contains the user data given to the Timer Service
+ * Routine when called.
+ */
+ void *routine_user_data;
+
+ /**
+ * @brief This member specifies which pre-condition context (none, interrupt
+ * context, server context) must be created before the
+ * rtems_timer_fire_when() action gets executed.
+ */
+ PreConditionContext pre_cond_contex;
+
+ /**
+ * @brief This member specifies the pre-condition state of the realtime
+ * clock. It should either be set to the value referenced by pre_cond_tod
+ * or if NULL, then the realtime clock should be not set.
+ */
+ const rtems_time_of_day *pre_cond_tod;
+
+ /**
+ * @brief This member stores internal clock and context settings of the timer
+ * before the execution of the test action.
+ */
+ Timer_Classes pre_class;
+
+ /**
+ * @brief This member stores the state of the timer before the execution of
+ * the test action.
+ */
+ Timer_States pre_state;
+
+ /**
+ * @brief This member stores the state of the timer after the execution of
+ * the test action.
+ */
+ Timer_States post_state;
+
+ /**
+ * @brief This member stores the scheduling data of the timer before the
+ * execution of the test action.
+ */
+ Timer_Scheduling_Data pre_scheduling_data;
+
+ /**
+ * @brief This member stores the scheduling data of the timer after the
+ * execution of the test action.
+ */
+ Timer_Scheduling_Data post_scheduling_data;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 7 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTimerReqFireWhen_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTimerReqFireWhen_Context;
+
+static RtemsTimerReqFireWhen_Context
+ RtemsTimerReqFireWhen_Instance;
+
+static const char * const RtemsTimerReqFireWhen_PreDesc_RtClock[] = {
+ "Set",
+ "Unset",
+ "NA"
+};
+
+static const char * const RtemsTimerReqFireWhen_PreDesc_Routine[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsTimerReqFireWhen_PreDesc_WallTime[] = {
+ "Valid",
+ "Invalid",
+ "Past",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsTimerReqFireWhen_PreDesc_Id[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTimerReqFireWhen_PreDesc_Context[] = {
+ "None",
+ "Interrupt",
+ "Server",
+ "NA"
+};
+
+static const char * const RtemsTimerReqFireWhen_PreDesc_Clock[] = {
+ "None",
+ "Ticks",
+ "Realtime",
+ "NA"
+};
+
+static const char * const RtemsTimerReqFireWhen_PreDesc_State[] = {
+ "Inactive",
+ "Scheduled",
+ "Pending",
+ "NA"
+};
+
+static const char * const * const RtemsTimerReqFireWhen_PreDesc[] = {
+ RtemsTimerReqFireWhen_PreDesc_RtClock,
+ RtemsTimerReqFireWhen_PreDesc_Routine,
+ RtemsTimerReqFireWhen_PreDesc_WallTime,
+ RtemsTimerReqFireWhen_PreDesc_Id,
+ RtemsTimerReqFireWhen_PreDesc_Context,
+ RtemsTimerReqFireWhen_PreDesc_Clock,
+ RtemsTimerReqFireWhen_PreDesc_State,
+ NULL
+};
+
+static const rtems_time_of_day tod_now = { 2000, 1, 1, 0, 0, 0, 0 };
+static const rtems_time_of_day tod_schedule = { 2000, 1, 1, 5, 0, 0, 0 };
+static const rtems_time_of_day tod_invalid = { 1985, 1, 1, 0, 0, 0, 0 };
+/*
+ * rtems_fire_when() ignores ticks and treads all wall times in the
+ * current second like being in the "past". This border case is tested.
+ */
+static const rtems_time_of_day tod_past = { 2000, 1, 1, 0, 0, 0, 50 };
+
+static void TriggerTimer(
+ const RtemsTimerReqFireWhen_Context *ctx,
+ rtems_time_of_day *tod_fire
+)
+{
+ rtems_time_of_day tod = tod_now;
+ int invocations_old = ctx->invocations;
+ int i;
+
+ /* Fire the timer service routine for ticks and realtime clock */
+ for ( i = 1; i <= SCHEDULE_MAX; ++i ) {
+ ClockTick();
+ }
+
+ for ( i = 1; i < 24; ++i ) {
+ tod.hour = i;
+ T_rsc_success( rtems_clock_set( &tod ) );
+ if ( tod_fire != NULL && ctx->invocations > invocations_old ) {
+ *tod_fire = tod;
+ break;
+ }
+ }
+}
+
+static void TimerServiceRoutine(
+ rtems_id timer_id,
+ void *user_data
+)
+{
+ RtemsTimerReqFireWhen_Context *ctx = user_data;
+ ++( ctx->invocations );
+ ctx->routine_user_data = user_data;
+}
+
+static void RtemsTimerReqFireWhen_Pre_RtClock_Prepare(
+ RtemsTimerReqFireWhen_Context *ctx,
+ RtemsTimerReqFireWhen_Pre_RtClock state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireWhen_Pre_RtClock_Set: {
+ /*
+ * While the realtime clock is set to a valid time-of-day.
+ */
+ ctx->pre_cond_tod = &tod_now;
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_RtClock_Unset: {
+ /*
+ * While the realtime clock has never been set.
+ */
+ ctx->pre_cond_tod = NULL;
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_RtClock_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireWhen_Pre_Routine_Prepare(
+ RtemsTimerReqFireWhen_Context *ctx,
+ RtemsTimerReqFireWhen_Pre_Routine state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireWhen_Pre_Routine_Valid: {
+ /*
+ * While the ``routine`` parameter references an object of type
+ * rtems_timer_service_routine_entry.
+ */
+ ctx->routine_param = TimerServiceRoutine;
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_Routine_Null: {
+ /*
+ * While the ``routine`` parameter is NULL..
+ */
+ ctx->routine_param = NULL;
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_Routine_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireWhen_Pre_WallTime_Prepare(
+ RtemsTimerReqFireWhen_Context *ctx,
+ RtemsTimerReqFireWhen_Pre_WallTime state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireWhen_Pre_WallTime_Valid: {
+ /*
+ * While the ``wall_time`` parameter references a time at least one
+ * second in the future but not later than the last second of the year
+ * 2105. (Times after 2105 are invalid.)
+ */
+ ctx->wall_time_param = &tod_schedule;
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_WallTime_Invalid: {
+ /*
+ * While the ``wall_time`` parameter is invalid.
+ */
+ ctx->wall_time_param = &tod_invalid;
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_WallTime_Past: {
+ /*
+ * While the ``wall_time`` parameter references a time in the current
+ * second or in the past but not earlier than 1988. (Times before 1988
+ * are invalid.)
+ */
+ ctx->wall_time_param = &tod_past;
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_WallTime_Null: {
+ /*
+ * While the ``wall_time`` parameter is 0.
+ */
+ ctx->wall_time_param = NULL;
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_WallTime_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireWhen_Pre_Id_Prepare(
+ RtemsTimerReqFireWhen_Context *ctx,
+ RtemsTimerReqFireWhen_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireWhen_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter is valid.
+ */
+ ctx->id_param = ctx->timer_id;
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is invalid.
+ */
+ ctx->id_param = RTEMS_ID_NONE;
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireWhen_Pre_Context_Prepare(
+ RtemsTimerReqFireWhen_Context *ctx,
+ RtemsTimerReqFireWhen_Pre_Context state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireWhen_Pre_Context_None: {
+ /*
+ * While the Timer Service Routine has never been scheduled since
+ * creation of the timer. See also none.
+ */
+ ctx->pre_cond_contex = PRE_NONE;
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_Context_Interrupt: {
+ /*
+ * While the timer is in interrupt context.
+ */
+ ctx->pre_cond_contex = PRE_INTERRUPT;
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_Context_Server: {
+ /*
+ * While the timer is in server context.
+ */
+ ctx->pre_cond_contex = PRE_SERVER;
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_Context_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireWhen_Pre_Clock_Prepare(
+ RtemsTimerReqFireWhen_Context *ctx,
+ RtemsTimerReqFireWhen_Pre_Clock state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireWhen_Pre_Clock_None: {
+ /*
+ * While the timer has never been scheduled since creation of the timer.
+ */
+ T_eq_int( ctx->pre_cond_contex, PRE_NONE );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_Clock_Ticks: {
+ /*
+ * While the clock used to determine when the timer will fire is the
+ * ticks based clock.
+ */
+ rtems_status_code status;
+
+ if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
+ status = rtems_timer_fire_after(
+ ctx->timer_id,
+ SCHEDULE_SOON,
+ TimerServiceRoutine,
+ ctx
+ );
+ } else {
+ status = rtems_timer_server_fire_after(
+ ctx->timer_id,
+ SCHEDULE_SOON,
+ TimerServiceRoutine,
+ ctx
+ );
+ }
+ T_rsc_success( status );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_Clock_Realtime: {
+ /*
+ * While the clock used to determine when the timer will fire is the
+ * realtime clock.
+ */
+ rtems_status_code status;
+ T_rsc_success( rtems_clock_set( &tod_now ) );
+
+ if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
+ status = rtems_timer_fire_when(
+ ctx->timer_id,
+ &tod_schedule,
+ TimerServiceRoutine,
+ ctx
+ );
+ } else {
+ status = rtems_timer_server_fire_when(
+ ctx->timer_id,
+ &tod_schedule,
+ TimerServiceRoutine,
+ ctx
+ );
+ }
+ T_rsc_success( status );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_Clock_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireWhen_Pre_State_Prepare(
+ RtemsTimerReqFireWhen_Context *ctx,
+ RtemsTimerReqFireWhen_Pre_State state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireWhen_Pre_State_Inactive: {
+ /*
+ * While the timer is in inactive state.
+ */
+ TriggerTimer( ctx, NULL );
+ T_eq_int(
+ ctx->invocations,
+ ( ctx->pre_cond_contex == PRE_NONE ) ? 0 : 1
+ );
+ ctx->invocations = 0;
+ ctx->pre_state = TIMER_INACTIVE;
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_State_Scheduled: {
+ /*
+ * While the timer is in scheduled state.
+ */
+ /* The timer was already scheduled in the "Clock" pre-conditions. */
+ ctx->pre_state = TIMER_SCHEDULED;
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_State_Pending: {
+ /*
+ * While the timer is in pending state.
+ */
+ T_rsc_success( rtems_task_suspend( GetTimerServerTaskId() ) );
+ TriggerTimer( ctx, NULL );
+ T_eq_int( ctx->invocations, 0 );
+ ctx->pre_state = TIMER_PENDING;
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Pre_State_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireWhen_Post_Status_Check(
+ RtemsTimerReqFireWhen_Context *ctx,
+ RtemsTimerReqFireWhen_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireWhen_Post_Status_Ok: {
+ /*
+ * The return status of rtems_timer_fire_when() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_Status_NotDef: {
+ /*
+ * The return status of rtems_timer_fire_when() shall be
+ * RTEMS_NOT_DEFINED
+ */
+ T_rsc( ctx->status, RTEMS_NOT_DEFINED );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_Status_InvId: {
+ /*
+ * The return status of rtems_timer_fire_when() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_timer_fire_when() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_Status_InvClock: {
+ /*
+ * The return status of rtems_timer_fire_when() shall be
+ * RTEMS_INVALID_CLOCK.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_CLOCK );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireWhen_Post_Context_Check(
+ RtemsTimerReqFireWhen_Context *ctx,
+ RtemsTimerReqFireWhen_Post_Context state
+)
+{
+ Timer_Classes class;
+ class = GetTimerClass( ctx->timer_id );
+
+ switch ( state ) {
+ case RtemsTimerReqFireWhen_Post_Context_None: {
+ /*
+ * The timer shall have never been scheduled. See also none.
+ */
+ T_eq_int( class, TIMER_DORMANT );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_Context_Interrupt: {
+ /*
+ * The timer shall be in interrupt context.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, 0 );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_Context_Server: {
+ /*
+ * The timer shall be in server context.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, TIMER_CLASS_BIT_ON_TASK );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_Context_Nop: {
+ /*
+ * Objects referenced by parameters in the past call to
+ * rtems_timer_fire_when() shall not be accessed by the
+ * rtems_timer_fire_when() call. See also Nop.
+ */
+ T_eq_int( class, ctx->pre_class );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_Context_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireWhen_Post_Clock_Check(
+ RtemsTimerReqFireWhen_Context *ctx,
+ RtemsTimerReqFireWhen_Post_Clock state
+)
+{
+ Timer_Classes class;
+ class = GetTimerClass( ctx->timer_id );
+
+ switch ( state ) {
+ case RtemsTimerReqFireWhen_Post_Clock_None: {
+ /*
+ * The timer shall have never been scheduled.
+ */
+ T_eq_int( class, TIMER_DORMANT );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_Clock_Ticks: {
+ /*
+ * The timer shall use the ticks based clock.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_TIME_OF_DAY, 0 );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_Clock_Realtime: {
+ /*
+ * The timer shall use the realtime clock.
+ */
+ T_eq_int(
+ class & TIMER_CLASS_BIT_TIME_OF_DAY,
+ TIMER_CLASS_BIT_TIME_OF_DAY
+ );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_Clock_Nop: {
+ /*
+ * Objects referenced by parameters in the past call to
+ * rtems_timer_fire_when() shall not be accessed by the
+ * rtems_timer_fire_when() call.
+ */
+ T_eq_int( class, ctx->pre_class );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_Clock_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireWhen_Post_State_Check(
+ RtemsTimerReqFireWhen_Context *ctx,
+ RtemsTimerReqFireWhen_Post_State state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireWhen_Post_State_Scheduled: {
+ /*
+ * The timer shall be in scheduled state.
+ */
+ TriggerTimer( ctx, &ctx->tod_till_fire );
+ T_eq_int( ctx->invocations, 1 );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_State_Nop: {
+ /*
+ * Objects referenced by parameters in the past call to
+ * rtems_timer_fire_when() shall not be accessed by the
+ * rtems_timer_fire_when() call.
+ */
+ T_eq_int( ctx->post_state, ctx->pre_state );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_State_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireWhen_Post_WallTime_Check(
+ RtemsTimerReqFireWhen_Context *ctx,
+ RtemsTimerReqFireWhen_Post_WallTime state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireWhen_Post_WallTime_Param: {
+ /*
+ * The Timer Service Routine shall be invoked at the wall time (see
+ * realtime clock) (ignoring ticks), which was provided by the
+ * ``wall_time`` parameter in the past call to rtems_timer_fire_when().
+ */
+ T_eq_mem(
+ &ctx->tod_till_fire,
+ ctx->wall_time_param,
+ sizeof( ctx->tod_till_fire )
+ );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_WallTime_Nop: {
+ /*
+ * If and when the Timer Service Routine will be invoked shall not be
+ * changed by the past call to rtems_timer_fire_when().
+ */
+ /*
+ * Whether the timer is scheduled has already been tested by the
+ * "Nop" "State" post-condition above.
+ */
+ T_eq_u32(
+ ctx->post_scheduling_data.interval,
+ ctx->pre_scheduling_data.interval
+ );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_WallTime_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireWhen_Post_Routine_Check(
+ RtemsTimerReqFireWhen_Context *ctx,
+ RtemsTimerReqFireWhen_Post_Routine state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireWhen_Post_Routine_Param: {
+ /*
+ * The function reference used to invoke the Timer Service Routine when
+ * the timer will fire shall be the one provided by the ``routine``
+ * parameter in the past call to rtems_timer_fire_when().
+ */
+ T_eq_int( ctx->invocations, 1 );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_Routine_Nop: {
+ /*
+ * The function reference used for any invocation of the Timer Service
+ * Routine shall not be changed by the past call to
+ * rtems_timer_fire_when().
+ */
+ T_eq_ptr(
+ ctx->post_scheduling_data.routine,
+ ctx->pre_scheduling_data.routine
+ );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_Routine_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireWhen_Post_UserData_Check(
+ RtemsTimerReqFireWhen_Context *ctx,
+ RtemsTimerReqFireWhen_Post_UserData state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqFireWhen_Post_UserData_Param: {
+ /*
+ * The user data argument for invoking the Timer Service Routine when the
+ * timer will fire shall be the one provided by the ``user_data``
+ * parameter in the past call to rtems_timer_fire_when().
+ */
+ T_eq_ptr( ctx->routine_user_data, ctx );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_UserData_Nop: {
+ /*
+ * The user data argument used for any invocation of the Timer Service
+ * Routine shall not be changed by the past call to
+ * rtems_timer_fire_when().
+ */
+ T_eq_ptr(
+ ctx->post_scheduling_data.user_data,
+ ctx->pre_scheduling_data.user_data
+ );
+ break;
+ }
+
+ case RtemsTimerReqFireWhen_Post_UserData_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqFireWhen_Setup( RtemsTimerReqFireWhen_Context *ctx )
+{
+ rtems_status_code status;
+ status = rtems_timer_initiate_server(
+ RTEMS_TIMER_SERVER_DEFAULT_PRIORITY,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_ATTRIBUTES
+ );
+ T_rsc_success( status );
+}
+
+static void RtemsTimerReqFireWhen_Setup_Wrap( void *arg )
+{
+ RtemsTimerReqFireWhen_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTimerReqFireWhen_Setup( ctx );
+}
+
+/**
+ * @brief Make sure the timer server is not running and the realtime clock is
+ * not set after this test.
+ */
+static void RtemsTimerReqFireWhen_Teardown(
+ RtemsTimerReqFireWhen_Context *ctx
+)
+{
+ DeleteTimerServer();
+ UnsetClock();
+}
+
+static void RtemsTimerReqFireWhen_Teardown_Wrap( void *arg )
+{
+ RtemsTimerReqFireWhen_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTimerReqFireWhen_Teardown( ctx );
+}
+
+static void RtemsTimerReqFireWhen_Prepare( RtemsTimerReqFireWhen_Context *ctx )
+{
+ rtems_status_code status;
+ status = rtems_timer_create(
+ rtems_build_name( 'T', 'I', 'M', 'E' ),
+ &ctx->timer_id
+ );
+ T_rsc_success( status );
+
+ ctx->invocations = 0;
+ ctx->routine_user_data = NULL;
+}
+
+static void RtemsTimerReqFireWhen_Action( RtemsTimerReqFireWhen_Context *ctx )
+{
+ GetTimerSchedulingData( ctx->timer_id, &ctx->pre_scheduling_data );
+ ctx->pre_class = GetTimerClass( ctx->timer_id );
+ if ( ctx->pre_cond_tod == NULL ) {
+ UnsetClock();
+ } else {
+ T_rsc_success( rtems_clock_set( ctx->pre_cond_tod ) );
+ }
+ ctx->status = rtems_timer_fire_when(
+ ctx->id_param,
+ ctx->wall_time_param,
+ ctx->routine_param,
+ ctx
+ );
+ ctx->post_state = GetTimerState( ctx->timer_id );
+ GetTimerSchedulingData( ctx->timer_id, &ctx->post_scheduling_data );
+ /* Ignoring return status: the timer server task may be suspended or not. */
+ rtems_task_resume( GetTimerServerTaskId() );
+}
+
+static void RtemsTimerReqFireWhen_Cleanup( RtemsTimerReqFireWhen_Context *ctx )
+{
+ T_rsc_success( rtems_timer_delete( ctx->timer_id ) );
+}
+
+static const RtemsTimerReqFireWhen_Entry
+RtemsTimerReqFireWhen_Entries[] = {
+ { 1, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireWhen_Post_Status_NA,
+ RtemsTimerReqFireWhen_Post_Context_NA, RtemsTimerReqFireWhen_Post_Clock_NA,
+ RtemsTimerReqFireWhen_Post_State_NA,
+ RtemsTimerReqFireWhen_Post_WallTime_NA,
+ RtemsTimerReqFireWhen_Post_Routine_NA,
+ RtemsTimerReqFireWhen_Post_UserData_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireWhen_Post_Status_InvAddr,
+ RtemsTimerReqFireWhen_Post_Context_Nop,
+ RtemsTimerReqFireWhen_Post_Clock_Nop, RtemsTimerReqFireWhen_Post_State_Nop,
+ RtemsTimerReqFireWhen_Post_WallTime_Nop,
+ RtemsTimerReqFireWhen_Post_Routine_Nop,
+ RtemsTimerReqFireWhen_Post_UserData_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireWhen_Post_Status_NotDef,
+ RtemsTimerReqFireWhen_Post_Context_Nop,
+ RtemsTimerReqFireWhen_Post_Clock_Nop, RtemsTimerReqFireWhen_Post_State_Nop,
+ RtemsTimerReqFireWhen_Post_WallTime_Nop,
+ RtemsTimerReqFireWhen_Post_Routine_Nop,
+ RtemsTimerReqFireWhen_Post_UserData_Nop },
+ { 1, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireWhen_Post_Status_NA,
+ RtemsTimerReqFireWhen_Post_Context_NA, RtemsTimerReqFireWhen_Post_Clock_NA,
+ RtemsTimerReqFireWhen_Post_State_NA,
+ RtemsTimerReqFireWhen_Post_WallTime_NA,
+ RtemsTimerReqFireWhen_Post_Routine_NA,
+ RtemsTimerReqFireWhen_Post_UserData_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireWhen_Post_Status_InvClock,
+ RtemsTimerReqFireWhen_Post_Context_Nop,
+ RtemsTimerReqFireWhen_Post_Clock_Nop, RtemsTimerReqFireWhen_Post_State_Nop,
+ RtemsTimerReqFireWhen_Post_WallTime_Nop,
+ RtemsTimerReqFireWhen_Post_Routine_Nop,
+ RtemsTimerReqFireWhen_Post_UserData_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireWhen_Post_Status_Ok,
+ RtemsTimerReqFireWhen_Post_Context_Interrupt,
+ RtemsTimerReqFireWhen_Post_Clock_Realtime,
+ RtemsTimerReqFireWhen_Post_State_Scheduled,
+ RtemsTimerReqFireWhen_Post_WallTime_Param,
+ RtemsTimerReqFireWhen_Post_Routine_Param,
+ RtemsTimerReqFireWhen_Post_UserData_Param },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqFireWhen_Post_Status_InvId,
+ RtemsTimerReqFireWhen_Post_Context_Nop,
+ RtemsTimerReqFireWhen_Post_Clock_Nop, RtemsTimerReqFireWhen_Post_State_Nop,
+ RtemsTimerReqFireWhen_Post_WallTime_Nop,
+ RtemsTimerReqFireWhen_Post_Routine_Nop,
+ RtemsTimerReqFireWhen_Post_UserData_Nop }
+};
+
+static const uint8_t
+RtemsTimerReqFireWhen_Map[] = {
+ 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5,
+ 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 6, 6, 0, 0, 0, 0, 6, 6, 6, 6,
+ 6, 6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0, 4, 4, 4,
+ 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0, 4, 4,
+ 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0, 4,
+ 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0,
+ 4, 4, 4, 4, 4, 4, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1,
+ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1,
+ 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,
+ 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
+ 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+ 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3, 3,
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3, 3,
+ 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2, 3,
+ 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2, 2,
+ 3, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2, 2,
+ 2, 3, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0, 2,
+ 2, 2, 3, 3, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 3, 3, 3, 0, 0, 0,
+ 2, 2, 2, 3, 3, 3
+};
+
+static size_t RtemsTimerReqFireWhen_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTimerReqFireWhen_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsTimerReqFireWhen_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTimerReqFireWhen_Fixture = {
+ .setup = RtemsTimerReqFireWhen_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTimerReqFireWhen_Teardown_Wrap,
+ .scope = RtemsTimerReqFireWhen_Scope,
+ .initial_context = &RtemsTimerReqFireWhen_Instance
+};
+
+static inline RtemsTimerReqFireWhen_Entry RtemsTimerReqFireWhen_PopEntry(
+ RtemsTimerReqFireWhen_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTimerReqFireWhen_Entries[
+ RtemsTimerReqFireWhen_Map[ index ]
+ ];
+}
+
+static void RtemsTimerReqFireWhen_TestVariant(
+ RtemsTimerReqFireWhen_Context *ctx
+)
+{
+ RtemsTimerReqFireWhen_Pre_RtClock_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTimerReqFireWhen_Pre_Routine_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTimerReqFireWhen_Pre_WallTime_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTimerReqFireWhen_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsTimerReqFireWhen_Pre_Context_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsTimerReqFireWhen_Pre_Clock_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsTimerReqFireWhen_Pre_State_Prepare( ctx, ctx->Map.pcs[ 6 ] );
+ RtemsTimerReqFireWhen_Action( ctx );
+ RtemsTimerReqFireWhen_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsTimerReqFireWhen_Post_Context_Check( ctx, ctx->Map.entry.Post_Context );
+ RtemsTimerReqFireWhen_Post_Clock_Check( ctx, ctx->Map.entry.Post_Clock );
+ RtemsTimerReqFireWhen_Post_State_Check( ctx, ctx->Map.entry.Post_State );
+ RtemsTimerReqFireWhen_Post_WallTime_Check(
+ ctx,
+ ctx->Map.entry.Post_WallTime
+ );
+ RtemsTimerReqFireWhen_Post_Routine_Check( ctx, ctx->Map.entry.Post_Routine );
+ RtemsTimerReqFireWhen_Post_UserData_Check(
+ ctx,
+ ctx->Map.entry.Post_UserData
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsTimerReqFireWhen( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTimerReqFireWhen, &RtemsTimerReqFireWhen_Fixture )
+{
+ RtemsTimerReqFireWhen_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsTimerReqFireWhen_Pre_RtClock_Set;
+ ctx->Map.pcs[ 0 ] < RtemsTimerReqFireWhen_Pre_RtClock_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsTimerReqFireWhen_Pre_Routine_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsTimerReqFireWhen_Pre_Routine_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsTimerReqFireWhen_Pre_WallTime_Valid;
+ ctx->Map.pcs[ 2 ] < RtemsTimerReqFireWhen_Pre_WallTime_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsTimerReqFireWhen_Pre_Id_Valid;
+ ctx->Map.pcs[ 3 ] < RtemsTimerReqFireWhen_Pre_Id_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = RtemsTimerReqFireWhen_Pre_Context_None;
+ ctx->Map.pcs[ 4 ] < RtemsTimerReqFireWhen_Pre_Context_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 5 ] = RtemsTimerReqFireWhen_Pre_Clock_None;
+ ctx->Map.pcs[ 5 ] < RtemsTimerReqFireWhen_Pre_Clock_NA;
+ ++ctx->Map.pcs[ 5 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 6 ] = RtemsTimerReqFireWhen_Pre_State_Inactive;
+ ctx->Map.pcs[ 6 ] < RtemsTimerReqFireWhen_Pre_State_NA;
+ ++ctx->Map.pcs[ 6 ]
+ ) {
+ ctx->Map.entry = RtemsTimerReqFireWhen_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsTimerReqFireWhen_Prepare( ctx );
+ RtemsTimerReqFireWhen_TestVariant( ctx );
+ RtemsTimerReqFireWhen_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-timer-ident.c b/testsuites/validation/tc-timer-ident.c
new file mode 100644
index 0000000000..e39ec73b9a
--- /dev/null
+++ b/testsuites/validation/tc-timer-ident.c
@@ -0,0 +1,117 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTimerValIdent
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-object-ident-local.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTimerValIdent spec:/rtems/timer/val/ident
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Test the rtems_timer_ident() directive.
+ *
+ * This test case performs the following actions:
+ *
+ * - Run the generic object identification tests for Classic API timer class
+ * objects defined by spec:/rtems/req/ident-local.
+ *
+ * @{
+ */
+
+#define NAME_LOCAL_OBJECT rtems_build_name( 'T', 'I', 'M', 'R' )
+
+static rtems_status_code ClassicTimerIdentAction(
+ rtems_name name,
+ rtems_id *id
+)
+{
+ return rtems_timer_ident( name, id );
+}
+
+/**
+ * @brief Run the generic object identification tests for Classic API timer
+ * class objects defined by spec:/rtems/req/ident-local.
+ */
+static void RtemsTimerValIdent_Action_0( void )
+{
+ rtems_status_code sc;
+ rtems_id id_local_object;
+
+ sc = rtems_timer_create(
+ NAME_LOCAL_OBJECT,
+ &id_local_object
+ );
+ T_assert_rsc_success( sc );
+
+ RtemsReqIdentLocal_Run(
+ id_local_object,
+ NAME_LOCAL_OBJECT,
+ ClassicTimerIdentAction
+ );
+
+ sc = rtems_timer_delete( id_local_object );
+ T_rsc_success( sc );
+}
+
+/**
+ * @fn void T_case_body_RtemsTimerValIdent( void )
+ */
+T_TEST_CASE( RtemsTimerValIdent )
+{
+ RtemsTimerValIdent_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-timer-initiate-server.c b/testsuites/validation/tc-timer-initiate-server.c
new file mode 100644
index 0000000000..7a21a3a10b
--- /dev/null
+++ b/testsuites/validation/tc-timer-initiate-server.c
@@ -0,0 +1,816 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTimerReqInitiateServer
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/rtems/timerimpl.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTimerReqInitiateServer spec:/rtems/timer/req/initiate-server
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTimerReqInitiateServer_Pre_Priority_Valid,
+ RtemsTimerReqInitiateServer_Pre_Priority_Default,
+ RtemsTimerReqInitiateServer_Pre_Priority_Invalid,
+ RtemsTimerReqInitiateServer_Pre_Priority_NA
+} RtemsTimerReqInitiateServer_Pre_Priority;
+
+typedef enum {
+ RtemsTimerReqInitiateServer_Pre_Stack_Allocatable,
+ RtemsTimerReqInitiateServer_Pre_Stack_TooLarge,
+ RtemsTimerReqInitiateServer_Pre_Stack_NA
+} RtemsTimerReqInitiateServer_Pre_Stack;
+
+typedef enum {
+ RtemsTimerReqInitiateServer_Pre_Started_Yes,
+ RtemsTimerReqInitiateServer_Pre_Started_No,
+ RtemsTimerReqInitiateServer_Pre_Started_NA
+} RtemsTimerReqInitiateServer_Pre_Started;
+
+typedef enum {
+ RtemsTimerReqInitiateServer_Pre_TaskObj_Available,
+ RtemsTimerReqInitiateServer_Pre_TaskObj_Unavailable,
+ RtemsTimerReqInitiateServer_Pre_TaskObj_NA
+} RtemsTimerReqInitiateServer_Pre_TaskObj;
+
+typedef enum {
+ RtemsTimerReqInitiateServer_Post_Status_Ok,
+ RtemsTimerReqInitiateServer_Post_Status_IncStat,
+ RtemsTimerReqInitiateServer_Post_Status_InvPrio,
+ RtemsTimerReqInitiateServer_Post_Status_TooMany,
+ RtemsTimerReqInitiateServer_Post_Status_Unsat,
+ RtemsTimerReqInitiateServer_Post_Status_NA
+} RtemsTimerReqInitiateServer_Post_Status;
+
+typedef enum {
+ RtemsTimerReqInitiateServer_Post_Started_Yes,
+ RtemsTimerReqInitiateServer_Post_Started_No,
+ RtemsTimerReqInitiateServer_Post_Started_NA
+} RtemsTimerReqInitiateServer_Post_Started;
+
+typedef enum {
+ RtemsTimerReqInitiateServer_Post_TaskPrio_Set,
+ RtemsTimerReqInitiateServer_Post_TaskPrio_Nop,
+ RtemsTimerReqInitiateServer_Post_TaskPrio_NA
+} RtemsTimerReqInitiateServer_Post_TaskPrio;
+
+typedef enum {
+ RtemsTimerReqInitiateServer_Post_TaskStack_Set,
+ RtemsTimerReqInitiateServer_Post_TaskStack_Nop,
+ RtemsTimerReqInitiateServer_Post_TaskStack_NA
+} RtemsTimerReqInitiateServer_Post_TaskStack;
+
+typedef enum {
+ RtemsTimerReqInitiateServer_Post_TaskAttr_Set,
+ RtemsTimerReqInitiateServer_Post_TaskAttr_Nop,
+ RtemsTimerReqInitiateServer_Post_TaskAttr_NA
+} RtemsTimerReqInitiateServer_Post_TaskAttr;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Priority_NA : 1;
+ uint16_t Pre_Stack_NA : 1;
+ uint16_t Pre_Started_NA : 1;
+ uint16_t Pre_TaskObj_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_Started : 2;
+ uint16_t Post_TaskPrio : 2;
+ uint16_t Post_TaskStack : 2;
+ uint16_t Post_TaskAttr : 2;
+} RtemsTimerReqInitiateServer_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/timer/req/initiate-server test case.
+ */
+typedef struct {
+ /**
+ * @brief If the Timer Server task exists before the action, its priority
+ * before the action.
+ */
+ rtems_task_priority before_priority;
+
+ /**
+ * @brief If the Timer Server task exists before the action, its stack size
+ * before the action.
+ */
+ size_t before_stack_size;
+
+ /**
+ * @brief If the Timer Server task exists before the action, whether the
+ * floating point attribute is set before the action.
+ */
+ bool before_has_floating_point;
+
+ /**
+ * @brief The ``priority`` parameter for the action.
+ */
+ rtems_task_priority priority;
+
+ /**
+ * @brief The ``stack_size`` parameter for the action.
+ */
+ size_t stack_size;
+
+ /**
+ * @brief The status value returned by the action
+ * rtems_timer_initiate_server().
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member is used by the T_seize_objects() and
+ * T_surrender_objects() support functions.
+ */
+ void *task_objects;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 4 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTimerReqInitiateServer_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTimerReqInitiateServer_Context;
+
+static RtemsTimerReqInitiateServer_Context
+ RtemsTimerReqInitiateServer_Instance;
+
+static const char * const RtemsTimerReqInitiateServer_PreDesc_Priority[] = {
+ "Valid",
+ "Default",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTimerReqInitiateServer_PreDesc_Stack[] = {
+ "Allocatable",
+ "TooLarge",
+ "NA"
+};
+
+static const char * const RtemsTimerReqInitiateServer_PreDesc_Started[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const RtemsTimerReqInitiateServer_PreDesc_TaskObj[] = {
+ "Available",
+ "Unavailable",
+ "NA"
+};
+
+static const char * const * const RtemsTimerReqInitiateServer_PreDesc[] = {
+ RtemsTimerReqInitiateServer_PreDesc_Priority,
+ RtemsTimerReqInitiateServer_PreDesc_Stack,
+ RtemsTimerReqInitiateServer_PreDesc_Started,
+ RtemsTimerReqInitiateServer_PreDesc_TaskObj,
+ NULL
+};
+
+static bool ExistTimerServer( void )
+{
+ return GetTimerServerTaskId() != RTEMS_INVALID_ID;
+}
+
+static rtems_task_priority GetTimerServerPriority( void )
+{
+ return GetPriority( GetTimerServerTaskId() );
+}
+
+static size_t GetTimerServerStackSize( void )
+{
+ rtems_tcb *tcb;
+ rtems_id server_task_id;
+ server_task_id = GetTimerServerTaskId();
+ T_ne_u32( server_task_id, RTEMS_INVALID_ID );
+ tcb = GetThread( server_task_id );
+ T_not_null( tcb );
+ return tcb->Start.Initial_stack.size;
+}
+
+static bool HasTimerServerFloatingPoint( void )
+{
+ rtems_tcb *tcb;
+ rtems_id server_task_id;
+ server_task_id = GetTimerServerTaskId();
+ T_ne_u32( server_task_id, RTEMS_INVALID_ID );
+ tcb = GetThread( server_task_id );
+ T_not_null( tcb );
+ return tcb->is_fp;
+}
+
+static rtems_status_code AllocateTaskObject( void *arg, rtems_id *task_id )
+{
+ (void) arg;
+
+ return rtems_task_create(
+ rtems_build_name( 'T', 'A', ' ', 'N' ),
+ PRIO_LOW,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_MODES,
+ RTEMS_DEFAULT_ATTRIBUTES,
+ task_id
+ );
+}
+
+static void RtemsTimerReqInitiateServer_Pre_Priority_Prepare(
+ RtemsTimerReqInitiateServer_Context *ctx,
+ RtemsTimerReqInitiateServer_Pre_Priority state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqInitiateServer_Pre_Priority_Valid: {
+ /*
+ * While the ``priority`` parameter is valid.
+ */
+ ctx->priority = 13;
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Pre_Priority_Default: {
+ /*
+ * While the ``priority`` parameter is equal to
+ * RTEMS_TIMER_SERVER_DEFAULT_PRIORITY.
+ */
+ ctx->priority = RTEMS_TIMER_SERVER_DEFAULT_PRIORITY;
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Pre_Priority_Invalid: {
+ /*
+ * While the ``priority`` parameter is invalid.
+ */
+ ctx->priority = PRIO_INVALID;
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Pre_Priority_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqInitiateServer_Pre_Stack_Prepare(
+ RtemsTimerReqInitiateServer_Context *ctx,
+ RtemsTimerReqInitiateServer_Pre_Stack state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqInitiateServer_Pre_Stack_Allocatable: {
+ /*
+ * While the ``stack_size`` parameter specifies a task stack size which
+ * is allocatable by the system.
+ */
+ ctx->stack_size = RTEMS_MINIMUM_STACK_SIZE;
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Pre_Stack_TooLarge: {
+ /*
+ * While the ``stack_size`` parameter specifies a task stack size which
+ * is not allocatable by the system.
+ */
+ ctx->stack_size = SIZE_MAX;
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Pre_Stack_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqInitiateServer_Pre_Started_Prepare(
+ RtemsTimerReqInitiateServer_Context *ctx,
+ RtemsTimerReqInitiateServer_Pre_Started state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqInitiateServer_Pre_Started_Yes: {
+ /*
+ * While the Timer Server task is started.
+ */
+ rtems_status_code status;
+
+ if ( !ExistTimerServer() ) {
+ status = rtems_timer_initiate_server(
+ RTEMS_TIMER_SERVER_DEFAULT_PRIORITY,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_ATTRIBUTES
+ );
+ T_rsc_success( status );
+ }
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Pre_Started_No: {
+ /*
+ * While the Timer Server task is not started.
+ */
+ DeleteTimerServer();
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Pre_Started_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqInitiateServer_Pre_TaskObj_Prepare(
+ RtemsTimerReqInitiateServer_Context *ctx,
+ RtemsTimerReqInitiateServer_Pre_TaskObj state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqInitiateServer_Pre_TaskObj_Available: {
+ /*
+ * While the system has at least one inactive task object available.
+ */
+ /* The test clean up ensures that all tasks objects are free. */
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Pre_TaskObj_Unavailable: {
+ /*
+ * While the system has no inactive task object available.
+ */
+ ctx->task_objects = T_seize_objects(
+ AllocateTaskObject,
+ NULL
+ );
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Pre_TaskObj_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqInitiateServer_Post_Status_Check(
+ RtemsTimerReqInitiateServer_Context *ctx,
+ RtemsTimerReqInitiateServer_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqInitiateServer_Post_Status_Ok: {
+ /*
+ * The return status of rtems_timer_initiate_server() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Post_Status_IncStat: {
+ /*
+ * The return status of rtems_timer_initiate_server() shall be
+ * RTEMS_INCORRECT_STATE
+ */
+ T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Post_Status_InvPrio: {
+ /*
+ * The return status of rtems_timer_initiate_server() shall be
+ * RTEMS_INVALID_PRIORITY.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_PRIORITY );
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Post_Status_TooMany: {
+ /*
+ * The return status of rtems_timer_initiate_server() shall be
+ * RTEMS_TOO_MANY.
+ */
+ T_rsc( ctx->status, RTEMS_TOO_MANY );
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Post_Status_Unsat: {
+ /*
+ * The return status of rtems_timer_initiate_server() shall be
+ * RTEMS_UNSATISFIED.
+ */
+ T_rsc( ctx->status, RTEMS_UNSATISFIED );
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqInitiateServer_Post_Started_Check(
+ RtemsTimerReqInitiateServer_Context *ctx,
+ RtemsTimerReqInitiateServer_Post_Started state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqInitiateServer_Post_Started_Yes: {
+ /*
+ * The Timer Server task shall be started after the
+ * rtems_timer_initiate_server() call.
+ */
+ T_true( ExistTimerServer() );
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Post_Started_No: {
+ /*
+ * The Timer Server task shall not be started after the
+ * rtems_timer_initiate_server() call.
+ */
+ T_false( ExistTimerServer() );
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Post_Started_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqInitiateServer_Post_TaskPrio_Check(
+ RtemsTimerReqInitiateServer_Context *ctx,
+ RtemsTimerReqInitiateServer_Post_TaskPrio state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqInitiateServer_Post_TaskPrio_Set: {
+ /*
+ * The priority of the Timer Server task shall be equal to the priority
+ * specified by the ``priority`` parameter in the
+ * rtems_timer_initiate_server() call.
+ */
+ if ( ctx->priority == RTEMS_TIMER_SERVER_DEFAULT_PRIORITY ) {
+ T_eq_u32( GetTimerServerPriority(), 0 );
+ } else {
+ T_eq_u32( GetTimerServerPriority(), ctx->priority );
+ }
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Post_TaskPrio_Nop: {
+ /*
+ * The priority of the Timer Server task shall not be modified by the
+ * rtems_timer_initiate_server() call.
+ */
+ T_eq_u32( GetTimerServerPriority(), ctx->before_priority );
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Post_TaskPrio_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqInitiateServer_Post_TaskStack_Check(
+ RtemsTimerReqInitiateServer_Context *ctx,
+ RtemsTimerReqInitiateServer_Post_TaskStack state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqInitiateServer_Post_TaskStack_Set: {
+ /*
+ * The stack size of the Timer Server task shall be greater than or equal
+ * to the stack size specified by the ``stack_size`` parameter in the
+ * rtems_timer_initiate_server() call.
+ */
+ T_ge_sz( GetTimerServerStackSize(), ctx->stack_size );
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Post_TaskStack_Nop: {
+ /*
+ * The stack size of the Timer Server task shall not be modified by the
+ * rtems_timer_initiate_server() call.
+ */
+ T_ge_sz( GetTimerServerStackSize(), ctx->before_stack_size );
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Post_TaskStack_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqInitiateServer_Post_TaskAttr_Check(
+ RtemsTimerReqInitiateServer_Context *ctx,
+ RtemsTimerReqInitiateServer_Post_TaskAttr state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqInitiateServer_Post_TaskAttr_Set: {
+ /*
+ * The task attributes of the Timer Server task shall be specified by the
+ * ``attribute_set`` parameter in the rtems_timer_initiate_server() call.
+ */
+ T_true( HasTimerServerFloatingPoint() );
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Post_TaskAttr_Nop: {
+ /*
+ * The task attributes of the Timer Server task shall not be modified by
+ * the rtems_timer_initiate_server() call.
+ */
+ T_true( HasTimerServerFloatingPoint() == ctx->before_has_floating_point );
+ break;
+ }
+
+ case RtemsTimerReqInitiateServer_Post_TaskAttr_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqInitiateServer_Setup(
+ RtemsTimerReqInitiateServer_Context *ctx
+)
+{
+ ctx->task_objects = NULL;
+}
+
+static void RtemsTimerReqInitiateServer_Setup_Wrap( void *arg )
+{
+ RtemsTimerReqInitiateServer_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTimerReqInitiateServer_Setup( ctx );
+}
+
+/**
+ * @brief Make sure the time server in not running after this test.
+ */
+static void RtemsTimerReqInitiateServer_Teardown(
+ RtemsTimerReqInitiateServer_Context *ctx
+)
+{
+ DeleteTimerServer();
+}
+
+static void RtemsTimerReqInitiateServer_Teardown_Wrap( void *arg )
+{
+ RtemsTimerReqInitiateServer_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTimerReqInitiateServer_Teardown( ctx );
+}
+
+static void RtemsTimerReqInitiateServer_Action(
+ RtemsTimerReqInitiateServer_Context *ctx
+)
+{
+ if ( ExistTimerServer() ) {
+ ctx->before_priority = GetTimerServerPriority();
+ ctx->before_stack_size = GetTimerServerStackSize();
+ ctx->before_has_floating_point = HasTimerServerFloatingPoint();
+ }
+
+ ctx->status = rtems_timer_initiate_server(
+ ctx->priority,
+ ctx->stack_size,
+ RTEMS_FLOATING_POINT
+ );
+}
+
+static void RtemsTimerReqInitiateServer_Cleanup(
+ RtemsTimerReqInitiateServer_Context *ctx
+)
+{
+ T_surrender_objects( &ctx->task_objects, rtems_task_delete );
+}
+
+static const RtemsTimerReqInitiateServer_Entry
+RtemsTimerReqInitiateServer_Entries[] = {
+ { 0, 0, 0, 0, 0, RtemsTimerReqInitiateServer_Post_Status_IncStat,
+ RtemsTimerReqInitiateServer_Post_Started_Yes,
+ RtemsTimerReqInitiateServer_Post_TaskPrio_Nop,
+ RtemsTimerReqInitiateServer_Post_TaskStack_Nop,
+ RtemsTimerReqInitiateServer_Post_TaskAttr_Nop },
+ { 0, 0, 0, 0, 0, RtemsTimerReqInitiateServer_Post_Status_TooMany,
+ RtemsTimerReqInitiateServer_Post_Started_No,
+ RtemsTimerReqInitiateServer_Post_TaskPrio_NA,
+ RtemsTimerReqInitiateServer_Post_TaskStack_NA,
+ RtemsTimerReqInitiateServer_Post_TaskAttr_NA },
+ { 0, 0, 0, 0, 0, RtemsTimerReqInitiateServer_Post_Status_InvPrio,
+ RtemsTimerReqInitiateServer_Post_Started_No,
+ RtemsTimerReqInitiateServer_Post_TaskPrio_NA,
+ RtemsTimerReqInitiateServer_Post_TaskStack_NA,
+ RtemsTimerReqInitiateServer_Post_TaskAttr_NA },
+ { 0, 0, 0, 0, 0, RtemsTimerReqInitiateServer_Post_Status_Ok,
+ RtemsTimerReqInitiateServer_Post_Started_Yes,
+ RtemsTimerReqInitiateServer_Post_TaskPrio_Set,
+ RtemsTimerReqInitiateServer_Post_TaskStack_Set,
+ RtemsTimerReqInitiateServer_Post_TaskAttr_Set },
+ { 0, 0, 0, 0, 0, RtemsTimerReqInitiateServer_Post_Status_Unsat,
+ RtemsTimerReqInitiateServer_Post_Started_No,
+ RtemsTimerReqInitiateServer_Post_TaskPrio_NA,
+ RtemsTimerReqInitiateServer_Post_TaskStack_NA,
+ RtemsTimerReqInitiateServer_Post_TaskAttr_NA }
+};
+
+static const uint8_t
+RtemsTimerReqInitiateServer_Map[] = {
+ 0, 0, 3, 1, 0, 0, 4, 1, 0, 0, 3, 1, 0, 0, 4, 1, 0, 0, 2, 2, 0, 0, 2, 2
+};
+
+static size_t RtemsTimerReqInitiateServer_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ RtemsTimerReqInitiateServer_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsTimerReqInitiateServer_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTimerReqInitiateServer_Fixture = {
+ .setup = RtemsTimerReqInitiateServer_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTimerReqInitiateServer_Teardown_Wrap,
+ .scope = RtemsTimerReqInitiateServer_Scope,
+ .initial_context = &RtemsTimerReqInitiateServer_Instance
+};
+
+static inline RtemsTimerReqInitiateServer_Entry
+RtemsTimerReqInitiateServer_PopEntry(
+ RtemsTimerReqInitiateServer_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTimerReqInitiateServer_Entries[
+ RtemsTimerReqInitiateServer_Map[ index ]
+ ];
+}
+
+static void RtemsTimerReqInitiateServer_TestVariant(
+ RtemsTimerReqInitiateServer_Context *ctx
+)
+{
+ RtemsTimerReqInitiateServer_Pre_Priority_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTimerReqInitiateServer_Pre_Stack_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTimerReqInitiateServer_Pre_Started_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTimerReqInitiateServer_Pre_TaskObj_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsTimerReqInitiateServer_Action( ctx );
+ RtemsTimerReqInitiateServer_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ RtemsTimerReqInitiateServer_Post_Started_Check(
+ ctx,
+ ctx->Map.entry.Post_Started
+ );
+ RtemsTimerReqInitiateServer_Post_TaskPrio_Check(
+ ctx,
+ ctx->Map.entry.Post_TaskPrio
+ );
+ RtemsTimerReqInitiateServer_Post_TaskStack_Check(
+ ctx,
+ ctx->Map.entry.Post_TaskStack
+ );
+ RtemsTimerReqInitiateServer_Post_TaskAttr_Check(
+ ctx,
+ ctx->Map.entry.Post_TaskAttr
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsTimerReqInitiateServer( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTimerReqInitiateServer,
+ &RtemsTimerReqInitiateServer_Fixture
+)
+{
+ RtemsTimerReqInitiateServer_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsTimerReqInitiateServer_Pre_Priority_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsTimerReqInitiateServer_Pre_Priority_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsTimerReqInitiateServer_Pre_Stack_Allocatable;
+ ctx->Map.pcs[ 1 ] < RtemsTimerReqInitiateServer_Pre_Stack_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsTimerReqInitiateServer_Pre_Started_Yes;
+ ctx->Map.pcs[ 2 ] < RtemsTimerReqInitiateServer_Pre_Started_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsTimerReqInitiateServer_Pre_TaskObj_Available;
+ ctx->Map.pcs[ 3 ] < RtemsTimerReqInitiateServer_Pre_TaskObj_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ ctx->Map.entry = RtemsTimerReqInitiateServer_PopEntry( ctx );
+ RtemsTimerReqInitiateServer_TestVariant( ctx );
+ RtemsTimerReqInitiateServer_Cleanup( ctx );
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-timer-reset.c b/testsuites/validation/tc-timer-reset.c
new file mode 100644
index 0000000000..709b9fe8a5
--- /dev/null
+++ b/testsuites/validation/tc-timer-reset.c
@@ -0,0 +1,1058 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTimerReqReset
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTimerReqReset spec:/rtems/timer/req/reset
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTimerReqReset_Pre_Id_Valid,
+ RtemsTimerReqReset_Pre_Id_Invalid,
+ RtemsTimerReqReset_Pre_Id_NA
+} RtemsTimerReqReset_Pre_Id;
+
+typedef enum {
+ RtemsTimerReqReset_Pre_Context_None,
+ RtemsTimerReqReset_Pre_Context_Interrupt,
+ RtemsTimerReqReset_Pre_Context_Server,
+ RtemsTimerReqReset_Pre_Context_NA
+} RtemsTimerReqReset_Pre_Context;
+
+typedef enum {
+ RtemsTimerReqReset_Pre_Clock_None,
+ RtemsTimerReqReset_Pre_Clock_Ticks,
+ RtemsTimerReqReset_Pre_Clock_Realtime,
+ RtemsTimerReqReset_Pre_Clock_NA
+} RtemsTimerReqReset_Pre_Clock;
+
+typedef enum {
+ RtemsTimerReqReset_Pre_State_Inactive,
+ RtemsTimerReqReset_Pre_State_Scheduled,
+ RtemsTimerReqReset_Pre_State_Pending,
+ RtemsTimerReqReset_Pre_State_NA
+} RtemsTimerReqReset_Pre_State;
+
+typedef enum {
+ RtemsTimerReqReset_Post_Status_Ok,
+ RtemsTimerReqReset_Post_Status_InvId,
+ RtemsTimerReqReset_Post_Status_NotDef,
+ RtemsTimerReqReset_Post_Status_NA
+} RtemsTimerReqReset_Post_Status;
+
+typedef enum {
+ RtemsTimerReqReset_Post_Context_None,
+ RtemsTimerReqReset_Post_Context_Interrupt,
+ RtemsTimerReqReset_Post_Context_Server,
+ RtemsTimerReqReset_Post_Context_Nop,
+ RtemsTimerReqReset_Post_Context_NA
+} RtemsTimerReqReset_Post_Context;
+
+typedef enum {
+ RtemsTimerReqReset_Post_Clock_None,
+ RtemsTimerReqReset_Post_Clock_Ticks,
+ RtemsTimerReqReset_Post_Clock_Realtime,
+ RtemsTimerReqReset_Post_Clock_Nop,
+ RtemsTimerReqReset_Post_Clock_NA
+} RtemsTimerReqReset_Post_Clock;
+
+typedef enum {
+ RtemsTimerReqReset_Post_State_Scheduled,
+ RtemsTimerReqReset_Post_State_Nop,
+ RtemsTimerReqReset_Post_State_NA
+} RtemsTimerReqReset_Post_State;
+
+typedef enum {
+ RtemsTimerReqReset_Post_Interval_Last,
+ RtemsTimerReqReset_Post_Interval_Nop,
+ RtemsTimerReqReset_Post_Interval_NA
+} RtemsTimerReqReset_Post_Interval;
+
+typedef enum {
+ RtemsTimerReqReset_Post_Routine_Last,
+ RtemsTimerReqReset_Post_Routine_Nop,
+ RtemsTimerReqReset_Post_Routine_NA
+} RtemsTimerReqReset_Post_Routine;
+
+typedef enum {
+ RtemsTimerReqReset_Post_UserData_Last,
+ RtemsTimerReqReset_Post_UserData_Nop,
+ RtemsTimerReqReset_Post_UserData_NA
+} RtemsTimerReqReset_Post_UserData;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_Id_NA : 1;
+ uint32_t Pre_Context_NA : 1;
+ uint32_t Pre_Clock_NA : 1;
+ uint32_t Pre_State_NA : 1;
+ uint32_t Post_Status : 2;
+ uint32_t Post_Context : 3;
+ uint32_t Post_Clock : 3;
+ uint32_t Post_State : 2;
+ uint32_t Post_Interval : 2;
+ uint32_t Post_Routine : 2;
+ uint32_t Post_UserData : 2;
+} RtemsTimerReqReset_Entry;
+
+typedef enum {
+ PRE_NONE = 0,
+ PRE_INTERRUPT = 1,
+ PRE_SERVER = 2
+} PreConditionContext;
+
+typedef enum {
+ SCHEDULE_NONE = 0,
+ SCHEDULE_SOON = 1,
+ SCHEDULE_LATER = 2,
+ SCHEDULE_MAX = 5
+} Scheduling_Ticks;
+
+/**
+ * @brief Test context for spec:/rtems/timer/req/reset test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a valid id of a timer.
+ */
+ rtems_id timer_id;
+
+ /**
+ * @brief This member specifies the ``id`` parameter for the action.
+ */
+ rtems_id id_param;
+
+ /**
+ * @brief This member contains the returned status code of the action.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member contains the user data for Timer Service Routine "A".
+ */
+ void *data_a;
+
+ /**
+ * @brief This member contains the user data for Timer Service Routine "B".
+ */
+ void *data_b;
+
+ /**
+ * @brief This member contains the counter for invocations of Timer Service
+ * Routine "A".
+ */
+ int invocations_a;
+
+ /**
+ * @brief This member contains the counter for invocations of Timer Service
+ * Routine "B".
+ */
+ int invocations_b;
+
+ /**
+ * @brief This member contains the number of ticks needed to fire the Timer
+ * Service Routine.
+ */
+ Scheduling_Ticks ticks_till_fire;
+
+ /**
+ * @brief This member identifier the user data given to the Timer Service
+ * Routine when called. It either the address of member data_a or data_b.
+ */
+ void **routine_user_data;
+
+ /**
+ * @brief This member contains a reference to the user data to be used in the
+ * next call to the Timer Service Routine.
+ */
+ void **scheduled_user_data;
+
+ /**
+ * @brief This member contains 1 if the Timer Service Routine "A" has been
+ * scheduled otherwise 0.
+ */
+ int scheduled_invocations_a;
+
+ /**
+ * @brief This member contains 1 if the Timer Service Routine "B" has been
+ * scheduled otherwise 0.
+ */
+ int scheduled_invocations_b;
+
+ /**
+ * @brief This member specifies the number of ticks till the scheduled Timer
+ * Service Routine should fire.
+ */
+ Scheduling_Ticks scheduled_ticks_till_fire;
+
+ /**
+ * @brief This member specifies which pre-condition context (none, interrupt
+ * context, server context) must be created before the rtems_timer_reset()
+ * action gets executed.
+ */
+ PreConditionContext pre_cond_contex;
+
+ /**
+ * @brief This member stores internal clock and context settings of the timer
+ * before the execution of the test action.
+ */
+ Timer_Classes pre_class;
+
+ /**
+ * @brief This member stores the state of the timer before the execution of
+ * the test action.
+ */
+ Timer_States pre_state;
+
+ /**
+ * @brief This member stores the state of the timer after the execution of
+ * the test action.
+ */
+ Timer_States post_state;
+
+ /**
+ * @brief This member stores the scheduling data of the timer before the
+ * execution of the test action.
+ */
+ Timer_Scheduling_Data pre_scheduling_data;
+
+ /**
+ * @brief This member stores the scheduling data of the timer after the
+ * execution of the test action.
+ */
+ Timer_Scheduling_Data post_scheduling_data;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 4 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTimerReqReset_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTimerReqReset_Context;
+
+static RtemsTimerReqReset_Context
+ RtemsTimerReqReset_Instance;
+
+static const char * const RtemsTimerReqReset_PreDesc_Id[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTimerReqReset_PreDesc_Context[] = {
+ "None",
+ "Interrupt",
+ "Server",
+ "NA"
+};
+
+static const char * const RtemsTimerReqReset_PreDesc_Clock[] = {
+ "None",
+ "Ticks",
+ "Realtime",
+ "NA"
+};
+
+static const char * const RtemsTimerReqReset_PreDesc_State[] = {
+ "Inactive",
+ "Scheduled",
+ "Pending",
+ "NA"
+};
+
+static const char * const * const RtemsTimerReqReset_PreDesc[] = {
+ RtemsTimerReqReset_PreDesc_Id,
+ RtemsTimerReqReset_PreDesc_Context,
+ RtemsTimerReqReset_PreDesc_Clock,
+ RtemsTimerReqReset_PreDesc_State,
+ NULL
+};
+
+static const rtems_time_of_day tod_now = { 2000, 1, 1, 0, 0, 0, 0 };
+static const rtems_time_of_day tod_schedule = { 2000, 1, 1, 1, 0, 0, 0 };
+static const rtems_time_of_day tod_fire = { 2000, 1, 2, 0, 0, 0, 0 };
+
+static Scheduling_Ticks TriggerTimer( const RtemsTimerReqReset_Context *ctx )
+{
+ int ticks_fired = SCHEDULE_NONE;
+ int invocations_old = ctx->invocations_a + ctx->invocations_b;
+
+ /* Fire the timer service routine for ticks and realtime clock */
+ int i;
+ for ( i = 1; i <= SCHEDULE_MAX; ++i ) {
+ ClockTick();
+ if ( ctx->invocations_a + ctx->invocations_b > invocations_old ) {
+ ticks_fired = i;
+ break;
+ }
+ }
+
+ T_rsc_success( rtems_clock_set( &tod_fire ) );
+
+ return ticks_fired;
+}
+
+static void TimerServiceRoutineA(
+ rtems_id timer_id,
+ void *user_data
+)
+{
+ RtemsTimerReqReset_Context *ctx =
+ *(RtemsTimerReqReset_Context **) user_data;
+ ++( ctx->invocations_a );
+ ctx->routine_user_data = user_data;
+}
+
+static void TimerServiceRoutineB(
+ rtems_id timer_id,
+ void *user_data
+)
+{
+ RtemsTimerReqReset_Context *ctx =
+ *(RtemsTimerReqReset_Context **) user_data;
+ ++( ctx->invocations_b );
+ ctx->routine_user_data = user_data;
+}
+
+static void RtemsTimerReqReset_Pre_Id_Prepare(
+ RtemsTimerReqReset_Context *ctx,
+ RtemsTimerReqReset_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqReset_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter is valid.
+ */
+ ctx->id_param = ctx->timer_id;
+ break;
+ }
+
+ case RtemsTimerReqReset_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is invalid.
+ */
+ ctx->id_param = RTEMS_ID_NONE;
+ break;
+ }
+
+ case RtemsTimerReqReset_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqReset_Pre_Context_Prepare(
+ RtemsTimerReqReset_Context *ctx,
+ RtemsTimerReqReset_Pre_Context state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqReset_Pre_Context_None: {
+ /*
+ * While the Timer Service Routine has never been scheduled since
+ * creation of the timer. See also none.
+ */
+ ctx->pre_cond_contex = PRE_NONE;
+ break;
+ }
+
+ case RtemsTimerReqReset_Pre_Context_Interrupt: {
+ /*
+ * While the timer is in interrupt context.
+ */
+ ctx->pre_cond_contex = PRE_INTERRUPT;
+ break;
+ }
+
+ case RtemsTimerReqReset_Pre_Context_Server: {
+ /*
+ * While the timer is in server context.
+ */
+ ctx->pre_cond_contex = PRE_SERVER;
+ break;
+ }
+
+ case RtemsTimerReqReset_Pre_Context_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqReset_Pre_Clock_Prepare(
+ RtemsTimerReqReset_Context *ctx,
+ RtemsTimerReqReset_Pre_Clock state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqReset_Pre_Clock_None: {
+ /*
+ * While the timer has never been scheduled since creation of the timer.
+ */
+ T_eq_int( ctx->pre_cond_contex, PRE_NONE );
+ break;
+ }
+
+ case RtemsTimerReqReset_Pre_Clock_Ticks: {
+ /*
+ * While the clock used to determine when the timer will fire is the
+ * ticks based clock.
+ */
+ rtems_status_code status;
+
+ if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
+ ctx->scheduled_ticks_till_fire = SCHEDULE_SOON;
+ ctx->scheduled_invocations_a = 1;
+ ctx->scheduled_user_data = &ctx->data_a;
+ status = rtems_timer_fire_after(
+ ctx->timer_id,
+ ctx->scheduled_ticks_till_fire,
+ TimerServiceRoutineA,
+ ctx->scheduled_user_data
+ );
+ } else {
+ ctx->scheduled_ticks_till_fire = SCHEDULE_LATER;
+ ctx->scheduled_invocations_b = 1;
+ ctx->scheduled_user_data = &ctx->data_b;
+ status = rtems_timer_server_fire_after(
+ ctx->timer_id,
+ ctx->scheduled_ticks_till_fire,
+ TimerServiceRoutineB,
+ ctx->scheduled_user_data
+ );
+ }
+ T_rsc_success( status );
+ break;
+ }
+
+ case RtemsTimerReqReset_Pre_Clock_Realtime: {
+ /*
+ * While the clock used to determine when the timer will fire is the
+ * realtime clock.
+ */
+ rtems_status_code status;
+
+ if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
+ status = rtems_timer_fire_when(
+ ctx->timer_id,
+ &tod_schedule,
+ TimerServiceRoutineA,
+ &ctx->data_a
+ );
+ } else {
+ status = rtems_timer_server_fire_when(
+ ctx->timer_id,
+ &tod_schedule,
+ TimerServiceRoutineB,
+ &ctx->data_b
+ );
+ }
+ T_rsc_success( status );
+ break;
+ }
+
+ case RtemsTimerReqReset_Pre_Clock_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqReset_Pre_State_Prepare(
+ RtemsTimerReqReset_Context *ctx,
+ RtemsTimerReqReset_Pre_State state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqReset_Pre_State_Inactive: {
+ /*
+ * While the timer is in inactive state.
+ */
+ TriggerTimer( ctx );
+ T_eq_int(
+ ctx->invocations_a + ctx->invocations_b,
+ ( ctx->pre_cond_contex == PRE_NONE ) ? 0 : 1
+ );
+ ctx->invocations_a = 0;
+ ctx->invocations_b = 0;
+ ctx->pre_state = TIMER_INACTIVE;
+ break;
+ }
+
+ case RtemsTimerReqReset_Pre_State_Scheduled: {
+ /*
+ * While the timer is in scheduled state.
+ */
+ /* The timer was already scheduled in the "Clock" pre-conditions. */
+ ctx->pre_state = TIMER_SCHEDULED;
+ break;
+ }
+
+ case RtemsTimerReqReset_Pre_State_Pending: {
+ /*
+ * While the timer is in pending state.
+ */
+ T_rsc_success( rtems_task_suspend( GetTimerServerTaskId() ) );
+ TriggerTimer( ctx );
+ T_eq_int( ctx->invocations_a + ctx->invocations_b, 0 );
+ ctx->pre_state = TIMER_PENDING;
+ break;
+ }
+
+ case RtemsTimerReqReset_Pre_State_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqReset_Post_Status_Check(
+ RtemsTimerReqReset_Context *ctx,
+ RtemsTimerReqReset_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqReset_Post_Status_Ok: {
+ /*
+ * The return status of rtems_timer_reset() shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_Status_InvId: {
+ /*
+ * The return status of rtems_timer_reset() shall be RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_Status_NotDef: {
+ /*
+ * The return status of rtems_timer_reset() shall be RTEMS_NOT_DEFINED
+ */
+ T_rsc( ctx->status, RTEMS_NOT_DEFINED );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqReset_Post_Context_Check(
+ RtemsTimerReqReset_Context *ctx,
+ RtemsTimerReqReset_Post_Context state
+)
+{
+ Timer_Classes class;
+ class = GetTimerClass( ctx->timer_id );
+
+ switch ( state ) {
+ case RtemsTimerReqReset_Post_Context_None: {
+ /*
+ * The timer shall have never been scheduled. See also none.
+ */
+ T_eq_int( class, TIMER_DORMANT );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_Context_Interrupt: {
+ /*
+ * The timer shall be in interrupt context.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, 0 );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_Context_Server: {
+ /*
+ * The timer shall be in server context.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, TIMER_CLASS_BIT_ON_TASK );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_Context_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past call to
+ * rtems_timer_reset() shall not be accessed by the rtems_timer_reset()
+ * call. See also Nop.
+ */
+ T_eq_int( class, ctx->pre_class );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_Context_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqReset_Post_Clock_Check(
+ RtemsTimerReqReset_Context *ctx,
+ RtemsTimerReqReset_Post_Clock state
+)
+{
+ Timer_Classes class;
+ class = GetTimerClass( ctx->timer_id );
+
+ switch ( state ) {
+ case RtemsTimerReqReset_Post_Clock_None: {
+ /*
+ * The timer shall have never been scheduled.
+ */
+ T_eq_int( class, TIMER_DORMANT );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_Clock_Ticks: {
+ /*
+ * The timer shall use the ticks based clock.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_TIME_OF_DAY, 0 );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_Clock_Realtime: {
+ /*
+ * The timer shall use the realtime clock.
+ */
+ T_eq_int(
+ class & TIMER_CLASS_BIT_TIME_OF_DAY,
+ TIMER_CLASS_BIT_TIME_OF_DAY
+ );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_Clock_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past call to
+ * rtems_timer_reset() shall not be accessed by the rtems_timer_reset()
+ * call.
+ */
+ T_eq_int( class, ctx->pre_class );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_Clock_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqReset_Post_State_Check(
+ RtemsTimerReqReset_Context *ctx,
+ RtemsTimerReqReset_Post_State state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqReset_Post_State_Scheduled: {
+ /*
+ * The timer shall be in scheduled state.
+ */
+ ctx->ticks_till_fire = TriggerTimer( ctx );
+ T_eq_int( ctx->invocations_a + ctx->invocations_b, 1 );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_State_Nop: {
+ /*
+ * Objects referenced by the ``id`` parameter in past call to
+ * rtems_timer_reset() shall not be accessed by the rtems_timer_reset()
+ * call.
+ */
+ T_eq_int( ctx->post_state, ctx->pre_state );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_State_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqReset_Post_Interval_Check(
+ RtemsTimerReqReset_Context *ctx,
+ RtemsTimerReqReset_Post_Interval state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqReset_Post_Interval_Last: {
+ /*
+ * The Timer Service Routine shall be invoked the same number of ticks
+ * (see tick), as defined by the last scheduled interval, after a point
+ * in time during the execution of the rtems_timer_reset() call.
+ */
+ T_eq_int( ctx->ticks_till_fire, ctx->scheduled_ticks_till_fire );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_Interval_Nop: {
+ /*
+ * If and when the Timer Service Routine will be invoked shall not be
+ * changed by the past call to rtems_timer_reset().
+ */
+ /*
+ * Whether the timer is scheduled has already been tested by the
+ * "Nop" "State" post-condition above.
+ */
+ T_eq_u32(
+ ctx->post_scheduling_data.interval,
+ ctx->pre_scheduling_data.interval
+ );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_Interval_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqReset_Post_Routine_Check(
+ RtemsTimerReqReset_Context *ctx,
+ RtemsTimerReqReset_Post_Routine state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqReset_Post_Routine_Last: {
+ /*
+ * The function reference used to invoke the Timer Service Routine when
+ * the timer will fire shall be the same one as the last one scheduled.
+ */
+ T_eq_int( ctx->invocations_a, ctx->scheduled_invocations_a );
+ T_eq_int( ctx->invocations_b, ctx->scheduled_invocations_b );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_Routine_Nop: {
+ /*
+ * The function reference used for any invocation of the Timer Service
+ * Routine shall not be changed by the past call to rtems_timer_reset().
+ */
+ T_eq_ptr(
+ ctx->post_scheduling_data.routine,
+ ctx->pre_scheduling_data.routine
+ );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_Routine_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqReset_Post_UserData_Check(
+ RtemsTimerReqReset_Context *ctx,
+ RtemsTimerReqReset_Post_UserData state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqReset_Post_UserData_Last: {
+ /*
+ * The user data argument for invoking the Timer Service Routine when the
+ * timer will fire shall be the same as the last scheduled user data
+ * argument.
+ */
+ T_eq_ptr( ctx->routine_user_data, ctx->scheduled_user_data);
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_UserData_Nop: {
+ /*
+ * The user data argument used for any invocation of the Timer Service
+ * Routine shall not be changed by the past call to rtems_timer_reset().
+ */
+ T_eq_ptr(
+ ctx->post_scheduling_data.user_data,
+ ctx->pre_scheduling_data.user_data
+ );
+ break;
+ }
+
+ case RtemsTimerReqReset_Post_UserData_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqReset_Setup( RtemsTimerReqReset_Context *ctx )
+{
+ rtems_status_code status;
+ status = rtems_timer_initiate_server(
+ RTEMS_TIMER_SERVER_DEFAULT_PRIORITY,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_ATTRIBUTES
+ );
+ T_rsc_success( status );
+}
+
+static void RtemsTimerReqReset_Setup_Wrap( void *arg )
+{
+ RtemsTimerReqReset_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTimerReqReset_Setup( ctx );
+}
+
+/**
+ * @brief Make sure the timer server is not running and the realtime clock is
+ * not set after this test.
+ */
+static void RtemsTimerReqReset_Teardown( RtemsTimerReqReset_Context *ctx )
+{
+ DeleteTimerServer();
+ UnsetClock();
+}
+
+static void RtemsTimerReqReset_Teardown_Wrap( void *arg )
+{
+ RtemsTimerReqReset_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTimerReqReset_Teardown( ctx );
+}
+
+static void RtemsTimerReqReset_Prepare( RtemsTimerReqReset_Context *ctx )
+{
+ rtems_status_code status;
+ status = rtems_timer_create(
+ rtems_build_name( 'T', 'I', 'M', 'E' ),
+ &ctx->timer_id
+ );
+ T_rsc_success( status );
+
+ ctx->data_a = ctx;
+ ctx->data_b = ctx;
+ ctx->invocations_a = 0;
+ ctx->invocations_b = 0;
+ ctx->ticks_till_fire = SCHEDULE_NONE;
+ ctx->routine_user_data = NULL;
+ ctx->scheduled_invocations_a = 0;
+ ctx->scheduled_invocations_b = 0;
+ ctx->scheduled_ticks_till_fire = SCHEDULE_NONE;
+ T_rsc_success( rtems_clock_set( &tod_now ) );
+}
+
+static void RtemsTimerReqReset_Action( RtemsTimerReqReset_Context *ctx )
+{
+ GetTimerSchedulingData( ctx->timer_id, &ctx->pre_scheduling_data );
+ ctx->pre_class = GetTimerClass( ctx->timer_id );
+ ctx->status = rtems_timer_reset( ctx->id_param );
+ ctx->post_state = GetTimerState( ctx->timer_id );
+ GetTimerSchedulingData( ctx->timer_id, &ctx->post_scheduling_data );
+ /* Ignoring return status: the timer server task may be suspended or not. */
+ rtems_task_resume( GetTimerServerTaskId() );
+}
+
+static void RtemsTimerReqReset_Cleanup( RtemsTimerReqReset_Context *ctx )
+{
+ T_rsc_success( rtems_timer_delete( ctx->timer_id ) );
+}
+
+static const RtemsTimerReqReset_Entry
+RtemsTimerReqReset_Entries[] = {
+ { 1, 0, 0, 0, 0, RtemsTimerReqReset_Post_Status_NA,
+ RtemsTimerReqReset_Post_Context_NA, RtemsTimerReqReset_Post_Clock_NA,
+ RtemsTimerReqReset_Post_State_NA, RtemsTimerReqReset_Post_Interval_NA,
+ RtemsTimerReqReset_Post_Routine_NA, RtemsTimerReqReset_Post_UserData_NA },
+ { 0, 0, 0, 0, 0, RtemsTimerReqReset_Post_Status_InvId,
+ RtemsTimerReqReset_Post_Context_Nop, RtemsTimerReqReset_Post_Clock_Nop,
+ RtemsTimerReqReset_Post_State_Nop, RtemsTimerReqReset_Post_Interval_Nop,
+ RtemsTimerReqReset_Post_Routine_Nop, RtemsTimerReqReset_Post_UserData_Nop },
+ { 0, 0, 0, 0, 0, RtemsTimerReqReset_Post_Status_NotDef,
+ RtemsTimerReqReset_Post_Context_Nop, RtemsTimerReqReset_Post_Clock_Nop,
+ RtemsTimerReqReset_Post_State_Nop, RtemsTimerReqReset_Post_Interval_Nop,
+ RtemsTimerReqReset_Post_Routine_Nop, RtemsTimerReqReset_Post_UserData_Nop },
+ { 0, 0, 0, 0, 0, RtemsTimerReqReset_Post_Status_Ok,
+ RtemsTimerReqReset_Post_Context_Server,
+ RtemsTimerReqReset_Post_Clock_Ticks,
+ RtemsTimerReqReset_Post_State_Scheduled,
+ RtemsTimerReqReset_Post_Interval_Last,
+ RtemsTimerReqReset_Post_Routine_Last, RtemsTimerReqReset_Post_UserData_Last },
+ { 0, 0, 0, 0, 0, RtemsTimerReqReset_Post_Status_Ok,
+ RtemsTimerReqReset_Post_Context_Interrupt,
+ RtemsTimerReqReset_Post_Clock_Ticks,
+ RtemsTimerReqReset_Post_State_Scheduled,
+ RtemsTimerReqReset_Post_Interval_Last,
+ RtemsTimerReqReset_Post_Routine_Last, RtemsTimerReqReset_Post_UserData_Last }
+};
+
+static const uint8_t
+RtemsTimerReqReset_Map[] = {
+ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 2, 2, 0, 0, 0, 0, 3, 3, 3, 2, 2,
+ 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
+ 1, 1
+};
+
+static size_t RtemsTimerReqReset_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsTimerReqReset_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsTimerReqReset_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTimerReqReset_Fixture = {
+ .setup = RtemsTimerReqReset_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsTimerReqReset_Teardown_Wrap,
+ .scope = RtemsTimerReqReset_Scope,
+ .initial_context = &RtemsTimerReqReset_Instance
+};
+
+static inline RtemsTimerReqReset_Entry RtemsTimerReqReset_PopEntry(
+ RtemsTimerReqReset_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTimerReqReset_Entries[
+ RtemsTimerReqReset_Map[ index ]
+ ];
+}
+
+static void RtemsTimerReqReset_TestVariant( RtemsTimerReqReset_Context *ctx )
+{
+ RtemsTimerReqReset_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTimerReqReset_Pre_Context_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTimerReqReset_Pre_Clock_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTimerReqReset_Pre_State_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsTimerReqReset_Action( ctx );
+ RtemsTimerReqReset_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsTimerReqReset_Post_Context_Check( ctx, ctx->Map.entry.Post_Context );
+ RtemsTimerReqReset_Post_Clock_Check( ctx, ctx->Map.entry.Post_Clock );
+ RtemsTimerReqReset_Post_State_Check( ctx, ctx->Map.entry.Post_State );
+ RtemsTimerReqReset_Post_Interval_Check( ctx, ctx->Map.entry.Post_Interval );
+ RtemsTimerReqReset_Post_Routine_Check( ctx, ctx->Map.entry.Post_Routine );
+ RtemsTimerReqReset_Post_UserData_Check( ctx, ctx->Map.entry.Post_UserData );
+}
+
+/**
+ * @fn void T_case_body_RtemsTimerReqReset( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTimerReqReset, &RtemsTimerReqReset_Fixture )
+{
+ RtemsTimerReqReset_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsTimerReqReset_Pre_Id_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsTimerReqReset_Pre_Id_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsTimerReqReset_Pre_Context_None;
+ ctx->Map.pcs[ 1 ] < RtemsTimerReqReset_Pre_Context_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsTimerReqReset_Pre_Clock_None;
+ ctx->Map.pcs[ 2 ] < RtemsTimerReqReset_Pre_Clock_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsTimerReqReset_Pre_State_Inactive;
+ ctx->Map.pcs[ 3 ] < RtemsTimerReqReset_Pre_State_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ ctx->Map.entry = RtemsTimerReqReset_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsTimerReqReset_Prepare( ctx );
+ RtemsTimerReqReset_TestVariant( ctx );
+ RtemsTimerReqReset_Cleanup( ctx );
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-timer-server-fire-after.c b/testsuites/validation/tc-timer-server-fire-after.c
new file mode 100644
index 0000000000..3ee91d8461
--- /dev/null
+++ b/testsuites/validation/tc-timer-server-fire-after.c
@@ -0,0 +1,1301 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTimerReqServerFireAfter
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTimerReqServerFireAfter \
+ * spec:/rtems/timer/req/server-fire-after
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTimerReqServerFireAfter_Pre_Server_Init,
+ RtemsTimerReqServerFireAfter_Pre_Server_NotInit,
+ RtemsTimerReqServerFireAfter_Pre_Server_NA
+} RtemsTimerReqServerFireAfter_Pre_Server;
+
+typedef enum {
+ RtemsTimerReqServerFireAfter_Pre_Ticks_Valid,
+ RtemsTimerReqServerFireAfter_Pre_Ticks_Is0,
+ RtemsTimerReqServerFireAfter_Pre_Ticks_NA
+} RtemsTimerReqServerFireAfter_Pre_Ticks;
+
+typedef enum {
+ RtemsTimerReqServerFireAfter_Pre_Routine_Valid,
+ RtemsTimerReqServerFireAfter_Pre_Routine_Null,
+ RtemsTimerReqServerFireAfter_Pre_Routine_NA
+} RtemsTimerReqServerFireAfter_Pre_Routine;
+
+typedef enum {
+ RtemsTimerReqServerFireAfter_Pre_Id_Valid,
+ RtemsTimerReqServerFireAfter_Pre_Id_Invalid,
+ RtemsTimerReqServerFireAfter_Pre_Id_NA
+} RtemsTimerReqServerFireAfter_Pre_Id;
+
+typedef enum {
+ RtemsTimerReqServerFireAfter_Pre_Context_None,
+ RtemsTimerReqServerFireAfter_Pre_Context_Interrupt,
+ RtemsTimerReqServerFireAfter_Pre_Context_Server,
+ RtemsTimerReqServerFireAfter_Pre_Context_NA
+} RtemsTimerReqServerFireAfter_Pre_Context;
+
+typedef enum {
+ RtemsTimerReqServerFireAfter_Pre_Clock_None,
+ RtemsTimerReqServerFireAfter_Pre_Clock_Ticks,
+ RtemsTimerReqServerFireAfter_Pre_Clock_Realtime,
+ RtemsTimerReqServerFireAfter_Pre_Clock_NA
+} RtemsTimerReqServerFireAfter_Pre_Clock;
+
+typedef enum {
+ RtemsTimerReqServerFireAfter_Pre_State_Inactive,
+ RtemsTimerReqServerFireAfter_Pre_State_Scheduled,
+ RtemsTimerReqServerFireAfter_Pre_State_Pending,
+ RtemsTimerReqServerFireAfter_Pre_State_NA
+} RtemsTimerReqServerFireAfter_Pre_State;
+
+typedef enum {
+ RtemsTimerReqServerFireAfter_Post_Status_Ok,
+ RtemsTimerReqServerFireAfter_Post_Status_InvId,
+ RtemsTimerReqServerFireAfter_Post_Status_InvAddr,
+ RtemsTimerReqServerFireAfter_Post_Status_InvNum,
+ RtemsTimerReqServerFireAfter_Post_Status_IncStat,
+ RtemsTimerReqServerFireAfter_Post_Status_NA
+} RtemsTimerReqServerFireAfter_Post_Status;
+
+typedef enum {
+ RtemsTimerReqServerFireAfter_Post_Context_None,
+ RtemsTimerReqServerFireAfter_Post_Context_Interrupt,
+ RtemsTimerReqServerFireAfter_Post_Context_Server,
+ RtemsTimerReqServerFireAfter_Post_Context_Nop,
+ RtemsTimerReqServerFireAfter_Post_Context_NA
+} RtemsTimerReqServerFireAfter_Post_Context;
+
+typedef enum {
+ RtemsTimerReqServerFireAfter_Post_Clock_None,
+ RtemsTimerReqServerFireAfter_Post_Clock_Ticks,
+ RtemsTimerReqServerFireAfter_Post_Clock_Realtime,
+ RtemsTimerReqServerFireAfter_Post_Clock_Nop,
+ RtemsTimerReqServerFireAfter_Post_Clock_NA
+} RtemsTimerReqServerFireAfter_Post_Clock;
+
+typedef enum {
+ RtemsTimerReqServerFireAfter_Post_State_Scheduled,
+ RtemsTimerReqServerFireAfter_Post_State_Nop,
+ RtemsTimerReqServerFireAfter_Post_State_NA
+} RtemsTimerReqServerFireAfter_Post_State;
+
+typedef enum {
+ RtemsTimerReqServerFireAfter_Post_Interval_Param,
+ RtemsTimerReqServerFireAfter_Post_Interval_Nop,
+ RtemsTimerReqServerFireAfter_Post_Interval_NA
+} RtemsTimerReqServerFireAfter_Post_Interval;
+
+typedef enum {
+ RtemsTimerReqServerFireAfter_Post_Routine_Param,
+ RtemsTimerReqServerFireAfter_Post_Routine_Nop,
+ RtemsTimerReqServerFireAfter_Post_Routine_NA
+} RtemsTimerReqServerFireAfter_Post_Routine;
+
+typedef enum {
+ RtemsTimerReqServerFireAfter_Post_UserData_Param,
+ RtemsTimerReqServerFireAfter_Post_UserData_Nop,
+ RtemsTimerReqServerFireAfter_Post_UserData_NA
+} RtemsTimerReqServerFireAfter_Post_UserData;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_Server_NA : 1;
+ uint32_t Pre_Ticks_NA : 1;
+ uint32_t Pre_Routine_NA : 1;
+ uint32_t Pre_Id_NA : 1;
+ uint32_t Pre_Context_NA : 1;
+ uint32_t Pre_Clock_NA : 1;
+ uint32_t Pre_State_NA : 1;
+ uint32_t Post_Status : 3;
+ uint32_t Post_Context : 3;
+ uint32_t Post_Clock : 3;
+ uint32_t Post_State : 2;
+ uint32_t Post_Interval : 2;
+ uint32_t Post_Routine : 2;
+ uint32_t Post_UserData : 2;
+} RtemsTimerReqServerFireAfter_Entry;
+
+typedef enum {
+ PRE_NONE = 0,
+ PRE_INTERRUPT = 1,
+ PRE_SERVER = 2
+} PreConditionContext;
+
+typedef enum {
+ SCHEDULE_NONE = 0,
+ SCHEDULE_VERY_SOON = 1,
+ SCHEDULE_SOON = 2,
+ SCHEDULE_LATER = 3,
+ SCHEDULE_MAX = 5
+} Scheduling_Ticks;
+
+/**
+ * @brief Test context for spec:/rtems/timer/req/server-fire-after test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a valid id of a timer.
+ */
+ rtems_id timer_id;
+
+ /**
+ * @brief This member contains a valid id of a second timer.
+ *
+ * This timer is used reach branch coverage in an if-statement which only
+ * serves performance optimization.
+ */
+ rtems_id timer_cover_id;
+
+ /**
+ * @brief This member specifies the ``id`` parameter for the action.
+ */
+ rtems_id id_param;
+
+ /**
+ * @brief This member specifies the ``ticks`` parameter for the action.
+ */
+ rtems_interval ticks_param;
+
+ /**
+ * @brief This member specifies the ``routine`` parameter for the action.
+ */
+ rtems_timer_service_routine_entry routine_param;
+
+ /**
+ * @brief This member contains the returned status code of the action.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member contains a counter for invocations of the Timer Service
+ * Routine.
+ */
+ int invocations;
+
+ /**
+ * @brief Function TriggerTimer() is used to figure out how many ticks (see
+ * tick) are needed till the Timer Service Routine gets executed. This
+ * member contains the number of ticks needed to fire the Timer Service
+ * Routine.
+ */
+ Scheduling_Ticks ticks_till_fire;
+
+ /**
+ * @brief This member contains the user data given to the Timer Service
+ * Routine when called.
+ */
+ void *routine_user_data;
+
+ /**
+ * @brief This member specifies which pre-condition context (none, interrupt
+ * context, server context) must be created before the
+ * rtems_timer_server_fire_after() action gets executed.
+ */
+ PreConditionContext pre_cond_contex;
+
+ /**
+ * @brief This member stores internal clock and context settings of the timer
+ * before the execution of the test action.
+ */
+ Timer_Classes pre_class;
+
+ /**
+ * @brief This member stores the state of the timer before the execution of
+ * the test action.
+ */
+ Timer_States pre_state;
+
+ /**
+ * @brief This member stores the state of the timer after the execution of
+ * the test action.
+ */
+ Timer_States post_state;
+
+ /**
+ * @brief This member stores the scheduling data of the timer before the
+ * execution of the test action.
+ */
+ Timer_Scheduling_Data pre_scheduling_data;
+
+ /**
+ * @brief This member stores the scheduling data of the timer after the
+ * execution of the test action.
+ */
+ Timer_Scheduling_Data post_scheduling_data;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 7 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTimerReqServerFireAfter_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTimerReqServerFireAfter_Context;
+
+static RtemsTimerReqServerFireAfter_Context
+ RtemsTimerReqServerFireAfter_Instance;
+
+static const char * const RtemsTimerReqServerFireAfter_PreDesc_Server[] = {
+ "Init",
+ "NotInit",
+ "NA"
+};
+
+static const char * const RtemsTimerReqServerFireAfter_PreDesc_Ticks[] = {
+ "Valid",
+ "Is0",
+ "NA"
+};
+
+static const char * const RtemsTimerReqServerFireAfter_PreDesc_Routine[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsTimerReqServerFireAfter_PreDesc_Id[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTimerReqServerFireAfter_PreDesc_Context[] = {
+ "None",
+ "Interrupt",
+ "Server",
+ "NA"
+};
+
+static const char * const RtemsTimerReqServerFireAfter_PreDesc_Clock[] = {
+ "None",
+ "Ticks",
+ "Realtime",
+ "NA"
+};
+
+static const char * const RtemsTimerReqServerFireAfter_PreDesc_State[] = {
+ "Inactive",
+ "Scheduled",
+ "Pending",
+ "NA"
+};
+
+static const char * const * const RtemsTimerReqServerFireAfter_PreDesc[] = {
+ RtemsTimerReqServerFireAfter_PreDesc_Server,
+ RtemsTimerReqServerFireAfter_PreDesc_Ticks,
+ RtemsTimerReqServerFireAfter_PreDesc_Routine,
+ RtemsTimerReqServerFireAfter_PreDesc_Id,
+ RtemsTimerReqServerFireAfter_PreDesc_Context,
+ RtemsTimerReqServerFireAfter_PreDesc_Clock,
+ RtemsTimerReqServerFireAfter_PreDesc_State,
+ NULL
+};
+
+static const rtems_time_of_day tod_now = { 2000, 1, 1, 0, 0, 0, 0 };
+static const rtems_time_of_day tod_schedule = { 2000, 1, 1, 1, 0, 0, 0 };
+static const rtems_time_of_day tod_fire = { 2000, 1, 2, 0, 0, 0, 0 };
+
+static Scheduling_Ticks TriggerTimer( const RtemsTimerReqServerFireAfter_Context *ctx )
+{
+ int ticks_fired = SCHEDULE_NONE;
+ int invocations_old = ctx->invocations;
+
+ /* Fire the timer service routine for ticks and realtime clock */
+ int i;
+ for ( i = 1; i <= SCHEDULE_MAX; ++i ) {
+ ClockTick();
+ if ( ctx->invocations > invocations_old ) {
+ ticks_fired = i;
+ break;
+ }
+ }
+
+ T_rsc_success( rtems_clock_set( &tod_fire ) );
+
+ return ticks_fired;
+}
+
+static void TimerServiceRoutine(
+ rtems_id timer_id,
+ void *user_data
+)
+{
+ RtemsTimerReqServerFireAfter_Context *ctx = user_data;
+ ++( ctx->invocations );
+ ctx->routine_user_data = user_data;
+}
+
+/*
+ * This service routine is used reach branch coverage in an if-statement
+ * which only serves performance optimization.
+ */
+static void TimerServiceRoutineCover(
+ rtems_id timer_cover_id,
+ void *user_data
+)
+{
+ (void) timer_cover_id;
+ (void) user_data;
+}
+
+static void RtemsTimerReqServerFireAfter_Pre_Server_Prepare(
+ RtemsTimerReqServerFireAfter_Context *ctx,
+ RtemsTimerReqServerFireAfter_Pre_Server state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireAfter_Pre_Server_Init: {
+ /*
+ * While the Timer Server task has been successfully initialized by a
+ * call to rtems_timer_initiate_server().
+ */
+ rtems_status_code status;
+ status = rtems_timer_initiate_server(
+ RTEMS_TIMER_SERVER_DEFAULT_PRIORITY,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_ATTRIBUTES
+ );
+ T_rsc_success( status );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Pre_Server_NotInit: {
+ /*
+ * While the Timer Server task has not been initialized and does not
+ * exist.
+ */
+ DeleteTimerServer();
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Pre_Server_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireAfter_Pre_Ticks_Prepare(
+ RtemsTimerReqServerFireAfter_Context *ctx,
+ RtemsTimerReqServerFireAfter_Pre_Ticks state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireAfter_Pre_Ticks_Valid: {
+ /*
+ * While the ``ticks`` parameter is a positive (greater 0) number.
+ */
+ ctx->ticks_param = SCHEDULE_LATER;
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Pre_Ticks_Is0: {
+ /*
+ * While the ``ticks`` parameter is 0.
+ */
+ ctx->ticks_param = 0;
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Pre_Ticks_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireAfter_Pre_Routine_Prepare(
+ RtemsTimerReqServerFireAfter_Context *ctx,
+ RtemsTimerReqServerFireAfter_Pre_Routine state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireAfter_Pre_Routine_Valid: {
+ /*
+ * While the ``routine`` parameter references an object of type
+ * rtems_timer_service_routine_entry.
+ */
+ ctx->routine_param = TimerServiceRoutine;
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Pre_Routine_Null: {
+ /*
+ * While the ``routine`` parameter is NULL..
+ */
+ ctx->routine_param = NULL;
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Pre_Routine_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireAfter_Pre_Id_Prepare(
+ RtemsTimerReqServerFireAfter_Context *ctx,
+ RtemsTimerReqServerFireAfter_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireAfter_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter is valid.
+ */
+ ctx->id_param = ctx->timer_id;
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is invalid.
+ */
+ ctx->id_param = RTEMS_ID_NONE;
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireAfter_Pre_Context_Prepare(
+ RtemsTimerReqServerFireAfter_Context *ctx,
+ RtemsTimerReqServerFireAfter_Pre_Context state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireAfter_Pre_Context_None: {
+ /*
+ * While the Timer Service Routine has never been scheduled since
+ * creation of the timer. See also none.
+ */
+ ctx->pre_cond_contex = PRE_NONE;
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Pre_Context_Interrupt: {
+ /*
+ * While the timer is in interrupt context.
+ */
+ ctx->pre_cond_contex = PRE_INTERRUPT;
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Pre_Context_Server: {
+ /*
+ * While the timer is in server context.
+ */
+ ctx->pre_cond_contex = PRE_SERVER;
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Pre_Context_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireAfter_Pre_Clock_Prepare(
+ RtemsTimerReqServerFireAfter_Context *ctx,
+ RtemsTimerReqServerFireAfter_Pre_Clock state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireAfter_Pre_Clock_None: {
+ /*
+ * While the timer has never been scheduled since creation of the timer.
+ */
+ T_eq_int( ctx->pre_cond_contex, PRE_NONE );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Pre_Clock_Ticks: {
+ /*
+ * While the clock used to determine when the timer will fire is the
+ * ticks based clock.
+ */
+ rtems_status_code status;
+
+ if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
+ status = rtems_timer_fire_after(
+ ctx->timer_id,
+ SCHEDULE_SOON,
+ TimerServiceRoutine,
+ ctx
+ );
+ } else {
+ status = rtems_timer_server_fire_after(
+ ctx->timer_id,
+ SCHEDULE_SOON,
+ TimerServiceRoutine,
+ ctx
+ );
+ }
+ T_rsc_success( status );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Pre_Clock_Realtime: {
+ /*
+ * While the clock used to determine when the timer will fire is the
+ * realtime clock.
+ */
+ rtems_status_code status;
+
+ if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
+ status = rtems_timer_fire_when(
+ ctx->timer_id,
+ &tod_schedule,
+ TimerServiceRoutine,
+ ctx
+ );
+ } else {
+ status = rtems_timer_server_fire_when(
+ ctx->timer_id,
+ &tod_schedule,
+ TimerServiceRoutine,
+ ctx
+ );
+ }
+ T_rsc_success( status );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Pre_Clock_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireAfter_Pre_State_Prepare(
+ RtemsTimerReqServerFireAfter_Context *ctx,
+ RtemsTimerReqServerFireAfter_Pre_State state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireAfter_Pre_State_Inactive: {
+ /*
+ * While the timer is in inactive state.
+ */
+ TriggerTimer( ctx );
+ T_eq_int(
+ ctx->invocations,
+ ( ctx->pre_cond_contex == PRE_NONE ) ? 0 : 1
+ );
+ ctx->invocations = 0;
+ ctx->pre_state = TIMER_INACTIVE;
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Pre_State_Scheduled: {
+ /*
+ * While the timer is in scheduled state.
+ */
+ /* The timer was already scheduled in the "Clock" pre-conditions. */
+ ctx->pre_state = TIMER_SCHEDULED;
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Pre_State_Pending: {
+ /*
+ * While the timer is in pending state.
+ */
+ rtems_status_code status;
+ if ( ctx->pre_cond_contex == PRE_SERVER ) {
+ /*
+ * This call to rtems_timer_fire_after() serves to reach branch coverage
+ * in an if-statement which only serves performance optimization.
+ *
+ * cpukit/rtems/src/timerserver.c:70 else-branch was not reached:
+ * if ( wakeup ) {
+ * (void) rtems_event_system_send( ts->server_id, RTEMS_EVENT_SYSTEM_SERVER );
+ * }
+ */
+ status = rtems_timer_server_fire_after(
+ ctx->timer_cover_id,
+ SCHEDULE_VERY_SOON,
+ TimerServiceRoutineCover,
+ ctx
+ );
+ T_rsc_success( status );
+ }
+
+ T_rsc_success( rtems_task_suspend( GetTimerServerTaskId() ) );
+ TriggerTimer( ctx );
+ T_eq_int( ctx->invocations, 0 );
+ ctx->pre_state = TIMER_PENDING;
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Pre_State_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireAfter_Post_Status_Check(
+ RtemsTimerReqServerFireAfter_Context *ctx,
+ RtemsTimerReqServerFireAfter_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireAfter_Post_Status_Ok: {
+ /*
+ * The return status of rtems_timer_server_fire_after() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_Status_InvId: {
+ /*
+ * The return status of rtems_timer_server_fire_after() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_timer_server_fire_after() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_Status_InvNum: {
+ /*
+ * The return status of rtems_timer_server_fire_after() shall be
+ * RTEMS_INVALID_NUMBER.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NUMBER );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_Status_IncStat: {
+ /*
+ * The return status of rtems_timer_server_fire_after() shall be
+ * RTEMS_INCORRECT_STATE.
+ */
+ T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireAfter_Post_Context_Check(
+ RtemsTimerReqServerFireAfter_Context *ctx,
+ RtemsTimerReqServerFireAfter_Post_Context state
+)
+{
+ Timer_Classes class;
+ class = GetTimerClass( ctx->timer_id );
+
+ switch ( state ) {
+ case RtemsTimerReqServerFireAfter_Post_Context_None: {
+ /*
+ * The timer shall have never been scheduled. See also none.
+ */
+ T_eq_int( class, TIMER_DORMANT );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_Context_Interrupt: {
+ /*
+ * The timer shall be in interrupt context.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, 0 );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_Context_Server: {
+ /*
+ * The timer shall be in server context.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, TIMER_CLASS_BIT_ON_TASK );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_Context_Nop: {
+ /*
+ * Objects referenced by the parameters in the past call to
+ * rtems_timer_server_fire_after() shall not be accessed by the
+ * rtems_timer_server_fire_after() call. See also Nop.
+ */
+ T_eq_int( class, ctx->pre_class );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_Context_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireAfter_Post_Clock_Check(
+ RtemsTimerReqServerFireAfter_Context *ctx,
+ RtemsTimerReqServerFireAfter_Post_Clock state
+)
+{
+ Timer_Classes class;
+ class = GetTimerClass( ctx->timer_id );
+
+ switch ( state ) {
+ case RtemsTimerReqServerFireAfter_Post_Clock_None: {
+ /*
+ * The timer shall have never been scheduled.
+ */
+ T_eq_int( class, TIMER_DORMANT );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_Clock_Ticks: {
+ /*
+ * The timer shall use the ticks based clock.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_TIME_OF_DAY, 0 );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_Clock_Realtime: {
+ /*
+ * The timer shall use the realtime clock.
+ */
+ T_eq_int(
+ class & TIMER_CLASS_BIT_TIME_OF_DAY,
+ TIMER_CLASS_BIT_TIME_OF_DAY
+ );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_Clock_Nop: {
+ /*
+ * Objects referenced by the parameters in the past call to
+ * rtems_timer_server_fire_after() shall not be accessed by the
+ * rtems_timer_server_fire_after() call.
+ */
+ T_eq_int( class, ctx->pre_class );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_Clock_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireAfter_Post_State_Check(
+ RtemsTimerReqServerFireAfter_Context *ctx,
+ RtemsTimerReqServerFireAfter_Post_State state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireAfter_Post_State_Scheduled: {
+ /*
+ * The timer shall be in scheduled state.
+ */
+ ctx->ticks_till_fire = TriggerTimer( ctx );
+ T_eq_int( ctx->invocations, 1 );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_State_Nop: {
+ /*
+ * Objects referenced by the parameters in the past call to
+ * rtems_timer_server_fire_after() shall not be accessed by the
+ * rtems_timer_server_fire_after() call.
+ */
+ T_eq_int( ctx->post_state, ctx->pre_state );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_State_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireAfter_Post_Interval_Check(
+ RtemsTimerReqServerFireAfter_Context *ctx,
+ RtemsTimerReqServerFireAfter_Post_Interval state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireAfter_Post_Interval_Param: {
+ /*
+ * The Timer Service Routine shall be invoked the number of ticks (see
+ * tick), which are provided by the ``ticks`` parameter in the past call
+ * to rtems_timer_server_fire_after(), after a point in time during the
+ * execution of the rtems_timer_server_fire_after() call.
+ */
+ T_eq_int( ctx->ticks_till_fire, ctx->ticks_param );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_Interval_Nop: {
+ /*
+ * If and when the Timer Service Routine will be invoked shall not be
+ * changed by the past call to rtems_timer_server_fire_after().
+ */
+ /*
+ * Whether the timer is scheduled has already been tested by the
+ * "Nop" "State" post-condition above.
+ */
+ T_eq_u32(
+ ctx->post_scheduling_data.interval,
+ ctx->pre_scheduling_data.interval
+ );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_Interval_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireAfter_Post_Routine_Check(
+ RtemsTimerReqServerFireAfter_Context *ctx,
+ RtemsTimerReqServerFireAfter_Post_Routine state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireAfter_Post_Routine_Param: {
+ /*
+ * The function reference used to invoke the Timer Service Routine when
+ * the timer will fire shall be the one provided by the ``routine``
+ * parameter in the past call to rtems_timer_server_fire_after().
+ */
+ T_eq_int( ctx->invocations, 1 );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_Routine_Nop: {
+ /*
+ * The function reference used for any invocation of the Timer Service
+ * Routine shall not be changed by the past call to
+ * rtems_timer_server_fire_after().
+ */
+ T_eq_ptr(
+ ctx->post_scheduling_data.routine,
+ ctx->pre_scheduling_data.routine
+ );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_Routine_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireAfter_Post_UserData_Check(
+ RtemsTimerReqServerFireAfter_Context *ctx,
+ RtemsTimerReqServerFireAfter_Post_UserData state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireAfter_Post_UserData_Param: {
+ /*
+ * The user data argument for invoking the Timer Service Routine when the
+ * timer will fire shall be the one provided by the ``user_data``
+ * parameter in the past call to rtems_timer_server_fire_after().
+ */
+ T_eq_ptr( ctx->routine_user_data, ctx );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_UserData_Nop: {
+ /*
+ * The user data argument used for any invocation of the Timer Service
+ * Routine shall not be changed by the past call to
+ * rtems_timer_server_fire_after().
+ */
+ T_eq_ptr(
+ ctx->post_scheduling_data.user_data,
+ ctx->pre_scheduling_data.user_data
+ );
+ break;
+ }
+
+ case RtemsTimerReqServerFireAfter_Post_UserData_NA:
+ break;
+ }
+}
+
+/**
+ * @brief Make sure the realtime clock is not set after this test.
+ */
+static void RtemsTimerReqServerFireAfter_Teardown(
+ RtemsTimerReqServerFireAfter_Context *ctx
+)
+{
+ UnsetClock();
+}
+
+static void RtemsTimerReqServerFireAfter_Teardown_Wrap( void *arg )
+{
+ RtemsTimerReqServerFireAfter_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTimerReqServerFireAfter_Teardown( ctx );
+}
+
+static void RtemsTimerReqServerFireAfter_Prepare(
+ RtemsTimerReqServerFireAfter_Context *ctx
+)
+{
+ rtems_status_code status;
+ status = rtems_timer_create(
+ rtems_build_name( 'T', 'I', 'M', 'E' ),
+ &ctx->timer_id
+ );
+ T_rsc_success( status );
+
+ status = rtems_timer_create(
+ rtems_build_name( 'C', 'O', 'V', 'R' ),
+ &ctx->timer_cover_id
+ );
+ T_rsc_success( status );
+
+ ctx->invocations = 0;
+ ctx->ticks_till_fire = SCHEDULE_NONE;
+ ctx->routine_user_data = NULL;
+ T_rsc_success( rtems_clock_set( &tod_now ) );
+}
+
+static void RtemsTimerReqServerFireAfter_Action(
+ RtemsTimerReqServerFireAfter_Context *ctx
+)
+{
+ GetTimerSchedulingData( ctx->timer_id, &ctx->pre_scheduling_data );
+ ctx->pre_class = GetTimerClass( ctx->timer_id );
+ ctx->status = rtems_timer_server_fire_after(
+ ctx->id_param,
+ ctx->ticks_param,
+ ctx->routine_param,
+ ctx
+ );
+ ctx->post_state = GetTimerState( ctx->timer_id );
+ GetTimerSchedulingData( ctx->timer_id, &ctx->post_scheduling_data );
+ /* Ignoring return status: the timer server task may be suspended or not. */
+ rtems_task_resume( GetTimerServerTaskId() );
+}
+
+static void RtemsTimerReqServerFireAfter_Cleanup(
+ RtemsTimerReqServerFireAfter_Context *ctx
+)
+{
+ T_rsc_success( rtems_timer_delete( ctx->timer_cover_id ) );
+ T_rsc_success( rtems_timer_delete( ctx->timer_id ) );
+ DeleteTimerServer();
+}
+
+static const RtemsTimerReqServerFireAfter_Entry
+RtemsTimerReqServerFireAfter_Entries[] = {
+ { 1, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqServerFireAfter_Post_Status_NA,
+ RtemsTimerReqServerFireAfter_Post_Context_NA,
+ RtemsTimerReqServerFireAfter_Post_Clock_NA,
+ RtemsTimerReqServerFireAfter_Post_State_NA,
+ RtemsTimerReqServerFireAfter_Post_Interval_NA,
+ RtemsTimerReqServerFireAfter_Post_Routine_NA,
+ RtemsTimerReqServerFireAfter_Post_UserData_NA },
+ { 1, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqServerFireAfter_Post_Status_NA,
+ RtemsTimerReqServerFireAfter_Post_Context_NA,
+ RtemsTimerReqServerFireAfter_Post_Clock_NA,
+ RtemsTimerReqServerFireAfter_Post_State_NA,
+ RtemsTimerReqServerFireAfter_Post_Interval_NA,
+ RtemsTimerReqServerFireAfter_Post_Routine_NA,
+ RtemsTimerReqServerFireAfter_Post_UserData_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqServerFireAfter_Post_Status_InvNum,
+ RtemsTimerReqServerFireAfter_Post_Context_Nop,
+ RtemsTimerReqServerFireAfter_Post_Clock_Nop,
+ RtemsTimerReqServerFireAfter_Post_State_Nop,
+ RtemsTimerReqServerFireAfter_Post_Interval_Nop,
+ RtemsTimerReqServerFireAfter_Post_Routine_Nop,
+ RtemsTimerReqServerFireAfter_Post_UserData_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqServerFireAfter_Post_Status_IncStat,
+ RtemsTimerReqServerFireAfter_Post_Context_Nop,
+ RtemsTimerReqServerFireAfter_Post_Clock_Nop,
+ RtemsTimerReqServerFireAfter_Post_State_Nop,
+ RtemsTimerReqServerFireAfter_Post_Interval_Nop,
+ RtemsTimerReqServerFireAfter_Post_Routine_Nop,
+ RtemsTimerReqServerFireAfter_Post_UserData_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqServerFireAfter_Post_Status_InvAddr,
+ RtemsTimerReqServerFireAfter_Post_Context_Nop,
+ RtemsTimerReqServerFireAfter_Post_Clock_Nop,
+ RtemsTimerReqServerFireAfter_Post_State_Nop,
+ RtemsTimerReqServerFireAfter_Post_Interval_Nop,
+ RtemsTimerReqServerFireAfter_Post_Routine_Nop,
+ RtemsTimerReqServerFireAfter_Post_UserData_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqServerFireAfter_Post_Status_Ok,
+ RtemsTimerReqServerFireAfter_Post_Context_Server,
+ RtemsTimerReqServerFireAfter_Post_Clock_Ticks,
+ RtemsTimerReqServerFireAfter_Post_State_Scheduled,
+ RtemsTimerReqServerFireAfter_Post_Interval_Param,
+ RtemsTimerReqServerFireAfter_Post_Routine_Param,
+ RtemsTimerReqServerFireAfter_Post_UserData_Param },
+ { 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqServerFireAfter_Post_Status_InvId,
+ RtemsTimerReqServerFireAfter_Post_Context_Nop,
+ RtemsTimerReqServerFireAfter_Post_Clock_Nop,
+ RtemsTimerReqServerFireAfter_Post_State_Nop,
+ RtemsTimerReqServerFireAfter_Post_Interval_Nop,
+ RtemsTimerReqServerFireAfter_Post_Routine_Nop,
+ RtemsTimerReqServerFireAfter_Post_UserData_Nop }
+};
+
+static const uint8_t
+RtemsTimerReqServerFireAfter_Map[] = {
+ 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 5, 5, 0, 0, 0, 0, 5, 5, 5, 5, 5,
+ 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 6, 6, 0, 0, 0, 0, 6, 6, 6, 6,
+ 6, 6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0, 4, 4, 4,
+ 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0, 0, 4, 4,
+ 4, 4, 4, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0, 2,
+ 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0, 0,
+ 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0, 0,
+ 0, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 2, 2, 0, 0,
+ 0, 0, 2, 2, 2, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 3, 3, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 3, 3,
+ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 3,
+ 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0,
+ 3, 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3,
+ 0, 3, 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 3, 0, 3, 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 3, 3, 0, 3, 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 3, 0, 3, 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1
+};
+
+static size_t RtemsTimerReqServerFireAfter_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ RtemsTimerReqServerFireAfter_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsTimerReqServerFireAfter_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTimerReqServerFireAfter_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = RtemsTimerReqServerFireAfter_Teardown_Wrap,
+ .scope = RtemsTimerReqServerFireAfter_Scope,
+ .initial_context = &RtemsTimerReqServerFireAfter_Instance
+};
+
+static inline RtemsTimerReqServerFireAfter_Entry
+RtemsTimerReqServerFireAfter_PopEntry(
+ RtemsTimerReqServerFireAfter_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTimerReqServerFireAfter_Entries[
+ RtemsTimerReqServerFireAfter_Map[ index ]
+ ];
+}
+
+static void RtemsTimerReqServerFireAfter_TestVariant(
+ RtemsTimerReqServerFireAfter_Context *ctx
+)
+{
+ RtemsTimerReqServerFireAfter_Pre_Server_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTimerReqServerFireAfter_Pre_Ticks_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTimerReqServerFireAfter_Pre_Routine_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTimerReqServerFireAfter_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsTimerReqServerFireAfter_Pre_Context_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsTimerReqServerFireAfter_Pre_Clock_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsTimerReqServerFireAfter_Pre_State_Prepare( ctx, ctx->Map.pcs[ 6 ] );
+ RtemsTimerReqServerFireAfter_Action( ctx );
+ RtemsTimerReqServerFireAfter_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ RtemsTimerReqServerFireAfter_Post_Context_Check(
+ ctx,
+ ctx->Map.entry.Post_Context
+ );
+ RtemsTimerReqServerFireAfter_Post_Clock_Check(
+ ctx,
+ ctx->Map.entry.Post_Clock
+ );
+ RtemsTimerReqServerFireAfter_Post_State_Check(
+ ctx,
+ ctx->Map.entry.Post_State
+ );
+ RtemsTimerReqServerFireAfter_Post_Interval_Check(
+ ctx,
+ ctx->Map.entry.Post_Interval
+ );
+ RtemsTimerReqServerFireAfter_Post_Routine_Check(
+ ctx,
+ ctx->Map.entry.Post_Routine
+ );
+ RtemsTimerReqServerFireAfter_Post_UserData_Check(
+ ctx,
+ ctx->Map.entry.Post_UserData
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsTimerReqServerFireAfter( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTimerReqServerFireAfter,
+ &RtemsTimerReqServerFireAfter_Fixture
+)
+{
+ RtemsTimerReqServerFireAfter_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsTimerReqServerFireAfter_Pre_Server_Init;
+ ctx->Map.pcs[ 0 ] < RtemsTimerReqServerFireAfter_Pre_Server_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsTimerReqServerFireAfter_Pre_Ticks_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsTimerReqServerFireAfter_Pre_Ticks_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsTimerReqServerFireAfter_Pre_Routine_Valid;
+ ctx->Map.pcs[ 2 ] < RtemsTimerReqServerFireAfter_Pre_Routine_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsTimerReqServerFireAfter_Pre_Id_Valid;
+ ctx->Map.pcs[ 3 ] < RtemsTimerReqServerFireAfter_Pre_Id_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = RtemsTimerReqServerFireAfter_Pre_Context_None;
+ ctx->Map.pcs[ 4 ] < RtemsTimerReqServerFireAfter_Pre_Context_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 5 ] = RtemsTimerReqServerFireAfter_Pre_Clock_None;
+ ctx->Map.pcs[ 5 ] < RtemsTimerReqServerFireAfter_Pre_Clock_NA;
+ ++ctx->Map.pcs[ 5 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 6 ] = RtemsTimerReqServerFireAfter_Pre_State_Inactive;
+ ctx->Map.pcs[ 6 ] < RtemsTimerReqServerFireAfter_Pre_State_NA;
+ ++ctx->Map.pcs[ 6 ]
+ ) {
+ ctx->Map.entry = RtemsTimerReqServerFireAfter_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsTimerReqServerFireAfter_Prepare( ctx );
+ RtemsTimerReqServerFireAfter_TestVariant( ctx );
+ RtemsTimerReqServerFireAfter_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-timer-server-fire-when.c b/testsuites/validation/tc-timer-server-fire-when.c
new file mode 100644
index 0000000000..d9c5ba8221
--- /dev/null
+++ b/testsuites/validation/tc-timer-server-fire-when.c
@@ -0,0 +1,1416 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTimerReqServerFireWhen
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTimerReqServerFireWhen spec:/rtems/timer/req/server-fire-when
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsTimerReqServerFireWhen_Pre_Server_Init,
+ RtemsTimerReqServerFireWhen_Pre_Server_NotInit,
+ RtemsTimerReqServerFireWhen_Pre_Server_NA
+} RtemsTimerReqServerFireWhen_Pre_Server;
+
+typedef enum {
+ RtemsTimerReqServerFireWhen_Pre_RtClock_Set,
+ RtemsTimerReqServerFireWhen_Pre_RtClock_Unset,
+ RtemsTimerReqServerFireWhen_Pre_RtClock_NA
+} RtemsTimerReqServerFireWhen_Pre_RtClock;
+
+typedef enum {
+ RtemsTimerReqServerFireWhen_Pre_Routine_Valid,
+ RtemsTimerReqServerFireWhen_Pre_Routine_Null,
+ RtemsTimerReqServerFireWhen_Pre_Routine_NA
+} RtemsTimerReqServerFireWhen_Pre_Routine;
+
+typedef enum {
+ RtemsTimerReqServerFireWhen_Pre_WallTime_Valid,
+ RtemsTimerReqServerFireWhen_Pre_WallTime_Invalid,
+ RtemsTimerReqServerFireWhen_Pre_WallTime_Past,
+ RtemsTimerReqServerFireWhen_Pre_WallTime_Null,
+ RtemsTimerReqServerFireWhen_Pre_WallTime_NA
+} RtemsTimerReqServerFireWhen_Pre_WallTime;
+
+typedef enum {
+ RtemsTimerReqServerFireWhen_Pre_Id_Valid,
+ RtemsTimerReqServerFireWhen_Pre_Id_Invalid,
+ RtemsTimerReqServerFireWhen_Pre_Id_NA
+} RtemsTimerReqServerFireWhen_Pre_Id;
+
+typedef enum {
+ RtemsTimerReqServerFireWhen_Pre_Context_None,
+ RtemsTimerReqServerFireWhen_Pre_Context_Interrupt,
+ RtemsTimerReqServerFireWhen_Pre_Context_Server,
+ RtemsTimerReqServerFireWhen_Pre_Context_NA
+} RtemsTimerReqServerFireWhen_Pre_Context;
+
+typedef enum {
+ RtemsTimerReqServerFireWhen_Pre_Clock_None,
+ RtemsTimerReqServerFireWhen_Pre_Clock_Ticks,
+ RtemsTimerReqServerFireWhen_Pre_Clock_Realtime,
+ RtemsTimerReqServerFireWhen_Pre_Clock_NA
+} RtemsTimerReqServerFireWhen_Pre_Clock;
+
+typedef enum {
+ RtemsTimerReqServerFireWhen_Pre_State_Inactive,
+ RtemsTimerReqServerFireWhen_Pre_State_Scheduled,
+ RtemsTimerReqServerFireWhen_Pre_State_Pending,
+ RtemsTimerReqServerFireWhen_Pre_State_NA
+} RtemsTimerReqServerFireWhen_Pre_State;
+
+typedef enum {
+ RtemsTimerReqServerFireWhen_Post_Status_Ok,
+ RtemsTimerReqServerFireWhen_Post_Status_NotDef,
+ RtemsTimerReqServerFireWhen_Post_Status_InvId,
+ RtemsTimerReqServerFireWhen_Post_Status_InvAddr,
+ RtemsTimerReqServerFireWhen_Post_Status_InvClock,
+ RtemsTimerReqServerFireWhen_Post_Status_IncStat,
+ RtemsTimerReqServerFireWhen_Post_Status_NA
+} RtemsTimerReqServerFireWhen_Post_Status;
+
+typedef enum {
+ RtemsTimerReqServerFireWhen_Post_Context_None,
+ RtemsTimerReqServerFireWhen_Post_Context_Interrupt,
+ RtemsTimerReqServerFireWhen_Post_Context_Server,
+ RtemsTimerReqServerFireWhen_Post_Context_Nop,
+ RtemsTimerReqServerFireWhen_Post_Context_NA
+} RtemsTimerReqServerFireWhen_Post_Context;
+
+typedef enum {
+ RtemsTimerReqServerFireWhen_Post_Clock_None,
+ RtemsTimerReqServerFireWhen_Post_Clock_Ticks,
+ RtemsTimerReqServerFireWhen_Post_Clock_Realtime,
+ RtemsTimerReqServerFireWhen_Post_Clock_Nop,
+ RtemsTimerReqServerFireWhen_Post_Clock_NA
+} RtemsTimerReqServerFireWhen_Post_Clock;
+
+typedef enum {
+ RtemsTimerReqServerFireWhen_Post_State_Scheduled,
+ RtemsTimerReqServerFireWhen_Post_State_Nop,
+ RtemsTimerReqServerFireWhen_Post_State_NA
+} RtemsTimerReqServerFireWhen_Post_State;
+
+typedef enum {
+ RtemsTimerReqServerFireWhen_Post_WallTime_Param,
+ RtemsTimerReqServerFireWhen_Post_WallTime_Nop,
+ RtemsTimerReqServerFireWhen_Post_WallTime_NA
+} RtemsTimerReqServerFireWhen_Post_WallTime;
+
+typedef enum {
+ RtemsTimerReqServerFireWhen_Post_Routine_Param,
+ RtemsTimerReqServerFireWhen_Post_Routine_Nop,
+ RtemsTimerReqServerFireWhen_Post_Routine_NA
+} RtemsTimerReqServerFireWhen_Post_Routine;
+
+typedef enum {
+ RtemsTimerReqServerFireWhen_Post_UserData_Param,
+ RtemsTimerReqServerFireWhen_Post_UserData_Nop,
+ RtemsTimerReqServerFireWhen_Post_UserData_NA
+} RtemsTimerReqServerFireWhen_Post_UserData;
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_Server_NA : 1;
+ uint32_t Pre_RtClock_NA : 1;
+ uint32_t Pre_Routine_NA : 1;
+ uint32_t Pre_WallTime_NA : 1;
+ uint32_t Pre_Id_NA : 1;
+ uint32_t Pre_Context_NA : 1;
+ uint32_t Pre_Clock_NA : 1;
+ uint32_t Pre_State_NA : 1;
+ uint32_t Post_Status : 3;
+ uint32_t Post_Context : 3;
+ uint32_t Post_Clock : 3;
+ uint32_t Post_State : 2;
+ uint32_t Post_WallTime : 2;
+ uint32_t Post_Routine : 2;
+ uint32_t Post_UserData : 2;
+} RtemsTimerReqServerFireWhen_Entry;
+
+typedef enum {
+ PRE_NONE = 0,
+ PRE_INTERRUPT = 1,
+ PRE_SERVER = 2
+} PreConditionContext;
+
+typedef enum {
+ SCHEDULE_NONE = 0,
+ SCHEDULE_SOON = 1,
+ SCHEDULE_MAX = 5
+} Scheduling_Ticks;
+
+/**
+ * @brief Test context for spec:/rtems/timer/req/server-fire-when test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a valid id of a timer.
+ */
+ rtems_id timer_id;
+
+ /**
+ * @brief This member specifies the ``id`` parameter for the action.
+ */
+ rtems_id id_param;
+
+ /**
+ * @brief This member specifies the ``wall_time`` parameter for the action.
+ */
+ const rtems_time_of_day *wall_time_param;
+
+ /**
+ * @brief This member specifies the ``routine`` parameter for the action.
+ */
+ rtems_timer_service_routine_entry routine_param;
+
+ /**
+ * @brief This member contains the returned status code of the action.
+ */
+ rtems_status_code status;
+
+ /**
+ * @brief This member contains a counter of invocations of the Timer Service
+ * Routine.
+ */
+ int invocations;
+
+ /**
+ * @brief Function TriggerTimer() is used to figure out when the Timer
+ * Service Routine gets executed. This member contains the time-of-day when
+ * the Timer Service Routine fires (see fire).
+ */
+ rtems_time_of_day tod_till_fire;
+
+ /**
+ * @brief This member contains the user data given to the Timer Service
+ * Routine when called.
+ */
+ void *routine_user_data;
+
+ /**
+ * @brief This member specifies which pre-condition context (none, interrupt
+ * context, server context) must be created before the
+ * rtems_timer_server_fire_when() action gets executed.
+ */
+ PreConditionContext pre_cond_contex;
+
+ /**
+ * @brief This member specifies the pre-condition state of the realtime
+ * clock. It should either be set to the value referenced by pre_cond_tod
+ * or if NULL, then the realtime clock should be not set.
+ */
+ const rtems_time_of_day *pre_cond_tod;
+
+ /**
+ * @brief This member stores internal clock and context settings of the timer
+ * before the execution of the test action.
+ */
+ Timer_Classes pre_class;
+
+ /**
+ * @brief This member stores the state of the timer before the execution of
+ * the test action.
+ */
+ Timer_States pre_state;
+
+ /**
+ * @brief This member stores the state of the timer after the execution of
+ * the test action.
+ */
+ Timer_States post_state;
+
+ /**
+ * @brief This member stores the scheduling data of the timer before the
+ * execution of the test action.
+ */
+ Timer_Scheduling_Data pre_scheduling_data;
+
+ /**
+ * @brief This member stores the scheduling data of the timer after the
+ * execution of the test action.
+ */
+ Timer_Scheduling_Data post_scheduling_data;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 8 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsTimerReqServerFireWhen_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsTimerReqServerFireWhen_Context;
+
+static RtemsTimerReqServerFireWhen_Context
+ RtemsTimerReqServerFireWhen_Instance;
+
+static const char * const RtemsTimerReqServerFireWhen_PreDesc_Server[] = {
+ "Init",
+ "NotInit",
+ "NA"
+};
+
+static const char * const RtemsTimerReqServerFireWhen_PreDesc_RtClock[] = {
+ "Set",
+ "Unset",
+ "NA"
+};
+
+static const char * const RtemsTimerReqServerFireWhen_PreDesc_Routine[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsTimerReqServerFireWhen_PreDesc_WallTime[] = {
+ "Valid",
+ "Invalid",
+ "Past",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsTimerReqServerFireWhen_PreDesc_Id[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsTimerReqServerFireWhen_PreDesc_Context[] = {
+ "None",
+ "Interrupt",
+ "Server",
+ "NA"
+};
+
+static const char * const RtemsTimerReqServerFireWhen_PreDesc_Clock[] = {
+ "None",
+ "Ticks",
+ "Realtime",
+ "NA"
+};
+
+static const char * const RtemsTimerReqServerFireWhen_PreDesc_State[] = {
+ "Inactive",
+ "Scheduled",
+ "Pending",
+ "NA"
+};
+
+static const char * const * const RtemsTimerReqServerFireWhen_PreDesc[] = {
+ RtemsTimerReqServerFireWhen_PreDesc_Server,
+ RtemsTimerReqServerFireWhen_PreDesc_RtClock,
+ RtemsTimerReqServerFireWhen_PreDesc_Routine,
+ RtemsTimerReqServerFireWhen_PreDesc_WallTime,
+ RtemsTimerReqServerFireWhen_PreDesc_Id,
+ RtemsTimerReqServerFireWhen_PreDesc_Context,
+ RtemsTimerReqServerFireWhen_PreDesc_Clock,
+ RtemsTimerReqServerFireWhen_PreDesc_State,
+ NULL
+};
+
+static const rtems_time_of_day tod_now = { 2000, 1, 1, 0, 0, 0, 0 };
+static const rtems_time_of_day tod_schedule = { 2000, 1, 1, 5, 0, 0, 0 };
+static const rtems_time_of_day tod_invalid = { 1985, 1, 1, 0, 0, 0, 0 };
+static const rtems_time_of_day tod_past = { 1999, 12, 31, 23, 59, 59, 1 };
+
+static void TriggerTimer(
+ const RtemsTimerReqServerFireWhen_Context *ctx,
+ rtems_time_of_day *tod_fire
+)
+{
+ rtems_time_of_day tod = tod_now;
+ int invocations_old = ctx->invocations;
+ int i;
+
+ /* Fire the timer service routine for ticks and realtime clock */
+ for ( i = 1; i <= SCHEDULE_MAX; ++i ) {
+ ClockTick();
+ }
+
+ for ( i = 1; i < 24; ++i ) {
+ tod.hour = i;
+ T_rsc_success( rtems_clock_set( &tod ) );
+ if ( tod_fire != NULL && ctx->invocations > invocations_old ) {
+ *tod_fire = tod;
+ break;
+ }
+ }
+}
+
+static void TimerServiceRoutine(
+ rtems_id timer_id,
+ void *user_data
+)
+{
+ RtemsTimerReqServerFireWhen_Context *ctx = user_data;
+ ++( ctx->invocations );
+ ctx->routine_user_data = user_data;
+}
+
+static void RtemsTimerReqServerFireWhen_Pre_Server_Prepare(
+ RtemsTimerReqServerFireWhen_Context *ctx,
+ RtemsTimerReqServerFireWhen_Pre_Server state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireWhen_Pre_Server_Init: {
+ /*
+ * While the Timer Server task has been successfully initialized by a
+ * call to rtems_timer_initiate_server().
+ */
+ rtems_status_code status;
+ status = rtems_timer_initiate_server(
+ RTEMS_TIMER_SERVER_DEFAULT_PRIORITY,
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_ATTRIBUTES
+ );
+ T_rsc_success( status );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_Server_NotInit: {
+ /*
+ * While the Timer Server task has not been initialized and does not
+ * exist.
+ */
+ DeleteTimerServer();
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_Server_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireWhen_Pre_RtClock_Prepare(
+ RtemsTimerReqServerFireWhen_Context *ctx,
+ RtemsTimerReqServerFireWhen_Pre_RtClock state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireWhen_Pre_RtClock_Set: {
+ /*
+ * While the realtime clock is set to a valid time-of-day.
+ */
+ ctx->pre_cond_tod = &tod_now;
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_RtClock_Unset: {
+ /*
+ * While the realtime clock has never been set.
+ */
+ ctx->pre_cond_tod = NULL;
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_RtClock_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireWhen_Pre_Routine_Prepare(
+ RtemsTimerReqServerFireWhen_Context *ctx,
+ RtemsTimerReqServerFireWhen_Pre_Routine state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireWhen_Pre_Routine_Valid: {
+ /*
+ * While the ``routine`` parameter references an object of type
+ * rtems_timer_service_routine_entry.
+ */
+ ctx->routine_param = TimerServiceRoutine;
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_Routine_Null: {
+ /*
+ * While the ``routine`` parameter is NULL..
+ */
+ ctx->routine_param = NULL;
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_Routine_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireWhen_Pre_WallTime_Prepare(
+ RtemsTimerReqServerFireWhen_Context *ctx,
+ RtemsTimerReqServerFireWhen_Pre_WallTime state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireWhen_Pre_WallTime_Valid: {
+ /*
+ * While the ``wall_time`` parameter references a time at least one
+ * second in the future but not later than the last second of the year
+ * 2105. (Times after 2105 are invalid.)
+ */
+ ctx->wall_time_param = &tod_schedule;
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_WallTime_Invalid: {
+ /*
+ * While the ``wall_time`` parameter is invalid.
+ */
+ ctx->wall_time_param = &tod_invalid;
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_WallTime_Past: {
+ /*
+ * While the ``wall_time`` parameter references a time in the current
+ * second or in the past but not earlier than 1988. (Times before 1988
+ * are invalid.)
+ */
+ ctx->wall_time_param = &tod_past;
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_WallTime_Null: {
+ /*
+ * While the ``wall_time`` parameter is 0.
+ */
+ ctx->wall_time_param = NULL;
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_WallTime_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireWhen_Pre_Id_Prepare(
+ RtemsTimerReqServerFireWhen_Context *ctx,
+ RtemsTimerReqServerFireWhen_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireWhen_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter is valid.
+ */
+ ctx->id_param = ctx->timer_id;
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_Id_Invalid: {
+ /*
+ * While the ``id`` parameter is invalid.
+ */
+ ctx->id_param = RTEMS_ID_NONE;
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireWhen_Pre_Context_Prepare(
+ RtemsTimerReqServerFireWhen_Context *ctx,
+ RtemsTimerReqServerFireWhen_Pre_Context state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireWhen_Pre_Context_None: {
+ /*
+ * While the Timer Service Routine has never been scheduled since
+ * creation of the timer. See also none.
+ */
+ ctx->pre_cond_contex = PRE_NONE;
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_Context_Interrupt: {
+ /*
+ * While the timer is in interrupt context.
+ */
+ ctx->pre_cond_contex = PRE_INTERRUPT;
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_Context_Server: {
+ /*
+ * While the timer is in server context.
+ */
+ ctx->pre_cond_contex = PRE_SERVER;
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_Context_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireWhen_Pre_Clock_Prepare(
+ RtemsTimerReqServerFireWhen_Context *ctx,
+ RtemsTimerReqServerFireWhen_Pre_Clock state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireWhen_Pre_Clock_None: {
+ /*
+ * While the timer has never been scheduled since creation of the timer.
+ */
+ T_eq_int( ctx->pre_cond_contex, PRE_NONE );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_Clock_Ticks: {
+ /*
+ * While the clock used to determine when the timer will fire is the
+ * ticks based clock.
+ */
+ rtems_status_code status;
+
+ if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
+ status = rtems_timer_fire_after(
+ ctx->timer_id,
+ SCHEDULE_SOON,
+ TimerServiceRoutine,
+ ctx
+ );
+ } else {
+ status = rtems_timer_server_fire_after(
+ ctx->timer_id,
+ SCHEDULE_SOON,
+ TimerServiceRoutine,
+ ctx
+ );
+ }
+ T_rsc_success( status );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_Clock_Realtime: {
+ /*
+ * While the clock used to determine when the timer will fire is the
+ * realtime clock.
+ */
+ rtems_status_code status;
+ T_rsc_success( rtems_clock_set( &tod_now ) );
+
+ if ( ctx->pre_cond_contex == PRE_INTERRUPT ) {
+ status = rtems_timer_fire_when(
+ ctx->timer_id,
+ &tod_schedule,
+ TimerServiceRoutine,
+ ctx
+ );
+ } else {
+ status = rtems_timer_server_fire_when(
+ ctx->timer_id,
+ &tod_schedule,
+ TimerServiceRoutine,
+ ctx
+ );
+ }
+ T_rsc_success( status );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_Clock_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireWhen_Pre_State_Prepare(
+ RtemsTimerReqServerFireWhen_Context *ctx,
+ RtemsTimerReqServerFireWhen_Pre_State state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireWhen_Pre_State_Inactive: {
+ /*
+ * While the timer is in inactive state.
+ */
+ TriggerTimer( ctx, NULL );
+ T_eq_int(
+ ctx->invocations,
+ ( ctx->pre_cond_contex == PRE_NONE ) ? 0 : 1
+ );
+ ctx->invocations = 0;
+ ctx->pre_state = TIMER_INACTIVE;
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_State_Scheduled: {
+ /*
+ * While the timer is in scheduled state.
+ */
+ /* The timer was already scheduled in the "Clock" pre-conditions. */
+ ctx->pre_state = TIMER_SCHEDULED;
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_State_Pending: {
+ /*
+ * While the timer is in pending state.
+ */
+ T_rsc_success( rtems_task_suspend( GetTimerServerTaskId() ) );
+ TriggerTimer( ctx, NULL );
+ T_eq_int( ctx->invocations, 0 );
+ ctx->pre_state = TIMER_PENDING;
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Pre_State_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireWhen_Post_Status_Check(
+ RtemsTimerReqServerFireWhen_Context *ctx,
+ RtemsTimerReqServerFireWhen_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireWhen_Post_Status_Ok: {
+ /*
+ * The return status of rtems_timer_server_fire_when() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_Status_NotDef: {
+ /*
+ * The return status of rtems_timer_server_fire_when() shall be
+ * RTEMS_NOT_DEFINED
+ */
+ T_rsc( ctx->status, RTEMS_NOT_DEFINED );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_Status_InvId: {
+ /*
+ * The return status of rtems_timer_server_fire_when() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_timer_server_fire_when() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_Status_InvClock: {
+ /*
+ * The return status of rtems_timer_server_fire_when() shall be
+ * RTEMS_INVALID_CLOCK.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_CLOCK );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_Status_IncStat: {
+ /*
+ * The return status of rtems_timer_server_fire_when() shall be
+ * RTEMS_INCORRECT_STATE.
+ */
+ T_rsc( ctx->status, RTEMS_INCORRECT_STATE );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireWhen_Post_Context_Check(
+ RtemsTimerReqServerFireWhen_Context *ctx,
+ RtemsTimerReqServerFireWhen_Post_Context state
+)
+{
+ Timer_Classes class;
+ class = GetTimerClass( ctx->timer_id );
+
+ switch ( state ) {
+ case RtemsTimerReqServerFireWhen_Post_Context_None: {
+ /*
+ * The timer shall have never been scheduled. See also none.
+ */
+ T_eq_int( class, TIMER_DORMANT );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_Context_Interrupt: {
+ /*
+ * The timer shall be in interrupt context.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, 0 );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_Context_Server: {
+ /*
+ * The timer shall be in server context.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_ON_TASK, TIMER_CLASS_BIT_ON_TASK );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_Context_Nop: {
+ /*
+ * Objects referenced by parameters in the past call to
+ * rtems_timer_server_fire_when() shall not be accessed by the
+ * rtems_timer_server_fire_when() call. See also Nop.
+ */
+ T_eq_int( class, ctx->pre_class );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_Context_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireWhen_Post_Clock_Check(
+ RtemsTimerReqServerFireWhen_Context *ctx,
+ RtemsTimerReqServerFireWhen_Post_Clock state
+)
+{
+ Timer_Classes class;
+ class = GetTimerClass( ctx->timer_id );
+
+ switch ( state ) {
+ case RtemsTimerReqServerFireWhen_Post_Clock_None: {
+ /*
+ * The timer shall have never been scheduled.
+ */
+ T_eq_int( class, TIMER_DORMANT );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_Clock_Ticks: {
+ /*
+ * The timer shall use the ticks based clock.
+ */
+ T_eq_int( class & TIMER_CLASS_BIT_TIME_OF_DAY, 0 );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_Clock_Realtime: {
+ /*
+ * The timer shall use the realtime clock.
+ */
+ T_eq_int(
+ class & TIMER_CLASS_BIT_TIME_OF_DAY,
+ TIMER_CLASS_BIT_TIME_OF_DAY
+ );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_Clock_Nop: {
+ /*
+ * Objects referenced by parameters in the past call to
+ * rtems_timer_server_fire_when() shall not be accessed by the
+ * rtems_timer_server_fire_when() call.
+ */
+ T_eq_int( class, ctx->pre_class );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_Clock_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireWhen_Post_State_Check(
+ RtemsTimerReqServerFireWhen_Context *ctx,
+ RtemsTimerReqServerFireWhen_Post_State state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireWhen_Post_State_Scheduled: {
+ /*
+ * The timer shall be in scheduled state.
+ */
+ TriggerTimer( ctx, &ctx->tod_till_fire );
+ T_eq_int( ctx->invocations, 1 );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_State_Nop: {
+ /*
+ * Objects referenced by parameters in the past call to
+ * rtems_timer_server_fire_when() shall not be accessed by the
+ * rtems_timer_server_fire_when() call.
+ */
+ T_eq_int( ctx->post_state, ctx->pre_state );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_State_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireWhen_Post_WallTime_Check(
+ RtemsTimerReqServerFireWhen_Context *ctx,
+ RtemsTimerReqServerFireWhen_Post_WallTime state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireWhen_Post_WallTime_Param: {
+ /*
+ * The Timer Service Routine shall be invoked at the wall time (see
+ * realtime clock) (ignoring ticks), which was provided by the
+ * ``wall_time`` parameter in the past call to
+ * rtems_timer_server_fire_when().
+ */
+ T_eq_mem(
+ &ctx->tod_till_fire,
+ ctx->wall_time_param,
+ sizeof( ctx->tod_till_fire )
+ );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_WallTime_Nop: {
+ /*
+ * If and when the Timer Service Routine will be invoked shall not be
+ * changed by the past call to rtems_timer_server_fire_when().
+ */
+ /*
+ * Whether the timer is scheduled has already been tested by the
+ * "Nop" "State" post-condition above.
+ */
+ T_eq_u32(
+ ctx->post_scheduling_data.interval,
+ ctx->pre_scheduling_data.interval
+ );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_WallTime_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireWhen_Post_Routine_Check(
+ RtemsTimerReqServerFireWhen_Context *ctx,
+ RtemsTimerReqServerFireWhen_Post_Routine state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireWhen_Post_Routine_Param: {
+ /*
+ * The function reference used to invoke the Timer Service Routine when
+ * the timer will fire shall be the one provided by the ``routine``
+ * parameter in the past call to rtems_timer_server_fire_when().
+ */
+ T_eq_int( ctx->invocations, 1 );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_Routine_Nop: {
+ /*
+ * The function reference used for any invocation of the Timer Service
+ * Routine shall not be changed by the past call to
+ * rtems_timer_server_fire_when().
+ */
+ T_eq_ptr(
+ ctx->post_scheduling_data.routine,
+ ctx->pre_scheduling_data.routine
+ );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_Routine_NA:
+ break;
+ }
+}
+
+static void RtemsTimerReqServerFireWhen_Post_UserData_Check(
+ RtemsTimerReqServerFireWhen_Context *ctx,
+ RtemsTimerReqServerFireWhen_Post_UserData state
+)
+{
+ switch ( state ) {
+ case RtemsTimerReqServerFireWhen_Post_UserData_Param: {
+ /*
+ * The user data argument for invoking the Timer Service Routine when the
+ * timer will fire shall be the one provided by the ``user_data``
+ * parameter in the past call to rtems_timer_server_fire_when().
+ */
+ T_eq_ptr( ctx->routine_user_data, ctx );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_UserData_Nop: {
+ /*
+ * The user data argument used for any invocation of the Timer Service
+ * Routine shall not be changed by the past call to
+ * rtems_timer_server_fire_when().
+ */
+ T_eq_ptr(
+ ctx->post_scheduling_data.user_data,
+ ctx->pre_scheduling_data.user_data
+ );
+ break;
+ }
+
+ case RtemsTimerReqServerFireWhen_Post_UserData_NA:
+ break;
+ }
+}
+
+/**
+ * @brief Make sure the realtime clock is not set after this test.
+ */
+static void RtemsTimerReqServerFireWhen_Teardown(
+ RtemsTimerReqServerFireWhen_Context *ctx
+)
+{
+ UnsetClock();
+}
+
+static void RtemsTimerReqServerFireWhen_Teardown_Wrap( void *arg )
+{
+ RtemsTimerReqServerFireWhen_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsTimerReqServerFireWhen_Teardown( ctx );
+}
+
+static void RtemsTimerReqServerFireWhen_Prepare(
+ RtemsTimerReqServerFireWhen_Context *ctx
+)
+{
+ rtems_status_code status;
+ status = rtems_timer_create(
+ rtems_build_name( 'T', 'I', 'M', 'E' ),
+ &ctx->timer_id
+ );
+ T_rsc_success( status );
+
+ ctx->invocations = 0;
+ ctx->routine_user_data = NULL;
+}
+
+static void RtemsTimerReqServerFireWhen_Action(
+ RtemsTimerReqServerFireWhen_Context *ctx
+)
+{
+ GetTimerSchedulingData( ctx->timer_id, &ctx->pre_scheduling_data );
+ ctx->pre_class = GetTimerClass( ctx->timer_id );
+ if ( ctx->pre_cond_tod == NULL ) {
+ UnsetClock();
+ } else {
+ T_rsc_success( rtems_clock_set( ctx->pre_cond_tod ) );
+ }
+ ctx->status = rtems_timer_server_fire_when(
+ ctx->id_param,
+ ctx->wall_time_param,
+ ctx->routine_param,
+ ctx
+ );
+ ctx->post_state = GetTimerState( ctx->timer_id );
+ GetTimerSchedulingData( ctx->timer_id, &ctx->post_scheduling_data );
+ /* Ignoring return status: the timer server task may be suspended or not. */
+ rtems_task_resume( GetTimerServerTaskId() );
+}
+
+static void RtemsTimerReqServerFireWhen_Cleanup(
+ RtemsTimerReqServerFireWhen_Context *ctx
+)
+{
+ T_rsc_success( rtems_timer_delete( ctx->timer_id ) );
+ DeleteTimerServer();
+}
+
+static const RtemsTimerReqServerFireWhen_Entry
+RtemsTimerReqServerFireWhen_Entries[] = {
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqServerFireWhen_Post_Status_NA,
+ RtemsTimerReqServerFireWhen_Post_Context_NA,
+ RtemsTimerReqServerFireWhen_Post_Clock_NA,
+ RtemsTimerReqServerFireWhen_Post_State_NA,
+ RtemsTimerReqServerFireWhen_Post_WallTime_NA,
+ RtemsTimerReqServerFireWhen_Post_Routine_NA,
+ RtemsTimerReqServerFireWhen_Post_UserData_NA },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqServerFireWhen_Post_Status_NA,
+ RtemsTimerReqServerFireWhen_Post_Context_NA,
+ RtemsTimerReqServerFireWhen_Post_Clock_NA,
+ RtemsTimerReqServerFireWhen_Post_State_NA,
+ RtemsTimerReqServerFireWhen_Post_WallTime_NA,
+ RtemsTimerReqServerFireWhen_Post_Routine_NA,
+ RtemsTimerReqServerFireWhen_Post_UserData_NA },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqServerFireWhen_Post_Status_NA,
+ RtemsTimerReqServerFireWhen_Post_Context_NA,
+ RtemsTimerReqServerFireWhen_Post_Clock_NA,
+ RtemsTimerReqServerFireWhen_Post_State_NA,
+ RtemsTimerReqServerFireWhen_Post_WallTime_NA,
+ RtemsTimerReqServerFireWhen_Post_Routine_NA,
+ RtemsTimerReqServerFireWhen_Post_UserData_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqServerFireWhen_Post_Status_IncStat,
+ RtemsTimerReqServerFireWhen_Post_Context_Nop,
+ RtemsTimerReqServerFireWhen_Post_Clock_Nop,
+ RtemsTimerReqServerFireWhen_Post_State_Nop,
+ RtemsTimerReqServerFireWhen_Post_WallTime_Nop,
+ RtemsTimerReqServerFireWhen_Post_Routine_Nop,
+ RtemsTimerReqServerFireWhen_Post_UserData_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqServerFireWhen_Post_Status_InvAddr,
+ RtemsTimerReqServerFireWhen_Post_Context_Nop,
+ RtemsTimerReqServerFireWhen_Post_Clock_Nop,
+ RtemsTimerReqServerFireWhen_Post_State_Nop,
+ RtemsTimerReqServerFireWhen_Post_WallTime_Nop,
+ RtemsTimerReqServerFireWhen_Post_Routine_Nop,
+ RtemsTimerReqServerFireWhen_Post_UserData_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqServerFireWhen_Post_Status_NotDef,
+ RtemsTimerReqServerFireWhen_Post_Context_Nop,
+ RtemsTimerReqServerFireWhen_Post_Clock_Nop,
+ RtemsTimerReqServerFireWhen_Post_State_Nop,
+ RtemsTimerReqServerFireWhen_Post_WallTime_Nop,
+ RtemsTimerReqServerFireWhen_Post_Routine_Nop,
+ RtemsTimerReqServerFireWhen_Post_UserData_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ RtemsTimerReqServerFireWhen_Post_Status_InvClock,
+ RtemsTimerReqServerFireWhen_Post_Context_Nop,
+ RtemsTimerReqServerFireWhen_Post_Clock_Nop,
+ RtemsTimerReqServerFireWhen_Post_State_Nop,
+ RtemsTimerReqServerFireWhen_Post_WallTime_Nop,
+ RtemsTimerReqServerFireWhen_Post_Routine_Nop,
+ RtemsTimerReqServerFireWhen_Post_UserData_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqServerFireWhen_Post_Status_Ok,
+ RtemsTimerReqServerFireWhen_Post_Context_Server,
+ RtemsTimerReqServerFireWhen_Post_Clock_Realtime,
+ RtemsTimerReqServerFireWhen_Post_State_Scheduled,
+ RtemsTimerReqServerFireWhen_Post_WallTime_Param,
+ RtemsTimerReqServerFireWhen_Post_Routine_Param,
+ RtemsTimerReqServerFireWhen_Post_UserData_Param },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, RtemsTimerReqServerFireWhen_Post_Status_InvId,
+ RtemsTimerReqServerFireWhen_Post_Context_Nop,
+ RtemsTimerReqServerFireWhen_Post_Clock_Nop,
+ RtemsTimerReqServerFireWhen_Post_State_Nop,
+ RtemsTimerReqServerFireWhen_Post_WallTime_Nop,
+ RtemsTimerReqServerFireWhen_Post_Routine_Nop,
+ RtemsTimerReqServerFireWhen_Post_UserData_Nop }
+};
+
+static const uint8_t
+RtemsTimerReqServerFireWhen_Map[] = {
+ 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 7, 7, 0, 0, 0, 0, 7, 7, 7, 7, 7,
+ 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 8, 8, 0, 0, 0, 0, 8, 8, 8, 8,
+ 8, 8, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 6, 6, 0, 0, 0, 0, 6, 6, 6,
+ 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 6, 6, 0, 0, 0, 0, 6, 6,
+ 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 6, 6, 0, 0, 0, 0, 6,
+ 6, 6, 6, 6, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 6, 0, 6, 6, 0, 0, 0, 0,
+ 6, 6, 6, 6, 6, 6, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0, 0,
+ 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 0, 0,
+ 0, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 4, 0,
+ 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4, 4,
+ 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 4,
+ 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0,
+ 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4,
+ 0, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
+ 4, 0, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 4, 4, 0, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 4, 4, 0, 4, 4, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 5, 5, 0, 2, 2, 2, 0, 0, 0, 5, 5, 5, 2, 2, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 5, 5, 0, 2, 2, 2, 0, 0, 0, 5, 5, 5, 2, 2, 2, 5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 5, 5, 0, 2, 2, 2, 0, 0, 0, 5, 5, 5, 2, 2, 2, 5, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 5, 5, 0, 2, 2, 2, 0, 0, 0, 5, 5, 5, 2, 2, 2, 5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 5, 5, 0, 2, 2, 2, 0, 0, 0, 5, 5, 5, 2, 2, 2, 5, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 2, 2, 2, 0, 0, 0, 5, 5, 5, 2, 2, 2, 5, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 2, 2, 2, 0, 0, 0, 5, 5, 5, 2, 2, 2, 5, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 2, 2, 2, 0, 0, 0, 5, 5, 5, 2, 2, 2, 5, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 2, 2, 2, 0, 0, 0, 5, 5, 5, 2, 2, 2, 5,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 2, 2, 2, 0, 0, 0, 5, 5, 5, 2, 2, 2,
+ 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 2, 2, 2, 0, 0, 0, 5, 5, 5, 2, 2,
+ 2, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 2, 2, 2, 0, 0, 0, 5, 5, 5, 2,
+ 2, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 2, 2, 2, 0, 0, 0, 5, 5, 5,
+ 2, 2, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 2, 2, 2, 0, 0, 0, 5, 5,
+ 5, 2, 2, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 2, 2, 2, 0, 0, 0, 5,
+ 5, 5, 2, 2, 2, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 2, 2, 2, 0, 0, 0,
+ 5, 5, 5, 2, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 3, 3, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 3, 3,
+ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 3,
+ 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0,
+ 3, 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3,
+ 0, 3, 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 3, 0, 3, 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 3, 3, 0, 3, 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 3, 3, 0, 3, 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 3, 3, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 2, 2, 2, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 2, 2, 2, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 2, 2, 2, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 2, 2, 2, 0, 0, 0, 1, 1, 1, 1, 1, 1,
+ 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 2, 2, 2, 0, 0, 0, 1, 1, 1, 1, 1,
+ 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 2, 2, 2, 0, 0, 0, 1, 1, 1, 1,
+ 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 2, 2, 2, 0, 0, 0, 1, 1, 1,
+ 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 2, 2, 2, 0, 0, 0, 1, 1,
+ 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 2, 2, 2, 0, 0, 0, 1,
+ 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 2, 2, 2, 0, 0, 0,
+ 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 2, 2, 2, 0, 0,
+ 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 2, 2, 2, 0,
+ 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 2, 2, 2,
+ 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 2, 2,
+ 2, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 2,
+ 2, 2, 0, 0, 0, 1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0,
+ 2, 2, 2, 0, 0, 0, 1, 1, 1, 1, 1, 1
+};
+
+static size_t RtemsTimerReqServerFireWhen_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ RtemsTimerReqServerFireWhen_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsTimerReqServerFireWhen_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsTimerReqServerFireWhen_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = RtemsTimerReqServerFireWhen_Teardown_Wrap,
+ .scope = RtemsTimerReqServerFireWhen_Scope,
+ .initial_context = &RtemsTimerReqServerFireWhen_Instance
+};
+
+static inline RtemsTimerReqServerFireWhen_Entry
+RtemsTimerReqServerFireWhen_PopEntry(
+ RtemsTimerReqServerFireWhen_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsTimerReqServerFireWhen_Entries[
+ RtemsTimerReqServerFireWhen_Map[ index ]
+ ];
+}
+
+static void RtemsTimerReqServerFireWhen_TestVariant(
+ RtemsTimerReqServerFireWhen_Context *ctx
+)
+{
+ RtemsTimerReqServerFireWhen_Pre_Server_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsTimerReqServerFireWhen_Pre_RtClock_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsTimerReqServerFireWhen_Pre_Routine_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsTimerReqServerFireWhen_Pre_WallTime_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsTimerReqServerFireWhen_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ RtemsTimerReqServerFireWhen_Pre_Context_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ RtemsTimerReqServerFireWhen_Pre_Clock_Prepare( ctx, ctx->Map.pcs[ 6 ] );
+ RtemsTimerReqServerFireWhen_Pre_State_Prepare( ctx, ctx->Map.pcs[ 7 ] );
+ RtemsTimerReqServerFireWhen_Action( ctx );
+ RtemsTimerReqServerFireWhen_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ RtemsTimerReqServerFireWhen_Post_Context_Check(
+ ctx,
+ ctx->Map.entry.Post_Context
+ );
+ RtemsTimerReqServerFireWhen_Post_Clock_Check(
+ ctx,
+ ctx->Map.entry.Post_Clock
+ );
+ RtemsTimerReqServerFireWhen_Post_State_Check(
+ ctx,
+ ctx->Map.entry.Post_State
+ );
+ RtemsTimerReqServerFireWhen_Post_WallTime_Check(
+ ctx,
+ ctx->Map.entry.Post_WallTime
+ );
+ RtemsTimerReqServerFireWhen_Post_Routine_Check(
+ ctx,
+ ctx->Map.entry.Post_Routine
+ );
+ RtemsTimerReqServerFireWhen_Post_UserData_Check(
+ ctx,
+ ctx->Map.entry.Post_UserData
+ );
+}
+
+/**
+ * @fn void T_case_body_RtemsTimerReqServerFireWhen( void )
+ */
+T_TEST_CASE_FIXTURE(
+ RtemsTimerReqServerFireWhen,
+ &RtemsTimerReqServerFireWhen_Fixture
+)
+{
+ RtemsTimerReqServerFireWhen_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsTimerReqServerFireWhen_Pre_Server_Init;
+ ctx->Map.pcs[ 0 ] < RtemsTimerReqServerFireWhen_Pre_Server_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsTimerReqServerFireWhen_Pre_RtClock_Set;
+ ctx->Map.pcs[ 1 ] < RtemsTimerReqServerFireWhen_Pre_RtClock_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsTimerReqServerFireWhen_Pre_Routine_Valid;
+ ctx->Map.pcs[ 2 ] < RtemsTimerReqServerFireWhen_Pre_Routine_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsTimerReqServerFireWhen_Pre_WallTime_Valid;
+ ctx->Map.pcs[ 3 ] < RtemsTimerReqServerFireWhen_Pre_WallTime_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = RtemsTimerReqServerFireWhen_Pre_Id_Valid;
+ ctx->Map.pcs[ 4 ] < RtemsTimerReqServerFireWhen_Pre_Id_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 5 ] = RtemsTimerReqServerFireWhen_Pre_Context_None;
+ ctx->Map.pcs[ 5 ] < RtemsTimerReqServerFireWhen_Pre_Context_NA;
+ ++ctx->Map.pcs[ 5 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 6 ] = RtemsTimerReqServerFireWhen_Pre_Clock_None;
+ ctx->Map.pcs[ 6 ] < RtemsTimerReqServerFireWhen_Pre_Clock_NA;
+ ++ctx->Map.pcs[ 6 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 7 ] = RtemsTimerReqServerFireWhen_Pre_State_Inactive;
+ ctx->Map.pcs[ 7 ] < RtemsTimerReqServerFireWhen_Pre_State_NA;
+ ++ctx->Map.pcs[ 7 ]
+ ) {
+ ctx->Map.entry = RtemsTimerReqServerFireWhen_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsTimerReqServerFireWhen_Prepare( ctx );
+ RtemsTimerReqServerFireWhen_TestVariant( ctx );
+ RtemsTimerReqServerFireWhen_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-timer.c b/testsuites/validation/tc-timer.c
new file mode 100644
index 0000000000..d33ad6b440
--- /dev/null
+++ b/testsuites/validation/tc-timer.c
@@ -0,0 +1,208 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTimerValTimer
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/score/atomic.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTimerValTimer spec:/rtems/timer/val/timer
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests general timer behaviour.
+ *
+ * This test case performs the following actions:
+ *
+ * - Create a couple of timers.
+ *
+ * - Schedule some timers at the same time point.
+ *
+ * - Fire the timers and check that they fired in the expected order.
+ *
+ * - Clean up all used resources.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/rtems/timer/val/timer test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the timer identifiers.
+ */
+ rtems_id timer_ids[ TEST_MAXIMUM_TIMERS ];
+
+ /**
+ * @brief This member contains the counter.
+ */
+ Atomic_Uint counter;
+
+ /**
+ * @brief This member contains the timer counter snapshots.
+ */
+ unsigned int counter_snapshots[ TEST_MAXIMUM_TIMERS ];
+} RtemsTimerValTimer_Context;
+
+static RtemsTimerValTimer_Context
+ RtemsTimerValTimer_Instance;
+
+typedef RtemsTimerValTimer_Context Context;
+
+static void Timer( rtems_id timer, void *arg )
+{
+ Context *ctx;
+ unsigned int *counter;
+
+ ctx = T_fixture_context();
+ counter = arg;
+ *counter = _Atomic_Fetch_add_uint(
+ &ctx->counter,
+ 1,
+ ATOMIC_ORDER_RELAXED
+ ) + 1;
+}
+
+static void Fire( Context *ctx, size_t i, rtems_interval ticks )
+{
+ rtems_status_code sc;
+
+ ctx->counter_snapshots[ i ] = 0;
+ sc = rtems_timer_fire_after(
+ ctx->timer_ids[ i ],
+ ticks,
+ Timer,
+ &ctx->counter_snapshots[ i ]
+ );
+ T_rsc_success( sc );
+}
+
+static T_fixture RtemsTimerValTimer_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &RtemsTimerValTimer_Instance
+};
+
+/**
+ * @brief Create a couple of timers.
+ */
+static void RtemsTimerValTimer_Action_0( RtemsTimerValTimer_Context *ctx )
+{
+ rtems_status_code sc;
+ size_t i;
+
+ T_assert_eq_sz( TEST_MAXIMUM_TIMERS, 10 );
+
+ _Atomic_Init_uint( &ctx->counter, 0 );
+
+ for ( i = 0; i < TEST_MAXIMUM_TIMERS ; ++i ) {
+ sc = rtems_timer_create(
+ rtems_build_name( 'T', 'E', 'S', 'T' ),
+ &ctx->timer_ids[ i ]
+ );
+ T_rsc_success( sc );
+ }
+
+ /*
+ * Schedule some timers at the same time point.
+ */
+ Fire( ctx, 3, 2 );
+ Fire( ctx, 0, 1 );
+ Fire( ctx, 7, 3 );
+ Fire( ctx, 4, 2 );
+ Fire( ctx, 5, 2 );
+ Fire( ctx, 8, 3 );
+ Fire( ctx, 9, 3 );
+ Fire( ctx, 1, 1 );
+ Fire( ctx, 2, 1 );
+ Fire( ctx, 6, 2 );
+
+ /*
+ * Fire the timers and check that they fired in the expected order.
+ */
+ FinalClockTick();
+
+ for ( i = 0; i < TEST_MAXIMUM_TIMERS ; ++i ) {
+ T_eq_sz( ctx->counter_snapshots[ i ], i + 1 );
+ }
+
+ /*
+ * Clean up all used resources.
+ */
+ for ( i = 0; i < TEST_MAXIMUM_TIMERS ; ++i ) {
+ sc = rtems_timer_delete( ctx->timer_ids[ i ] );
+ T_rsc_success( sc );
+ }
+}
+
+/**
+ * @fn void T_case_body_RtemsTimerValTimer( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsTimerValTimer, &RtemsTimerValTimer_Fixture )
+{
+ RtemsTimerValTimer_Context *ctx;
+
+ ctx = T_fixture_context();
+
+ RtemsTimerValTimer_Action_0( ctx );
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-type.c b/testsuites/validation/tc-type.c
new file mode 100644
index 0000000000..14f9aa1743
--- /dev/null
+++ b/testsuites/validation/tc-type.c
@@ -0,0 +1,130 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsTypeValType
+ */
+
+/*
+ * Copyright (C) 2021, 2023 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/score/objectimpl.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsTypeValType spec:/rtems/type/val/type
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests some @ref RTEMSAPIClassicTypes interfaces.
+ *
+ * This test case performs the following actions:
+ *
+ * - Validate the RTEMS_ID_NONE constant.
+ *
+ * - Assert that RTEMS_ID_NONE cannot be associated with an object because it
+ * has an object index outside the range of valid object indices.
+ *
+ * - Validate the RTEMS_NO_TIMEOUT constant.
+ *
+ * - Assert that RTEMS_NO_TIMEOUT is a compile time constant which evaluates
+ * to a value of zero.
+ *
+ * - Check that RTEMS_NO_TIMEOUT evaluates to a value of zero.
+ *
+ * @{
+ */
+
+/**
+ * @brief Validate the RTEMS_ID_NONE constant.
+ */
+static void RtemsTypeValType_Action_0( void )
+{
+ /* Nothing to do */
+
+ /*
+ * Assert that RTEMS_ID_NONE cannot be associated with an object because it
+ * has an object index outside the range of valid object indices.
+ */
+ RTEMS_STATIC_ASSERT(
+ ( ( RTEMS_ID_NONE >> OBJECTS_INDEX_START_BIT ) &
+ OBJECTS_INDEX_VALID_BITS ) < OBJECTS_INDEX_MINIMUM,
+ ID_NONE
+ );
+}
+
+/**
+ * @brief Validate the RTEMS_NO_TIMEOUT constant.
+ */
+static void RtemsTypeValType_Action_1( void )
+{
+ /* Nothing to do */
+
+ /*
+ * Assert that RTEMS_NO_TIMEOUT is a compile time constant which evaluates to
+ * a value of zero.
+ */
+ RTEMS_STATIC_ASSERT( RTEMS_NO_TIMEOUT == 0, NO_TIMEOUT );
+
+ /*
+ * Check that RTEMS_NO_TIMEOUT evaluates to a value of zero.
+ */
+ T_eq_u32( RTEMS_NO_TIMEOUT, 0 );
+}
+
+/**
+ * @fn void T_case_body_RtemsTypeValType( void )
+ */
+T_TEST_CASE( RtemsTypeValType )
+{
+ RtemsTypeValType_Action_0();
+ RtemsTypeValType_Action_1();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-userext-create.c b/testsuites/validation/tc-userext-create.c
new file mode 100644
index 0000000000..a15ccf6c1a
--- /dev/null
+++ b/testsuites/validation/tc-userext-create.c
@@ -0,0 +1,610 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsUserextReqCreate
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsUserextReqCreate spec:/rtems/userext/req/create
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsUserextReqCreate_Pre_Name_Valid,
+ RtemsUserextReqCreate_Pre_Name_Invalid,
+ RtemsUserextReqCreate_Pre_Name_NA
+} RtemsUserextReqCreate_Pre_Name;
+
+typedef enum {
+ RtemsUserextReqCreate_Pre_Id_Valid,
+ RtemsUserextReqCreate_Pre_Id_Null,
+ RtemsUserextReqCreate_Pre_Id_NA
+} RtemsUserextReqCreate_Pre_Id;
+
+typedef enum {
+ RtemsUserextReqCreate_Pre_Table_TdSw,
+ RtemsUserextReqCreate_Pre_Table_NoTdSw,
+ RtemsUserextReqCreate_Pre_Table_Null,
+ RtemsUserextReqCreate_Pre_Table_NA
+} RtemsUserextReqCreate_Pre_Table;
+
+typedef enum {
+ RtemsUserextReqCreate_Pre_Free_Yes,
+ RtemsUserextReqCreate_Pre_Free_No,
+ RtemsUserextReqCreate_Pre_Free_NA
+} RtemsUserextReqCreate_Pre_Free;
+
+typedef enum {
+ RtemsUserextReqCreate_Post_Status_Ok,
+ RtemsUserextReqCreate_Post_Status_InvName,
+ RtemsUserextReqCreate_Post_Status_InvAddr,
+ RtemsUserextReqCreate_Post_Status_TooMany,
+ RtemsUserextReqCreate_Post_Status_NA
+} RtemsUserextReqCreate_Post_Status;
+
+typedef enum {
+ RtemsUserextReqCreate_Post_Name_Valid,
+ RtemsUserextReqCreate_Post_Name_Invalid,
+ RtemsUserextReqCreate_Post_Name_NA
+} RtemsUserextReqCreate_Post_Name;
+
+typedef enum {
+ RtemsUserextReqCreate_Post_IdVar_Set,
+ RtemsUserextReqCreate_Post_IdVar_Nop,
+ RtemsUserextReqCreate_Post_IdVar_NA
+} RtemsUserextReqCreate_Post_IdVar;
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Name_NA : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_Table_NA : 1;
+ uint16_t Pre_Free_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_Name : 2;
+ uint16_t Post_IdVar : 2;
+} RtemsUserextReqCreate_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/userext/req/create test case.
+ */
+typedef struct {
+ void *seized_objects;
+
+ rtems_extensions_table table_variable;
+
+ rtems_id id_value;
+
+ rtems_name name;
+
+ rtems_extensions_table *table;
+
+ rtems_id *id;
+
+ rtems_status_code status;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 4 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsUserextReqCreate_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsUserextReqCreate_Context;
+
+static RtemsUserextReqCreate_Context
+ RtemsUserextReqCreate_Instance;
+
+static const char * const RtemsUserextReqCreate_PreDesc_Name[] = {
+ "Valid",
+ "Invalid",
+ "NA"
+};
+
+static const char * const RtemsUserextReqCreate_PreDesc_Id[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsUserextReqCreate_PreDesc_Table[] = {
+ "TdSw",
+ "NoTdSw",
+ "Null",
+ "NA"
+};
+
+static const char * const RtemsUserextReqCreate_PreDesc_Free[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const * const RtemsUserextReqCreate_PreDesc[] = {
+ RtemsUserextReqCreate_PreDesc_Name,
+ RtemsUserextReqCreate_PreDesc_Id,
+ RtemsUserextReqCreate_PreDesc_Table,
+ RtemsUserextReqCreate_PreDesc_Free,
+ NULL
+};
+
+#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+static rtems_status_code Create( void *arg, uint32_t *id )
+{
+ static const rtems_extensions_table table;
+
+ return rtems_extension_create(
+ rtems_build_name( 'S', 'I', 'Z', 'E' ),
+ &table,
+ id
+ );
+}
+
+static void ThreadSwitch( rtems_tcb *executing, rtems_tcb *heir)
+{
+ (void) executing;
+ (void) heir;
+}
+
+static void RtemsUserextReqCreate_Pre_Name_Prepare(
+ RtemsUserextReqCreate_Context *ctx,
+ RtemsUserextReqCreate_Pre_Name state
+)
+{
+ switch ( state ) {
+ case RtemsUserextReqCreate_Pre_Name_Valid: {
+ /*
+ * While the ``name`` parameter is valid.
+ */
+ ctx->name = NAME;
+ break;
+ }
+
+ case RtemsUserextReqCreate_Pre_Name_Invalid: {
+ /*
+ * While the ``name`` parameter is invalid.
+ */
+ ctx->name = 0;
+ break;
+ }
+
+ case RtemsUserextReqCreate_Pre_Name_NA:
+ break;
+ }
+}
+
+static void RtemsUserextReqCreate_Pre_Id_Prepare(
+ RtemsUserextReqCreate_Context *ctx,
+ RtemsUserextReqCreate_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsUserextReqCreate_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter references an object of type rtems_id.
+ */
+ ctx->id = &ctx->id_value;
+ break;
+ }
+
+ case RtemsUserextReqCreate_Pre_Id_Null: {
+ /*
+ * While the ``id`` parameter is NULL.
+ */
+ ctx->id = NULL;
+ break;
+ }
+
+ case RtemsUserextReqCreate_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsUserextReqCreate_Pre_Table_Prepare(
+ RtemsUserextReqCreate_Context *ctx,
+ RtemsUserextReqCreate_Pre_Table state
+)
+{
+ switch ( state ) {
+ case RtemsUserextReqCreate_Pre_Table_TdSw: {
+ /*
+ * While the ``extension_table`` parameter references an object of type
+ * rtems_extensions_table, while all extensions except the thread switch
+ * extension of the referenced object are set to NULL or the address of a
+ * corresponding extension, while the thread switch extension of the
+ * referenced object is set to the address of a thread switch extension.
+ */
+ ctx->table = &ctx->table_variable;
+ ctx->table_variable.thread_switch = ThreadSwitch;
+ break;
+ }
+
+ case RtemsUserextReqCreate_Pre_Table_NoTdSw: {
+ /*
+ * While the ``extension_table`` parameter references an object of type
+ * rtems_id, while all extensions except the thread switch extension of
+ * the referenced object are set to NULL or the address of a
+ * corresponding extension, while the thread switch extension of the
+ * referenced object is set to NULL.
+ */
+ ctx->table = &ctx->table_variable;
+ ctx->table_variable.thread_switch = NULL;
+ break;
+ }
+
+ case RtemsUserextReqCreate_Pre_Table_Null: {
+ /*
+ * While the ``extension_table`` parameter is NULL.
+ */
+ ctx->table = NULL;
+ break;
+ }
+
+ case RtemsUserextReqCreate_Pre_Table_NA:
+ break;
+ }
+}
+
+static void RtemsUserextReqCreate_Pre_Free_Prepare(
+ RtemsUserextReqCreate_Context *ctx,
+ RtemsUserextReqCreate_Pre_Free state
+)
+{
+ switch ( state ) {
+ case RtemsUserextReqCreate_Pre_Free_Yes: {
+ /*
+ * While the system has at least one inactive extension set object
+ * available.
+ */
+ /* Nothing to do */
+ break;
+ }
+
+ case RtemsUserextReqCreate_Pre_Free_No: {
+ /*
+ * While the system has no inactive extension set object available.
+ */
+ ctx->seized_objects = T_seize_objects( Create, NULL );
+ break;
+ }
+
+ case RtemsUserextReqCreate_Pre_Free_NA:
+ break;
+ }
+}
+
+static void RtemsUserextReqCreate_Post_Status_Check(
+ RtemsUserextReqCreate_Context *ctx,
+ RtemsUserextReqCreate_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsUserextReqCreate_Post_Status_Ok: {
+ /*
+ * The return status of rtems_extension_create() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsUserextReqCreate_Post_Status_InvName: {
+ /*
+ * The return status of rtems_extension_create() shall be
+ * RTEMS_INVALID_NAME.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsUserextReqCreate_Post_Status_InvAddr: {
+ /*
+ * The return status of rtems_extension_create() shall be
+ * RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsUserextReqCreate_Post_Status_TooMany: {
+ /*
+ * The return status of rtems_extension_create() shall be RTEMS_TOO_MANY.
+ */
+ T_rsc( ctx->status, RTEMS_TOO_MANY );
+ break;
+ }
+
+ case RtemsUserextReqCreate_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsUserextReqCreate_Post_Name_Check(
+ RtemsUserextReqCreate_Context *ctx,
+ RtemsUserextReqCreate_Post_Name state
+)
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ switch ( state ) {
+ case RtemsUserextReqCreate_Post_Name_Valid: {
+ /*
+ * The unique object name shall identify the extension set created by the
+ * rtems_extension_create() call.
+ */
+ id = 0;
+ sc = rtems_extension_ident( NAME, &id );
+ T_rsc_success( sc );
+ T_eq_u32( id, ctx->id_value );
+ break;
+ }
+
+ case RtemsUserextReqCreate_Post_Name_Invalid: {
+ /*
+ * The unique object name shall not identify an extension set.
+ */
+ sc = rtems_extension_ident( NAME, &id );
+ T_rsc( sc, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsUserextReqCreate_Post_Name_NA:
+ break;
+ }
+}
+
+static void RtemsUserextReqCreate_Post_IdVar_Check(
+ RtemsUserextReqCreate_Context *ctx,
+ RtemsUserextReqCreate_Post_IdVar state
+)
+{
+ switch ( state ) {
+ case RtemsUserextReqCreate_Post_IdVar_Set: {
+ /*
+ * The value of the object referenced by the ``extension_table``
+ * parameter shall be set to the object identifier of the created
+ * extension set after the return of the rtems_extension_create() call.
+ */
+ T_eq_ptr( ctx->id, &ctx->id_value );
+ T_ne_u32( ctx->id_value, INVALID_ID );
+ break;
+ }
+
+ case RtemsUserextReqCreate_Post_IdVar_Nop: {
+ /*
+ * Objects referenced by the ``extension_table`` parameter in past calls
+ * to rtems_extension_create() shall not be accessed by the
+ * rtems_extension_create() call.
+ */
+ T_eq_u32( ctx->id_value, INVALID_ID );
+ break;
+ }
+
+ case RtemsUserextReqCreate_Post_IdVar_NA:
+ break;
+ }
+}
+
+static void RtemsUserextReqCreate_Setup( RtemsUserextReqCreate_Context *ctx )
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->id_value = INVALID_ID;
+}
+
+static void RtemsUserextReqCreate_Setup_Wrap( void *arg )
+{
+ RtemsUserextReqCreate_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsUserextReqCreate_Setup( ctx );
+}
+
+static void RtemsUserextReqCreate_Action( RtemsUserextReqCreate_Context *ctx )
+{
+ ctx->status = rtems_extension_create( ctx->name, ctx->table, ctx->id );
+}
+
+static void RtemsUserextReqCreate_Cleanup( RtemsUserextReqCreate_Context *ctx )
+{
+ if ( ctx->id_value != INVALID_ID ) {
+ rtems_status_code sc;
+
+ sc = rtems_extension_delete( ctx->id_value );
+ T_rsc_success( sc );
+
+ ctx->id_value = INVALID_ID;
+ }
+
+ T_surrender_objects( &ctx->seized_objects, rtems_extension_delete );
+}
+
+static const RtemsUserextReqCreate_Entry
+RtemsUserextReqCreate_Entries[] = {
+ { 0, 0, 0, 0, 0, RtemsUserextReqCreate_Post_Status_InvName,
+ RtemsUserextReqCreate_Post_Name_Invalid,
+ RtemsUserextReqCreate_Post_IdVar_Nop },
+ { 0, 0, 0, 0, 0, RtemsUserextReqCreate_Post_Status_InvAddr,
+ RtemsUserextReqCreate_Post_Name_Invalid,
+ RtemsUserextReqCreate_Post_IdVar_Nop },
+ { 0, 0, 0, 0, 0, RtemsUserextReqCreate_Post_Status_Ok,
+ RtemsUserextReqCreate_Post_Name_Valid, RtemsUserextReqCreate_Post_IdVar_Set },
+ { 0, 0, 0, 0, 0, RtemsUserextReqCreate_Post_Status_TooMany,
+ RtemsUserextReqCreate_Post_Name_Invalid,
+ RtemsUserextReqCreate_Post_IdVar_Nop }
+};
+
+static const uint8_t
+RtemsUserextReqCreate_Map[] = {
+ 2, 3, 2, 3, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static size_t RtemsUserextReqCreate_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsUserextReqCreate_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsUserextReqCreate_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsUserextReqCreate_Fixture = {
+ .setup = RtemsUserextReqCreate_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsUserextReqCreate_Scope,
+ .initial_context = &RtemsUserextReqCreate_Instance
+};
+
+static inline RtemsUserextReqCreate_Entry RtemsUserextReqCreate_PopEntry(
+ RtemsUserextReqCreate_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsUserextReqCreate_Entries[
+ RtemsUserextReqCreate_Map[ index ]
+ ];
+}
+
+static void RtemsUserextReqCreate_TestVariant(
+ RtemsUserextReqCreate_Context *ctx
+)
+{
+ RtemsUserextReqCreate_Pre_Name_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsUserextReqCreate_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsUserextReqCreate_Pre_Table_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsUserextReqCreate_Pre_Free_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsUserextReqCreate_Action( ctx );
+ RtemsUserextReqCreate_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsUserextReqCreate_Post_Name_Check( ctx, ctx->Map.entry.Post_Name );
+ RtemsUserextReqCreate_Post_IdVar_Check( ctx, ctx->Map.entry.Post_IdVar );
+}
+
+/**
+ * @fn void T_case_body_RtemsUserextReqCreate( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsUserextReqCreate, &RtemsUserextReqCreate_Fixture )
+{
+ RtemsUserextReqCreate_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsUserextReqCreate_Pre_Name_Valid;
+ ctx->Map.pcs[ 0 ] < RtemsUserextReqCreate_Pre_Name_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsUserextReqCreate_Pre_Id_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsUserextReqCreate_Pre_Id_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsUserextReqCreate_Pre_Table_TdSw;
+ ctx->Map.pcs[ 2 ] < RtemsUserextReqCreate_Pre_Table_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = RtemsUserextReqCreate_Pre_Free_Yes;
+ ctx->Map.pcs[ 3 ] < RtemsUserextReqCreate_Pre_Free_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ ctx->Map.entry = RtemsUserextReqCreate_PopEntry( ctx );
+ RtemsUserextReqCreate_TestVariant( ctx );
+ RtemsUserextReqCreate_Cleanup( ctx );
+ }
+ }
+ }
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-userext-delete.c b/testsuites/validation/tc-userext-delete.c
new file mode 100644
index 0000000000..9827d715bc
--- /dev/null
+++ b/testsuites/validation/tc-userext-delete.c
@@ -0,0 +1,387 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsUserextReqDelete
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <string.h>
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsUserextReqDelete spec:/rtems/userext/req/delete
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsUserextReqDelete_Pre_Id_NoObj,
+ RtemsUserextReqDelete_Pre_Id_ExtTdSw,
+ RtemsUserextReqDelete_Pre_Id_ExtNoTdSw,
+ RtemsUserextReqDelete_Pre_Id_NA
+} RtemsUserextReqDelete_Pre_Id;
+
+typedef enum {
+ RtemsUserextReqDelete_Post_Status_Ok,
+ RtemsUserextReqDelete_Post_Status_InvId,
+ RtemsUserextReqDelete_Post_Status_NA
+} RtemsUserextReqDelete_Post_Status;
+
+typedef enum {
+ RtemsUserextReqDelete_Post_Name_Valid,
+ RtemsUserextReqDelete_Post_Name_Invalid,
+ RtemsUserextReqDelete_Post_Name_NA
+} RtemsUserextReqDelete_Post_Name;
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Post_Status : 2;
+ uint8_t Post_Name : 2;
+} RtemsUserextReqDelete_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/userext/req/delete test case.
+ */
+typedef struct {
+ rtems_id extension_id;
+
+ rtems_extensions_table table;
+
+ rtems_id id;
+
+ rtems_status_code status;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsUserextReqDelete_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsUserextReqDelete_Context;
+
+static RtemsUserextReqDelete_Context
+ RtemsUserextReqDelete_Instance;
+
+static const char * const RtemsUserextReqDelete_PreDesc_Id[] = {
+ "NoObj",
+ "ExtTdSw",
+ "ExtNoTdSw",
+ "NA"
+};
+
+static const char * const * const RtemsUserextReqDelete_PreDesc[] = {
+ RtemsUserextReqDelete_PreDesc_Id,
+ NULL
+};
+
+#define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
+static void ThreadSwitch( rtems_tcb *executing, rtems_tcb *heir)
+{
+ (void) executing;
+ (void) heir;
+}
+
+static void RtemsUserextReqDelete_Pre_Id_Prepare(
+ RtemsUserextReqDelete_Context *ctx,
+ RtemsUserextReqDelete_Pre_Id state
+)
+{
+ rtems_status_code sc;
+ bool valid_id;
+
+ valid_id = false;
+
+ switch ( state ) {
+ case RtemsUserextReqDelete_Pre_Id_NoObj: {
+ /*
+ * While the ``id`` parameter is not associated with an extension set.
+ */
+ /* Already set by prologue */
+ break;
+ }
+
+ case RtemsUserextReqDelete_Pre_Id_ExtTdSw: {
+ /*
+ * While the ``id`` parameter is associated with an extension set with a
+ * thread switch extension.
+ */
+ valid_id = true;
+ ctx->table.thread_switch = ThreadSwitch;
+ break;
+ }
+
+ case RtemsUserextReqDelete_Pre_Id_ExtNoTdSw: {
+ /*
+ * While the ``id`` parameter is associated with an extension set without
+ * a thread switch extension.
+ */
+ valid_id = true;
+ ctx->table.thread_switch = NULL;
+ break;
+ }
+
+ case RtemsUserextReqDelete_Pre_Id_NA:
+ break;
+ }
+
+ sc = rtems_extension_create(
+ NAME,
+ &ctx->table,
+ &ctx->extension_id
+ );
+ T_rsc_success( sc );
+
+ if ( valid_id ) {
+ ctx->id = ctx->extension_id;
+ } else {
+ ctx->id = 0;
+ }
+}
+
+static void RtemsUserextReqDelete_Post_Status_Check(
+ RtemsUserextReqDelete_Context *ctx,
+ RtemsUserextReqDelete_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsUserextReqDelete_Post_Status_Ok: {
+ /*
+ * The return status of rtems_extension_delete() shall be
+ * RTEMS_SUCCESSFUL.
+ */
+ ctx->extension_id = 0;
+ T_rsc_success( ctx->status );
+ break;
+ }
+
+ case RtemsUserextReqDelete_Post_Status_InvId: {
+ /*
+ * The return status of rtems_extension_delete() shall be
+ * RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsUserextReqDelete_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsUserextReqDelete_Post_Name_Check(
+ RtemsUserextReqDelete_Context *ctx,
+ RtemsUserextReqDelete_Post_Name state
+)
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ switch ( state ) {
+ case RtemsUserextReqDelete_Post_Name_Valid: {
+ /*
+ * The unique object name shall identify an extension set.
+ */
+ id = 0;
+ sc = rtems_extension_ident( NAME, &id );
+ T_rsc_success( sc );
+ T_eq_u32( id, ctx->extension_id );
+ break;
+ }
+
+ case RtemsUserextReqDelete_Post_Name_Invalid: {
+ /*
+ * The unique object name shall not identify an extension set.
+ */
+ sc = rtems_extension_ident( NAME, &id );
+ T_rsc( sc, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsUserextReqDelete_Post_Name_NA:
+ break;
+ }
+}
+
+static void RtemsUserextReqDelete_Setup( RtemsUserextReqDelete_Context *ctx )
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+}
+
+static void RtemsUserextReqDelete_Setup_Wrap( void *arg )
+{
+ RtemsUserextReqDelete_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsUserextReqDelete_Setup( ctx );
+}
+
+static void RtemsUserextReqDelete_Action( RtemsUserextReqDelete_Context *ctx )
+{
+ ctx->status = rtems_extension_delete( ctx->id );
+}
+
+static void RtemsUserextReqDelete_Cleanup( RtemsUserextReqDelete_Context *ctx )
+{
+ if ( ctx->extension_id != 0 ) {
+ rtems_status_code sc;
+
+ sc = rtems_extension_delete( ctx->extension_id );
+ T_rsc_success( sc );
+ }
+}
+
+static const RtemsUserextReqDelete_Entry
+RtemsUserextReqDelete_Entries[] = {
+ { 0, 0, RtemsUserextReqDelete_Post_Status_Ok,
+ RtemsUserextReqDelete_Post_Name_Invalid },
+ { 0, 0, RtemsUserextReqDelete_Post_Status_InvId,
+ RtemsUserextReqDelete_Post_Name_Valid }
+};
+
+static const uint8_t
+RtemsUserextReqDelete_Map[] = {
+ 1, 0, 0
+};
+
+static size_t RtemsUserextReqDelete_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsUserextReqDelete_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsUserextReqDelete_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsUserextReqDelete_Fixture = {
+ .setup = RtemsUserextReqDelete_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsUserextReqDelete_Scope,
+ .initial_context = &RtemsUserextReqDelete_Instance
+};
+
+static inline RtemsUserextReqDelete_Entry RtemsUserextReqDelete_PopEntry(
+ RtemsUserextReqDelete_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsUserextReqDelete_Entries[
+ RtemsUserextReqDelete_Map[ index ]
+ ];
+}
+
+static void RtemsUserextReqDelete_TestVariant(
+ RtemsUserextReqDelete_Context *ctx
+)
+{
+ RtemsUserextReqDelete_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsUserextReqDelete_Action( ctx );
+ RtemsUserextReqDelete_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsUserextReqDelete_Post_Name_Check( ctx, ctx->Map.entry.Post_Name );
+}
+
+/**
+ * @fn void T_case_body_RtemsUserextReqDelete( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsUserextReqDelete, &RtemsUserextReqDelete_Fixture )
+{
+ RtemsUserextReqDelete_Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsUserextReqDelete_Pre_Id_NoObj;
+ ctx->Map.pcs[ 0 ] < RtemsUserextReqDelete_Pre_Id_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = RtemsUserextReqDelete_PopEntry( ctx );
+ RtemsUserextReqDelete_TestVariant( ctx );
+ RtemsUserextReqDelete_Cleanup( ctx );
+ }
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-userext-ident.c b/testsuites/validation/tc-userext-ident.c
new file mode 100644
index 0000000000..24646b6a54
--- /dev/null
+++ b/testsuites/validation/tc-userext-ident.c
@@ -0,0 +1,119 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsUserextValIdent
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-object-ident-local.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsUserextValIdent spec:/rtems/userext/val/ident
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Test the rtems_extension_ident() directive.
+ *
+ * This test case performs the following actions:
+ *
+ * - Run the generic object identification tests for Classic API user extension
+ * class objects defined by spec:/rtems/req/ident-local.
+ *
+ * @{
+ */
+
+#define NAME_LOCAL_OBJECT rtems_build_name( 'U', 'E', 'X', 'T' )
+
+static rtems_status_code ClassicUserExtIdentAction(
+ rtems_name name,
+ rtems_id *id
+)
+{
+ return rtems_extension_ident( name, id );
+}
+
+/**
+ * @brief Run the generic object identification tests for Classic API user
+ * extension class objects defined by spec:/rtems/req/ident-local.
+ */
+static void RtemsUserextValIdent_Action_0( void )
+{
+ static const rtems_extensions_table table;
+ rtems_status_code sc;
+ rtems_id id_local_object;
+
+ sc = rtems_extension_create(
+ NAME_LOCAL_OBJECT,
+ &table,
+ &id_local_object
+ );
+ T_assert_rsc_success( sc );
+
+ RtemsReqIdentLocal_Run(
+ id_local_object,
+ NAME_LOCAL_OBJECT,
+ ClassicUserExtIdentAction
+ );
+
+ sc = rtems_extension_delete( id_local_object );
+ T_rsc_success( sc );
+}
+
+/**
+ * @fn void T_case_body_RtemsUserextValIdent( void )
+ */
+T_TEST_CASE( RtemsUserextValIdent )
+{
+ RtemsUserextValIdent_Action_0();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-userext.c b/testsuites/validation/tc-userext.c
new file mode 100644
index 0000000000..192be30669
--- /dev/null
+++ b/testsuites/validation/tc-userext.c
@@ -0,0 +1,918 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsUserextValUserext
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <rtems/score/apimutex.h>
+#include <rtems/score/atomic.h>
+
+#include "tc-userext.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsUserextValUserext spec:/rtems/userext/val/userext
+ *
+ * @ingroup TestsuitesUserext
+ *
+ * @brief Tests the thread user extensions.
+ *
+ * This test case performs the following actions:
+ *
+ * - Create five dynamic extensions. Switch to a started thread. Delete three
+ * dynamic extension during the thread begin invocation. Clean up the used
+ * resources.
+ *
+ * - Check that the thread switch extensions were invoked in the right order
+ * before the thread begin extensions.
+ *
+ * - Check that the thread begin extensions were invoked in the right order.
+ *
+ * - Check that the other extensions were not invoked.
+ *
+ * - Check that the thread begin extension of the extension set deleted
+ * before its turn in the invocation was not invoked.
+ *
+ * - Create five dynamic extensions. Create a thread. Delete three dynamic
+ * extension during the thread create invocation. Clean up the used
+ * resources.
+ *
+ * - Check that the thread create extensions were invoked in the right order.
+ *
+ * - Check that the thread create extensions were invoked under protection of
+ * the allocator mutex.
+ *
+ * - Check that the other extensions were not invoked.
+ *
+ * - Check that the thread create extension of the extension set deleted
+ * before its turn in the invocation was not invoked.
+ *
+ * - Create five dynamic extensions. Delete a thread. Delete three dynamic
+ * extension during the thread delete invocation. Clean up the used
+ * resources.
+ *
+ * - Check that the thread delete extensions were invoked in the right order.
+ *
+ * - Check that the thread delete extensions were invoked under protection of
+ * the allocator mutex.
+ *
+ * - Check that the other extensions were not invoked.
+ *
+ * - Check that the thread delete extension of the extension set deleted
+ * before its turn in the invocation was not invoked.
+ *
+ * - Create five dynamic extensions. Return from a thread entry. Delete three
+ * dynamic extension during the thread exitted invocation. Clean up the used
+ * resources.
+ *
+ * - Check that the thread exitted extensions were invoked in the right
+ * order.
+ *
+ * - Check that the other extensions were not invoked.
+ *
+ * - Check that the thread exitted extension of the extension set deleted
+ * before its turn in the invocation was not invoked.
+ *
+ * - Create five dynamic extensions. Restart a thread. Delete three dynamic
+ * extension during the thread restart invocation. Clean up the used
+ * resources.
+ *
+ * - Check that the thread restart extensions were invoked in the right
+ * order.
+ *
+ * - Check that the other extensions were not invoked.
+ *
+ * - Check that the thread restart extension of the extension set deleted
+ * before its turn in the invocation was not invoked.
+ *
+ * - Create five dynamic extensions. Start a thread. Delete three dynamic
+ * extension during the thread start invocation. Clean up the used
+ * resources.
+ *
+ * - Check that the thread start extensions were invoked in the right order.
+ *
+ * - Check that the other extensions were not invoked.
+ *
+ * - Check that the thread start extension of the extension set deleted
+ * before its turn in the invocation was not invoked.
+ *
+ * - Create five dynamic extensions. Terminate a thread. Delete three dynamic
+ * extension during the thread terminate invocation. Clean up the used
+ * resources.
+ *
+ * - Check that the thread terminate extensions were invoked in the right
+ * order.
+ *
+ * - Check that the other extensions were not invoked.
+ *
+ * - Check that the thread terminate extension of the extension set deleted
+ * before its turn in the invocation was not invoked.
+ *
+ * - Create five dynamic extensions. Let an idle thread return from its entry.
+ * Delete three dynamic extension during the thread exitted invocation.
+ * Clean up the used resources.
+ *
+ * - Check that the thread exitted extensions were invoked in the right
+ * order.
+ *
+ * - Check that the other extensions were not invoked.
+ *
+ * - Check that the thread exitted extension of the extension set deleted
+ * before its turn in the invocation was not invoked.
+ *
+ * @{
+ */
+
+typedef struct {
+ unsigned int counter;
+ rtems_tcb *executing;
+ rtems_tcb *thread;
+} ExtensionEvent;
+
+typedef enum {
+ THREAD_BEGIN,
+ THREAD_CREATE,
+ THREAD_DELETE,
+ THREAD_EXITTED,
+ THREAD_RESTART,
+ THREAD_START,
+ THREAD_SWITCH,
+ THREAD_TERMINATE,
+ EXTENSION_KIND_COUNT
+} ExtensionKind;
+
+static rtems_id extension_ids[ 7 ];
+
+static Atomic_Uint extension_counter[ RTEMS_ARRAY_SIZE( extension_ids ) ]
+ [ EXTENSION_KIND_COUNT ];
+
+static ExtensionEvent extension_events[ RTEMS_ARRAY_SIZE( extension_ids ) ]
+ [ EXTENSION_KIND_COUNT ][ 3 ];
+
+static Atomic_Uint global_counter;
+
+static ExtensionKind extension_under_test = EXTENSION_KIND_COUNT;
+
+static uint32_t thread_create_allocator_owner_count;
+
+static uint32_t thread_delete_allocator_owner_count;
+
+static void StopTestCase( void )
+{
+ ExtensionKind kind;
+ rtems_status_code sc;
+
+ kind = extension_under_test;
+ extension_under_test = EXTENSION_KIND_COUNT;
+
+ sc = rtems_extension_delete( extension_ids[ 2 ] );
+ T_rsc_success( sc );
+
+ if ( kind == THREAD_SWITCH ) {
+ sc = rtems_extension_delete( extension_ids[ 3 ] );
+ T_rsc_success( sc );
+
+ sc = rtems_extension_delete( extension_ids[ 4 ] );
+ T_rsc_success( sc );
+
+ sc = rtems_extension_delete( extension_ids[ 5 ] );
+ T_rsc_success( sc );
+ }
+
+ sc = rtems_extension_delete( extension_ids[ 6 ] );
+ T_rsc_success( sc );
+}
+
+static void Extension(
+ size_t index,
+ ExtensionKind kind,
+ rtems_tcb *executing,
+ rtems_tcb *thread
+)
+{
+ unsigned int gc;
+ unsigned int c;
+ rtems_status_code sc;
+
+ if ( extension_under_test == EXTENSION_KIND_COUNT ) {
+ return;
+ }
+
+ if ( kind == THREAD_CREATE && _RTEMS_Allocator_is_owner() ) {
+ ++thread_create_allocator_owner_count;
+ }
+
+ if ( kind == THREAD_DELETE && _RTEMS_Allocator_is_owner() ) {
+ ++thread_delete_allocator_owner_count;
+ }
+
+ gc = _Atomic_Fetch_add_uint( &global_counter, 1, ATOMIC_ORDER_RELAXED ) + 1;
+ c = _Atomic_Fetch_add_uint(
+ &extension_counter[ index ][ kind ],
+ 1,
+ ATOMIC_ORDER_RELAXED
+ );
+
+ if ( c < RTEMS_ARRAY_SIZE( extension_events[ index ][ kind ] ) ) {
+ extension_events[ index ][ kind ][ c ].counter = gc;
+ extension_events[ index ][ kind ][ c ].executing = executing;
+ extension_events[ index ][ kind ][ c ].thread = thread;
+ }
+
+ if ( kind == THREAD_SWITCH ) {
+ /* Extension set deletion is not allowed in thread switch extensions */
+ return;
+ }
+
+ if ( kind != extension_under_test ) {
+ return;
+ }
+
+ if ( kind == THREAD_DELETE || kind == THREAD_TERMINATE ) {
+ if ( index == 6 ) {
+ sc = rtems_extension_delete( extension_ids[ 5 ] );
+ T_rsc_success( sc );
+ } else if ( index == 3 ) {
+ sc = rtems_extension_delete( extension_ids[ 3 ] );
+ T_rsc_success( sc );
+ } else if ( index == 2 ) {
+ sc = rtems_extension_delete( extension_ids[ 4 ] );
+ T_rsc_success( sc );
+ }
+ } else {
+ if ( index == 2 ) {
+ sc = rtems_extension_delete( extension_ids[ 3 ] );
+ T_rsc_success( sc );
+ } else if ( index == 5 ) {
+ sc = rtems_extension_delete( extension_ids[ 5 ] );
+ T_rsc_success( sc );
+ } else if ( index == 6 ) {
+ sc = rtems_extension_delete( extension_ids[ 4 ] );
+ T_rsc_success( sc );
+ }
+ }
+
+ if ( index == 6 && ( kind == THREAD_EXITTED || kind == THREAD_RESTART ) ) {
+ StopTestCase();
+
+ if ( GetExecuting()->is_idle ) {
+ SetSelfPriority( RTEMS_MAXIMUM_PRIORITY );
+ _CPU_Thread_Idle_body( 0 );
+ } else {
+ rtems_task_exit();
+ }
+ }
+
+ if ( index == 0 && kind == THREAD_TERMINATE ) {
+ StopTestCase();
+ }
+}
+
+#define DEFINE_EXTENSIONS( index, linkage ) \
+ linkage void ThreadBeginExtension##index( rtems_tcb *executing ) \
+ { \
+ Extension( index, THREAD_BEGIN, executing, NULL ); \
+ } \
+ linkage bool ThreadCreateExtension##index( \
+ rtems_tcb *executing, \
+ rtems_tcb *created \
+ ) \
+ { \
+ Extension( index, THREAD_CREATE, executing, created ); \
+ return true; \
+ } \
+ linkage void ThreadDeleteExtension##index( \
+ rtems_tcb *executing, \
+ rtems_tcb *deleted \
+ ) \
+ { \
+ Extension( index, THREAD_DELETE, executing, deleted ); \
+ } \
+ linkage void ThreadExittedExtension##index( rtems_tcb *executing ) \
+ { \
+ Extension( index, THREAD_EXITTED, executing, NULL ); \
+ } \
+ linkage void ThreadRestartExtension##index( \
+ rtems_tcb *executing, \
+ rtems_tcb *restarted \
+ ) \
+ { \
+ Extension( index, THREAD_RESTART, executing, restarted ); \
+ } \
+ linkage void ThreadStartExtension##index( \
+ rtems_tcb *executing, \
+ rtems_tcb *started \
+ ) \
+ { \
+ Extension( index, THREAD_START, executing, started ); \
+ } \
+ linkage void ThreadSwitchExtension##index( \
+ rtems_tcb *executing, \
+ rtems_tcb *heir \
+ ) \
+ { \
+ Extension( index, THREAD_SWITCH, executing, heir ); \
+ } \
+ linkage void ThreadTerminateExtension##index( rtems_tcb *executing ) \
+ { \
+ Extension( index, THREAD_TERMINATE, executing, NULL ); \
+ }
+
+DEFINE_EXTENSIONS( 0, )
+DEFINE_EXTENSIONS( 1, )
+
+#define DEFINE_EXTENSIONS_AND_TABLE( index ) \
+ DEFINE_EXTENSIONS( index, static ) \
+ static const rtems_extensions_table table_##index = { \
+ .thread_begin = ThreadBeginExtension##index, \
+ .thread_create = ThreadCreateExtension##index, \
+ .thread_delete = ThreadDeleteExtension##index, \
+ .thread_exitted = ThreadExittedExtension##index, \
+ .thread_restart = ThreadRestartExtension##index, \
+ .thread_start = ThreadStartExtension##index, \
+ .thread_switch = ThreadSwitchExtension##index, \
+ .thread_terminate = ThreadTerminateExtension##index \
+ }
+
+DEFINE_EXTENSIONS_AND_TABLE( 2 );
+DEFINE_EXTENSIONS_AND_TABLE( 3 );
+DEFINE_EXTENSIONS_AND_TABLE( 4 );
+DEFINE_EXTENSIONS_AND_TABLE( 5 );
+DEFINE_EXTENSIONS_AND_TABLE( 6 );
+
+static const rtems_extensions_table * const tables[] = {
+ NULL,
+ NULL,
+ &table_2,
+ &table_3,
+ &table_4,
+ &table_5,
+ &table_6
+};
+
+static rtems_tcb *StartTestCase( ExtensionKind kind )
+{
+ size_t i;
+
+ thread_create_allocator_owner_count = 0;
+ thread_delete_allocator_owner_count = 0;
+ _Atomic_Store_uint( &global_counter, 0, ATOMIC_ORDER_RELAXED );
+ memset( extension_counter, 0, sizeof( extension_counter ) );
+ memset( extension_events, 0, sizeof( extension_events ) );
+
+ extension_under_test = kind;
+
+ for ( i = 2; i < RTEMS_ARRAY_SIZE( extension_ids ); ++i ) {
+ rtems_status_code sc;
+
+ sc = rtems_extension_create(
+ rtems_build_name( ' ', ' ', ' ', '2' + i ),
+ tables[ i ],
+ &extension_ids[ i ]
+ );
+ T_rsc_success( sc );
+ }
+
+ return GetExecuting();
+}
+
+static void CheckForward(
+ ExtensionKind kind,
+ unsigned int counter,
+ unsigned int increment,
+ rtems_tcb *executing,
+ rtems_tcb *thread
+)
+{
+ size_t i;
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( extension_ids ); ++i ) {
+ if ( i == 3 && kind != THREAD_SWITCH ) {
+ continue;
+ }
+
+ if ( counter == 0 ) {
+ T_eq_uint( extension_counter[ i ][ kind ], 0 );
+ } else {
+ T_eq_uint( extension_counter[ i ][ kind ], 1 );
+ T_eq_uint( extension_events[ i ][ kind ][ 0 ].counter, counter );
+ T_eq_ptr( extension_events[ i ][ kind ][ 0 ].executing, executing );
+ T_eq_ptr( extension_events[ i ][ kind ][ 0 ].thread, thread );
+
+ counter += increment;
+ }
+ }
+}
+
+static void CheckReverse(
+ ExtensionKind kind,
+ unsigned int counter,
+ unsigned int increment,
+ rtems_tcb *executing,
+ rtems_tcb *thread
+)
+{
+ size_t i;
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( extension_ids ); ++i ) {
+ if ( i == 5 && kind != THREAD_SWITCH ) {
+ continue;
+ }
+
+ if ( counter == 0 ) {
+ T_eq_uint( extension_counter[ i ][ kind ], 0 );
+ } else {
+ T_eq_uint( extension_counter[ i ][ kind ], 1 );
+ T_eq_uint(
+ extension_events[ i ][ kind ][ 0 ].counter,
+ 7 - counter
+ );
+ T_eq_ptr( extension_events[ i ][ kind ][ 0 ].executing, executing );
+ T_eq_ptr( extension_events[ i ][ kind ][ 0 ].thread, thread );
+
+ counter += increment;
+ }
+ }
+}
+
+static void CheckDeletedNotInvoked( ExtensionKind kind )
+{
+ size_t index;
+
+ if ( kind == THREAD_DELETE || kind == THREAD_TERMINATE ) {
+ index = 5;
+ } else {
+ index = 3;
+ }
+
+ T_eq_uint( extension_events[ index ][ kind ][ 0 ].counter, 0 );
+ T_null( extension_events[ index ][ kind ][ 0 ].executing );
+ T_null( extension_events[ index ][ kind ][ 0 ].thread );
+}
+
+static void BeginWorker( rtems_task_argument arg )
+{
+ T_eq_u32( arg, 0 );
+ StopTestCase();
+ rtems_task_exit();
+}
+
+static void ExittedWorker( rtems_task_argument arg )
+{
+ T_eq_u32( arg, 0 );
+ (void) StartTestCase( THREAD_EXITTED );
+}
+
+static void RestartWorker( rtems_task_argument arg )
+{
+ T_eq_u32( arg, 0 );
+ (void) StartTestCase( THREAD_RESTART );
+ (void) rtems_task_restart( RTEMS_SELF, 1 );
+}
+
+static void StartWorker( rtems_task_argument arg )
+{
+ (void) arg;
+ T_unreachable();
+}
+
+static void TerminateWorker( rtems_task_argument arg )
+{
+ T_eq_u32( arg, 0 );
+ (void) StartTestCase( THREAD_TERMINATE );
+ rtems_task_exit();
+}
+
+void *IdleBody( uintptr_t arg )
+{
+ rtems_event_set events;
+
+ do {
+ events = PollAnyEvents();
+ } while ( events == 0 );
+
+ (void) StartTestCase( THREAD_EXITTED );
+ return (void *) arg;
+}
+
+static void RtemsUserextValUserext_Setup( void *ctx )
+{
+ SetSelfPriority( PRIO_NORMAL );
+}
+
+static void RtemsUserextValUserext_Teardown( void *ctx )
+{
+ RestoreRunnerPriority();
+}
+
+static T_fixture RtemsUserextValUserext_Fixture = {
+ .setup = RtemsUserextValUserext_Setup,
+ .stop = NULL,
+ .teardown = RtemsUserextValUserext_Teardown,
+ .scope = NULL,
+ .initial_context = NULL
+};
+
+/**
+ * @brief Create five dynamic extensions. Switch to a started thread. Delete
+ * three dynamic extension during the thread begin invocation. Clean up the
+ * used resources.
+ */
+static void RtemsUserextValUserext_Action_0( void )
+{
+ rtems_tcb *executing;
+ rtems_tcb *thread;
+ rtems_id id;
+
+ id = CreateTask( "WORK", PRIO_LOW );
+ thread = GetThread( id );
+ StartTask( id, BeginWorker, NULL );
+ executing = StartTestCase( THREAD_BEGIN );
+ SetPriority( id, PRIO_HIGH );
+ KillZombies();
+
+ /*
+ * Check that the thread switch extensions were invoked in the right order
+ * before the thread begin extensions.
+ */
+ CheckForward( THREAD_SWITCH, 1, 1, executing, thread );
+
+ /*
+ * Check that the thread begin extensions were invoked in the right order.
+ */
+ CheckForward( THREAD_BEGIN, 8, 1, thread, NULL );
+
+ /*
+ * Check that the other extensions were not invoked.
+ */
+ CheckForward( THREAD_CREATE, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_DELETE, 0, 0, NULL, NULL );
+ CheckForward( THREAD_EXITTED, 0, 0, NULL, NULL );
+ CheckForward( THREAD_RESTART, 0, 0, NULL, NULL );
+ CheckForward( THREAD_START, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_TERMINATE, 0, 0, NULL, NULL );
+
+ /*
+ * Check that the thread begin extension of the extension set deleted before
+ * its turn in the invocation was not invoked.
+ */
+ CheckDeletedNotInvoked( THREAD_BEGIN );
+}
+
+/**
+ * @brief Create five dynamic extensions. Create a thread. Delete three
+ * dynamic extension during the thread create invocation. Clean up the used
+ * resources.
+ */
+static void RtemsUserextValUserext_Action_1( void )
+{
+ rtems_tcb *executing;
+ rtems_tcb *thread;
+ rtems_id id;
+
+ executing = StartTestCase( THREAD_CREATE );
+ id = CreateTask( "WORK", PRIO_NORMAL );
+ thread = GetThread( id );
+ StopTestCase();
+ DeleteTask( id );
+ KillZombies();
+
+ /*
+ * Check that the thread create extensions were invoked in the right order.
+ */
+ CheckForward( THREAD_CREATE, 1, 1, executing, thread );
+
+ /*
+ * Check that the thread create extensions were invoked under protection of
+ * the allocator mutex.
+ */
+ T_eq_u32( thread_create_allocator_owner_count, 6 );
+
+ /*
+ * Check that the other extensions were not invoked.
+ */
+ CheckForward( THREAD_BEGIN, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_DELETE, 0, 0, NULL, NULL );
+ CheckForward( THREAD_EXITTED, 0, 0, NULL, NULL );
+ CheckForward( THREAD_RESTART, 0, 0, NULL, NULL );
+ CheckForward( THREAD_START, 0, 0, NULL, NULL );
+ CheckForward( THREAD_SWITCH, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_TERMINATE, 0, 0, NULL, NULL );
+
+ /*
+ * Check that the thread create extension of the extension set deleted before
+ * its turn in the invocation was not invoked.
+ */
+ CheckDeletedNotInvoked( THREAD_CREATE );
+}
+
+/**
+ * @brief Create five dynamic extensions. Delete a thread. Delete three
+ * dynamic extension during the thread delete invocation. Clean up the used
+ * resources.
+ */
+static void RtemsUserextValUserext_Action_2( void )
+{
+ rtems_tcb *executing;
+ rtems_tcb *thread;
+ rtems_id id;
+
+ id = CreateTask( "WORK", PRIO_NORMAL );
+ thread = GetThread( id );
+ DeleteTask( id );
+ executing = StartTestCase( THREAD_DELETE );
+ KillZombies();
+ StopTestCase();
+
+ /*
+ * Check that the thread delete extensions were invoked in the right order.
+ */
+ CheckReverse( THREAD_DELETE, 1, 1, executing, thread );
+
+ /*
+ * Check that the thread delete extensions were invoked under protection of
+ * the allocator mutex.
+ */
+ T_eq_u32( thread_delete_allocator_owner_count, 6 );
+
+ /*
+ * Check that the other extensions were not invoked.
+ */
+ CheckForward( THREAD_BEGIN, 0, 0, NULL, NULL );
+ CheckForward( THREAD_CREATE, 0, 0, NULL, NULL );
+ CheckForward( THREAD_EXITTED, 0, 0, NULL, NULL );
+ CheckForward( THREAD_RESTART, 0, 0, NULL, NULL );
+ CheckForward( THREAD_START, 0, 0, NULL, NULL );
+ CheckForward( THREAD_SWITCH, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_TERMINATE, 0, 0, NULL, NULL );
+
+ /*
+ * Check that the thread delete extension of the extension set deleted before
+ * its turn in the invocation was not invoked.
+ */
+ CheckDeletedNotInvoked( THREAD_DELETE );
+}
+
+/**
+ * @brief Create five dynamic extensions. Return from a thread entry. Delete
+ * three dynamic extension during the thread exitted invocation. Clean up
+ * the used resources.
+ */
+static void RtemsUserextValUserext_Action_3( void )
+{
+ rtems_tcb *thread;
+ rtems_id id;
+
+ id = CreateTask( "WORK", PRIO_HIGH );
+ thread = GetThread( id );
+ StartTask( id, ExittedWorker, NULL );
+ KillZombies();
+
+ /*
+ * Check that the thread exitted extensions were invoked in the right order.
+ */
+ CheckForward( THREAD_EXITTED, 1, 1, thread, NULL );
+
+ /*
+ * Check that the other extensions were not invoked.
+ */
+ CheckForward( THREAD_BEGIN, 0, 0, NULL, NULL );
+ CheckForward( THREAD_CREATE, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_DELETE, 0, 0, NULL, NULL );
+ CheckForward( THREAD_RESTART, 0, 0, NULL, NULL );
+ CheckForward( THREAD_START, 0, 0, NULL, NULL );
+ CheckForward( THREAD_SWITCH, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_TERMINATE, 0, 0, NULL, NULL );
+
+ /*
+ * Check that the thread exitted extension of the extension set deleted
+ * before its turn in the invocation was not invoked.
+ */
+ CheckDeletedNotInvoked( THREAD_EXITTED );
+}
+
+/**
+ * @brief Create five dynamic extensions. Restart a thread. Delete three
+ * dynamic extension during the thread restart invocation. Clean up the used
+ * resources.
+ */
+static void RtemsUserextValUserext_Action_4( void )
+{
+ rtems_tcb *thread;
+ rtems_id id;
+
+ id = CreateTask( "WORK", PRIO_HIGH );
+ thread = GetThread( id );
+ StartTask( id, RestartWorker, NULL );
+ KillZombies();
+
+ /*
+ * Check that the thread restart extensions were invoked in the right order.
+ */
+ CheckForward( THREAD_RESTART, 1, 1, thread, thread );
+
+ /*
+ * Check that the other extensions were not invoked.
+ */
+ CheckForward( THREAD_BEGIN, 0, 0, NULL, NULL );
+ CheckForward( THREAD_EXITTED, 0, 0, NULL, NULL );
+ CheckForward( THREAD_CREATE, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_DELETE, 0, 0, NULL, NULL );
+ CheckForward( THREAD_START, 0, 0, NULL, NULL );
+ CheckForward( THREAD_SWITCH, 0, 0, NULL, NULL );
+ CheckForward( THREAD_TERMINATE, 0, 0, NULL, NULL );
+
+ /*
+ * Check that the thread restart extension of the extension set deleted
+ * before its turn in the invocation was not invoked.
+ */
+ CheckDeletedNotInvoked( THREAD_RESTART );
+}
+
+/**
+ * @brief Create five dynamic extensions. Start a thread. Delete three
+ * dynamic extension during the thread start invocation. Clean up the used
+ * resources.
+ */
+static void RtemsUserextValUserext_Action_5( void )
+{
+ rtems_tcb *executing;
+ rtems_tcb *thread;
+ rtems_id id;
+
+ id = CreateTask( "WORK", PRIO_LOW );
+ thread = GetThread( id );
+ executing = StartTestCase( THREAD_START );
+ StartTask( id, StartWorker, NULL );
+ StopTestCase();
+ DeleteTask( id );
+ KillZombies();
+
+ /*
+ * Check that the thread start extensions were invoked in the right order.
+ */
+ CheckForward( THREAD_START, 1, 1, executing, thread );
+
+ /*
+ * Check that the other extensions were not invoked.
+ */
+ CheckForward( THREAD_BEGIN, 0, 0, NULL, NULL );
+ CheckForward( THREAD_EXITTED, 0, 0, NULL, NULL );
+ CheckForward( THREAD_CREATE, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_DELETE, 0, 0, NULL, NULL );
+ CheckForward( THREAD_RESTART, 0, 0, NULL, NULL );
+ CheckForward( THREAD_SWITCH, 0, 0, NULL, NULL );
+ CheckForward( THREAD_TERMINATE, 0, 0, NULL, NULL );
+
+ /*
+ * Check that the thread start extension of the extension set deleted before
+ * its turn in the invocation was not invoked.
+ */
+ CheckDeletedNotInvoked( THREAD_START );
+}
+
+/**
+ * @brief Create five dynamic extensions. Terminate a thread. Delete three
+ * dynamic extension during the thread terminate invocation. Clean up the
+ * used resources.
+ */
+static void RtemsUserextValUserext_Action_6( void )
+{
+ rtems_tcb *thread;
+ rtems_id id;
+
+ id = CreateTask( "WORK", PRIO_HIGH );
+ thread = GetThread( id );
+ StartTask( id, TerminateWorker, NULL );
+ KillZombies();
+
+ /*
+ * Check that the thread terminate extensions were invoked in the right
+ * order.
+ */
+ CheckReverse( THREAD_TERMINATE, 1, 1, thread, NULL );
+
+ /*
+ * Check that the other extensions were not invoked.
+ */
+ CheckForward( THREAD_BEGIN, 0, 0, NULL, NULL );
+ CheckForward( THREAD_EXITTED, 0, 0, NULL, NULL );
+ CheckForward( THREAD_CREATE, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_DELETE, 0, 0, NULL, NULL );
+ CheckForward( THREAD_RESTART, 0, 0, NULL, NULL );
+ CheckForward( THREAD_START, 0, 0, NULL, NULL );
+ CheckForward( THREAD_SWITCH, 0, 0, NULL, NULL );
+
+ /*
+ * Check that the thread terminate extension of the extension set deleted
+ * before its turn in the invocation was not invoked.
+ */
+ CheckDeletedNotInvoked( THREAD_TERMINATE );
+}
+
+/**
+ * @brief Create five dynamic extensions. Let an idle thread return from its
+ * entry. Delete three dynamic extension during the thread exitted
+ * invocation. Clean up the used resources.
+ */
+static void RtemsUserextValUserext_Action_7( void )
+{
+ rtems_tcb *thread;
+ rtems_id id;
+
+ /* ID of idle thread of processor 0 */
+ id = 0x09010001;
+ thread = GetThread( id );
+ SendEvents( id, RTEMS_EVENT_0 );
+ SetPriority( id, PRIO_HIGH );
+
+ /*
+ * Check that the thread exitted extensions were invoked in the right order.
+ */
+ CheckForward( THREAD_EXITTED, 1, 1, thread, NULL );
+
+ /*
+ * Check that the other extensions were not invoked.
+ */
+ CheckForward( THREAD_BEGIN, 0, 0, NULL, NULL );
+ CheckForward( THREAD_CREATE, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_DELETE, 0, 0, NULL, NULL );
+ CheckForward( THREAD_RESTART, 0, 0, NULL, NULL );
+ CheckForward( THREAD_START, 0, 0, NULL, NULL );
+ CheckForward( THREAD_SWITCH, 0, 0, NULL, NULL );
+ CheckReverse( THREAD_TERMINATE, 0, 0, NULL, NULL );
+
+ /*
+ * Check that the thread exitted extension of the extension set deleted
+ * before its turn in the invocation was not invoked.
+ */
+ CheckDeletedNotInvoked( THREAD_EXITTED );
+}
+
+/**
+ * @fn void T_case_body_RtemsUserextValUserext( void )
+ */
+T_TEST_CASE_FIXTURE( RtemsUserextValUserext, &RtemsUserextValUserext_Fixture )
+{
+ RtemsUserextValUserext_Action_0();
+ RtemsUserextValUserext_Action_1();
+ RtemsUserextValUserext_Action_2();
+ RtemsUserextValUserext_Action_3();
+ RtemsUserextValUserext_Action_4();
+ RtemsUserextValUserext_Action_5();
+ RtemsUserextValUserext_Action_6();
+ RtemsUserextValUserext_Action_7();
+}
+
+/** @} */
diff --git a/testsuites/validation/tc-userext.h b/testsuites/validation/tc-userext.h
new file mode 100644
index 0000000000..538180dfd4
--- /dev/null
+++ b/testsuites/validation/tc-userext.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreInterrValTerminate
+ *
+ * @brief This header file provides functions used by corresponding test suite.
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _TC_USEREXT_H
+#define _TC_USEREXT_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void ThreadBeginExtension0( rtems_tcb *executing );
+
+bool ThreadCreateExtension0( rtems_tcb *executing, rtems_tcb *created );
+
+void ThreadDeleteExtension0( rtems_tcb *executing, rtems_tcb *deleted );
+
+void ThreadExittedExtension0( rtems_tcb *executing );
+
+void ThreadRestartExtension0( rtems_tcb *executing, rtems_tcb *restarted );
+
+void ThreadStartExtension0( rtems_tcb *executing, rtems_tcb *started );
+
+void ThreadSwitchExtension0( rtems_tcb *executing, rtems_tcb *heir );
+
+void ThreadTerminateExtension0( rtems_tcb *executing );
+
+void FatalExtension0(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code
+);
+
+void ThreadBeginExtension1( rtems_tcb *executing );
+
+bool ThreadCreateExtension1( rtems_tcb *executing, rtems_tcb *created );
+
+void ThreadDeleteExtension1( rtems_tcb *executing, rtems_tcb *deleted );
+
+void ThreadExittedExtension1( rtems_tcb *executing );
+
+void ThreadRestartExtension1( rtems_tcb *executing, rtems_tcb *restarted );
+
+void ThreadStartExtension1( rtems_tcb *executing, rtems_tcb *started );
+
+void ThreadSwitchExtension1( rtems_tcb *executing, rtems_tcb *heir );
+
+void ThreadTerminateExtension1( rtems_tcb *executing );
+
+void FatalExtension1(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TC_USEREXT_H */
diff --git a/testsuites/validation/tr-event-constant.c b/testsuites/validation/tr-event-constant.c
new file mode 100644
index 0000000000..a0327973de
--- /dev/null
+++ b/testsuites/validation/tr-event-constant.c
@@ -0,0 +1,726 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsEventValEventConstant
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tr-event-constant.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsEventValEventConstant spec:/rtems/event/val/event-constant
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests an event constant and number of the Event Manager using the
+ * Classic and system event sets of the executing task.
+ *
+ * This test case performs the following actions:
+ *
+ * - Validate the event constant.
+ *
+ * - Check that the event constant is equal to the event number bit in the
+ * event set.
+ *
+ * - Check that the event number bit of the event constant is not set in
+ * RTEMS_PENDING_EVENTS.
+ *
+ * - Get all pending events of the Classic event set of the executing task.
+ *
+ * - Check that the directive call was successful.
+ *
+ * - Check that there were no pending events.
+ *
+ * - Get all pending events of the system event set of the executing task.
+ *
+ * - Check that the directive call was successful.
+ *
+ * - Check that there were no pending events.
+ *
+ * - Receive all pending events of the Classic event set of the executing task.
+ *
+ * - Check that the directive call was unsatisfied.
+ *
+ * - Check that there were no events received.
+ *
+ * - Receive all pending events of the system event set of the executing task.
+ *
+ * - Check that the directive call was unsatisfied.
+ *
+ * - Check that there were no events received.
+ *
+ * - Send the event to the Classic event set of the executing task.
+ *
+ * - Check that the directive call was successful.
+ *
+ * - Get all pending events of the Classic event set of the executing task.
+ *
+ * - Check that the directive call was successful.
+ *
+ * - Check that the pending event is equal to the event sent by a previous
+ * action.
+ *
+ * - Get all pending events of the system event set of the executing task.
+ *
+ * - Check that the directive call was successful.
+ *
+ * - Check that there were no pending events.
+ *
+ * - Receive any event of the Classic event set of the executing task.
+ *
+ * - Check that the directive call was successful.
+ *
+ * - Check that the received event is equal to the event sent by a previous
+ * action.
+ *
+ * - Receive any event of the system event set of the executing task.
+ *
+ * - Check that the directive call was unsatisfied.
+ *
+ * - Check that the no events were received.
+ *
+ * - Send the event to the Classic event set of the executing task.
+ *
+ * - Check that the directive call was successful.
+ *
+ * - Get all pending events of the Classic event set of the executing task.
+ *
+ * - Check that the directive call was successful.
+ *
+ * - Check that there were no pending events.
+ *
+ * - Get all pending events of the system event set of the executing task.
+ *
+ * - Check that the directive call was successful.
+ *
+ * - Check that the pending event is equal to the event sent by a previous
+ * action.
+ *
+ * - Receive any event of the Classic event set of the executing task.
+ *
+ * - Check that the directive call was unsatisfied.
+ *
+ * - Check that the no events were received.
+ *
+ * - Receive any event of the system event set of the executing task.
+ *
+ * - Check that the directive call was successful.
+ *
+ * - Check that the received event is equal to the event sent by a previous
+ * action.
+ *
+ * - Get all pending events of the Classic event set of the executing task.
+ *
+ * - Check that the directive call was successful.
+ *
+ * - Check that there were no pending events.
+ *
+ * - Get all pending events of the system event set of the executing task.
+ *
+ * - Check that the directive call was successful.
+ *
+ * - Check that there were no pending events.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/rtems/event/val/event-constant test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a copy of the corresponding
+ * RtemsEventValEventConstant_Run() parameter.
+ */
+ rtems_event_set event;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * RtemsEventValEventConstant_Run() parameter.
+ */
+ int number;
+} RtemsEventValEventConstant_Context;
+
+static RtemsEventValEventConstant_Context
+ RtemsEventValEventConstant_Instance;
+
+static T_fixture RtemsEventValEventConstant_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &RtemsEventValEventConstant_Instance
+};
+
+/**
+ * @brief Validate the event constant.
+ */
+static void RtemsEventValEventConstant_Action_0(
+ RtemsEventValEventConstant_Context *ctx
+)
+{
+ /* No action */
+
+ /*
+ * Check that the event constant is equal to the event number bit in the
+ * event set.
+ */
+ T_step_eq_u32(
+ 0,
+ ctx->event,
+ ( (rtems_event_set) 1 ) << ctx->number
+ );
+
+ /*
+ * Check that the event number bit of the event constant is not set in
+ * RTEMS_PENDING_EVENTS.
+ */
+ T_step_eq_u32( 1, ctx->event & RTEMS_PENDING_EVENTS, 0 );
+}
+
+/**
+ * @brief Get all pending events of the Classic event set of the executing
+ * task.
+ */
+static void RtemsEventValEventConstant_Action_1(
+ RtemsEventValEventConstant_Context *ctx
+)
+{
+ rtems_status_code sc;
+ rtems_event_set out;
+
+ out = RTEMS_ALL_EVENTS;
+ sc = rtems_event_receive(
+ RTEMS_PENDING_EVENTS,
+ RTEMS_DEFAULT_OPTIONS,
+ 0,
+ &out
+ );
+
+ /*
+ * Check that the directive call was successful.
+ */
+ T_step_rsc_success( 2, sc );
+
+ /*
+ * Check that there were no pending events.
+ */
+ T_step_eq_u32( 3, out, 0 );
+}
+
+/**
+ * @brief Get all pending events of the system event set of the executing task.
+ */
+static void RtemsEventValEventConstant_Action_2(
+ RtemsEventValEventConstant_Context *ctx
+)
+{
+ rtems_status_code sc;
+ rtems_event_set out;
+
+ out = RTEMS_ALL_EVENTS;
+ sc = rtems_event_system_receive(
+ RTEMS_PENDING_EVENTS,
+ RTEMS_DEFAULT_OPTIONS,
+ 0,
+ &out
+ );
+
+ /*
+ * Check that the directive call was successful.
+ */
+ T_step_rsc_success( 4, sc );
+
+ /*
+ * Check that there were no pending events.
+ */
+ T_step_eq_u32( 5, out, 0 );
+}
+
+/**
+ * @brief Receive all pending events of the Classic event set of the executing
+ * task.
+ */
+static void RtemsEventValEventConstant_Action_3(
+ RtemsEventValEventConstant_Context *ctx
+)
+{
+ rtems_status_code sc;
+ rtems_event_set out;
+
+ out = RTEMS_ALL_EVENTS;
+ sc = rtems_event_receive(
+ RTEMS_ALL_EVENTS,
+ RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
+ 0,
+ &out
+ );
+
+ /*
+ * Check that the directive call was unsatisfied.
+ */
+ T_step_rsc( 6, sc, RTEMS_UNSATISFIED );
+
+ /*
+ * Check that there were no events received.
+ */
+ T_step_eq_u32( 7, out, 0 );
+}
+
+/**
+ * @brief Receive all pending events of the system event set of the executing
+ * task.
+ */
+static void RtemsEventValEventConstant_Action_4(
+ RtemsEventValEventConstant_Context *ctx
+)
+{
+ rtems_status_code sc;
+ rtems_event_set out;
+
+ out = RTEMS_ALL_EVENTS;
+ sc = rtems_event_system_receive(
+ RTEMS_ALL_EVENTS,
+ RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
+ 0,
+ &out
+ );
+
+ /*
+ * Check that the directive call was unsatisfied.
+ */
+ T_step_rsc( 8, sc, RTEMS_UNSATISFIED );
+
+ /*
+ * Check that there were no events received.
+ */
+ T_step_eq_u32( 9, out, 0 );
+}
+
+/**
+ * @brief Send the event to the Classic event set of the executing task.
+ */
+static void RtemsEventValEventConstant_Action_5(
+ RtemsEventValEventConstant_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ sc = rtems_event_send( RTEMS_SELF, ctx->event );
+
+ /*
+ * Check that the directive call was successful.
+ */
+ T_step_rsc_success( 10, sc );
+}
+
+/**
+ * @brief Get all pending events of the Classic event set of the executing
+ * task.
+ */
+static void RtemsEventValEventConstant_Action_6(
+ RtemsEventValEventConstant_Context *ctx
+)
+{
+ rtems_status_code sc;
+ rtems_event_set out;
+
+ out = RTEMS_ALL_EVENTS;
+ sc = rtems_event_receive(
+ RTEMS_PENDING_EVENTS,
+ RTEMS_DEFAULT_OPTIONS,
+ 0,
+ &out
+ );
+
+ /*
+ * Check that the directive call was successful.
+ */
+ T_step_rsc_success( 11, sc );
+
+ /*
+ * Check that the pending event is equal to the event sent by a previous
+ * action.
+ */
+ T_step_eq_u32( 12, out, ctx->event );
+}
+
+/**
+ * @brief Get all pending events of the system event set of the executing task.
+ */
+static void RtemsEventValEventConstant_Action_7(
+ RtemsEventValEventConstant_Context *ctx
+)
+{
+ rtems_status_code sc;
+ rtems_event_set out;
+
+ out = RTEMS_ALL_EVENTS;
+ sc = rtems_event_system_receive(
+ RTEMS_PENDING_EVENTS,
+ RTEMS_DEFAULT_OPTIONS,
+ 0,
+ &out
+ );
+
+ /*
+ * Check that the directive call was successful.
+ */
+ T_step_rsc_success( 13, sc );
+
+ /*
+ * Check that there were no pending events.
+ */
+ T_step_eq_u32( 14, out, 0 );
+}
+
+/**
+ * @brief Receive any event of the Classic event set of the executing task.
+ */
+static void RtemsEventValEventConstant_Action_8(
+ RtemsEventValEventConstant_Context *ctx
+)
+{
+ rtems_status_code sc;
+ rtems_event_set out;
+
+ out = 0;
+ sc = rtems_event_receive(
+ RTEMS_ALL_EVENTS,
+ RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
+ 0,
+ &out
+ );
+
+ /*
+ * Check that the directive call was successful.
+ */
+ T_step_rsc_success( 15, sc );
+
+ /*
+ * Check that the received event is equal to the event sent by a previous
+ * action.
+ */
+ T_step_eq_u32( 16, out, ctx->event );
+}
+
+/**
+ * @brief Receive any event of the system event set of the executing task.
+ */
+static void RtemsEventValEventConstant_Action_9(
+ RtemsEventValEventConstant_Context *ctx
+)
+{
+ rtems_status_code sc;
+ rtems_event_set out;
+
+ out = RTEMS_ALL_EVENTS;
+ sc = rtems_event_system_receive(
+ RTEMS_ALL_EVENTS,
+ RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
+ 0,
+ &out
+ );
+
+ /*
+ * Check that the directive call was unsatisfied.
+ */
+ T_step_rsc( 17, sc, RTEMS_UNSATISFIED );
+
+ /*
+ * Check that the no events were received.
+ */
+ T_step_eq_u32( 18, out, 0 );
+}
+
+/**
+ * @brief Send the event to the Classic event set of the executing task.
+ */
+static void RtemsEventValEventConstant_Action_10(
+ RtemsEventValEventConstant_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ sc = rtems_event_system_send( RTEMS_SELF, ctx->event );
+
+ /*
+ * Check that the directive call was successful.
+ */
+ T_step_rsc_success( 19, sc );
+}
+
+/**
+ * @brief Get all pending events of the Classic event set of the executing
+ * task.
+ */
+static void RtemsEventValEventConstant_Action_11(
+ RtemsEventValEventConstant_Context *ctx
+)
+{
+ rtems_status_code sc;
+ rtems_event_set out;
+
+ out = RTEMS_ALL_EVENTS;
+ sc = rtems_event_receive(
+ RTEMS_PENDING_EVENTS,
+ RTEMS_DEFAULT_OPTIONS,
+ 0,
+ &out
+ );
+
+ /*
+ * Check that the directive call was successful.
+ */
+ T_step_rsc_success( 20, sc );
+
+ /*
+ * Check that there were no pending events.
+ */
+ T_step_eq_u32( 21, out, 0 );
+}
+
+/**
+ * @brief Get all pending events of the system event set of the executing task.
+ */
+static void RtemsEventValEventConstant_Action_12(
+ RtemsEventValEventConstant_Context *ctx
+)
+{
+ rtems_status_code sc;
+ rtems_event_set out;
+
+ out = RTEMS_ALL_EVENTS;
+ sc = rtems_event_system_receive(
+ RTEMS_PENDING_EVENTS,
+ RTEMS_DEFAULT_OPTIONS,
+ 0,
+ &out
+ );
+
+ /*
+ * Check that the directive call was successful.
+ */
+ T_step_rsc_success( 22, sc );
+
+ /*
+ * Check that the pending event is equal to the event sent by a previous
+ * action.
+ */
+ T_step_eq_u32( 23, out, ctx->event );
+}
+
+/**
+ * @brief Receive any event of the Classic event set of the executing task.
+ */
+static void RtemsEventValEventConstant_Action_13(
+ RtemsEventValEventConstant_Context *ctx
+)
+{
+ rtems_status_code sc;
+ rtems_event_set out;
+
+ out = RTEMS_ALL_EVENTS;
+ sc = rtems_event_receive(
+ RTEMS_ALL_EVENTS,
+ RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
+ 0,
+ &out
+ );
+
+ /*
+ * Check that the directive call was unsatisfied.
+ */
+ T_step_rsc( 24, sc, RTEMS_UNSATISFIED );
+
+ /*
+ * Check that the no events were received.
+ */
+ T_step_eq_u32( 25, out, 0 );
+}
+
+/**
+ * @brief Receive any event of the system event set of the executing task.
+ */
+static void RtemsEventValEventConstant_Action_14(
+ RtemsEventValEventConstant_Context *ctx
+)
+{
+ rtems_status_code sc;
+ rtems_event_set out;
+
+ out = 0;
+ sc = rtems_event_system_receive(
+ RTEMS_ALL_EVENTS,
+ RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
+ 0,
+ &out
+ );
+
+ /*
+ * Check that the directive call was successful.
+ */
+ T_step_rsc_success( 26, sc );
+
+ /*
+ * Check that the received event is equal to the event sent by a previous
+ * action.
+ */
+ T_step_eq_u32( 27, out, ctx->event );
+}
+
+/**
+ * @brief Get all pending events of the Classic event set of the executing
+ * task.
+ */
+static void RtemsEventValEventConstant_Action_15(
+ RtemsEventValEventConstant_Context *ctx
+)
+{
+ rtems_status_code sc;
+ rtems_event_set out;
+
+ out = RTEMS_ALL_EVENTS;
+ sc = rtems_event_receive(
+ RTEMS_PENDING_EVENTS,
+ RTEMS_DEFAULT_OPTIONS,
+ 0,
+ &out
+ );
+
+ /*
+ * Check that the directive call was successful.
+ */
+ T_step_rsc_success( 28, sc );
+
+ /*
+ * Check that there were no pending events.
+ */
+ T_step_eq_u32( 29, out, 0 );
+}
+
+/**
+ * @brief Get all pending events of the system event set of the executing task.
+ */
+static void RtemsEventValEventConstant_Action_16(
+ RtemsEventValEventConstant_Context *ctx
+)
+{
+ rtems_status_code sc;
+ rtems_event_set out;
+
+ out = RTEMS_ALL_EVENTS;
+ sc = rtems_event_system_receive(
+ RTEMS_PENDING_EVENTS,
+ RTEMS_DEFAULT_OPTIONS,
+ 0,
+ &out
+ );
+
+ /*
+ * Check that the directive call was successful.
+ */
+ T_step_rsc_success( 30, sc );
+
+ /*
+ * Check that there were no pending events.
+ */
+ T_step_eq_u32( 31, out, 0 );
+}
+
+static T_fixture_node RtemsEventValEventConstant_Node;
+
+static T_remark RtemsEventValEventConstant_Remark = {
+ .next = NULL,
+ .remark = "RtemsEventValEventConstant"
+};
+
+void RtemsEventValEventConstant_Run( rtems_event_set event, int number )
+{
+ RtemsEventValEventConstant_Context *ctx;
+
+ ctx = &RtemsEventValEventConstant_Instance;
+ ctx->event = event;
+ ctx->number = number;
+
+ ctx = T_push_fixture(
+ &RtemsEventValEventConstant_Node,
+ &RtemsEventValEventConstant_Fixture
+ );
+
+ T_plan( 32 );
+
+ RtemsEventValEventConstant_Action_0( ctx );
+ RtemsEventValEventConstant_Action_1( ctx );
+ RtemsEventValEventConstant_Action_2( ctx );
+ RtemsEventValEventConstant_Action_3( ctx );
+ RtemsEventValEventConstant_Action_4( ctx );
+ RtemsEventValEventConstant_Action_5( ctx );
+ RtemsEventValEventConstant_Action_6( ctx );
+ RtemsEventValEventConstant_Action_7( ctx );
+ RtemsEventValEventConstant_Action_8( ctx );
+ RtemsEventValEventConstant_Action_9( ctx );
+ RtemsEventValEventConstant_Action_10( ctx );
+ RtemsEventValEventConstant_Action_11( ctx );
+ RtemsEventValEventConstant_Action_12( ctx );
+ RtemsEventValEventConstant_Action_13( ctx );
+ RtemsEventValEventConstant_Action_14( ctx );
+ RtemsEventValEventConstant_Action_15( ctx );
+ RtemsEventValEventConstant_Action_16( ctx );
+
+ T_add_remark( &RtemsEventValEventConstant_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-event-constant.h b/testsuites/validation/tr-event-constant.h
new file mode 100644
index 0000000000..9c57ca2d8a
--- /dev/null
+++ b/testsuites/validation/tr-event-constant.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsEventValEventConstant
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_EVENT_CONSTANT_H
+#define _TR_EVENT_CONSTANT_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup RtemsEventValEventConstant
+ *
+ * @{
+ */
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param event is the event constant.
+ *
+ * @param number is the event number.
+ */
+void RtemsEventValEventConstant_Run( rtems_event_set event, int number );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_EVENT_CONSTANT_H */
diff --git a/testsuites/validation/tr-event-send-receive.c b/testsuites/validation/tr-event-send-receive.c
new file mode 100644
index 0000000000..85d0040615
--- /dev/null
+++ b/testsuites/validation/tr-event-send-receive.c
@@ -0,0 +1,1321 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsEventReqSendReceive
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/threadimpl.h>
+
+#include "tr-event-send-receive.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsEventReqSendReceive spec:/rtems/event/req/send-receive
+ *
+ * @ingroup TestsuitesValidation0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Pre_Send_NA : 1;
+ uint16_t Pre_ReceiverState_NA : 1;
+ uint16_t Pre_Satisfy_NA : 1;
+ uint16_t Post_SendStatus : 2;
+ uint16_t Post_ReceiveStatus : 3;
+ uint16_t Post_SenderPreemption : 2;
+} RtemsEventReqSendReceive_Entry;
+
+#define PRIO_OTHER UINT32_MAX
+
+typedef enum {
+ SENDER_NONE,
+ SENDER_SELF,
+ SENDER_SELF_2,
+ SENDER_WORKER,
+ SENDER_INTERRUPT
+} SenderTypes;
+
+typedef enum {
+ RECEIVE_SKIP,
+ RECEIVE_NORMAL,
+ RECEIVE_INTERRUPT
+} ReceiveTypes;
+
+typedef enum {
+ RECEIVE_COND_UNKNOWN,
+ RECEIVE_COND_SATSIFIED,
+ RECEIVE_COND_UNSATISFIED
+} ReceiveConditionStates;
+
+/**
+ * @brief Test context for spec:/rtems/event/req/send-receive test case.
+ */
+typedef struct {
+ /**
+ * @brief This member defines the sender type to perform the event send
+ * action.
+ */
+ SenderTypes sender_type;
+
+ /**
+ * @brief This member defines the sender task priority.
+ */
+ rtems_task_priority sender_prio;
+
+ /**
+ * @brief This member defines the receiver ID used for the event send action.
+ */
+ rtems_id receiver_id;
+
+ /**
+ * @brief This member defines the events to send for the event send action.
+ */
+ rtems_event_set events_to_send;
+
+ /**
+ * @brief This member contains the status of the event send action.
+ */
+ rtems_status_code send_status;
+
+ /**
+ * @brief This member contains the scheduler ID of the runner task.
+ */
+ ReceiveTypes receive_type;
+
+ /**
+ * @brief This member defines the option set used for the event receive
+ * action.
+ */
+ rtems_option receive_option_set;
+
+ /**
+ * @brief This member defines the timeout used for the event receive action.
+ */
+ rtems_interval receive_timeout;
+
+ /**
+ * @brief This member contains the events received by the event receive
+ * action.
+ */
+ rtems_event_set received_events;
+
+ /**
+ * @brief This member references the event set received by the event receive
+ * action or is NULL.
+ */
+ rtems_event_set *received_events_parameter;
+
+ /**
+ * @brief This member contains the status of the event receive action.
+ */
+ rtems_status_code receive_status;
+
+ /**
+ * @brief This member contains the event condition state of the receiver task
+ * after the event send action.
+ */
+ ReceiveConditionStates receive_condition_state;
+
+ /**
+ * @brief This member contains the pending events after an event send action
+ * which did not satisify the event condition of the receiver.
+ */
+ rtems_event_set unsatisfied_pending;
+
+ /**
+ * @brief This member contains the TCB of the runner task.
+ */
+ Thread_Control *runner_thread;
+
+ /**
+ * @brief This member contains the ID of the runner task.
+ */
+ rtems_id runner_id;
+
+ /**
+ * @brief This member contains the task ID of the worker task.
+ */
+ rtems_id worker_id;
+
+ /**
+ * @brief This member contains the ID of the semaphore used to wake up the
+ * worker task.
+ */
+ rtems_id worker_wakeup;
+
+ /**
+ * @brief This member contains the ID of the semaphore used to wake up the
+ * runner task.
+ */
+ rtems_id runner_wakeup;
+
+ /**
+ * @brief This member contains the scheduler ID of scheduler used by the
+ * runner task.
+ */
+ rtems_id runner_sched;
+
+ /**
+ * @brief This member contains the scheduler ID of another scheduler which is
+ * not used by the runner task.
+ */
+ rtems_id other_sched;
+
+ /**
+ * @brief This member contains the thread switch log.
+ */
+ T_thread_switch_log_4 thread_switch_log;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * RtemsEventReqSendReceive_Run() parameter.
+ */
+ rtems_status_code ( *send )( rtems_id, rtems_event_set );
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * RtemsEventReqSendReceive_Run() parameter.
+ */
+ rtems_status_code ( *receive )( rtems_event_set, rtems_option, rtems_interval, rtems_event_set * );
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * RtemsEventReqSendReceive_Run() parameter.
+ */
+ rtems_event_set ( *get_pending_events )( Thread_Control * );
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * RtemsEventReqSendReceive_Run() parameter.
+ */
+ unsigned int wait_class;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * RtemsEventReqSendReceive_Run() parameter.
+ */
+ int waiting_for_event;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 4 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 4 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsEventReqSendReceive_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsEventReqSendReceive_Context;
+
+static RtemsEventReqSendReceive_Context
+ RtemsEventReqSendReceive_Instance;
+
+static const char * const RtemsEventReqSendReceive_PreDesc_Id[] = {
+ "InvId",
+ "Task",
+ "NA"
+};
+
+static const char * const RtemsEventReqSendReceive_PreDesc_Send[] = {
+ "Zero",
+ "Unrelated",
+ "Any",
+ "All",
+ "MixedAny",
+ "MixedAll",
+ "NA"
+};
+
+static const char * const RtemsEventReqSendReceive_PreDesc_ReceiverState[] = {
+ "InvAddr",
+ "NotWaiting",
+ "Poll",
+ "Timeout",
+ "Lower",
+ "Equal",
+ "Higher",
+ "Other",
+ "Intend",
+ "NA"
+};
+
+static const char * const RtemsEventReqSendReceive_PreDesc_Satisfy[] = {
+ "All",
+ "Any",
+ "NA"
+};
+
+static const char * const * const RtemsEventReqSendReceive_PreDesc[] = {
+ RtemsEventReqSendReceive_PreDesc_Id,
+ RtemsEventReqSendReceive_PreDesc_Send,
+ RtemsEventReqSendReceive_PreDesc_ReceiverState,
+ RtemsEventReqSendReceive_PreDesc_Satisfy,
+ NULL
+};
+
+#define INPUT_EVENTS ( RTEMS_EVENT_5 | RTEMS_EVENT_23 )
+
+typedef RtemsEventReqSendReceive_Context Context;
+
+static rtems_id CreateWakeupSema( void )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'W', 'K', 'U', 'P' ),
+ 0,
+ RTEMS_SIMPLE_BINARY_SEMAPHORE,
+ 0,
+ &id
+ );
+ T_assert_rsc_success( sc );
+
+ return id;
+}
+
+static void DeleteWakeupSema( rtems_id id )
+{
+ if ( id != 0 ) {
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_delete( id );
+ T_rsc_success( sc );
+ }
+}
+
+static void Wait( rtems_id id )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_obtain( id, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
+ T_quiet_rsc_success( sc );
+}
+
+static void Wakeup( rtems_id id )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_release( id );
+ T_quiet_rsc_success( sc );
+}
+
+static bool BlockedForEvent( Context *ctx, Thread_Wait_flags flags )
+{
+ return flags == ( ctx->wait_class | THREAD_WAIT_STATE_BLOCKED );
+}
+
+static bool IntendsToBlockForEvent( Context *ctx, Thread_Wait_flags flags )
+{
+ return flags == ( ctx->wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK );
+}
+
+static bool IsReady( Context *ctx, Thread_Wait_flags flags )
+{
+ return flags == THREAD_WAIT_STATE_READY;
+}
+
+static bool IsSatisfiedFlags( Context *ctx )
+{
+ return IsReady(
+ ctx,
+ _Thread_Wait_flags_get( ctx->runner_thread )
+ );
+}
+
+static bool IsSatisfiedState( Context *ctx )
+{
+ return ctx->runner_thread->current_state != ctx->waiting_for_event;
+}
+
+static void SendAction( Context *ctx )
+{
+ T_thread_switch_log *log;
+
+ log = T_thread_switch_record_4( &ctx->thread_switch_log );
+ T_quiet_null( log );
+ ctx->send_status = ( *ctx->send )( ctx->receiver_id, ctx->events_to_send );
+ log = T_thread_switch_record( NULL );
+ T_quiet_eq_ptr( &log->header, &ctx->thread_switch_log.header );
+}
+
+static void Send(
+ Context *ctx,
+ bool ( *is_satsified )( Context * )
+)
+{
+ SendAction( ctx );
+
+ if ( ( *is_satsified )( ctx ) ) {
+ ctx->receive_condition_state = RECEIVE_COND_SATSIFIED;
+ } else {
+ rtems_status_code sc;
+ rtems_event_set pending;
+ rtems_event_set missing;
+
+ ctx->receive_condition_state = RECEIVE_COND_UNSATISFIED;
+ pending = ( *ctx->get_pending_events )( ctx->runner_thread );
+ ctx->unsatisfied_pending = pending;
+
+ missing = INPUT_EVENTS & ~ctx->events_to_send;
+ T_ne_u32( missing, 0 );
+ sc = ( *ctx->send )( ctx->runner_id, missing );
+ T_rsc_success( sc );
+
+ pending = ( *ctx->get_pending_events )( ctx->runner_thread );
+ T_eq_u32( pending, ctx->events_to_send & ~INPUT_EVENTS );
+ }
+}
+
+static void Worker( rtems_task_argument arg )
+{
+ Context *ctx;
+
+ ctx = (Context *) arg;
+
+ while ( true ) {
+ rtems_status_code sc;
+ rtems_task_priority prio;
+ T_thread_switch_log *log;
+
+ Wait( ctx->worker_wakeup );
+
+ switch ( ctx->sender_prio ) {
+ case PRIO_NORMAL:
+ case PRIO_HIGH:
+ prio = SetSelfPriority( ctx->sender_prio );
+ T_eq_u32( prio, PRIO_LOW );
+ break;
+ case PRIO_OTHER:
+ log = T_thread_switch_record_4( &ctx->thread_switch_log );
+ T_null( log );
+ sc = rtems_task_set_scheduler(
+ RTEMS_SELF,
+ ctx->other_sched,
+ PRIO_LOW
+ );
+ T_rsc_success( sc );
+
+ /*
+ * Make sure the context switch to the IDLE thread on the previous
+ * CPU is recorded, otherwise the preemption check may sporadically
+ * fail on some targets.
+ */
+ while (ctx->thread_switch_log.header.recorded < 2) {
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ }
+
+ log = T_thread_switch_record( NULL );
+ T_eq_ptr( &log->header, &ctx->thread_switch_log.header );
+ break;
+ case PRIO_LOW:
+ break;
+ }
+
+ Send( ctx, IsSatisfiedState );
+
+ sc = rtems_task_set_scheduler(
+ RTEMS_SELF,
+ ctx->runner_sched,
+ PRIO_HIGH
+ );
+ T_rsc_success( sc );
+
+ Wakeup( ctx->runner_wakeup );
+ }
+}
+
+static rtems_event_set GetPendingEvents( Context *ctx )
+{
+ rtems_event_set pending;
+ rtems_status_code sc;
+
+ sc = ( *ctx->receive )(
+ RTEMS_PENDING_EVENTS,
+ RTEMS_DEFAULT_OPTIONS,
+ 0,
+ &pending
+ );
+ T_quiet_rsc_success( sc );
+
+ return pending;
+}
+
+static void RtemsEventReqSendReceive_Cleanup( Context *ctx );
+
+static void InterruptPrepare( void *arg )
+{
+ RtemsEventReqSendReceive_Cleanup( arg );
+}
+
+static void InterruptAction( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ ctx->receive_status = ( *ctx->receive )(
+ INPUT_EVENTS,
+ ctx->receive_option_set,
+ ctx->receive_timeout,
+ &ctx->received_events
+ );
+ T_quiet_rsc_success( ctx->receive_status );
+}
+
+static void InterruptContinue( Context *ctx )
+{
+ rtems_status_code sc;
+
+ sc = ( *ctx->send )( ctx->receiver_id, INPUT_EVENTS );
+ T_quiet_rsc_success( sc );
+}
+
+static T_interrupt_test_state Interrupt( void *arg )
+{
+ Context *ctx;
+ Thread_Wait_flags flags;
+ T_interrupt_test_state next_state;
+ T_interrupt_test_state previous_state;
+
+ ctx = arg;
+ flags = _Thread_Wait_flags_get( ctx->runner_thread );
+
+ if ( IntendsToBlockForEvent( ctx, flags ) ) {
+ next_state = T_INTERRUPT_TEST_DONE;
+ } else if ( BlockedForEvent( ctx, flags ) ) {
+ next_state = T_INTERRUPT_TEST_LATE;
+ } else {
+ next_state = T_INTERRUPT_TEST_EARLY;
+ }
+
+ previous_state = T_interrupt_test_change_state(
+ T_INTERRUPT_TEST_ACTION,
+ next_state
+ );
+
+ if ( previous_state == T_INTERRUPT_TEST_ACTION ) {
+ if ( next_state == T_INTERRUPT_TEST_DONE ) {
+ Send( ctx, IsSatisfiedFlags );
+ } else {
+ InterruptContinue( ctx );
+ }
+ }
+
+ return next_state;
+}
+
+static const T_interrupt_test_config InterruptConfig = {
+ .prepare = InterruptPrepare,
+ .action = InterruptAction,
+ .interrupt = Interrupt,
+ .max_iteration_count = 10000
+};
+
+static void RtemsEventReqSendReceive_Pre_Id_Prepare(
+ RtemsEventReqSendReceive_Context *ctx,
+ RtemsEventReqSendReceive_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsEventReqSendReceive_Pre_Id_InvId: {
+ /*
+ * While the id parameter of the send directive is not associated with a
+ * task.
+ */
+ ctx->receiver_id = 0xffffffff;
+ ctx->sender_type = SENDER_SELF;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_Id_Task: {
+ /*
+ * While the id parameter of the send directive is is associated with a
+ * task.
+ */
+ ctx->receiver_id = ctx->runner_id;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsEventReqSendReceive_Pre_Send_Prepare(
+ RtemsEventReqSendReceive_Context *ctx,
+ RtemsEventReqSendReceive_Pre_Send state
+)
+{
+ switch ( state ) {
+ case RtemsEventReqSendReceive_Pre_Send_Zero: {
+ /*
+ * While the event set sent is the empty.
+ */
+ ctx->events_to_send = 0;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_Send_Unrelated: {
+ /*
+ * While the event set sent is unrelated to the event receive condition.
+ */
+ ctx->events_to_send = RTEMS_EVENT_7;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_Send_Any: {
+ /*
+ * While the event set sent is contain at least one but not all events of
+ * the event receive condition.
+ */
+ ctx->events_to_send = RTEMS_EVENT_5;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_Send_All: {
+ /*
+ * While the event set sent is contain all events of the event receive
+ * condition.
+ */
+ ctx->events_to_send = RTEMS_EVENT_5 | RTEMS_EVENT_23;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_Send_MixedAny: {
+ /*
+ * While the event set sent is contain at least one but not all events of
+ * the event receive condition and at least one unrelated event.
+ */
+ ctx->events_to_send = RTEMS_EVENT_5 | RTEMS_EVENT_7;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_Send_MixedAll: {
+ /*
+ * While the event set sent is contain all events of the event receive
+ * condition and at least one unrelated event.
+ */
+ ctx->events_to_send = RTEMS_EVENT_5 | RTEMS_EVENT_7 | RTEMS_EVENT_23;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_Send_NA:
+ break;
+ }
+}
+
+static void RtemsEventReqSendReceive_Pre_ReceiverState_Prepare(
+ RtemsEventReqSendReceive_Context *ctx,
+ RtemsEventReqSendReceive_Pre_ReceiverState state
+)
+{
+ switch ( state ) {
+ case RtemsEventReqSendReceive_Pre_ReceiverState_InvAddr: {
+ /*
+ * While the receiver task calls the receive directive with the event set
+ * to receive parameter set to NULL.
+ */
+ ctx->sender_type = SENDER_SELF;
+ ctx->receive_type = RECEIVE_NORMAL;
+ ctx->received_events_parameter = NULL;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_ReceiverState_NotWaiting: {
+ /*
+ * While the receiver task is not waiting for events.
+ */
+ ctx->sender_type = SENDER_SELF;
+ ctx->receive_type = RECEIVE_SKIP;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_ReceiverState_Poll: {
+ /*
+ * While the receiver task polls for events.
+ */
+ ctx->sender_type = SENDER_SELF;
+ ctx->receive_type = RECEIVE_NORMAL;
+ ctx->receive_option_set |= RTEMS_NO_WAIT;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_ReceiverState_Timeout: {
+ /*
+ * While the receiver task waited for events with a timeout which
+ * occurred.
+ */
+ ctx->sender_type = SENDER_SELF_2;
+ ctx->receive_type = RECEIVE_NORMAL;
+ ctx->receive_timeout = 1;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_ReceiverState_Lower: {
+ /*
+ * While the receiver task is blocked waiting for events and the receiver
+ * task shall have a lower priority than the sender task.
+ */
+ ctx->sender_type = SENDER_WORKER;
+ ctx->sender_prio = PRIO_HIGH;
+ ctx->receive_type = RECEIVE_NORMAL;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_ReceiverState_Equal: {
+ /*
+ * While the receiver task is blocked waiting for events and the receiver
+ * task shall have a priority equal to the sender task.
+ */
+ ctx->sender_type = SENDER_WORKER;
+ ctx->sender_prio = PRIO_NORMAL;
+ ctx->receive_type = RECEIVE_NORMAL;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_ReceiverState_Higher: {
+ /*
+ * While the receiver task is blocked waiting for events and the receiver
+ * task shall have a higher priority than the sender task.
+ */
+ ctx->sender_type = SENDER_WORKER;
+ ctx->sender_prio = PRIO_LOW;
+ ctx->receive_type = RECEIVE_NORMAL;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_ReceiverState_Other: {
+ /*
+ * While the receiver task is blocked waiting for events and the receiver
+ * task shall be on another scheduler instance than the sender task.
+ */
+ ctx->sender_type = SENDER_WORKER;
+ ctx->sender_prio = PRIO_OTHER;
+ ctx->receive_type = RECEIVE_NORMAL;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_ReceiverState_Intend: {
+ /*
+ * While the receiver task intends to block for waiting for events.
+ */
+ ctx->sender_type = SENDER_INTERRUPT;
+ ctx->receive_type = RECEIVE_INTERRUPT;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_ReceiverState_NA:
+ break;
+ }
+}
+
+static void RtemsEventReqSendReceive_Pre_Satisfy_Prepare(
+ RtemsEventReqSendReceive_Context *ctx,
+ RtemsEventReqSendReceive_Pre_Satisfy state
+)
+{
+ switch ( state ) {
+ case RtemsEventReqSendReceive_Pre_Satisfy_All: {
+ /*
+ * While the receiver task is interested in all input events.
+ */
+ ctx->receive_option_set |= RTEMS_EVENT_ALL;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_Satisfy_Any: {
+ /*
+ * While the receiver task is interested in any input event.
+ */
+ ctx->receive_option_set |= RTEMS_EVENT_ANY;
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Pre_Satisfy_NA:
+ break;
+ }
+}
+
+static void RtemsEventReqSendReceive_Post_SendStatus_Check(
+ RtemsEventReqSendReceive_Context *ctx,
+ RtemsEventReqSendReceive_Post_SendStatus state
+)
+{
+ switch ( state ) {
+ case RtemsEventReqSendReceive_Post_SendStatus_Ok: {
+ /*
+ * The send event status shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc_success( ctx->send_status );
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Post_SendStatus_InvId: {
+ /*
+ * The send event status shall be RTEMS_INVALID_ID.
+ */
+ T_rsc( ctx->send_status, RTEMS_INVALID_ID );
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Post_SendStatus_NA:
+ break;
+ }
+}
+
+static void RtemsEventReqSendReceive_Post_ReceiveStatus_Check(
+ RtemsEventReqSendReceive_Context *ctx,
+ RtemsEventReqSendReceive_Post_ReceiveStatus state
+)
+{
+ switch ( state ) {
+ case RtemsEventReqSendReceive_Post_ReceiveStatus_None: {
+ /*
+ * The receiver task shall not have pending events.
+ */
+ T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN );
+ T_eq_u32( GetPendingEvents( ctx ), 0 );
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Post_ReceiveStatus_Pending: {
+ /*
+ * The receiver task shall have all events sent pending.
+ */
+ T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN );
+ T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send );
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Post_ReceiveStatus_Timeout: {
+ /*
+ * The receive event status shall be RTEMS_TIMEOUT. The receiver task
+ * shall have all events sent after the timeout pending.
+ */
+ T_rsc( ctx->receive_status, RTEMS_TIMEOUT );
+ T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN );
+ T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send );
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Post_ReceiveStatus_Satisfied: {
+ /*
+ * The receive event status shall be RTEMS_SUCCESSFUL. The receiver task
+ * shall receive all events sent which are an element of the input
+ * events. The receiver task shall have all events sent which are not an
+ * element of the input events pending.
+ */
+ T_rsc( ctx->receive_status, RTEMS_SUCCESSFUL );
+
+ if ( ctx->receive_type != RECEIVE_NORMAL ) {
+ T_eq_int( ctx->receive_condition_state, RECEIVE_COND_SATSIFIED );
+ }
+
+ T_eq_u32( ctx->received_events, ctx->events_to_send & INPUT_EVENTS );
+ T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send & ~INPUT_EVENTS );
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Post_ReceiveStatus_Unsatisfied: {
+ /*
+ * The receive event status shall be RTEMS_UNSATISFIED. The receiver task
+ * shall have all events sent pending.
+ */
+ T_rsc( ctx->receive_status, RTEMS_UNSATISFIED );
+ T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN );
+ T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send );
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Post_ReceiveStatus_Blocked: {
+ /*
+ * The receiver task shall remain blocked waiting for events after the
+ * directive call. The receiver task shall have all events sent pending.
+ */
+ T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNSATISFIED );
+ T_eq_u32( ctx->unsatisfied_pending, ctx->events_to_send );
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Post_ReceiveStatus_InvAddr: {
+ /*
+ * The receive event status shall be RTEMS_INVALID_ADDRESS. The receiver
+ * task shall have all events sent pending.
+ */
+ T_rsc( ctx->receive_status, RTEMS_INVALID_ADDRESS );
+ T_eq_int( ctx->receive_condition_state, RECEIVE_COND_UNKNOWN );
+ T_eq_u32( GetPendingEvents( ctx ), ctx->events_to_send );
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Post_ReceiveStatus_NA:
+ break;
+ }
+}
+
+static void RtemsEventReqSendReceive_Post_SenderPreemption_Check(
+ RtemsEventReqSendReceive_Context *ctx,
+ RtemsEventReqSendReceive_Post_SenderPreemption state
+)
+{
+ const T_thread_switch_log_4 *log;
+ size_t i;
+
+ log = &ctx->thread_switch_log;
+
+ switch ( state ) {
+ case RtemsEventReqSendReceive_Post_SenderPreemption_No: {
+ /*
+ * When the sender task calls the directive to send the events, the
+ * sender task shall not be preempted as a result of the call.
+ */
+ /*
+ * There may be a thread switch to the runner thread if the sender thread
+ * was on another scheduler instance.
+ */
+
+ T_le_sz( log->header.recorded, 1 );
+
+ for ( i = 0; i < log->header.recorded; ++i ) {
+ T_ne_u32( log->events[ i ].executing, ctx->worker_id );
+ T_eq_u32( log->events[ i ].heir, ctx->runner_id );
+ }
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Post_SenderPreemption_Yes: {
+ /*
+ * When the sender task calls the directive to send the events, the
+ * sender task shall be preempted as a result of the call.
+ */
+ T_eq_sz( log->header.recorded, 2 );
+ T_eq_u32( log->events[ 0 ].heir, ctx->runner_id );
+ T_eq_u32( log->events[ 1 ].heir, ctx->worker_id );
+ break;
+ }
+
+ case RtemsEventReqSendReceive_Post_SenderPreemption_NA:
+ break;
+ }
+}
+
+static void RtemsEventReqSendReceive_Setup(
+ RtemsEventReqSendReceive_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ ctx->runner_thread = _Thread_Get_executing();
+ ctx->runner_id = ctx->runner_thread->Object.id;
+ ctx->worker_wakeup = CreateWakeupSema();
+ ctx->runner_wakeup = CreateWakeupSema();
+
+ sc = rtems_task_get_scheduler( RTEMS_SELF, &ctx->runner_sched );
+ T_rsc_success( sc );
+
+ #if defined(RTEMS_SMP)
+ sc = rtems_scheduler_ident_by_processor( 1, &ctx->other_sched );
+ T_rsc_success( sc );
+ T_ne_u32( ctx->runner_sched, ctx->other_sched );
+ #endif
+
+ SetSelfPriority( PRIO_NORMAL );
+ ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
+ StartTask( ctx->worker_id, Worker, ctx );
+}
+
+static void RtemsEventReqSendReceive_Setup_Wrap( void *arg )
+{
+ RtemsEventReqSendReceive_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsEventReqSendReceive_Setup( ctx );
+}
+
+static void RtemsEventReqSendReceive_Teardown(
+ RtemsEventReqSendReceive_Context *ctx
+)
+{
+ DeleteTask( ctx->worker_id );
+ DeleteWakeupSema( ctx->worker_wakeup );
+ DeleteWakeupSema( ctx->runner_wakeup );
+ RestoreRunnerPriority();
+}
+
+static void RtemsEventReqSendReceive_Teardown_Wrap( void *arg )
+{
+ RtemsEventReqSendReceive_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ RtemsEventReqSendReceive_Teardown( ctx );
+}
+
+static void RtemsEventReqSendReceive_Prepare(
+ RtemsEventReqSendReceive_Context *ctx
+)
+{
+ ctx->events_to_send = 0;
+ ctx->send_status = RTEMS_INCORRECT_STATE;
+ ctx->received_events = 0xffffffff;
+ ctx->received_events_parameter = &ctx->received_events;
+ ctx->receive_option_set = 0;
+ ctx->receive_timeout = RTEMS_NO_TIMEOUT;
+ ctx->sender_type = SENDER_NONE;
+ ctx->sender_prio = PRIO_NORMAL;
+ ctx->receive_type = RECEIVE_SKIP;
+ ctx->receive_condition_state = RECEIVE_COND_UNKNOWN;
+ ctx->unsatisfied_pending = 0xffffffff;
+ memset( &ctx->thread_switch_log, 0, sizeof( ctx->thread_switch_log ) );
+ T_eq_u32( GetPendingEvents( ctx ), 0 );
+}
+
+static void RtemsEventReqSendReceive_Action(
+ RtemsEventReqSendReceive_Context *ctx
+)
+{
+ if ( ctx->sender_type == SENDER_SELF ) {
+ SendAction( ctx );
+ } else if ( ctx->sender_type == SENDER_WORKER ) {
+ Wakeup( ctx->worker_wakeup );
+ }
+
+ if ( ctx->receive_type == RECEIVE_NORMAL ) {
+ ctx->receive_status = ( *ctx->receive )(
+ INPUT_EVENTS,
+ ctx->receive_option_set,
+ ctx->receive_timeout,
+ ctx->received_events_parameter
+ );
+ } else if ( ctx->receive_type == RECEIVE_INTERRUPT ) {
+ T_interrupt_test_state state;
+
+ state = T_interrupt_test( &InterruptConfig, ctx );
+ T_eq_int( state, T_INTERRUPT_TEST_DONE );
+ }
+
+ if ( ctx->sender_type == SENDER_SELF_2 ) {
+ SendAction( ctx );
+ } else if ( ctx->sender_type == SENDER_WORKER ) {
+ rtems_task_priority prio;
+
+ Wait( ctx->runner_wakeup );
+ prio = SetPriority( ctx->worker_id, PRIO_LOW );
+ T_eq_u32( prio, PRIO_HIGH );
+ }
+}
+
+static void RtemsEventReqSendReceive_Cleanup(
+ RtemsEventReqSendReceive_Context *ctx
+)
+{
+ rtems_status_code sc;
+ rtems_event_set events;
+
+ events = 0;
+ sc = ( *ctx->receive )(
+ RTEMS_ALL_EVENTS,
+ RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
+ 0,
+ &events
+ );
+ if ( sc == RTEMS_SUCCESSFUL ) {
+ T_quiet_ne_u32( events, 0 );
+ } else {
+ T_quiet_rsc( sc, RTEMS_UNSATISFIED );
+ T_quiet_eq_u32( events, 0 );
+ }
+}
+
+static const RtemsEventReqSendReceive_Entry
+RtemsEventReqSendReceive_Entries[] = {
+ { 0, 0, 1, 1, 1, RtemsEventReqSendReceive_Post_SendStatus_InvId,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_None,
+ RtemsEventReqSendReceive_Post_SenderPreemption_No },
+ { 0, 0, 0, 0, 1, RtemsEventReqSendReceive_Post_SendStatus_Ok,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_Pending,
+ RtemsEventReqSendReceive_Post_SenderPreemption_No },
+ { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_Blocked,
+ RtemsEventReqSendReceive_Post_SenderPreemption_No },
+ { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_Satisfied,
+ RtemsEventReqSendReceive_Post_SenderPreemption_No },
+ { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_Timeout,
+ RtemsEventReqSendReceive_Post_SenderPreemption_No },
+ { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_Unsatisfied,
+ RtemsEventReqSendReceive_Post_SenderPreemption_No },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_Blocked,
+ RtemsEventReqSendReceive_Post_SenderPreemption_No },
+#else
+ { 1, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_NA,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_NA,
+ RtemsEventReqSendReceive_Post_SenderPreemption_NA },
+#endif
+ { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_Satisfied,
+ RtemsEventReqSendReceive_Post_SenderPreemption_Yes },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_Ok,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_Satisfied,
+ RtemsEventReqSendReceive_Post_SenderPreemption_No }
+#else
+ { 1, 0, 0, 0, 0, RtemsEventReqSendReceive_Post_SendStatus_NA,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_NA,
+ RtemsEventReqSendReceive_Post_SenderPreemption_NA }
+#endif
+};
+
+static const uint8_t
+RtemsEventReqSendReceive_Map[] = {
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 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,
+ 3, 3, 7, 7, 8, 8, 3, 3
+};
+
+static size_t RtemsEventReqSendReceive_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsEventReqSendReceive_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ RtemsEventReqSendReceive_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsEventReqSendReceive_Fixture = {
+ .setup = RtemsEventReqSendReceive_Setup_Wrap,
+ .stop = NULL,
+ .teardown = RtemsEventReqSendReceive_Teardown_Wrap,
+ .scope = RtemsEventReqSendReceive_Scope,
+ .initial_context = &RtemsEventReqSendReceive_Instance
+};
+
+static inline RtemsEventReqSendReceive_Entry RtemsEventReqSendReceive_PopEntry(
+ RtemsEventReqSendReceive_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsEventReqSendReceive_Entries[
+ RtemsEventReqSendReceive_Map[ index ]
+ ];
+}
+
+static void RtemsEventReqSendReceive_SetPreConditionStates(
+ RtemsEventReqSendReceive_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+
+ if ( ctx->Map.entry.Pre_Send_NA ) {
+ ctx->Map.pcs[ 1 ] = RtemsEventReqSendReceive_Pre_Send_NA;
+ } else {
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ }
+
+ if ( ctx->Map.entry.Pre_ReceiverState_NA ) {
+ ctx->Map.pcs[ 2 ] = RtemsEventReqSendReceive_Pre_ReceiverState_NA;
+ } else {
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ }
+
+ if ( ctx->Map.entry.Pre_Satisfy_NA ) {
+ ctx->Map.pcs[ 3 ] = RtemsEventReqSendReceive_Pre_Satisfy_NA;
+ } else {
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ }
+}
+
+static void RtemsEventReqSendReceive_TestVariant(
+ RtemsEventReqSendReceive_Context *ctx
+)
+{
+ RtemsEventReqSendReceive_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsEventReqSendReceive_Pre_Send_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsEventReqSendReceive_Pre_ReceiverState_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsEventReqSendReceive_Pre_Satisfy_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ RtemsEventReqSendReceive_Action( ctx );
+ RtemsEventReqSendReceive_Post_SendStatus_Check(
+ ctx,
+ ctx->Map.entry.Post_SendStatus
+ );
+ RtemsEventReqSendReceive_Post_ReceiveStatus_Check(
+ ctx,
+ ctx->Map.entry.Post_ReceiveStatus
+ );
+ RtemsEventReqSendReceive_Post_SenderPreemption_Check(
+ ctx,
+ ctx->Map.entry.Post_SenderPreemption
+ );
+}
+
+static T_fixture_node RtemsEventReqSendReceive_Node;
+
+static T_remark RtemsEventReqSendReceive_Remark = {
+ .next = NULL,
+ .remark = "RtemsEventReqSendReceive"
+};
+
+void RtemsEventReqSendReceive_Run(
+ rtems_status_code ( *send )( rtems_id, rtems_event_set ),
+ rtems_status_code ( *receive )( rtems_event_set, rtems_option, rtems_interval, rtems_event_set * ),
+ rtems_event_set ( *get_pending_events )( Thread_Control * ),
+ unsigned int wait_class,
+ int waiting_for_event
+)
+{
+ RtemsEventReqSendReceive_Context *ctx;
+
+ ctx = &RtemsEventReqSendReceive_Instance;
+ ctx->send = send;
+ ctx->receive = receive;
+ ctx->get_pending_events = get_pending_events;
+ ctx->wait_class = wait_class;
+ ctx->waiting_for_event = waiting_for_event;
+
+ ctx = T_push_fixture(
+ &RtemsEventReqSendReceive_Node,
+ &RtemsEventReqSendReceive_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = RtemsEventReqSendReceive_Pre_Id_InvId;
+ ctx->Map.pci[ 0 ] < RtemsEventReqSendReceive_Pre_Id_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = RtemsEventReqSendReceive_Pre_Send_Zero;
+ ctx->Map.pci[ 1 ] < RtemsEventReqSendReceive_Pre_Send_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = RtemsEventReqSendReceive_Pre_ReceiverState_InvAddr;
+ ctx->Map.pci[ 2 ] < RtemsEventReqSendReceive_Pre_ReceiverState_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = RtemsEventReqSendReceive_Pre_Satisfy_All;
+ ctx->Map.pci[ 3 ] < RtemsEventReqSendReceive_Pre_Satisfy_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ ctx->Map.entry = RtemsEventReqSendReceive_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ RtemsEventReqSendReceive_SetPreConditionStates( ctx );
+ RtemsEventReqSendReceive_Prepare( ctx );
+ RtemsEventReqSendReceive_TestVariant( ctx );
+ RtemsEventReqSendReceive_Cleanup( ctx );
+ }
+ }
+ }
+ }
+
+ T_add_remark( &RtemsEventReqSendReceive_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-event-send-receive.h b/testsuites/validation/tr-event-send-receive.h
new file mode 100644
index 0000000000..f6dee4ddca
--- /dev/null
+++ b/testsuites/validation/tr-event-send-receive.h
@@ -0,0 +1,152 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsEventReqSendReceive
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_EVENT_SEND_RECEIVE_H
+#define _TR_EVENT_SEND_RECEIVE_H
+
+#include <rtems.h>
+#include <rtems/score/thread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup RtemsEventReqSendReceive
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsEventReqSendReceive_Pre_Id_InvId,
+ RtemsEventReqSendReceive_Pre_Id_Task,
+ RtemsEventReqSendReceive_Pre_Id_NA
+} RtemsEventReqSendReceive_Pre_Id;
+
+typedef enum {
+ RtemsEventReqSendReceive_Pre_Send_Zero,
+ RtemsEventReqSendReceive_Pre_Send_Unrelated,
+ RtemsEventReqSendReceive_Pre_Send_Any,
+ RtemsEventReqSendReceive_Pre_Send_All,
+ RtemsEventReqSendReceive_Pre_Send_MixedAny,
+ RtemsEventReqSendReceive_Pre_Send_MixedAll,
+ RtemsEventReqSendReceive_Pre_Send_NA
+} RtemsEventReqSendReceive_Pre_Send;
+
+typedef enum {
+ RtemsEventReqSendReceive_Pre_ReceiverState_InvAddr,
+ RtemsEventReqSendReceive_Pre_ReceiverState_NotWaiting,
+ RtemsEventReqSendReceive_Pre_ReceiverState_Poll,
+ RtemsEventReqSendReceive_Pre_ReceiverState_Timeout,
+ RtemsEventReqSendReceive_Pre_ReceiverState_Lower,
+ RtemsEventReqSendReceive_Pre_ReceiverState_Equal,
+ RtemsEventReqSendReceive_Pre_ReceiverState_Higher,
+ RtemsEventReqSendReceive_Pre_ReceiverState_Other,
+ RtemsEventReqSendReceive_Pre_ReceiverState_Intend,
+ RtemsEventReqSendReceive_Pre_ReceiverState_NA
+} RtemsEventReqSendReceive_Pre_ReceiverState;
+
+typedef enum {
+ RtemsEventReqSendReceive_Pre_Satisfy_All,
+ RtemsEventReqSendReceive_Pre_Satisfy_Any,
+ RtemsEventReqSendReceive_Pre_Satisfy_NA
+} RtemsEventReqSendReceive_Pre_Satisfy;
+
+typedef enum {
+ RtemsEventReqSendReceive_Post_SendStatus_Ok,
+ RtemsEventReqSendReceive_Post_SendStatus_InvId,
+ RtemsEventReqSendReceive_Post_SendStatus_NA
+} RtemsEventReqSendReceive_Post_SendStatus;
+
+typedef enum {
+ RtemsEventReqSendReceive_Post_ReceiveStatus_None,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_Pending,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_Timeout,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_Satisfied,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_Unsatisfied,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_Blocked,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_InvAddr,
+ RtemsEventReqSendReceive_Post_ReceiveStatus_NA
+} RtemsEventReqSendReceive_Post_ReceiveStatus;
+
+typedef enum {
+ RtemsEventReqSendReceive_Post_SenderPreemption_No,
+ RtemsEventReqSendReceive_Post_SenderPreemption_Yes,
+ RtemsEventReqSendReceive_Post_SenderPreemption_NA
+} RtemsEventReqSendReceive_Post_SenderPreemption;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param send is the event send handler.
+ *
+ * @param receive is the event receive handler.
+ *
+ * @param get_pending_events is the get pending events handler.
+ *
+ * @param wait_class is the thread wait class.
+ *
+ * @param waiting_for_event is the thread waiting for event state.
+ */
+void RtemsEventReqSendReceive_Run(
+ rtems_status_code ( *send )( rtems_id, rtems_event_set ),
+ rtems_status_code ( *receive )( rtems_event_set, rtems_option, rtems_interval, rtems_event_set * ),
+ rtems_event_set ( *get_pending_events )( Thread_Control * ),
+ unsigned int wait_class,
+ int waiting_for_event
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_EVENT_SEND_RECEIVE_H */
diff --git a/testsuites/validation/tr-fatal-boot-processor-not-assigned-to-scheduler.c b/testsuites/validation/tr-fatal-boot-processor-not-assigned-to-scheduler.c
new file mode 100644
index 0000000000..d02e2df8b6
--- /dev/null
+++ b/testsuites/validation/tr-fatal-boot-processor-not-assigned-to-scheduler.c
@@ -0,0 +1,159 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSmpValFatalBootProcessorNotAssignedToScheduler
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/smpimpl.h>
+
+#include "tr-fatal-boot-processor-not-assigned-to-scheduler.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreSmpValFatalBootProcessorNotAssignedToScheduler \
+ * spec:/score/smp/val/fatal-boot-processor-not-assigned-to-scheduler
+ *
+ * @ingroup TestsuitesFatalBootProcessorNotAssignedToScheduler
+ *
+ * @brief Tests a fatal error.
+ *
+ * This test case performs the following actions:
+ *
+ * - The test action is carried out by the application configuration of the
+ * test suite.
+ *
+ * - Check that the expected fatal source is present.
+ *
+ * - Check that the expected fatal code is present.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for
+ * spec:/score/smp/val/fatal-boot-processor-not-assigned-to-scheduler test
+ * case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreSmpValFatalBootProcessorNotAssignedToScheduler_Run() parameter.
+ */
+ rtems_fatal_source source;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreSmpValFatalBootProcessorNotAssignedToScheduler_Run() parameter.
+ */
+ rtems_fatal_code code;
+} ScoreSmpValFatalBootProcessorNotAssignedToScheduler_Context;
+
+static ScoreSmpValFatalBootProcessorNotAssignedToScheduler_Context
+ ScoreSmpValFatalBootProcessorNotAssignedToScheduler_Instance;
+
+static T_fixture ScoreSmpValFatalBootProcessorNotAssignedToScheduler_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &ScoreSmpValFatalBootProcessorNotAssignedToScheduler_Instance
+};
+
+/**
+ * @brief The test action is carried out by the application configuration of
+ * the test suite.
+ */
+static void ScoreSmpValFatalBootProcessorNotAssignedToScheduler_Action_0(
+ ScoreSmpValFatalBootProcessorNotAssignedToScheduler_Context *ctx
+)
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the expected fatal source is present.
+ */
+ T_step_eq_int( 0, ctx->source, RTEMS_FATAL_SOURCE_SMP );
+
+ /*
+ * Check that the expected fatal code is present.
+ */
+ T_step_eq_ulong(
+ 1,
+ ctx->code,
+ SMP_FATAL_BOOT_PROCESSOR_NOT_ASSIGNED_TO_SCHEDULER
+ );
+}
+
+void ScoreSmpValFatalBootProcessorNotAssignedToScheduler_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+)
+{
+ ScoreSmpValFatalBootProcessorNotAssignedToScheduler_Context *ctx;
+
+ ctx = &ScoreSmpValFatalBootProcessorNotAssignedToScheduler_Instance;
+ ctx->source = source;
+ ctx->code = code;
+
+ ctx = T_case_begin(
+ "ScoreSmpValFatalBootProcessorNotAssignedToScheduler",
+ &ScoreSmpValFatalBootProcessorNotAssignedToScheduler_Fixture
+ );
+
+ T_plan( 2 );
+
+ ScoreSmpValFatalBootProcessorNotAssignedToScheduler_Action_0( ctx );
+
+ T_case_end();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-fatal-boot-processor-not-assigned-to-scheduler.h b/testsuites/validation/tr-fatal-boot-processor-not-assigned-to-scheduler.h
new file mode 100644
index 0000000000..77299a5b39
--- /dev/null
+++ b/testsuites/validation/tr-fatal-boot-processor-not-assigned-to-scheduler.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSmpValFatalBootProcessorNotAssignedToScheduler
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_FATAL_BOOT_PROCESSOR_NOT_ASSIGNED_TO_SCHEDULER_H
+#define _TR_FATAL_BOOT_PROCESSOR_NOT_ASSIGNED_TO_SCHEDULER_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreSmpValFatalBootProcessorNotAssignedToScheduler
+ *
+ * @{
+ */
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param source is fatal source.
+ *
+ * @param code is fatal code.
+ */
+void ScoreSmpValFatalBootProcessorNotAssignedToScheduler_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_FATAL_BOOT_PROCESSOR_NOT_ASSIGNED_TO_SCHEDULER_H */
diff --git a/testsuites/validation/tr-fatal-idle-thread-create-failed.c b/testsuites/validation/tr-fatal-idle-thread-create-failed.c
new file mode 100644
index 0000000000..60a400c43d
--- /dev/null
+++ b/testsuites/validation/tr-fatal-idle-thread-create-failed.c
@@ -0,0 +1,158 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreThreadValFatalIdleThreadCreateFailed
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tr-fatal-idle-thread-create-failed.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreThreadValFatalIdleThreadCreateFailed \
+ * spec:/score/thread/val/fatal-idle-thread-create-failed
+ *
+ * @ingroup TestsuitesFatalIdleThreadCreateFailed
+ *
+ * @brief Tests a fatal error caused by a failing task create extension.
+ *
+ * This test case performs the following actions:
+ *
+ * - The test action is carried out by configuring a task create extension
+ * which always fails.
+ *
+ * - Check that the expected fatal source is present.
+ *
+ * - Check that the expected fatal code is present.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for
+ * spec:/score/thread/val/fatal-idle-thread-create-failed test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreThreadValFatalIdleThreadCreateFailed_Run() parameter.
+ */
+ rtems_fatal_source source;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreThreadValFatalIdleThreadCreateFailed_Run() parameter.
+ */
+ rtems_fatal_code code;
+} ScoreThreadValFatalIdleThreadCreateFailed_Context;
+
+static ScoreThreadValFatalIdleThreadCreateFailed_Context
+ ScoreThreadValFatalIdleThreadCreateFailed_Instance;
+
+static T_fixture ScoreThreadValFatalIdleThreadCreateFailed_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &ScoreThreadValFatalIdleThreadCreateFailed_Instance
+};
+
+/**
+ * @brief The test action is carried out by configuring a task create extension
+ * which always fails.
+ */
+static void ScoreThreadValFatalIdleThreadCreateFailed_Action_0(
+ ScoreThreadValFatalIdleThreadCreateFailed_Context *ctx
+)
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the expected fatal source is present.
+ */
+ T_step_eq_int( 0, ctx->source, INTERNAL_ERROR_CORE );
+
+ /*
+ * Check that the expected fatal code is present.
+ */
+ T_step_eq_ulong(
+ 1,
+ ctx->code,
+ INTERNAL_ERROR_IDLE_THREAD_CREATE_FAILED
+ );
+}
+
+void ScoreThreadValFatalIdleThreadCreateFailed_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+)
+{
+ ScoreThreadValFatalIdleThreadCreateFailed_Context *ctx;
+
+ ctx = &ScoreThreadValFatalIdleThreadCreateFailed_Instance;
+ ctx->source = source;
+ ctx->code = code;
+
+ ctx = T_case_begin(
+ "ScoreThreadValFatalIdleThreadCreateFailed",
+ &ScoreThreadValFatalIdleThreadCreateFailed_Fixture
+ );
+
+ T_plan( 2 );
+
+ ScoreThreadValFatalIdleThreadCreateFailed_Action_0( ctx );
+
+ T_case_end();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-fatal-idle-thread-create-failed.h b/testsuites/validation/tr-fatal-idle-thread-create-failed.h
new file mode 100644
index 0000000000..d521f3ed29
--- /dev/null
+++ b/testsuites/validation/tr-fatal-idle-thread-create-failed.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreThreadValFatalIdleThreadCreateFailed
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_FATAL_IDLE_THREAD_CREATE_FAILED_H
+#define _TR_FATAL_IDLE_THREAD_CREATE_FAILED_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreThreadValFatalIdleThreadCreateFailed
+ *
+ * @{
+ */
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param source is the fatal source.
+ *
+ * @param code is the fatal code.
+ */
+void ScoreThreadValFatalIdleThreadCreateFailed_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_FATAL_IDLE_THREAD_CREATE_FAILED_H */
diff --git a/testsuites/validation/tr-fatal-idle-thread-stack-too-small.c b/testsuites/validation/tr-fatal-idle-thread-stack-too-small.c
new file mode 100644
index 0000000000..34a428c883
--- /dev/null
+++ b/testsuites/validation/tr-fatal-idle-thread-stack-too-small.c
@@ -0,0 +1,175 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreThreadValFatalIdleThreadStackTooSmall
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tr-fatal-idle-thread-stack-too-small.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreThreadValFatalIdleThreadStackTooSmall \
+ * spec:/score/thread/val/fatal-idle-thread-stack-too-small
+ *
+ * @ingroup TestsuitesFatalIdleThreadStackTooSmall
+ *
+ * @brief Tests a fatal error caused by a too small idle thread stack size.
+ *
+ * This test case performs the following actions:
+ *
+ * - The test action is carried out by configuring a thread-local storage
+ * demand which leads to a too small idle thread stack size.
+ *
+ * - Check that the expected fatal source is present.
+ *
+ * - Check that the expected fatal code is present.
+ *
+ * - Check the configured value of CONFIGURE_IDLE_TASK_STORAGE_SIZE.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for
+ * spec:/score/thread/val/fatal-idle-thread-stack-too-small test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreThreadValFatalIdleThreadStackTooSmall_Run() parameter.
+ */
+ rtems_fatal_source source;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreThreadValFatalIdleThreadStackTooSmall_Run() parameter.
+ */
+ rtems_fatal_code code;
+} ScoreThreadValFatalIdleThreadStackTooSmall_Context;
+
+static ScoreThreadValFatalIdleThreadStackTooSmall_Context
+ ScoreThreadValFatalIdleThreadStackTooSmall_Instance;
+
+static T_fixture ScoreThreadValFatalIdleThreadStackTooSmall_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &ScoreThreadValFatalIdleThreadStackTooSmall_Instance
+};
+
+/**
+ * @brief The test action is carried out by configuring a thread-local storage
+ * demand which leads to a too small idle thread stack size.
+ */
+static void ScoreThreadValFatalIdleThreadStackTooSmall_Action_0(
+ ScoreThreadValFatalIdleThreadStackTooSmall_Context *ctx
+)
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the expected fatal source is present.
+ */
+ T_step_eq_int( 0, ctx->source, INTERNAL_ERROR_CORE );
+
+ /*
+ * Check that the expected fatal code is present.
+ */
+ T_step_eq_ulong(
+ 1,
+ ctx->code,
+ INTERNAL_ERROR_IDLE_THREAD_STACK_TOO_SMALL
+ );
+
+ /*
+ * Check the configured value of CONFIGURE_IDLE_TASK_STORAGE_SIZE.
+ */
+ T_step_eq_sz(
+ 2,
+ _Stack_Allocator_allocate_for_idle_storage_size,
+ RTEMS_ALIGN_UP(
+ RTEMS_TASK_STORAGE_SIZE(
+ RTEMS_MINIMUM_STACK_SIZE,
+ RTEMS_DEFAULT_ATTRIBUTES
+ ),
+ CPU_INTERRUPT_STACK_ALIGNMENT
+ )
+ );
+}
+
+void ScoreThreadValFatalIdleThreadStackTooSmall_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+)
+{
+ ScoreThreadValFatalIdleThreadStackTooSmall_Context *ctx;
+
+ ctx = &ScoreThreadValFatalIdleThreadStackTooSmall_Instance;
+ ctx->source = source;
+ ctx->code = code;
+
+ ctx = T_case_begin(
+ "ScoreThreadValFatalIdleThreadStackTooSmall",
+ &ScoreThreadValFatalIdleThreadStackTooSmall_Fixture
+ );
+
+ T_plan( 3 );
+
+ ScoreThreadValFatalIdleThreadStackTooSmall_Action_0( ctx );
+
+ T_case_end();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-fatal-idle-thread-stack-too-small.h b/testsuites/validation/tr-fatal-idle-thread-stack-too-small.h
new file mode 100644
index 0000000000..be29df8a39
--- /dev/null
+++ b/testsuites/validation/tr-fatal-idle-thread-stack-too-small.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreThreadValFatalIdleThreadStackTooSmall
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_FATAL_IDLE_THREAD_STACK_TOO_SMALL_H
+#define _TR_FATAL_IDLE_THREAD_STACK_TOO_SMALL_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreThreadValFatalIdleThreadStackTooSmall
+ *
+ * @{
+ */
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param source is the fatal source.
+ *
+ * @param code is the fatal code.
+ */
+void ScoreThreadValFatalIdleThreadStackTooSmall_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_FATAL_IDLE_THREAD_STACK_TOO_SMALL_H */
diff --git a/testsuites/validation/tr-fatal-init-task-construct-failed.c b/testsuites/validation/tr-fatal-init-task-construct-failed.c
new file mode 100644
index 0000000000..2bef7b73d8
--- /dev/null
+++ b/testsuites/validation/tr-fatal-init-task-construct-failed.c
@@ -0,0 +1,172 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup AcfgValFatalInitTaskConstructFailed
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/rtems/tasksdata.h>
+
+#include "tr-fatal-init-task-construct-failed.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup AcfgValFatalInitTaskConstructFailed \
+ * spec:/acfg/val/fatal-init-task-construct-failed
+ *
+ * @ingroup TestsuitesFatalInitTaskConstructFailed
+ *
+ * @brief Tests a fatal error caused by an invalid application configuration.
+ *
+ * This test case performs the following actions:
+ *
+ * - The test action is carried out by configuring an invalid task priority
+ * used to construct the initialization task.
+ *
+ * - Check that the expected fatal source is present.
+ *
+ * - Check that the expected fatal code is present.
+ *
+ * - Check that the CONFIGURE_INIT_TASK_PRIORITY application configuration
+ * option resulted in the expected system setting.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/acfg/val/fatal-init-task-construct-failed test
+ * case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a copy of the corresponding
+ * AcfgValFatalInitTaskConstructFailed_Run() parameter.
+ */
+ rtems_fatal_source source;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * AcfgValFatalInitTaskConstructFailed_Run() parameter.
+ */
+ rtems_fatal_code code;
+} AcfgValFatalInitTaskConstructFailed_Context;
+
+static AcfgValFatalInitTaskConstructFailed_Context
+ AcfgValFatalInitTaskConstructFailed_Instance;
+
+static T_fixture AcfgValFatalInitTaskConstructFailed_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &AcfgValFatalInitTaskConstructFailed_Instance
+};
+
+/**
+ * @brief The test action is carried out by configuring an invalid task
+ * priority used to construct the initialization task.
+ */
+static void AcfgValFatalInitTaskConstructFailed_Action_0(
+ AcfgValFatalInitTaskConstructFailed_Context *ctx
+)
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the expected fatal source is present.
+ */
+ T_step_eq_int( 0, ctx->source, INTERNAL_ERROR_CORE );
+
+ /*
+ * Check that the expected fatal code is present.
+ */
+ T_step_eq_ulong(
+ 1,
+ ctx->code,
+ INTERNAL_ERROR_RTEMS_INIT_TASK_CONSTRUCT_FAILED
+ );
+
+ /*
+ * Check that the CONFIGURE_INIT_TASK_PRIORITY application configuration
+ * option resulted in the expected system setting.
+ */
+ T_step_eq_u32(
+ 2,
+ _RTEMS_tasks_User_task_config.config.initial_priority,
+ 0
+ );
+}
+
+void AcfgValFatalInitTaskConstructFailed_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+)
+{
+ AcfgValFatalInitTaskConstructFailed_Context *ctx;
+
+ ctx = &AcfgValFatalInitTaskConstructFailed_Instance;
+ ctx->source = source;
+ ctx->code = code;
+
+ ctx = T_case_begin(
+ "AcfgValFatalInitTaskConstructFailed",
+ &AcfgValFatalInitTaskConstructFailed_Fixture
+ );
+
+ T_plan( 3 );
+
+ AcfgValFatalInitTaskConstructFailed_Action_0( ctx );
+
+ T_case_end();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-fatal-init-task-construct-failed.h b/testsuites/validation/tr-fatal-init-task-construct-failed.h
new file mode 100644
index 0000000000..9288a7f724
--- /dev/null
+++ b/testsuites/validation/tr-fatal-init-task-construct-failed.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup AcfgValFatalInitTaskConstructFailed
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_FATAL_INIT_TASK_CONSTRUCT_FAILED_H
+#define _TR_FATAL_INIT_TASK_CONSTRUCT_FAILED_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup AcfgValFatalInitTaskConstructFailed
+ *
+ * @{
+ */
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param source is fatal source.
+ *
+ * @param code is fatal code.
+ */
+void AcfgValFatalInitTaskConstructFailed_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_FATAL_INIT_TASK_CONSTRUCT_FAILED_H */
diff --git a/testsuites/validation/tr-fatal-mandatory-processor-not-present.c b/testsuites/validation/tr-fatal-mandatory-processor-not-present.c
new file mode 100644
index 0000000000..00b5678e1c
--- /dev/null
+++ b/testsuites/validation/tr-fatal-mandatory-processor-not-present.c
@@ -0,0 +1,158 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSmpValFatalMandatoryProcessorNotPresent
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/smpimpl.h>
+
+#include "tr-fatal-mandatory-processor-not-present.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreSmpValFatalMandatoryProcessorNotPresent \
+ * spec:/score/smp/val/fatal-mandatory-processor-not-present
+ *
+ * @ingroup TestsuitesFatalMandatoryProcessorNotPresent
+ *
+ * @brief Tests a fatal error.
+ *
+ * This test case performs the following actions:
+ *
+ * - The test action is carried out by the application configuration of the
+ * test suite.
+ *
+ * - Check that the expected fatal source is present.
+ *
+ * - Check that the expected fatal code is present.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for
+ * spec:/score/smp/val/fatal-mandatory-processor-not-present test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreSmpValFatalMandatoryProcessorNotPresent_Run() parameter.
+ */
+ rtems_fatal_source source;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreSmpValFatalMandatoryProcessorNotPresent_Run() parameter.
+ */
+ rtems_fatal_code code;
+} ScoreSmpValFatalMandatoryProcessorNotPresent_Context;
+
+static ScoreSmpValFatalMandatoryProcessorNotPresent_Context
+ ScoreSmpValFatalMandatoryProcessorNotPresent_Instance;
+
+static T_fixture ScoreSmpValFatalMandatoryProcessorNotPresent_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &ScoreSmpValFatalMandatoryProcessorNotPresent_Instance
+};
+
+/**
+ * @brief The test action is carried out by the application configuration of
+ * the test suite.
+ */
+static void ScoreSmpValFatalMandatoryProcessorNotPresent_Action_0(
+ ScoreSmpValFatalMandatoryProcessorNotPresent_Context *ctx
+)
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the expected fatal source is present.
+ */
+ T_step_eq_int( 0, ctx->source, RTEMS_FATAL_SOURCE_SMP );
+
+ /*
+ * Check that the expected fatal code is present.
+ */
+ T_step_eq_ulong(
+ 1,
+ ctx->code,
+ SMP_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT
+ );
+}
+
+void ScoreSmpValFatalMandatoryProcessorNotPresent_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+)
+{
+ ScoreSmpValFatalMandatoryProcessorNotPresent_Context *ctx;
+
+ ctx = &ScoreSmpValFatalMandatoryProcessorNotPresent_Instance;
+ ctx->source = source;
+ ctx->code = code;
+
+ ctx = T_case_begin(
+ "ScoreSmpValFatalMandatoryProcessorNotPresent",
+ &ScoreSmpValFatalMandatoryProcessorNotPresent_Fixture
+ );
+
+ T_plan( 2 );
+
+ ScoreSmpValFatalMandatoryProcessorNotPresent_Action_0( ctx );
+
+ T_case_end();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-fatal-mandatory-processor-not-present.h b/testsuites/validation/tr-fatal-mandatory-processor-not-present.h
new file mode 100644
index 0000000000..46d1581cc2
--- /dev/null
+++ b/testsuites/validation/tr-fatal-mandatory-processor-not-present.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSmpValFatalMandatoryProcessorNotPresent
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT_H
+#define _TR_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreSmpValFatalMandatoryProcessorNotPresent
+ *
+ * @{
+ */
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param source is fatal source.
+ *
+ * @param code is fatal code.
+ */
+void ScoreSmpValFatalMandatoryProcessorNotPresent_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_FATAL_MANDATORY_PROCESSOR_NOT_PRESENT_H */
diff --git a/testsuites/validation/tr-fatal-scheduler-requires-exactly-one-processor.c b/testsuites/validation/tr-fatal-scheduler-requires-exactly-one-processor.c
new file mode 100644
index 0000000000..8ac69193fa
--- /dev/null
+++ b/testsuites/validation/tr-fatal-scheduler-requires-exactly-one-processor.c
@@ -0,0 +1,159 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/smpimpl.h>
+
+#include "tr-fatal-scheduler-requires-exactly-one-processor.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor \
+ * spec:/score/smp/val/fatal-scheduler-requires-exactly-one-processor
+ *
+ * @ingroup TestsuitesFatalSchedulerRequiresExactlyOneProcessor
+ *
+ * @brief Tests a fatal error.
+ *
+ * This test case performs the following actions:
+ *
+ * - The test action is carried out by the application configuration of the
+ * test suite.
+ *
+ * - Check that the expected fatal source is present.
+ *
+ * - Check that the expected fatal code is present.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for
+ * spec:/score/smp/val/fatal-scheduler-requires-exactly-one-processor test
+ * case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor_Run() parameter.
+ */
+ rtems_fatal_source source;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor_Run() parameter.
+ */
+ rtems_fatal_code code;
+} ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor_Context;
+
+static ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor_Context
+ ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor_Instance;
+
+static T_fixture ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor_Instance
+};
+
+/**
+ * @brief The test action is carried out by the application configuration of
+ * the test suite.
+ */
+static void ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor_Action_0(
+ ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor_Context *ctx
+)
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the expected fatal source is present.
+ */
+ T_step_eq_int( 0, ctx->source, RTEMS_FATAL_SOURCE_SMP );
+
+ /*
+ * Check that the expected fatal code is present.
+ */
+ T_step_eq_ulong(
+ 1,
+ ctx->code,
+ SMP_FATAL_SCHEDULER_REQUIRES_EXACTLY_ONE_PROCESSOR
+ );
+}
+
+void ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+)
+{
+ ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor_Context *ctx;
+
+ ctx = &ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor_Instance;
+ ctx->source = source;
+ ctx->code = code;
+
+ ctx = T_case_begin(
+ "ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor",
+ &ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor_Fixture
+ );
+
+ T_plan( 2 );
+
+ ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor_Action_0( ctx );
+
+ T_case_end();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-fatal-scheduler-requires-exactly-one-processor.h b/testsuites/validation/tr-fatal-scheduler-requires-exactly-one-processor.h
new file mode 100644
index 0000000000..6bfb18fcfd
--- /dev/null
+++ b/testsuites/validation/tr-fatal-scheduler-requires-exactly-one-processor.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_FATAL_SCHEDULER_REQUIRES_EXACTLY_ONE_PROCESSOR_H
+#define _TR_FATAL_SCHEDULER_REQUIRES_EXACTLY_ONE_PROCESSOR_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor
+ *
+ * @{
+ */
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param source is fatal source.
+ *
+ * @param code is fatal code.
+ */
+void ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_FATAL_SCHEDULER_REQUIRES_EXACTLY_ONE_PROCESSOR_H */
diff --git a/testsuites/validation/tr-fatal-smp.c b/testsuites/validation/tr-fatal-smp.c
new file mode 100644
index 0000000000..c2369d0ae7
--- /dev/null
+++ b/testsuites/validation/tr-fatal-smp.c
@@ -0,0 +1,320 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSmpValFatal
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <setjmp.h>
+#include <rtems/sysinit.h>
+#include <rtems/score/atomic.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/smpimpl.h>
+
+#include "tr-fatal-smp.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreSmpValFatal spec:/score/smp/val/fatal
+ *
+ * @ingroup TestsuitesFatalSmp
+ *
+ * @brief Tests four fatal errors.
+ *
+ * This test case performs the following actions:
+ *
+ * - The test action is carried out by TriggerTestCase().
+ *
+ * - Check that the expected fatal source is present.
+ *
+ * - Check that the expected fatal code is present.
+ *
+ * - Check that the processor state is shutdown.
+ *
+ * - Check that a second shutdown request does not end in a recursive
+ * shutdown response.
+ *
+ * - Issue a job on a processor in the shutdown state. Check that the right
+ * fatal error occurs if we try to wait for this job to complete.
+ *
+ * - Start multitasking on an invalid processor. Check that the right fatal
+ * error occurs.
+ *
+ * - Start multitasking on an unassigned processor. Check that the right fatal
+ * error occurs.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/score/smp/val/fatal test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreSmpValFatal_Run() parameter.
+ */
+ rtems_fatal_source source;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreSmpValFatal_Run() parameter.
+ */
+ rtems_fatal_code code;
+} ScoreSmpValFatal_Context;
+
+static ScoreSmpValFatal_Context
+ ScoreSmpValFatal_Instance;
+
+static void TriggerTestCase( void )
+{
+ _SMP_Request_shutdown();
+ (void) _CPU_Thread_Idle_body( 0 );
+}
+
+RTEMS_SYSINIT_ITEM(
+ TriggerTestCase,
+ RTEMS_SYSINIT_DEVICE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_MIDDLE
+);
+
+static jmp_buf fatal_before;
+
+static Atomic_Uint fatal_counter;
+
+static rtems_fatal_source fatal_source;
+
+static rtems_fatal_code fatal_code;
+
+static void FatalRecordAndJump(
+ rtems_fatal_source source,
+ rtems_fatal_code code,
+ void *arg
+)
+{
+ (void) arg;
+
+ fatal_source = source;
+ fatal_code = code;
+ _Atomic_Fetch_add_uint( &fatal_counter, 1, ATOMIC_ORDER_RELAXED );
+ longjmp( fatal_before, 1 );
+}
+
+static void DoNothing( void *arg )
+{
+ (void) arg;
+}
+
+static const Per_CPU_Job_context job_context = {
+ .handler = DoNothing
+};
+
+Per_CPU_Job job = {
+ .context = &job_context
+};
+
+static T_fixture ScoreSmpValFatal_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &ScoreSmpValFatal_Instance
+};
+
+/**
+ * @brief The test action is carried out by TriggerTestCase().
+ */
+static void ScoreSmpValFatal_Action_0( ScoreSmpValFatal_Context *ctx )
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the expected fatal source is present.
+ */
+ T_step_eq_int( 0, ctx->source, RTEMS_FATAL_SOURCE_SMP );
+
+ /*
+ * Check that the expected fatal code is present.
+ */
+ T_step_eq_ulong( 1, ctx->code, SMP_FATAL_SHUTDOWN_RESPONSE );
+
+ /*
+ * Check that the processor state is shutdown.
+ */
+ T_step_eq_int(
+ 2,
+ _Per_CPU_Get_state( _Per_CPU_Get() ),
+ PER_CPU_STATE_SHUTDOWN
+ );
+
+ /*
+ * Check that a second shutdown request does not end in a recursive shutdown
+ * response.
+ */
+ _SMP_Process_message( _Per_CPU_Get(), SMP_MESSAGE_SHUTDOWN );
+}
+
+/**
+ * @brief Issue a job on a processor in the shutdown state. Check that the
+ * right fatal error occurs if we try to wait for this job to complete.
+ */
+static void ScoreSmpValFatal_Action_1( ScoreSmpValFatal_Context *ctx )
+{
+ Per_CPU_Control *cpu;
+
+ SetFatalHandler( FatalRecordAndJump, ctx );
+ cpu = _Per_CPU_Get_by_index( 0 );
+ _Per_CPU_Submit_job( cpu, &job );
+
+ if ( setjmp( fatal_before ) == 0 ) {
+ _Per_CPU_Wait_for_job( cpu, &job );
+ }
+
+ T_step_eq_uint(
+ 3,
+ _Atomic_Load_uint( &fatal_counter, ATOMIC_ORDER_RELAXED ),
+ 1
+ );
+ T_step_eq_int( 4, fatal_source, RTEMS_FATAL_SOURCE_SMP );
+ T_step_eq_ulong(
+ 5,
+ fatal_code,
+ SMP_FATAL_WRONG_CPU_STATE_TO_PERFORM_JOBS
+ );
+ SetFatalHandler( NULL, NULL );
+}
+
+/**
+ * @brief Start multitasking on an invalid processor. Check that the right
+ * fatal error occurs.
+ */
+static void ScoreSmpValFatal_Action_2( ScoreSmpValFatal_Context *ctx )
+{
+ Per_CPU_Control *cpu;
+
+ SetFatalHandler( FatalRecordAndJump, ctx );
+
+ /*
+ * This element is outside the array. This is not an issue since
+ * _SMP_Start_multitasking_on_secondary_processor() does not access the
+ * structure.
+ */
+ cpu = _Per_CPU_Get_by_index( 3 );
+
+ if ( setjmp( fatal_before ) == 0 ) {
+ _SMP_Start_multitasking_on_secondary_processor( cpu );
+ }
+
+ T_step_eq_uint(
+ 6,
+ _Atomic_Load_uint( &fatal_counter, ATOMIC_ORDER_RELAXED ),
+ 2
+ );
+ T_step_eq_int( 7, fatal_source, RTEMS_FATAL_SOURCE_SMP );
+ T_step_eq_ulong(
+ 8,
+ fatal_code,
+ SMP_FATAL_MULTITASKING_START_ON_INVALID_PROCESSOR
+ );
+ SetFatalHandler( NULL, NULL );
+}
+
+/**
+ * @brief Start multitasking on an unassigned processor. Check that the right
+ * fatal error occurs.
+ */
+static void ScoreSmpValFatal_Action_3( ScoreSmpValFatal_Context *ctx )
+{
+ Per_CPU_Control *cpu;
+
+ SetFatalHandler( FatalRecordAndJump, ctx );
+ cpu = _Per_CPU_Get_by_index( 2 );
+
+ if ( setjmp( fatal_before ) == 0 ) {
+ _SMP_Start_multitasking_on_secondary_processor( cpu );
+ }
+
+ T_step_eq_uint(
+ 9,
+ _Atomic_Load_uint( &fatal_counter, ATOMIC_ORDER_RELAXED ),
+ 3
+ );
+ T_step_eq_int( 10, fatal_source, RTEMS_FATAL_SOURCE_SMP );
+ T_step_eq_ulong(
+ 11,
+ fatal_code,
+ SMP_FATAL_MULTITASKING_START_ON_UNASSIGNED_PROCESSOR
+ );
+ SetFatalHandler( NULL, NULL );
+}
+
+void ScoreSmpValFatal_Run( rtems_fatal_source source, rtems_fatal_code code )
+{
+ ScoreSmpValFatal_Context *ctx;
+
+ ctx = &ScoreSmpValFatal_Instance;
+ ctx->source = source;
+ ctx->code = code;
+
+ ctx = T_case_begin( "ScoreSmpValFatal", &ScoreSmpValFatal_Fixture );
+
+ T_plan( 12 );
+
+ ScoreSmpValFatal_Action_0( ctx );
+ ScoreSmpValFatal_Action_1( ctx );
+ ScoreSmpValFatal_Action_2( ctx );
+ ScoreSmpValFatal_Action_3( ctx );
+
+ T_case_end();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-fatal-smp.h b/testsuites/validation/tr-fatal-smp.h
new file mode 100644
index 0000000000..ff7406a47f
--- /dev/null
+++ b/testsuites/validation/tr-fatal-smp.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSmpValFatal
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_FATAL_SMP_H
+#define _TR_FATAL_SMP_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreSmpValFatal
+ *
+ * @{
+ */
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param source is fatal source.
+ *
+ * @param code is fatal code.
+ */
+void ScoreSmpValFatal_Run( rtems_fatal_source source, rtems_fatal_code code );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_FATAL_SMP_H */
diff --git a/testsuites/validation/tr-fatal-start-of-mandatory-processor-failed.c b/testsuites/validation/tr-fatal-start-of-mandatory-processor-failed.c
new file mode 100644
index 0000000000..5c1be8271a
--- /dev/null
+++ b/testsuites/validation/tr-fatal-start-of-mandatory-processor-failed.c
@@ -0,0 +1,166 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSmpValFatalStartOfMandatoryProcessorFailed
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/smpimpl.h>
+
+#include "tr-fatal-start-of-mandatory-processor-failed.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreSmpValFatalStartOfMandatoryProcessorFailed \
+ * spec:/score/smp/val/fatal-start-of-mandatory-processor-failed
+ *
+ * @ingroup TestsuitesFatalStartOfMandatoryProcessorFailed
+ *
+ * @brief Tests a fatal error.
+ *
+ * This test case performs the following actions:
+ *
+ * - The test action is carried out by the application configuration of the
+ * test suite and the wrapped _CPU_SMP_Start_processor().
+ *
+ * - Check that the expected fatal source is present.
+ *
+ * - Check that the expected fatal code is present.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for
+ * spec:/score/smp/val/fatal-start-of-mandatory-processor-failed test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreSmpValFatalStartOfMandatoryProcessorFailed_Run() parameter.
+ */
+ rtems_fatal_source source;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreSmpValFatalStartOfMandatoryProcessorFailed_Run() parameter.
+ */
+ rtems_fatal_code code;
+} ScoreSmpValFatalStartOfMandatoryProcessorFailed_Context;
+
+static ScoreSmpValFatalStartOfMandatoryProcessorFailed_Context
+ ScoreSmpValFatalStartOfMandatoryProcessorFailed_Instance;
+
+bool __wrap__CPU_SMP_Start_processor( uint32_t cpu_index );
+
+bool __wrap__CPU_SMP_Start_processor( uint32_t cpu_index )
+{
+ (void) cpu_index;
+ return false;
+}
+
+static T_fixture ScoreSmpValFatalStartOfMandatoryProcessorFailed_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &ScoreSmpValFatalStartOfMandatoryProcessorFailed_Instance
+};
+
+/**
+ * @brief The test action is carried out by the application configuration of
+ * the test suite and the wrapped _CPU_SMP_Start_processor().
+ */
+static void ScoreSmpValFatalStartOfMandatoryProcessorFailed_Action_0(
+ ScoreSmpValFatalStartOfMandatoryProcessorFailed_Context *ctx
+)
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the expected fatal source is present.
+ */
+ T_step_eq_int( 0, ctx->source, RTEMS_FATAL_SOURCE_SMP );
+
+ /*
+ * Check that the expected fatal code is present.
+ */
+ T_step_eq_ulong(
+ 1,
+ ctx->code,
+ SMP_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED
+ );
+}
+
+void ScoreSmpValFatalStartOfMandatoryProcessorFailed_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+)
+{
+ ScoreSmpValFatalStartOfMandatoryProcessorFailed_Context *ctx;
+
+ ctx = &ScoreSmpValFatalStartOfMandatoryProcessorFailed_Instance;
+ ctx->source = source;
+ ctx->code = code;
+
+ ctx = T_case_begin(
+ "ScoreSmpValFatalStartOfMandatoryProcessorFailed",
+ &ScoreSmpValFatalStartOfMandatoryProcessorFailed_Fixture
+ );
+
+ T_plan( 2 );
+
+ ScoreSmpValFatalStartOfMandatoryProcessorFailed_Action_0( ctx );
+
+ T_case_end();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-fatal-start-of-mandatory-processor-failed.h b/testsuites/validation/tr-fatal-start-of-mandatory-processor-failed.h
new file mode 100644
index 0000000000..b233ddc00c
--- /dev/null
+++ b/testsuites/validation/tr-fatal-start-of-mandatory-processor-failed.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSmpValFatalStartOfMandatoryProcessorFailed
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED_H
+#define _TR_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreSmpValFatalStartOfMandatoryProcessorFailed
+ *
+ * @{
+ */
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param source is fatal source.
+ *
+ * @param code is fatal code.
+ */
+void ScoreSmpValFatalStartOfMandatoryProcessorFailed_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_FATAL_START_OF_MANDATORY_PROCESSOR_FAILED_H */
diff --git a/testsuites/validation/tr-fatal-start-on-not-online-processor.c b/testsuites/validation/tr-fatal-start-on-not-online-processor.c
new file mode 100644
index 0000000000..2773b00783
--- /dev/null
+++ b/testsuites/validation/tr-fatal-start-on-not-online-processor.c
@@ -0,0 +1,167 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSmpValFatalStartOnNotOnlineProcessor
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/smpimpl.h>
+
+#include "tr-fatal-start-on-not-online-processor.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreSmpValFatalStartOnNotOnlineProcessor \
+ * spec:/score/smp/val/fatal-start-on-not-online-processor
+ *
+ * @ingroup TestsuitesFatalStartOnNotOnlineProcessor
+ *
+ * @brief Tests a fatal error.
+ *
+ * This test case performs the following actions:
+ *
+ * - The test action is carried out by the wrapped _CPU_SMP_Start_processor().
+ *
+ * - Check that the expected fatal source is present.
+ *
+ * - Check that the expected fatal code is present.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for
+ * spec:/score/smp/val/fatal-start-on-not-online-processor test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreSmpValFatalStartOnNotOnlineProcessor_Run() parameter.
+ */
+ rtems_fatal_source source;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreSmpValFatalStartOnNotOnlineProcessor_Run() parameter.
+ */
+ rtems_fatal_code code;
+} ScoreSmpValFatalStartOnNotOnlineProcessor_Context;
+
+static ScoreSmpValFatalStartOnNotOnlineProcessor_Context
+ ScoreSmpValFatalStartOnNotOnlineProcessor_Instance;
+
+bool __real__CPU_SMP_Start_processor( uint32_t cpu_index );
+
+bool __wrap__CPU_SMP_Start_processor( uint32_t cpu_index );
+
+bool __wrap__CPU_SMP_Start_processor( uint32_t cpu_index )
+{
+ (void) __real__CPU_SMP_Start_processor( cpu_index );
+ return false;
+}
+
+static T_fixture ScoreSmpValFatalStartOnNotOnlineProcessor_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &ScoreSmpValFatalStartOnNotOnlineProcessor_Instance
+};
+
+/**
+ * @brief The test action is carried out by the wrapped
+ * _CPU_SMP_Start_processor().
+ */
+static void ScoreSmpValFatalStartOnNotOnlineProcessor_Action_0(
+ ScoreSmpValFatalStartOnNotOnlineProcessor_Context *ctx
+)
+{
+ /* Nothing to do */
+
+ /*
+ * Check that the expected fatal source is present.
+ */
+ T_step_eq_int( 0, ctx->source, RTEMS_FATAL_SOURCE_SMP );
+
+ /*
+ * Check that the expected fatal code is present.
+ */
+ T_step_eq_ulong(
+ 1,
+ ctx->code,
+ SMP_FATAL_MULTITASKING_START_ON_NOT_ONLINE_PROCESSOR
+ );
+}
+
+void ScoreSmpValFatalStartOnNotOnlineProcessor_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+)
+{
+ ScoreSmpValFatalStartOnNotOnlineProcessor_Context *ctx;
+
+ ctx = &ScoreSmpValFatalStartOnNotOnlineProcessor_Instance;
+ ctx->source = source;
+ ctx->code = code;
+
+ ctx = T_case_begin(
+ "ScoreSmpValFatalStartOnNotOnlineProcessor",
+ &ScoreSmpValFatalStartOnNotOnlineProcessor_Fixture
+ );
+
+ T_plan( 2 );
+
+ ScoreSmpValFatalStartOnNotOnlineProcessor_Action_0( ctx );
+
+ T_case_end();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-fatal-start-on-not-online-processor.h b/testsuites/validation/tr-fatal-start-on-not-online-processor.h
new file mode 100644
index 0000000000..58e9641c4f
--- /dev/null
+++ b/testsuites/validation/tr-fatal-start-on-not-online-processor.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSmpValFatalStartOnNotOnlineProcessor
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_FATAL_START_ON_NOT_ONLINE_PROCESSOR_H
+#define _TR_FATAL_START_ON_NOT_ONLINE_PROCESSOR_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreSmpValFatalStartOnNotOnlineProcessor
+ *
+ * @{
+ */
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param source is fatal source.
+ *
+ * @param code is fatal code.
+ */
+void ScoreSmpValFatalStartOnNotOnlineProcessor_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_FATAL_START_ON_NOT_ONLINE_PROCESSOR_H */
diff --git a/testsuites/validation/tr-fatal-too-large-tls-size.c b/testsuites/validation/tr-fatal-too-large-tls-size.c
new file mode 100644
index 0000000000..9bf5dcda97
--- /dev/null
+++ b/testsuites/validation/tr-fatal-too-large-tls-size.c
@@ -0,0 +1,182 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup AcfgValFatalTooLargeTlsSize
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/score/thread.h>
+
+#include "tr-fatal-too-large-tls-size.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup AcfgValFatalTooLargeTlsSize \
+ * spec:/acfg/val/fatal-too-large-tls-size
+ *
+ * @ingroup TestsuitesFatalTooLargeTlsSize
+ *
+ * @brief Tests a fatal error.
+ *
+ * This test case performs the following actions:
+ *
+ * - The test action is carried out by providing a thread-local storage object
+ * of sufficient size with respect to the application configuration of the
+ * test suite.
+ *
+ * - Check that the expected fatal source is present.
+ *
+ * - Check that the expected fatal code is present.
+ *
+ * - Check that the CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE application
+ * configuration option resulted in the expected system setting.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/acfg/val/fatal-too-large-tls-size test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a copy of the corresponding
+ * AcfgValFatalTooLargeTlsSize_Run() parameter.
+ */
+ rtems_fatal_source source;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * AcfgValFatalTooLargeTlsSize_Run() parameter.
+ */
+ rtems_fatal_code code;
+} AcfgValFatalTooLargeTlsSize_Context;
+
+static AcfgValFatalTooLargeTlsSize_Context
+ AcfgValFatalTooLargeTlsSize_Instance;
+
+static volatile _Thread_local uint8_t large_tls_object[ RTEMS_TASK_STORAGE_ALIGNMENT + 1 ];
+
+static volatile bool shall_not_load_the_value;
+
+static T_fixture AcfgValFatalTooLargeTlsSize_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &AcfgValFatalTooLargeTlsSize_Instance
+};
+
+/**
+ * @brief The test action is carried out by providing a thread-local storage
+ * object of sufficient size with respect to the application configuration of
+ * the test suite.
+ */
+static void AcfgValFatalTooLargeTlsSize_Action_0(
+ AcfgValFatalTooLargeTlsSize_Context *ctx
+)
+{
+ if ( shall_not_load_the_value ) {
+ uint8_t value;
+
+ value = large_tls_object[ 0 ];
+ RTEMS_OBFUSCATE_VARIABLE( value );
+ }
+
+ /*
+ * Check that the expected fatal source is present.
+ */
+ T_step_eq_int( 0, ctx->source, INTERNAL_ERROR_CORE );
+
+ /*
+ * Check that the expected fatal code is present.
+ */
+ T_step_eq_ulong(
+ 1,
+ ctx->code,
+ INTERNAL_ERROR_TOO_LARGE_TLS_SIZE
+ );
+
+ /*
+ * Check that the CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE application
+ * configuration option resulted in the expected system setting.
+ */
+ T_step_eq_sz(
+ 2,
+ _Thread_Maximum_TLS_size,
+ RTEMS_TASK_STORAGE_ALIGNMENT
+ );
+}
+
+void AcfgValFatalTooLargeTlsSize_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+)
+{
+ AcfgValFatalTooLargeTlsSize_Context *ctx;
+
+ ctx = &AcfgValFatalTooLargeTlsSize_Instance;
+ ctx->source = source;
+ ctx->code = code;
+
+ ctx = T_case_begin(
+ "AcfgValFatalTooLargeTlsSize",
+ &AcfgValFatalTooLargeTlsSize_Fixture
+ );
+
+ T_plan( 3 );
+
+ AcfgValFatalTooLargeTlsSize_Action_0( ctx );
+
+ T_case_end();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-fatal-too-large-tls-size.h b/testsuites/validation/tr-fatal-too-large-tls-size.h
new file mode 100644
index 0000000000..c1504261d2
--- /dev/null
+++ b/testsuites/validation/tr-fatal-too-large-tls-size.h
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup AcfgValFatalTooLargeTlsSize
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_FATAL_TOO_LARGE_TLS_SIZE_H
+#define _TR_FATAL_TOO_LARGE_TLS_SIZE_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup AcfgValFatalTooLargeTlsSize
+ *
+ * @{
+ */
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param source is fatal source.
+ *
+ * @param code is fatal code.
+ */
+void AcfgValFatalTooLargeTlsSize_Run(
+ rtems_fatal_source source,
+ rtems_fatal_code code
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_FATAL_TOO_LARGE_TLS_SIZE_H */
diff --git a/testsuites/validation/tr-io-kernel.c b/testsuites/validation/tr-io-kernel.c
new file mode 100644
index 0000000000..bbebfe5a26
--- /dev/null
+++ b/testsuites/validation/tr-io-kernel.c
@@ -0,0 +1,125 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsIoValKernel
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/bspIo.h>
+
+#include "tr-io-kernel.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsIoValKernel spec:/rtems/io/val/kernel
+ *
+ * @ingroup TestsuitesValidationIoKernel
+ *
+ * @brief Tests the functions referenced by BSP_output_char and BSP_poll_char.
+ *
+ * This test case performs the following actions:
+ *
+ * - Call the function referenced by BSP_output_char.
+ *
+ * - If BSP_poll_char references a function, then call it.
+ *
+ * - Check that the returned value is minus one or an unsigned character
+ * value.
+ *
+ * @{
+ */
+
+/**
+ * @brief Call the function referenced by BSP_output_char.
+ */
+static void RtemsIoValKernel_Action_0( void )
+{
+ T_report_hash_sha256_update( 'X' );
+ ( *BSP_output_char )( 'X' );
+ T_report_hash_sha256_update( '\n' );
+ ( *BSP_output_char )( '\n' );
+}
+
+/**
+ * @brief If BSP_poll_char references a function, then call it.
+ */
+static void RtemsIoValKernel_Action_1( void )
+{
+ BSP_polling_getchar_function_type poll_char;
+ int c;
+
+ poll_char = BSP_poll_char;
+
+ if ( poll_char != NULL ) {
+ c = ( *poll_char )();
+ } else {
+ c = -1;
+ }
+
+ /*
+ * Check that the returned value is minus one or an unsigned character value.
+ */
+ T_step_true( 0, c == -1 || ( c & ~0xff ) == 0 );
+}
+
+void RtemsIoValKernel_Run( void )
+{
+ T_case_begin( "RtemsIoValKernel", &T_empty_fixture );
+
+ T_plan( 1 );
+
+ RtemsIoValKernel_Action_0();
+ RtemsIoValKernel_Action_1();
+
+ T_case_end();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-io-kernel.h b/testsuites/validation/tr-io-kernel.h
new file mode 100644
index 0000000000..ef878982dc
--- /dev/null
+++ b/testsuites/validation/tr-io-kernel.h
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsIoValKernel
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_IO_KERNEL_H
+#define _TR_IO_KERNEL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup RtemsIoValKernel
+ *
+ * @{
+ */
+
+/**
+ * @brief Runs the parameterized test case.
+ */
+void RtemsIoValKernel_Run( void );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_IO_KERNEL_H */
diff --git a/testsuites/validation/tr-mtx-seize-try.c b/testsuites/validation/tr-mtx-seize-try.c
new file mode 100644
index 0000000000..ddc995c2e1
--- /dev/null
+++ b/testsuites/validation/tr-mtx-seize-try.c
@@ -0,0 +1,868 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreMtxReqSeizeTry
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-mtx-seize-try.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreMtxReqSeizeTry spec:/score/mtx/req/seize-try
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Protocol_NA : 1;
+ uint16_t Pre_Discipline_NA : 1;
+ uint16_t Pre_Recursive_NA : 1;
+ uint16_t Pre_Owner_NA : 1;
+ uint16_t Pre_Priority_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_Owner : 2;
+ uint16_t Post_Priority : 2;
+} ScoreMtxReqSeizeTry_Entry;
+
+/**
+ * @brief Test context for spec:/score/mtx/req/seize-try test case.
+ */
+typedef struct {
+ /**
+ * @brief If this member is true, then the calling thread shall be the owner
+ * of the mutex.
+ */
+ bool owner_caller;
+
+ /**
+ * @brief If this member is true, then a thread other than the calling thread
+ * shall be the owner of the mutex.
+ */
+ bool owner_other;
+
+ /**
+ * @brief This member contains the current priority of the calling thread
+ * before the directive call.
+ */
+ rtems_task_priority priority_before;
+
+ /**
+ * @brief This member contains the owner of the mutex after the directive
+ * call.
+ */
+ const rtems_tcb *owner_after;
+
+ /**
+ * @brief This member contains the current priority of the calling thread
+ * after the directive call.
+ */
+ rtems_task_priority priority_after;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreMtxReqSeizeTry_Run() parameter.
+ */
+ TQMtxContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 5 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 5 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreMtxReqSeizeTry_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreMtxReqSeizeTry_Context;
+
+static ScoreMtxReqSeizeTry_Context
+ ScoreMtxReqSeizeTry_Instance;
+
+static const char * const ScoreMtxReqSeizeTry_PreDesc_Protocol[] = {
+ "Ceiling",
+ "MrsP",
+ "Other",
+ "NA"
+};
+
+static const char * const ScoreMtxReqSeizeTry_PreDesc_Discipline[] = {
+ "FIFO",
+ "Priority",
+ "NA"
+};
+
+static const char * const ScoreMtxReqSeizeTry_PreDesc_Recursive[] = {
+ "Allowed",
+ "Unavailable",
+ "Deadlock",
+ "NA"
+};
+
+static const char * const ScoreMtxReqSeizeTry_PreDesc_Owner[] = {
+ "None",
+ "Caller",
+ "Other",
+ "NA"
+};
+
+static const char * const ScoreMtxReqSeizeTry_PreDesc_Priority[] = {
+ "High",
+ "Equal",
+ "Low",
+ "NA"
+};
+
+static const char * const * const ScoreMtxReqSeizeTry_PreDesc[] = {
+ ScoreMtxReqSeizeTry_PreDesc_Protocol,
+ ScoreMtxReqSeizeTry_PreDesc_Discipline,
+ ScoreMtxReqSeizeTry_PreDesc_Recursive,
+ ScoreMtxReqSeizeTry_PreDesc_Owner,
+ ScoreMtxReqSeizeTry_PreDesc_Priority,
+ NULL
+};
+
+typedef ScoreMtxReqSeizeTry_Context Context;
+
+static Status_Control Status( const Context *ctx, Status_Control status )
+{
+ return TQConvertStatus( &ctx->tq_ctx->base, status );
+}
+
+static bool IsEnqueueStatus( const Context *ctx, Status_Control expected )
+{
+ return ctx->tq_ctx->base.status[ TQ_BLOCKER_A ] == Status( ctx, expected );
+}
+
+static void Action( Context *ctx )
+{
+ TQSetScheduler(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ SCHEDULER_A_ID,
+ PRIO_VERY_HIGH
+ );
+
+ if ( ctx->owner_caller ) {
+ TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
+ } else if ( ctx->owner_other ) {
+ TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_B, TQ_EVENT_ENQUEUE );
+ }
+
+ TQSetPriority( &ctx->tq_ctx->base, TQ_BLOCKER_A, ctx->priority_before );
+ TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
+ ctx->owner_after = TQGetOwner( &ctx->tq_ctx->base );
+ ctx->priority_after = TQGetPriority( &ctx->tq_ctx->base, TQ_BLOCKER_A );
+
+ if ( ctx->owner_caller ) {
+ TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_SURRENDER );
+ } else if ( ctx->owner_other ) {
+ TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_B, TQ_EVENT_SURRENDER );
+ }
+
+ if ( IsEnqueueStatus( ctx, STATUS_SUCCESSFUL ) ) {
+ TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_SURRENDER );
+ }
+}
+
+static void ActionSticky( Context *ctx )
+{
+ TQSetScheduler(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ SCHEDULER_B_ID,
+ PRIO_VERY_HIGH
+ );
+
+ if ( ctx->owner_caller ) {
+ TQSendAndSynchronizeRunner(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ TQ_EVENT_ENQUEUE
+ );
+ } else if ( ctx->owner_other ) {
+ SetSelfScheduler( SCHEDULER_B_ID, PRIO_ULTRA_HIGH );
+ TQSendAndSynchronizeRunner(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_B,
+ TQ_EVENT_ENQUEUE
+ );
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_ULTRA_HIGH );
+ }
+
+ TQSetPriority( &ctx->tq_ctx->base, TQ_BLOCKER_A, ctx->priority_before );
+ TQClearDone( &ctx->tq_ctx->base, TQ_BLOCKER_A );
+ TQSendAndWaitForExecutionStopOrIntendToBlock(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ TQ_EVENT_ENQUEUE
+ );
+ ctx->owner_after = TQGetOwner( &ctx->tq_ctx->base );
+ ctx->priority_after = TQGetPriority( &ctx->tq_ctx->base, TQ_BLOCKER_A );
+
+ if ( ctx->owner_caller ) {
+ TQSendAndSynchronizeRunner(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ TQ_EVENT_SURRENDER
+ );
+ } else if ( ctx->owner_other ) {
+ SetSelfScheduler( SCHEDULER_B_ID, PRIO_ULTRA_HIGH );
+ TQSendAndSynchronizeRunner(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_B,
+ TQ_EVENT_SURRENDER
+ );
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_NORMAL );
+ }
+
+ TQWaitForDone( &ctx->tq_ctx->base, TQ_BLOCKER_A );
+
+ if ( IsEnqueueStatus( ctx, STATUS_SUCCESSFUL ) ) {
+ TQSendAndSynchronizeRunner(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ TQ_EVENT_SURRENDER
+ );
+ }
+}
+
+static void ScoreMtxReqSeizeTry_Pre_Protocol_Prepare(
+ ScoreMtxReqSeizeTry_Context *ctx,
+ ScoreMtxReqSeizeTry_Pre_Protocol state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeTry_Pre_Protocol_Ceiling: {
+ /*
+ * Where the mutex uses the priority ceiling locking protocol.
+ */
+ if (
+ ctx->tq_ctx->priority_ceiling == PRIO_INVALID ||
+ ctx->tq_ctx->base.enqueue_variant == TQ_ENQUEUE_STICKY
+ ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Pre_Protocol_MrsP: {
+ /*
+ * Where the mutex uses the MrsP locking protocol.
+ */
+ if (
+ ctx->tq_ctx->priority_ceiling == PRIO_INVALID ||
+ ctx->tq_ctx->base.enqueue_variant != TQ_ENQUEUE_STICKY
+ ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Pre_Protocol_Other: {
+ /*
+ * Where the mutex does not use the priority ceiling or MrsP locking
+ * protocol.
+ */
+ if ( ctx->tq_ctx->priority_ceiling != PRIO_INVALID ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Pre_Protocol_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeTry_Pre_Discipline_Prepare(
+ ScoreMtxReqSeizeTry_Context *ctx,
+ ScoreMtxReqSeizeTry_Pre_Discipline state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeTry_Pre_Discipline_FIFO: {
+ /*
+ * Where the thread queue of the mutex uses the FIFO discipline.
+ */
+ if ( ctx->tq_ctx->base.discipline != TQ_FIFO ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Pre_Discipline_Priority: {
+ /*
+ * Where the thread queue of the mutex uses the priority discipline.
+ */
+ if ( ctx->tq_ctx->base.discipline != TQ_PRIORITY ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Pre_Discipline_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeTry_Pre_Recursive_Prepare(
+ ScoreMtxReqSeizeTry_Context *ctx,
+ ScoreMtxReqSeizeTry_Pre_Recursive state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeTry_Pre_Recursive_Allowed: {
+ /*
+ * Where a recursive seize of the mutex is allowed.
+ */
+ if ( ctx->tq_ctx->recursive != TQ_MTX_RECURSIVE_ALLOWED ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Pre_Recursive_Unavailable: {
+ /*
+ * Where a recursive seize of the mutex results in an unavailable status.
+ */
+ if ( ctx->tq_ctx->recursive != TQ_MTX_RECURSIVE_UNAVAILABLE ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Pre_Recursive_Deadlock: {
+ /*
+ * Where a recursive seize of the mutex results in a deadlock status.
+ */
+ if ( ctx->tq_ctx->recursive != TQ_MTX_RECURSIVE_DEADLOCK ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Pre_Recursive_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeTry_Pre_Owner_Prepare(
+ ScoreMtxReqSeizeTry_Context *ctx,
+ ScoreMtxReqSeizeTry_Pre_Owner state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeTry_Pre_Owner_None: {
+ /*
+ * While the mutex has no owner.
+ */
+ /* This is the default */
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Pre_Owner_Caller: {
+ /*
+ * While the owner of the mutex is the calling thread.
+ */
+ ctx->owner_caller = true;
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Pre_Owner_Other: {
+ /*
+ * While the owner of the mutex is a thread other than the calling
+ * thread.
+ */
+ ctx->owner_other = true;
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Pre_Owner_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeTry_Pre_Priority_Prepare(
+ ScoreMtxReqSeizeTry_Context *ctx,
+ ScoreMtxReqSeizeTry_Pre_Priority state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeTry_Pre_Priority_High: {
+ /*
+ * While the calling thread has a current priority higher than the
+ * priority ceiling.
+ */
+ ctx->priority_before = ctx->tq_ctx->priority_ceiling - 1;
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Pre_Priority_Equal: {
+ /*
+ * While the calling thread has a current priority equal to the priority
+ * ceiling.
+ */
+ ctx->priority_before = ctx->tq_ctx->priority_ceiling;
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Pre_Priority_Low: {
+ /*
+ * While the calling thread has a current priority lower than the
+ * priority ceiling.
+ */
+ ctx->priority_before = ctx->tq_ctx->priority_ceiling + 1;
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Pre_Priority_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeTry_Post_Status_Check(
+ ScoreMtxReqSeizeTry_Context *ctx,
+ ScoreMtxReqSeizeTry_Post_Status state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeTry_Post_Status_Ok: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_SUCCESSFUL.
+ */
+ T_true( IsEnqueueStatus( ctx, STATUS_SUCCESSFUL ) );
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Post_Status_MutexCeilingViolated: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_MUTEX_CEILING_VIOLATED.
+ */
+ T_true( IsEnqueueStatus( ctx, STATUS_MUTEX_CEILING_VIOLATED ) );
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Post_Status_Deadlock: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_DEADLOCK.
+ */
+ T_true( IsEnqueueStatus( ctx, STATUS_DEADLOCK ) );
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Post_Status_Unavailable: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_UNAVAILABLE.
+ */
+ T_true( IsEnqueueStatus( ctx, STATUS_UNAVAILABLE ) );
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Post_Status_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeTry_Post_Owner_Check(
+ ScoreMtxReqSeizeTry_Context *ctx,
+ ScoreMtxReqSeizeTry_Post_Owner state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeTry_Post_Owner_Other: {
+ /*
+ * The owner of the mutex shall not be modified.
+ */
+ T_eq_ptr(
+ ctx->owner_after,
+ ctx->tq_ctx->base.worker_tcb[ TQ_BLOCKER_B ]
+ );
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Post_Owner_Caller: {
+ /*
+ * The owner of the mutex shall be the calling thread.
+ */
+ T_eq_ptr(
+ ctx->owner_after,
+ ctx->tq_ctx->base.worker_tcb[ TQ_BLOCKER_A ]
+ );
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Post_Owner_None: {
+ /*
+ * The mutex shall have no owner.
+ */
+ T_null( ctx->owner_after );
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Post_Owner_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeTry_Post_Priority_Check(
+ ScoreMtxReqSeizeTry_Context *ctx,
+ ScoreMtxReqSeizeTry_Post_Priority state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeTry_Post_Priority_Nop: {
+ /*
+ * The priorities of the calling thread shall not be modified.
+ */
+ T_eq_u32( ctx->priority_after, ctx->priority_before );
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Post_Priority_Ceiling: {
+ /*
+ * The calling thread shall use the priority ceiling of the mutex.
+ */
+ T_eq_u32( ctx->priority_after, ctx->tq_ctx->priority_ceiling );
+ break;
+ }
+
+ case ScoreMtxReqSeizeTry_Post_Priority_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeTry_Prepare( ScoreMtxReqSeizeTry_Context *ctx )
+{
+ ctx->owner_caller = false;
+ ctx->owner_other = false;
+ ctx->priority_before = PRIO_VERY_HIGH;
+}
+
+static void ScoreMtxReqSeizeTry_Action( ScoreMtxReqSeizeTry_Context *ctx )
+{
+ TQSetScheduler(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_B,
+ SCHEDULER_A_ID,
+ PRIO_VERY_HIGH
+ );
+
+ if ( ctx->tq_ctx->base.enqueue_variant == TQ_ENQUEUE_STICKY ) {
+ ActionSticky( ctx );
+ } else {
+ Action( ctx );
+ }
+}
+
+static const ScoreMtxReqSeizeTry_Entry
+ScoreMtxReqSeizeTry_Entries[] = {
+ { 1, 0, 0, 0, 0, 0, ScoreMtxReqSeizeTry_Post_Status_NA,
+ ScoreMtxReqSeizeTry_Post_Owner_NA, ScoreMtxReqSeizeTry_Post_Priority_NA },
+ { 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeTry_Post_Status_Ok,
+ ScoreMtxReqSeizeTry_Post_Owner_Caller,
+ ScoreMtxReqSeizeTry_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeTry_Post_Status_Unavailable,
+ ScoreMtxReqSeizeTry_Post_Owner_Other, ScoreMtxReqSeizeTry_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeTry_Post_Status_Unavailable,
+ ScoreMtxReqSeizeTry_Post_Owner_Other, ScoreMtxReqSeizeTry_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeTry_Post_Status_Ok,
+ ScoreMtxReqSeizeTry_Post_Owner_Caller,
+ ScoreMtxReqSeizeTry_Post_Priority_Ceiling },
+ { 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeTry_Post_Status_MutexCeilingViolated,
+ ScoreMtxReqSeizeTry_Post_Owner_None, ScoreMtxReqSeizeTry_Post_Priority_Nop },
+ { 1, 0, 0, 0, 0, 0, ScoreMtxReqSeizeTry_Post_Status_NA,
+ ScoreMtxReqSeizeTry_Post_Owner_NA, ScoreMtxReqSeizeTry_Post_Priority_NA },
+ { 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeTry_Post_Status_Unavailable,
+ ScoreMtxReqSeizeTry_Post_Owner_Caller,
+ ScoreMtxReqSeizeTry_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeTry_Post_Status_Deadlock,
+ ScoreMtxReqSeizeTry_Post_Owner_Caller,
+ ScoreMtxReqSeizeTry_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeTry_Post_Status_Ok,
+ ScoreMtxReqSeizeTry_Post_Owner_Caller,
+ ScoreMtxReqSeizeTry_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeTry_Post_Status_Unavailable,
+ ScoreMtxReqSeizeTry_Post_Owner_Caller,
+ ScoreMtxReqSeizeTry_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeTry_Post_Status_Deadlock,
+ ScoreMtxReqSeizeTry_Post_Owner_Caller,
+ ScoreMtxReqSeizeTry_Post_Priority_Nop }
+};
+
+static const uint8_t
+ScoreMtxReqSeizeTry_Map[] = {
+ 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,
+ 0, 5, 4, 4, 9, 9, 6, 2, 2, 2, 5, 4, 4, 10, 10, 6, 2, 2, 2, 5, 4, 4, 11, 11,
+ 6, 2, 2, 2, 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, 0, 5, 4, 4, 9, 9, 6, 2, 2, 2, 5, 4, 4, 10, 10, 6, 2, 2, 2, 5, 4,
+ 4, 11, 11, 6, 2, 2, 2, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 7, 7, 7, 3, 3, 3,
+ 1, 1, 1, 8, 8, 8, 3, 3, 3, 1, 1, 1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 7, 7, 7, 3, 3,
+ 3, 1, 1, 1, 8, 8, 8, 3, 3, 3
+};
+
+static size_t ScoreMtxReqSeizeTry_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreMtxReqSeizeTry_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( ScoreMtxReqSeizeTry_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreMtxReqSeizeTry_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = ScoreMtxReqSeizeTry_Scope,
+ .initial_context = &ScoreMtxReqSeizeTry_Instance
+};
+
+static const uint8_t ScoreMtxReqSeizeTry_Weights[] = {
+ 54, 27, 9, 3, 1
+};
+
+static void ScoreMtxReqSeizeTry_Skip(
+ ScoreMtxReqSeizeTry_Context *ctx,
+ size_t index
+)
+{
+ switch ( index + 1 ) {
+ case 1:
+ ctx->Map.pci[ 1 ] = ScoreMtxReqSeizeTry_Pre_Discipline_NA - 1;
+ /* Fall through */
+ case 2:
+ ctx->Map.pci[ 2 ] = ScoreMtxReqSeizeTry_Pre_Recursive_NA - 1;
+ /* Fall through */
+ case 3:
+ ctx->Map.pci[ 3 ] = ScoreMtxReqSeizeTry_Pre_Owner_NA - 1;
+ /* Fall through */
+ case 4:
+ ctx->Map.pci[ 4 ] = ScoreMtxReqSeizeTry_Pre_Priority_NA - 1;
+ break;
+ }
+}
+
+static inline ScoreMtxReqSeizeTry_Entry ScoreMtxReqSeizeTry_PopEntry(
+ ScoreMtxReqSeizeTry_Context *ctx
+)
+{
+ size_t index;
+
+ if ( ctx->Map.skip ) {
+ size_t i;
+
+ ctx->Map.skip = false;
+ index = 0;
+
+ for ( i = 0; i < 5; ++i ) {
+ index += ScoreMtxReqSeizeTry_Weights[ i ] * ctx->Map.pci[ i ];
+ }
+ } else {
+ index = ctx->Map.index;
+ }
+
+ ctx->Map.index = index + 1;
+
+ return ScoreMtxReqSeizeTry_Entries[
+ ScoreMtxReqSeizeTry_Map[ index ]
+ ];
+}
+
+static void ScoreMtxReqSeizeTry_SetPreConditionStates(
+ ScoreMtxReqSeizeTry_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+
+ if ( ctx->Map.entry.Pre_Priority_NA ) {
+ ctx->Map.pcs[ 4 ] = ScoreMtxReqSeizeTry_Pre_Priority_NA;
+ } else {
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+ }
+}
+
+static void ScoreMtxReqSeizeTry_TestVariant( ScoreMtxReqSeizeTry_Context *ctx )
+{
+ ScoreMtxReqSeizeTry_Pre_Protocol_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+
+ if ( ctx->Map.skip ) {
+ ScoreMtxReqSeizeTry_Skip( ctx, 0 );
+ return;
+ }
+
+ ScoreMtxReqSeizeTry_Pre_Discipline_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+
+ if ( ctx->Map.skip ) {
+ ScoreMtxReqSeizeTry_Skip( ctx, 1 );
+ return;
+ }
+
+ ScoreMtxReqSeizeTry_Pre_Recursive_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+
+ if ( ctx->Map.skip ) {
+ ScoreMtxReqSeizeTry_Skip( ctx, 2 );
+ return;
+ }
+
+ ScoreMtxReqSeizeTry_Pre_Owner_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ ScoreMtxReqSeizeTry_Pre_Priority_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ ScoreMtxReqSeizeTry_Action( ctx );
+ ScoreMtxReqSeizeTry_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ ScoreMtxReqSeizeTry_Post_Owner_Check( ctx, ctx->Map.entry.Post_Owner );
+ ScoreMtxReqSeizeTry_Post_Priority_Check( ctx, ctx->Map.entry.Post_Priority );
+}
+
+static T_fixture_node ScoreMtxReqSeizeTry_Node;
+
+static T_remark ScoreMtxReqSeizeTry_Remark = {
+ .next = NULL,
+ .remark = "ScoreMtxReqSeizeTry"
+};
+
+void ScoreMtxReqSeizeTry_Run( TQMtxContext *tq_ctx )
+{
+ ScoreMtxReqSeizeTry_Context *ctx;
+
+ ctx = &ScoreMtxReqSeizeTry_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreMtxReqSeizeTry_Node,
+ &ScoreMtxReqSeizeTry_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+ ctx->Map.skip = false;
+
+ for (
+ ctx->Map.pci[ 0 ] = ScoreMtxReqSeizeTry_Pre_Protocol_Ceiling;
+ ctx->Map.pci[ 0 ] < ScoreMtxReqSeizeTry_Pre_Protocol_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = ScoreMtxReqSeizeTry_Pre_Discipline_FIFO;
+ ctx->Map.pci[ 1 ] < ScoreMtxReqSeizeTry_Pre_Discipline_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = ScoreMtxReqSeizeTry_Pre_Recursive_Allowed;
+ ctx->Map.pci[ 2 ] < ScoreMtxReqSeizeTry_Pre_Recursive_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = ScoreMtxReqSeizeTry_Pre_Owner_None;
+ ctx->Map.pci[ 3 ] < ScoreMtxReqSeizeTry_Pre_Owner_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ for (
+ ctx->Map.pci[ 4 ] = ScoreMtxReqSeizeTry_Pre_Priority_High;
+ ctx->Map.pci[ 4 ] < ScoreMtxReqSeizeTry_Pre_Priority_NA;
+ ++ctx->Map.pci[ 4 ]
+ ) {
+ ctx->Map.entry = ScoreMtxReqSeizeTry_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ ScoreMtxReqSeizeTry_SetPreConditionStates( ctx );
+ ScoreMtxReqSeizeTry_Prepare( ctx );
+ ScoreMtxReqSeizeTry_TestVariant( ctx );
+ }
+ }
+ }
+ }
+ }
+
+ T_add_remark( &ScoreMtxReqSeizeTry_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-mtx-seize-try.h b/testsuites/validation/tr-mtx-seize-try.h
new file mode 100644
index 0000000000..28bac7d25d
--- /dev/null
+++ b/testsuites/validation/tr-mtx-seize-try.h
@@ -0,0 +1,134 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreMtxReqSeizeTry
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_MTX_SEIZE_TRY_H
+#define _TR_MTX_SEIZE_TRY_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreMtxReqSeizeTry
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreMtxReqSeizeTry_Pre_Protocol_Ceiling,
+ ScoreMtxReqSeizeTry_Pre_Protocol_MrsP,
+ ScoreMtxReqSeizeTry_Pre_Protocol_Other,
+ ScoreMtxReqSeizeTry_Pre_Protocol_NA
+} ScoreMtxReqSeizeTry_Pre_Protocol;
+
+typedef enum {
+ ScoreMtxReqSeizeTry_Pre_Discipline_FIFO,
+ ScoreMtxReqSeizeTry_Pre_Discipline_Priority,
+ ScoreMtxReqSeizeTry_Pre_Discipline_NA
+} ScoreMtxReqSeizeTry_Pre_Discipline;
+
+typedef enum {
+ ScoreMtxReqSeizeTry_Pre_Recursive_Allowed,
+ ScoreMtxReqSeizeTry_Pre_Recursive_Unavailable,
+ ScoreMtxReqSeizeTry_Pre_Recursive_Deadlock,
+ ScoreMtxReqSeizeTry_Pre_Recursive_NA
+} ScoreMtxReqSeizeTry_Pre_Recursive;
+
+typedef enum {
+ ScoreMtxReqSeizeTry_Pre_Owner_None,
+ ScoreMtxReqSeizeTry_Pre_Owner_Caller,
+ ScoreMtxReqSeizeTry_Pre_Owner_Other,
+ ScoreMtxReqSeizeTry_Pre_Owner_NA
+} ScoreMtxReqSeizeTry_Pre_Owner;
+
+typedef enum {
+ ScoreMtxReqSeizeTry_Pre_Priority_High,
+ ScoreMtxReqSeizeTry_Pre_Priority_Equal,
+ ScoreMtxReqSeizeTry_Pre_Priority_Low,
+ ScoreMtxReqSeizeTry_Pre_Priority_NA
+} ScoreMtxReqSeizeTry_Pre_Priority;
+
+typedef enum {
+ ScoreMtxReqSeizeTry_Post_Status_Ok,
+ ScoreMtxReqSeizeTry_Post_Status_MutexCeilingViolated,
+ ScoreMtxReqSeizeTry_Post_Status_Deadlock,
+ ScoreMtxReqSeizeTry_Post_Status_Unavailable,
+ ScoreMtxReqSeizeTry_Post_Status_NA
+} ScoreMtxReqSeizeTry_Post_Status;
+
+typedef enum {
+ ScoreMtxReqSeizeTry_Post_Owner_Other,
+ ScoreMtxReqSeizeTry_Post_Owner_Caller,
+ ScoreMtxReqSeizeTry_Post_Owner_None,
+ ScoreMtxReqSeizeTry_Post_Owner_NA
+} ScoreMtxReqSeizeTry_Post_Owner;
+
+typedef enum {
+ ScoreMtxReqSeizeTry_Post_Priority_Nop,
+ ScoreMtxReqSeizeTry_Post_Priority_Ceiling,
+ ScoreMtxReqSeizeTry_Post_Priority_NA
+} ScoreMtxReqSeizeTry_Post_Priority;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue context.
+ */
+void ScoreMtxReqSeizeTry_Run( TQMtxContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_MTX_SEIZE_TRY_H */
diff --git a/testsuites/validation/tr-mtx-seize-wait.c b/testsuites/validation/tr-mtx-seize-wait.c
new file mode 100644
index 0000000000..2e2fe9d1ec
--- /dev/null
+++ b/testsuites/validation/tr-mtx-seize-wait.c
@@ -0,0 +1,1152 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreMtxReqSeizeWait
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-mtx-seize-wait.h"
+#include "tr-tq-enqueue-ceiling.h"
+#include "tr-tq-enqueue-deadlock.h"
+#include "tr-tq-enqueue-fifo.h"
+#include "tr-tq-enqueue-priority-inherit.h"
+#include "tr-tq-enqueue-priority.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreMtxReqSeizeWait spec:/score/mtx/req/seize-wait
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_Protocol_NA : 1;
+ uint32_t Pre_Discipline_NA : 1;
+ uint32_t Pre_DeadlockResult_NA : 1;
+ uint32_t Pre_Recursive_NA : 1;
+ uint32_t Pre_Owner_NA : 1;
+ uint32_t Pre_Priority_NA : 1;
+ uint32_t Post_Status : 3;
+ uint32_t Post_Enqueued : 3;
+ uint32_t Post_Owner : 2;
+ uint32_t Post_Priority : 2;
+} ScoreMtxReqSeizeWait_Entry;
+
+/**
+ * @brief Test context for spec:/score/mtx/req/seize-wait test case.
+ */
+typedef struct {
+ /**
+ * @brief If this member is true, then the calling thread shall be the owner
+ * of the mutex.
+ */
+ bool owner_caller;
+
+ /**
+ * @brief If this member is true, then a thread other than the calling thread
+ * shall be the owner of the mutex.
+ */
+ bool owner_other;
+
+ /**
+ * @brief If this member is true, then a deadlock shall occur.
+ */
+ bool deadlock;
+
+ /**
+ * @brief This member contains the current priority of the calling thread
+ * before the directive call.
+ */
+ rtems_task_priority priority_before;
+
+ /**
+ * @brief This member contains the owner of the mutex after the directive
+ * call.
+ */
+ const rtems_tcb *owner_after;
+
+ /**
+ * @brief This member contains the current priority of the calling thread
+ * after the directive call.
+ */
+ rtems_task_priority priority_after;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreMtxReqSeizeWait_Run() parameter.
+ */
+ TQMtxContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 6 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 6 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreMtxReqSeizeWait_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreMtxReqSeizeWait_Context;
+
+static ScoreMtxReqSeizeWait_Context
+ ScoreMtxReqSeizeWait_Instance;
+
+static const char * const ScoreMtxReqSeizeWait_PreDesc_Protocol[] = {
+ "None",
+ "Inherit",
+ "Ceiling",
+ "MrsP",
+ "NA"
+};
+
+static const char * const ScoreMtxReqSeizeWait_PreDesc_Discipline[] = {
+ "FIFO",
+ "Priority",
+ "NA"
+};
+
+static const char * const ScoreMtxReqSeizeWait_PreDesc_DeadlockResult[] = {
+ "Status",
+ "Fatal",
+ "NA"
+};
+
+static const char * const ScoreMtxReqSeizeWait_PreDesc_Recursive[] = {
+ "Allowed",
+ "Deadlock",
+ "NA"
+};
+
+static const char * const ScoreMtxReqSeizeWait_PreDesc_Owner[] = {
+ "None",
+ "Caller",
+ "Other",
+ "Deadlock",
+ "NA"
+};
+
+static const char * const ScoreMtxReqSeizeWait_PreDesc_Priority[] = {
+ "High",
+ "Equal",
+ "Low",
+ "NA"
+};
+
+static const char * const * const ScoreMtxReqSeizeWait_PreDesc[] = {
+ ScoreMtxReqSeizeWait_PreDesc_Protocol,
+ ScoreMtxReqSeizeWait_PreDesc_Discipline,
+ ScoreMtxReqSeizeWait_PreDesc_DeadlockResult,
+ ScoreMtxReqSeizeWait_PreDesc_Recursive,
+ ScoreMtxReqSeizeWait_PreDesc_Owner,
+ ScoreMtxReqSeizeWait_PreDesc_Priority,
+ NULL
+};
+
+#if defined(RTEMS_SMP)
+#include "tr-tq-enqueue-mrsp.h"
+#endif
+
+typedef ScoreMtxReqSeizeWait_Context Context;
+
+static Status_Control Status( const Context *ctx, Status_Control status )
+{
+ return TQConvertStatus( &ctx->tq_ctx->base, status );
+}
+
+static bool IsEnqueueStatus( const Context *ctx, Status_Control expected )
+{
+ return ctx->tq_ctx->base.status[ TQ_BLOCKER_A ] == Status( ctx, expected );
+}
+
+static void Action( Context *ctx )
+{
+ TQEvent enqueue;
+
+ TQSetScheduler(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ SCHEDULER_A_ID,
+ PRIO_VERY_HIGH
+ );
+
+ if ( ctx->owner_caller ) {
+ TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
+ } else if ( ctx->owner_other ) {
+ if ( ctx->deadlock ) {
+ TQSend(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ TQ_EVENT_MUTEX_NO_PROTOCOL_OBTAIN
+ );
+ }
+
+ TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_B, TQ_EVENT_ENQUEUE );
+
+ if ( ctx->deadlock ) {
+ TQSend(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_B,
+ TQ_EVENT_MUTEX_NO_PROTOCOL_OBTAIN
+ );
+ }
+ }
+
+ TQSetPriority( &ctx->tq_ctx->base, TQ_BLOCKER_A, ctx->priority_before );
+
+ if ( ctx->tq_ctx->base.deadlock == TQ_DEADLOCK_FATAL ) {
+ enqueue = TQ_EVENT_ENQUEUE_FATAL;
+ } else {
+ enqueue = TQ_EVENT_ENQUEUE;
+ }
+
+ TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, enqueue );
+ ctx->owner_after = TQGetOwner( &ctx->tq_ctx->base );
+ ctx->priority_after = TQGetPriority( &ctx->tq_ctx->base, TQ_BLOCKER_A );
+
+ if ( ctx->owner_caller ) {
+ TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_SURRENDER );
+ } else if ( ctx->owner_other ) {
+ if ( ctx->deadlock ) {
+ TQSend(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ TQ_EVENT_MUTEX_NO_PROTOCOL_RELEASE
+ );
+ }
+
+ TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_B, TQ_EVENT_SURRENDER );
+
+ if ( ctx->deadlock ) {
+ TQSend(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_B,
+ TQ_EVENT_MUTEX_NO_PROTOCOL_RELEASE
+ );
+ }
+ }
+
+ if ( IsEnqueueStatus( ctx, STATUS_SUCCESSFUL ) ) {
+ TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_SURRENDER );
+ }
+}
+
+static void ActionSticky( Context *ctx )
+{
+ TQSetScheduler(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ SCHEDULER_B_ID,
+ PRIO_VERY_HIGH
+ );
+
+ if ( ctx->owner_caller ) {
+ TQSendAndSynchronizeRunner(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ TQ_EVENT_ENQUEUE
+ );
+ } else if ( ctx->owner_other ) {
+ if ( ctx->deadlock ) {
+ TQSendAndSynchronizeRunner(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ TQ_EVENT_MUTEX_NO_PROTOCOL_OBTAIN
+ );
+ }
+
+ SetSelfScheduler( SCHEDULER_B_ID, PRIO_ULTRA_HIGH );
+ TQSendAndSynchronizeRunner(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_B,
+ TQ_EVENT_ENQUEUE
+ );
+
+ if ( ctx->deadlock ) {
+ TQSendAndWaitForExecutionStop(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_B,
+ TQ_EVENT_MUTEX_NO_PROTOCOL_OBTAIN
+ );
+ }
+
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_ULTRA_HIGH );
+ }
+
+ TQSetPriority( &ctx->tq_ctx->base, TQ_BLOCKER_A, ctx->priority_before );
+ TQClearDone( &ctx->tq_ctx->base, TQ_BLOCKER_A );
+ TQSendAndWaitForExecutionStopOrIntendToBlock(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ TQ_EVENT_ENQUEUE
+ );
+ ctx->owner_after = TQGetOwner( &ctx->tq_ctx->base );
+ ctx->priority_after = TQGetPriority( &ctx->tq_ctx->base, TQ_BLOCKER_A );
+
+ if ( ctx->owner_caller ) {
+ TQSendAndSynchronizeRunner(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ TQ_EVENT_SURRENDER
+ );
+ } else if ( ctx->owner_other ) {
+ if ( ctx->deadlock ) {
+ TQSendAndSynchronizeRunner(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ TQ_EVENT_MUTEX_NO_PROTOCOL_RELEASE
+ );
+ }
+
+ SetSelfScheduler( SCHEDULER_B_ID, PRIO_ULTRA_HIGH );
+ TQSendAndSynchronizeRunner(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_B,
+ TQ_EVENT_SURRENDER
+ );
+
+ if ( ctx->deadlock ) {
+ TQSendAndSynchronizeRunner(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_B,
+ TQ_EVENT_MUTEX_NO_PROTOCOL_RELEASE
+ );
+ }
+
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_NORMAL );
+ }
+
+ TQWaitForDone( &ctx->tq_ctx->base, TQ_BLOCKER_A );
+
+ if ( IsEnqueueStatus( ctx, STATUS_SUCCESSFUL ) ) {
+ TQSendAndSynchronizeRunner(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ TQ_EVENT_SURRENDER
+ );
+ }
+}
+
+static void ScoreMtxReqSeizeWait_Pre_Protocol_Prepare(
+ ScoreMtxReqSeizeWait_Context *ctx,
+ ScoreMtxReqSeizeWait_Pre_Protocol state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeWait_Pre_Protocol_None: {
+ /*
+ * Where the mutex does not use a locking protocol.
+ */
+ if ( ctx->tq_ctx->protocol != TQ_MTX_NO_PROTOCOL ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Pre_Protocol_Inherit: {
+ /*
+ * Where the mutex uses the priority inheritance locking protocol.
+ */
+ if ( ctx->tq_ctx->protocol != TQ_MTX_PRIORITY_INHERIT ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Pre_Protocol_Ceiling: {
+ /*
+ * Where the mutex uses the priority ceiling locking protocol.
+ */
+ if ( ctx->tq_ctx->protocol != TQ_MTX_PRIORITY_CEILING ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Pre_Protocol_MrsP: {
+ /*
+ * Where the mutex uses the MrsP locking protocol.
+ */
+ if ( ctx->tq_ctx->protocol != TQ_MTX_MRSP ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Pre_Protocol_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeWait_Pre_Discipline_Prepare(
+ ScoreMtxReqSeizeWait_Context *ctx,
+ ScoreMtxReqSeizeWait_Pre_Discipline state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeWait_Pre_Discipline_FIFO: {
+ /*
+ * Where the thread queue of the mutex uses the FIFO discipline.
+ */
+ if ( ctx->tq_ctx->base.discipline != TQ_FIFO ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Pre_Discipline_Priority: {
+ /*
+ * Where the thread queue of the mutex uses the priority discipline.
+ */
+ if ( ctx->tq_ctx->base.discipline != TQ_PRIORITY ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Pre_Discipline_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeWait_Pre_DeadlockResult_Prepare(
+ ScoreMtxReqSeizeWait_Context *ctx,
+ ScoreMtxReqSeizeWait_Pre_DeadlockResult state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeWait_Pre_DeadlockResult_Status: {
+ /*
+ * Where a detected deadlock results in a return with a status code.
+ */
+ if ( ctx->tq_ctx->base.deadlock != TQ_DEADLOCK_STATUS ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Pre_DeadlockResult_Fatal: {
+ /*
+ * Where a detected deadlock results in a fatal error.
+ */
+ if ( ctx->tq_ctx->base.deadlock != TQ_DEADLOCK_FATAL ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Pre_DeadlockResult_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeWait_Pre_Recursive_Prepare(
+ ScoreMtxReqSeizeWait_Context *ctx,
+ ScoreMtxReqSeizeWait_Pre_Recursive state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeWait_Pre_Recursive_Allowed: {
+ /*
+ * Where a recursive seize of the mutex is allowed.
+ */
+ if ( ctx->tq_ctx->recursive != TQ_MTX_RECURSIVE_ALLOWED ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Pre_Recursive_Deadlock: {
+ /*
+ * Where a recursive seize of the mutex results in a deadlock.
+ */
+ if ( ctx->tq_ctx->recursive != TQ_MTX_RECURSIVE_DEADLOCK ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Pre_Recursive_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeWait_Pre_Owner_Prepare(
+ ScoreMtxReqSeizeWait_Context *ctx,
+ ScoreMtxReqSeizeWait_Pre_Owner state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeWait_Pre_Owner_None: {
+ /*
+ * While the mutex has no owner.
+ */
+ /* This is the default */
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Pre_Owner_Caller: {
+ /*
+ * While the owner of the mutex is the calling thread.
+ */
+ ctx->owner_caller = true;
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Pre_Owner_Other: {
+ /*
+ * While the owner of the mutex is a thread other than the calling
+ * thread.
+ */
+ ctx->owner_other = true;
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Pre_Owner_Deadlock: {
+ /*
+ * While the attempt to seize the mutex results in a deadlock.
+ */
+ ctx->owner_other = true;
+ ctx->deadlock = true;
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Pre_Owner_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeWait_Pre_Priority_Prepare(
+ ScoreMtxReqSeizeWait_Context *ctx,
+ ScoreMtxReqSeizeWait_Pre_Priority state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeWait_Pre_Priority_High: {
+ /*
+ * While the calling thread has a current priority higher than the
+ * priority ceiling.
+ */
+ ctx->priority_before = ctx->tq_ctx->priority_ceiling - 1;
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Pre_Priority_Equal: {
+ /*
+ * While the calling thread has a current priority equal to the priority
+ * ceiling.
+ */
+ ctx->priority_before = ctx->tq_ctx->priority_ceiling;
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Pre_Priority_Low: {
+ /*
+ * While the calling thread has a current priority lower than the
+ * priority ceiling.
+ */
+ ctx->priority_before = ctx->tq_ctx->priority_ceiling + 1;
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Pre_Priority_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeWait_Post_Status_Check(
+ ScoreMtxReqSeizeWait_Context *ctx,
+ ScoreMtxReqSeizeWait_Post_Status state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeWait_Post_Status_Ok: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_SUCCESSFUL.
+ */
+ T_true( IsEnqueueStatus( ctx, STATUS_SUCCESSFUL ) );
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Post_Status_MutexCeilingViolated: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_MUTEX_CEILING_VIOLATED.
+ */
+ T_true( IsEnqueueStatus( ctx, STATUS_MUTEX_CEILING_VIOLATED ) );
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Post_Status_DeadlockStatus: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_DEADLOCK.
+ */
+ T_true( IsEnqueueStatus( ctx, STATUS_DEADLOCK ) );
+ ScoreTqReqEnqueueDeadlock_Run( &ctx->tq_ctx->base );
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Post_Status_DeadlockFatal: {
+ /*
+ * The system shall terminate with the INTERNAL_ERROR_CORE fatal source
+ * and the INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK fatal code.
+ */
+ T_eq_int( ctx->tq_ctx->base.status[ TQ_BLOCKER_A ], STATUS_DEADLOCK );
+ ScoreTqReqEnqueueDeadlock_Run( &ctx->tq_ctx->base );
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Post_Status_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeWait_Post_Enqueued_Check(
+ ScoreMtxReqSeizeWait_Context *ctx,
+ ScoreMtxReqSeizeWait_Post_Enqueued state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeWait_Post_Enqueued_No: {
+ /*
+ * The calling thread shall not be enqueued on the thread queue of the
+ * mutex.
+ */
+ /* The test runner would block if the worker is enqueued */
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Post_Enqueued_FIFO: {
+ /*
+ * The calling thread shall be enqueued in FIFO order.
+ */
+ ScoreTqReqEnqueueFifo_Run( &ctx->tq_ctx->base );
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Post_Enqueued_Priority: {
+ /*
+ * The calling thread shall be enqueued in priority order.
+ */
+ ScoreTqReqEnqueuePriority_Run( &ctx->tq_ctx->base );
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Post_Enqueued_PriorityInherit: {
+ /*
+ * The calling thread shall be enqueued in priority order with priority
+ * inheritance.
+ */
+ ScoreTqReqEnqueuePriorityInherit_Run( &ctx->tq_ctx->base );
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Post_Enqueued_PriorityCeiling: {
+ /*
+ * The calling thread shall be enqueued in priority order according to
+ * the priority ceiling locking protocol.
+ */
+ ScoreTqReqEnqueueCeiling_Run( &ctx->tq_ctx->base );
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Post_Enqueued_PriorityMrsP: {
+ /*
+ * The calling thread shall be enqueued in priority order according to
+ * the MrsP locking protocol.
+ */
+ #if defined(RTEMS_SMP)
+ ScoreTqReqEnqueueMrsp_Run( &ctx->tq_ctx->base );
+ #else
+ T_unreachable();
+ #endif
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Post_Enqueued_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeWait_Post_Owner_Check(
+ ScoreMtxReqSeizeWait_Context *ctx,
+ ScoreMtxReqSeizeWait_Post_Owner state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeWait_Post_Owner_Other: {
+ /*
+ * The owner of the mutex shall not be modified.
+ */
+ T_eq_ptr(
+ ctx->owner_after,
+ ctx->tq_ctx->base.worker_tcb[ TQ_BLOCKER_B ]
+ );
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Post_Owner_Caller: {
+ /*
+ * The owner of the mutex shall be the calling thread.
+ */
+ T_eq_ptr(
+ ctx->owner_after,
+ ctx->tq_ctx->base.worker_tcb[ TQ_BLOCKER_A ]
+ );
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Post_Owner_None: {
+ /*
+ * The mutex shall have no owner.
+ */
+ T_null( ctx->owner_after );
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Post_Owner_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeWait_Post_Priority_Check(
+ ScoreMtxReqSeizeWait_Context *ctx,
+ ScoreMtxReqSeizeWait_Post_Priority state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSeizeWait_Post_Priority_Nop: {
+ /*
+ * The priorities of the calling thread shall not be modified.
+ */
+ T_eq_u32( ctx->priority_after, ctx->priority_before );
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Post_Priority_Ceiling: {
+ /*
+ * The calling thread shall use the priority ceiling of the mutex.
+ */
+ T_eq_u32( ctx->priority_after, ctx->tq_ctx->priority_ceiling );
+ break;
+ }
+
+ case ScoreMtxReqSeizeWait_Post_Priority_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSeizeWait_Prepare( ScoreMtxReqSeizeWait_Context *ctx )
+{
+ ctx->owner_caller = false;
+ ctx->owner_other = false;
+ ctx->deadlock = false;
+ ctx->priority_before = PRIO_VERY_HIGH;
+}
+
+static void ScoreMtxReqSeizeWait_Action( ScoreMtxReqSeizeWait_Context *ctx )
+{
+ TQSetScheduler(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_B,
+ SCHEDULER_A_ID,
+ PRIO_VERY_HIGH
+ );
+
+ if ( ctx->tq_ctx->base.enqueue_variant == TQ_ENQUEUE_STICKY ) {
+ ActionSticky( ctx );
+ } else {
+ Action( ctx );
+ }
+}
+
+static const ScoreMtxReqSeizeWait_Entry
+ScoreMtxReqSeizeWait_Entries[] = {
+ { 1, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_NA,
+ ScoreMtxReqSeizeWait_Post_Enqueued_NA, ScoreMtxReqSeizeWait_Post_Owner_NA,
+ ScoreMtxReqSeizeWait_Post_Priority_NA },
+ { 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeWait_Post_Status_Ok,
+ ScoreMtxReqSeizeWait_Post_Enqueued_No,
+ ScoreMtxReqSeizeWait_Post_Owner_Caller,
+ ScoreMtxReqSeizeWait_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeWait_Post_Status_DeadlockStatus,
+ ScoreMtxReqSeizeWait_Post_Enqueued_No,
+ ScoreMtxReqSeizeWait_Post_Owner_Other,
+ ScoreMtxReqSeizeWait_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeWait_Post_Status_DeadlockFatal,
+ ScoreMtxReqSeizeWait_Post_Enqueued_No,
+ ScoreMtxReqSeizeWait_Post_Owner_Other,
+ ScoreMtxReqSeizeWait_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_Ok,
+ ScoreMtxReqSeizeWait_Post_Enqueued_No,
+ ScoreMtxReqSeizeWait_Post_Owner_Caller,
+ ScoreMtxReqSeizeWait_Post_Priority_Ceiling },
+ { 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeWait_Post_Status_NA,
+ ScoreMtxReqSeizeWait_Post_Enqueued_FIFO,
+ ScoreMtxReqSeizeWait_Post_Owner_Other,
+ ScoreMtxReqSeizeWait_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeWait_Post_Status_NA,
+ ScoreMtxReqSeizeWait_Post_Enqueued_Priority,
+ ScoreMtxReqSeizeWait_Post_Owner_Other,
+ ScoreMtxReqSeizeWait_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeWait_Post_Status_NA,
+ ScoreMtxReqSeizeWait_Post_Enqueued_PriorityInherit,
+ ScoreMtxReqSeizeWait_Post_Owner_Other,
+ ScoreMtxReqSeizeWait_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_NA,
+ ScoreMtxReqSeizeWait_Post_Enqueued_PriorityCeiling,
+ ScoreMtxReqSeizeWait_Post_Owner_Other,
+ ScoreMtxReqSeizeWait_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_DeadlockStatus,
+ ScoreMtxReqSeizeWait_Post_Enqueued_No,
+ ScoreMtxReqSeizeWait_Post_Owner_Other,
+ ScoreMtxReqSeizeWait_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_DeadlockFatal,
+ ScoreMtxReqSeizeWait_Post_Enqueued_No,
+ ScoreMtxReqSeizeWait_Post_Owner_Other,
+ ScoreMtxReqSeizeWait_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeWait_Post_Status_DeadlockStatus,
+ ScoreMtxReqSeizeWait_Post_Enqueued_No,
+ ScoreMtxReqSeizeWait_Post_Owner_Caller,
+ ScoreMtxReqSeizeWait_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSeizeWait_Post_Status_DeadlockFatal,
+ ScoreMtxReqSeizeWait_Post_Enqueued_No,
+ ScoreMtxReqSeizeWait_Post_Owner_Caller,
+ ScoreMtxReqSeizeWait_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_MutexCeilingViolated,
+ ScoreMtxReqSeizeWait_Post_Enqueued_No,
+ ScoreMtxReqSeizeWait_Post_Owner_None,
+ ScoreMtxReqSeizeWait_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_Ok,
+ ScoreMtxReqSeizeWait_Post_Enqueued_No,
+ ScoreMtxReqSeizeWait_Post_Owner_Caller,
+ ScoreMtxReqSeizeWait_Post_Priority_Nop },
+ { 1, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_NA,
+ ScoreMtxReqSeizeWait_Post_Enqueued_NA, ScoreMtxReqSeizeWait_Post_Owner_NA,
+ ScoreMtxReqSeizeWait_Post_Priority_NA },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_MutexCeilingViolated,
+ ScoreMtxReqSeizeWait_Post_Enqueued_No,
+ ScoreMtxReqSeizeWait_Post_Owner_Other,
+ ScoreMtxReqSeizeWait_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_NA,
+ ScoreMtxReqSeizeWait_Post_Enqueued_PriorityMrsP,
+ ScoreMtxReqSeizeWait_Post_Owner_Other,
+ ScoreMtxReqSeizeWait_Post_Priority_Ceiling },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_DeadlockStatus,
+ ScoreMtxReqSeizeWait_Post_Enqueued_No,
+ ScoreMtxReqSeizeWait_Post_Owner_Caller,
+ ScoreMtxReqSeizeWait_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSeizeWait_Post_Status_DeadlockFatal,
+ ScoreMtxReqSeizeWait_Post_Enqueued_No,
+ ScoreMtxReqSeizeWait_Post_Owner_Caller,
+ ScoreMtxReqSeizeWait_Post_Priority_Nop }
+};
+
+static const uint8_t
+ScoreMtxReqSeizeWait_Map[] = {
+ 1, 1, 1, 1, 1, 1, 5, 5, 5, 2, 2, 2, 1, 1, 1, 11, 11, 11, 5, 5, 5, 2, 2, 2, 1,
+ 1, 1, 1, 1, 1, 5, 5, 5, 3, 3, 3, 1, 1, 1, 12, 12, 12, 5, 5, 5, 3, 3, 3, 1, 1,
+ 1, 1, 1, 1, 6, 6, 6, 2, 2, 2, 1, 1, 1, 11, 11, 11, 6, 6, 6, 2, 2, 2, 1, 1, 1,
+ 1, 1, 1, 6, 6, 6, 3, 3, 3, 1, 1, 1, 12, 12, 12, 6, 6, 6, 3, 3, 3, 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, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 7, 7,
+ 7, 2, 2, 2, 1, 1, 1, 11, 11, 11, 7, 7, 7, 2, 2, 2, 1, 1, 1, 1, 1, 1, 7, 7, 7,
+ 3, 3, 3, 1, 1, 1, 12, 12, 12, 7, 7, 7, 3, 3, 3, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 14, 14, 15, 8, 8, 8, 9, 9, 9,
+ 13, 4, 4, 18, 18, 15, 8, 8, 8, 9, 9, 9, 13, 4, 4, 14, 14, 15, 8, 8, 8, 10,
+ 10, 10, 13, 4, 4, 19, 19, 15, 8, 8, 8, 10, 10, 10, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 4, 4, 14, 14, 15, 16, 17, 17, 16,
+ 9, 9, 13, 4, 4, 18, 18, 15, 16, 17, 17, 16, 9, 9, 13, 4, 4, 14, 14, 15, 16,
+ 17, 17, 16, 10, 10, 13, 4, 4, 19, 19, 15, 16, 17, 17, 16, 10, 10
+};
+
+static size_t ScoreMtxReqSeizeWait_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreMtxReqSeizeWait_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( ScoreMtxReqSeizeWait_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreMtxReqSeizeWait_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = ScoreMtxReqSeizeWait_Scope,
+ .initial_context = &ScoreMtxReqSeizeWait_Instance
+};
+
+static const uint8_t ScoreMtxReqSeizeWait_Weights[] = {
+ 96, 48, 24, 12, 3, 1
+};
+
+static void ScoreMtxReqSeizeWait_Skip(
+ ScoreMtxReqSeizeWait_Context *ctx,
+ size_t index
+)
+{
+ switch ( index + 1 ) {
+ case 1:
+ ctx->Map.pci[ 1 ] = ScoreMtxReqSeizeWait_Pre_Discipline_NA - 1;
+ /* Fall through */
+ case 2:
+ ctx->Map.pci[ 2 ] = ScoreMtxReqSeizeWait_Pre_DeadlockResult_NA - 1;
+ /* Fall through */
+ case 3:
+ ctx->Map.pci[ 3 ] = ScoreMtxReqSeizeWait_Pre_Recursive_NA - 1;
+ /* Fall through */
+ case 4:
+ ctx->Map.pci[ 4 ] = ScoreMtxReqSeizeWait_Pre_Owner_NA - 1;
+ /* Fall through */
+ case 5:
+ ctx->Map.pci[ 5 ] = ScoreMtxReqSeizeWait_Pre_Priority_NA - 1;
+ break;
+ }
+}
+
+static inline ScoreMtxReqSeizeWait_Entry ScoreMtxReqSeizeWait_PopEntry(
+ ScoreMtxReqSeizeWait_Context *ctx
+)
+{
+ size_t index;
+
+ if ( ctx->Map.skip ) {
+ size_t i;
+
+ ctx->Map.skip = false;
+ index = 0;
+
+ for ( i = 0; i < 6; ++i ) {
+ index += ScoreMtxReqSeizeWait_Weights[ i ] * ctx->Map.pci[ i ];
+ }
+ } else {
+ index = ctx->Map.index;
+ }
+
+ ctx->Map.index = index + 1;
+
+ return ScoreMtxReqSeizeWait_Entries[
+ ScoreMtxReqSeizeWait_Map[ index ]
+ ];
+}
+
+static void ScoreMtxReqSeizeWait_SetPreConditionStates(
+ ScoreMtxReqSeizeWait_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+
+ if ( ctx->Map.entry.Pre_Priority_NA ) {
+ ctx->Map.pcs[ 5 ] = ScoreMtxReqSeizeWait_Pre_Priority_NA;
+ } else {
+ ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
+ }
+}
+
+static void ScoreMtxReqSeizeWait_TestVariant(
+ ScoreMtxReqSeizeWait_Context *ctx
+)
+{
+ ScoreMtxReqSeizeWait_Pre_Protocol_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+
+ if ( ctx->Map.skip ) {
+ ScoreMtxReqSeizeWait_Skip( ctx, 0 );
+ return;
+ }
+
+ ScoreMtxReqSeizeWait_Pre_Discipline_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+
+ if ( ctx->Map.skip ) {
+ ScoreMtxReqSeizeWait_Skip( ctx, 1 );
+ return;
+ }
+
+ ScoreMtxReqSeizeWait_Pre_DeadlockResult_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+
+ if ( ctx->Map.skip ) {
+ ScoreMtxReqSeizeWait_Skip( ctx, 2 );
+ return;
+ }
+
+ ScoreMtxReqSeizeWait_Pre_Recursive_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+
+ if ( ctx->Map.skip ) {
+ ScoreMtxReqSeizeWait_Skip( ctx, 3 );
+ return;
+ }
+
+ ScoreMtxReqSeizeWait_Pre_Owner_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ ScoreMtxReqSeizeWait_Pre_Priority_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ ScoreMtxReqSeizeWait_Action( ctx );
+ ScoreMtxReqSeizeWait_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ ScoreMtxReqSeizeWait_Post_Enqueued_Check(
+ ctx,
+ ctx->Map.entry.Post_Enqueued
+ );
+ ScoreMtxReqSeizeWait_Post_Owner_Check( ctx, ctx->Map.entry.Post_Owner );
+ ScoreMtxReqSeizeWait_Post_Priority_Check(
+ ctx,
+ ctx->Map.entry.Post_Priority
+ );
+}
+
+static T_fixture_node ScoreMtxReqSeizeWait_Node;
+
+static T_remark ScoreMtxReqSeizeWait_Remark = {
+ .next = NULL,
+ .remark = "ScoreMtxReqSeizeWait"
+};
+
+void ScoreMtxReqSeizeWait_Run( TQMtxContext *tq_ctx )
+{
+ ScoreMtxReqSeizeWait_Context *ctx;
+
+ ctx = &ScoreMtxReqSeizeWait_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreMtxReqSeizeWait_Node,
+ &ScoreMtxReqSeizeWait_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+ ctx->Map.skip = false;
+
+ for (
+ ctx->Map.pci[ 0 ] = ScoreMtxReqSeizeWait_Pre_Protocol_None;
+ ctx->Map.pci[ 0 ] < ScoreMtxReqSeizeWait_Pre_Protocol_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = ScoreMtxReqSeizeWait_Pre_Discipline_FIFO;
+ ctx->Map.pci[ 1 ] < ScoreMtxReqSeizeWait_Pre_Discipline_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = ScoreMtxReqSeizeWait_Pre_DeadlockResult_Status;
+ ctx->Map.pci[ 2 ] < ScoreMtxReqSeizeWait_Pre_DeadlockResult_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = ScoreMtxReqSeizeWait_Pre_Recursive_Allowed;
+ ctx->Map.pci[ 3 ] < ScoreMtxReqSeizeWait_Pre_Recursive_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ for (
+ ctx->Map.pci[ 4 ] = ScoreMtxReqSeizeWait_Pre_Owner_None;
+ ctx->Map.pci[ 4 ] < ScoreMtxReqSeizeWait_Pre_Owner_NA;
+ ++ctx->Map.pci[ 4 ]
+ ) {
+ for (
+ ctx->Map.pci[ 5 ] = ScoreMtxReqSeizeWait_Pre_Priority_High;
+ ctx->Map.pci[ 5 ] < ScoreMtxReqSeizeWait_Pre_Priority_NA;
+ ++ctx->Map.pci[ 5 ]
+ ) {
+ ctx->Map.entry = ScoreMtxReqSeizeWait_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ ScoreMtxReqSeizeWait_SetPreConditionStates( ctx );
+ ScoreMtxReqSeizeWait_Prepare( ctx );
+ ScoreMtxReqSeizeWait_TestVariant( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ T_add_remark( &ScoreMtxReqSeizeWait_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-mtx-seize-wait.h b/testsuites/validation/tr-mtx-seize-wait.h
new file mode 100644
index 0000000000..0d3beeb97b
--- /dev/null
+++ b/testsuites/validation/tr-mtx-seize-wait.h
@@ -0,0 +1,151 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreMtxReqSeizeWait
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_MTX_SEIZE_WAIT_H
+#define _TR_MTX_SEIZE_WAIT_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreMtxReqSeizeWait
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreMtxReqSeizeWait_Pre_Protocol_None,
+ ScoreMtxReqSeizeWait_Pre_Protocol_Inherit,
+ ScoreMtxReqSeizeWait_Pre_Protocol_Ceiling,
+ ScoreMtxReqSeizeWait_Pre_Protocol_MrsP,
+ ScoreMtxReqSeizeWait_Pre_Protocol_NA
+} ScoreMtxReqSeizeWait_Pre_Protocol;
+
+typedef enum {
+ ScoreMtxReqSeizeWait_Pre_Discipline_FIFO,
+ ScoreMtxReqSeizeWait_Pre_Discipline_Priority,
+ ScoreMtxReqSeizeWait_Pre_Discipline_NA
+} ScoreMtxReqSeizeWait_Pre_Discipline;
+
+typedef enum {
+ ScoreMtxReqSeizeWait_Pre_DeadlockResult_Status,
+ ScoreMtxReqSeizeWait_Pre_DeadlockResult_Fatal,
+ ScoreMtxReqSeizeWait_Pre_DeadlockResult_NA
+} ScoreMtxReqSeizeWait_Pre_DeadlockResult;
+
+typedef enum {
+ ScoreMtxReqSeizeWait_Pre_Recursive_Allowed,
+ ScoreMtxReqSeizeWait_Pre_Recursive_Deadlock,
+ ScoreMtxReqSeizeWait_Pre_Recursive_NA
+} ScoreMtxReqSeizeWait_Pre_Recursive;
+
+typedef enum {
+ ScoreMtxReqSeizeWait_Pre_Owner_None,
+ ScoreMtxReqSeizeWait_Pre_Owner_Caller,
+ ScoreMtxReqSeizeWait_Pre_Owner_Other,
+ ScoreMtxReqSeizeWait_Pre_Owner_Deadlock,
+ ScoreMtxReqSeizeWait_Pre_Owner_NA
+} ScoreMtxReqSeizeWait_Pre_Owner;
+
+typedef enum {
+ ScoreMtxReqSeizeWait_Pre_Priority_High,
+ ScoreMtxReqSeizeWait_Pre_Priority_Equal,
+ ScoreMtxReqSeizeWait_Pre_Priority_Low,
+ ScoreMtxReqSeizeWait_Pre_Priority_NA
+} ScoreMtxReqSeizeWait_Pre_Priority;
+
+typedef enum {
+ ScoreMtxReqSeizeWait_Post_Status_Ok,
+ ScoreMtxReqSeizeWait_Post_Status_MutexCeilingViolated,
+ ScoreMtxReqSeizeWait_Post_Status_DeadlockStatus,
+ ScoreMtxReqSeizeWait_Post_Status_DeadlockFatal,
+ ScoreMtxReqSeizeWait_Post_Status_NA
+} ScoreMtxReqSeizeWait_Post_Status;
+
+typedef enum {
+ ScoreMtxReqSeizeWait_Post_Enqueued_No,
+ ScoreMtxReqSeizeWait_Post_Enqueued_FIFO,
+ ScoreMtxReqSeizeWait_Post_Enqueued_Priority,
+ ScoreMtxReqSeizeWait_Post_Enqueued_PriorityInherit,
+ ScoreMtxReqSeizeWait_Post_Enqueued_PriorityCeiling,
+ ScoreMtxReqSeizeWait_Post_Enqueued_PriorityMrsP,
+ ScoreMtxReqSeizeWait_Post_Enqueued_NA
+} ScoreMtxReqSeizeWait_Post_Enqueued;
+
+typedef enum {
+ ScoreMtxReqSeizeWait_Post_Owner_Other,
+ ScoreMtxReqSeizeWait_Post_Owner_Caller,
+ ScoreMtxReqSeizeWait_Post_Owner_None,
+ ScoreMtxReqSeizeWait_Post_Owner_NA
+} ScoreMtxReqSeizeWait_Post_Owner;
+
+typedef enum {
+ ScoreMtxReqSeizeWait_Post_Priority_Nop,
+ ScoreMtxReqSeizeWait_Post_Priority_Ceiling,
+ ScoreMtxReqSeizeWait_Post_Priority_NA
+} ScoreMtxReqSeizeWait_Post_Priority;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue context.
+ */
+void ScoreMtxReqSeizeWait_Run( TQMtxContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_MTX_SEIZE_WAIT_H */
diff --git a/testsuites/validation/tr-mtx-surrender.c b/testsuites/validation/tr-mtx-surrender.c
new file mode 100644
index 0000000000..3c60726803
--- /dev/null
+++ b/testsuites/validation/tr-mtx-surrender.c
@@ -0,0 +1,1246 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreMtxReqSurrender
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-mtx-surrender.h"
+#include "tr-tq-surrender-priority-inherit.h"
+#include "tr-tq-surrender.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreMtxReqSurrender spec:/score/mtx/req/surrender
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_Protocol_NA : 1;
+ uint32_t Pre_Discipline_NA : 1;
+ uint32_t Pre_Recursive_NA : 1;
+ uint32_t Pre_OwnerCheck_NA : 1;
+ uint32_t Pre_Owner_NA : 1;
+ uint32_t Pre_Nested_NA : 1;
+ uint32_t Pre_Blocked_NA : 1;
+ uint32_t Pre_Priority_NA : 1;
+ uint32_t Post_Status : 2;
+ uint32_t Post_Owner : 3;
+ uint32_t Post_Surrender : 3;
+ uint32_t Post_Priority : 2;
+} ScoreMtxReqSurrender_Entry;
+
+/**
+ * @brief Test context for spec:/score/mtx/req/surrender test case.
+ */
+typedef struct {
+ /**
+ * @brief If this member is true, then the calling thread shall be the owner
+ * of the mutex.
+ */
+ bool owner_caller;
+
+ /**
+ * @brief If this member is true, then a thread other than the calling thread
+ * shall be the owner of the mutex.
+ */
+ bool owner_other;
+
+ /**
+ * @brief If this member is true, then the calling thread shall have seized
+ * the mutex recursively.
+ */
+ bool nested;
+
+ /**
+ * @brief If this member is true, then there shall be a thread blocked
+ * waiting for the mutex.
+ */
+ bool blocked;
+
+ /**
+ * @brief This member contains the real priority of the calling thread.
+ */
+ rtems_task_priority priority_real;
+
+ /**
+ * @brief This member contains the current priority of the calling thread
+ * before the directive call.
+ */
+ rtems_task_priority priority_before;
+
+ /**
+ * @brief This member contains the return status of the directive call.
+ */
+ Status_Control status;
+
+ /**
+ * @brief This member contains the owner of the mutex after the directive
+ * call.
+ */
+ const rtems_tcb *owner_after;
+
+ /**
+ * @brief This member contains the current priority of the calling thread
+ * after the directive call.
+ */
+ rtems_task_priority priority_after;
+
+ /**
+ * @brief This member contains the counter snapshot after the directive call.
+ */
+ uint32_t counter;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreMtxReqSurrender_Run() parameter.
+ */
+ TQMtxContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 8 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 8 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreMtxReqSurrender_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreMtxReqSurrender_Context;
+
+static ScoreMtxReqSurrender_Context
+ ScoreMtxReqSurrender_Instance;
+
+static const char * const ScoreMtxReqSurrender_PreDesc_Protocol[] = {
+ "None",
+ "Inherit",
+ "Ceiling",
+ "MrsP",
+ "NA"
+};
+
+static const char * const ScoreMtxReqSurrender_PreDesc_Discipline[] = {
+ "FIFO",
+ "Priority",
+ "NA"
+};
+
+static const char * const ScoreMtxReqSurrender_PreDesc_Recursive[] = {
+ "Allowed",
+ "NotAllowed",
+ "NA"
+};
+
+static const char * const ScoreMtxReqSurrender_PreDesc_OwnerCheck[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const ScoreMtxReqSurrender_PreDesc_Owner[] = {
+ "None",
+ "Caller",
+ "Other",
+ "NA"
+};
+
+static const char * const ScoreMtxReqSurrender_PreDesc_Nested[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const ScoreMtxReqSurrender_PreDesc_Blocked[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const ScoreMtxReqSurrender_PreDesc_Priority[] = {
+ "High",
+ "Equal",
+ "Low",
+ "NA"
+};
+
+static const char * const * const ScoreMtxReqSurrender_PreDesc[] = {
+ ScoreMtxReqSurrender_PreDesc_Protocol,
+ ScoreMtxReqSurrender_PreDesc_Discipline,
+ ScoreMtxReqSurrender_PreDesc_Recursive,
+ ScoreMtxReqSurrender_PreDesc_OwnerCheck,
+ ScoreMtxReqSurrender_PreDesc_Owner,
+ ScoreMtxReqSurrender_PreDesc_Nested,
+ ScoreMtxReqSurrender_PreDesc_Blocked,
+ ScoreMtxReqSurrender_PreDesc_Priority,
+ NULL
+};
+
+#if defined(RTEMS_SMP)
+#include "tr-tq-surrender-mrsp.h"
+#endif
+
+typedef ScoreMtxReqSurrender_Context Context;
+
+static Status_Control Status( const Context *ctx, Status_Control status )
+{
+ return TQConvertStatus( &ctx->tq_ctx->base, status );
+}
+
+static void Action( Context *ctx )
+{
+ Status_Control status;
+
+ TQSetScheduler(
+ &ctx->tq_ctx->base,
+ TQ_HELPER_A,
+ SCHEDULER_A_ID,
+ PRIO_VERY_HIGH
+ );
+ TQSetScheduler(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ SCHEDULER_A_ID,
+ PRIO_VERY_HIGH
+ );
+
+ if ( ctx->owner_caller ) {
+ status = TQEnqueue( &ctx->tq_ctx->base, TQ_NO_WAIT );
+ T_eq_int( status, Status( ctx, STATUS_SUCCESSFUL ) );
+ } else if ( ctx->owner_other ) {
+ TQSend( &ctx->tq_ctx->base, TQ_HELPER_A, TQ_EVENT_ENQUEUE );
+ }
+
+ if ( ctx->nested ) {
+ status = TQEnqueue( &ctx->tq_ctx->base, TQ_NO_WAIT );
+ T_eq_int( status, Status( ctx, STATUS_SUCCESSFUL ) );
+ }
+
+ if ( ctx->blocked ) {
+ TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
+ Yield();
+ }
+
+ TQResetCounter( &ctx->tq_ctx->base );
+ SetSelfPriority( ctx->priority_real );
+ ctx->priority_before = GetSelfPriority();
+ TQSchedulerRecordStart( &ctx->tq_ctx->base );
+ ctx->status = TQSurrender( &ctx->tq_ctx->base );
+ TQSchedulerRecordStop( &ctx->tq_ctx->base );
+ ctx->owner_after = TQGetOwner( &ctx->tq_ctx->base );
+ ctx->priority_after = GetSelfPriority();
+ SetSelfPriority( PRIO_NORMAL );
+ Yield();
+ ctx->counter = TQGetCounter( &ctx->tq_ctx->base );
+
+ if ( ctx->nested ) {
+ status = TQSurrender( &ctx->tq_ctx->base );
+ T_eq_int( status, Status( ctx, STATUS_SUCCESSFUL ) );
+ }
+
+ if ( ctx->owner_other ) {
+ TQSend( &ctx->tq_ctx->base, TQ_HELPER_A, TQ_EVENT_SURRENDER );
+ }
+
+ if ( ctx->blocked ) {
+ TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_SURRENDER );
+ }
+}
+
+static void ActionSticky( Context *ctx )
+{
+ Status_Control status;
+
+ TQSetScheduler(
+ &ctx->tq_ctx->base,
+ TQ_HELPER_A,
+ SCHEDULER_A_ID,
+ PRIO_VERY_HIGH
+ );
+ TQSetScheduler(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ SCHEDULER_B_ID,
+ PRIO_VERY_HIGH
+ );
+
+ if ( ctx->owner_caller ) {
+ status = TQEnqueue( &ctx->tq_ctx->base, TQ_NO_WAIT );
+ T_eq_int( status, Status( ctx, STATUS_SUCCESSFUL ) );
+ } else if ( ctx->owner_other ) {
+ SetSelfScheduler( SCHEDULER_B_ID, PRIO_ULTRA_HIGH );
+ TQSendAndSynchronizeRunner(
+ &ctx->tq_ctx->base,
+ TQ_HELPER_A,
+ TQ_EVENT_ENQUEUE
+ );
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_ULTRA_HIGH );
+ }
+
+ if ( ctx->nested ) {
+ status = TQEnqueue( &ctx->tq_ctx->base, TQ_NO_WAIT );
+ T_eq_int( status, Status( ctx, STATUS_SUCCESSFUL ) );
+ }
+
+ if ( ctx->blocked ) {
+ TQSendAndWaitForIntendToBlock(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ TQ_EVENT_ENQUEUE
+ );
+ }
+
+ TQResetCounter( &ctx->tq_ctx->base );
+ SetSelfPriority( ctx->priority_real );
+ ctx->priority_before = GetSelfPriority();
+ TQSchedulerRecordStart( &ctx->tq_ctx->base );
+ ctx->status = TQSurrender( &ctx->tq_ctx->base );
+ TQSchedulerRecordStop( &ctx->tq_ctx->base );
+ ctx->owner_after = TQGetOwner( &ctx->tq_ctx->base );
+ ctx->priority_after = GetSelfPriority();
+
+ if ( ctx->status == Status( ctx, STATUS_SUCCESSFUL ) ) {
+ TQWaitForExecutionStop( &ctx->tq_ctx->base, TQ_BLOCKER_A );
+ }
+
+ ctx->counter = TQGetCounter( &ctx->tq_ctx->base );
+
+ if ( ctx->nested ) {
+ status = TQSurrender( &ctx->tq_ctx->base );
+ T_eq_int( status, Status( ctx, STATUS_SUCCESSFUL ) );
+ }
+
+ if ( ctx->owner_other ) {
+ SetSelfScheduler( SCHEDULER_B_ID, PRIO_ULTRA_HIGH );
+ TQSendAndSynchronizeRunner(
+ &ctx->tq_ctx->base,
+ TQ_HELPER_A,
+ TQ_EVENT_SURRENDER
+ );
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_NORMAL );
+ } else {
+ SetSelfPriority( PRIO_NORMAL );
+ }
+
+ if ( ctx->blocked ) {
+ TQSendAndSynchronizeRunner(
+ &ctx->tq_ctx->base,
+ TQ_BLOCKER_A,
+ TQ_EVENT_SURRENDER
+ );
+ }
+}
+
+static void ScoreMtxReqSurrender_Pre_Protocol_Prepare(
+ ScoreMtxReqSurrender_Context *ctx,
+ ScoreMtxReqSurrender_Pre_Protocol state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSurrender_Pre_Protocol_None: {
+ /*
+ * Where the mutex does not use a locking protocol.
+ */
+ if ( ctx->tq_ctx->protocol != TQ_MTX_NO_PROTOCOL ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Protocol_Inherit: {
+ /*
+ * Where the mutex uses the priority inheritance locking protocol.
+ */
+ if ( ctx->tq_ctx->protocol != TQ_MTX_PRIORITY_INHERIT ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Protocol_Ceiling: {
+ /*
+ * Where the mutex uses the priority ceiling locking protocol.
+ */
+ if ( ctx->tq_ctx->protocol != TQ_MTX_PRIORITY_CEILING ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Protocol_MrsP: {
+ /*
+ * Where the mutex uses the MrsP locking protocol.
+ */
+ if ( ctx->tq_ctx->protocol != TQ_MTX_MRSP ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Protocol_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSurrender_Pre_Discipline_Prepare(
+ ScoreMtxReqSurrender_Context *ctx,
+ ScoreMtxReqSurrender_Pre_Discipline state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSurrender_Pre_Discipline_FIFO: {
+ /*
+ * Where the thread queue of the mutex uses the FIFO discipline.
+ */
+ if ( ctx->tq_ctx->base.discipline != TQ_FIFO ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Discipline_Priority: {
+ /*
+ * Where the thread queue of the mutex uses the priority discipline.
+ */
+ if ( ctx->tq_ctx->base.discipline != TQ_PRIORITY ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Discipline_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSurrender_Pre_Recursive_Prepare(
+ ScoreMtxReqSurrender_Context *ctx,
+ ScoreMtxReqSurrender_Pre_Recursive state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSurrender_Pre_Recursive_Allowed: {
+ /*
+ * Where a recursive seize of the mutex is allowed.
+ */
+ if ( ctx->tq_ctx->recursive != TQ_MTX_RECURSIVE_ALLOWED ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Recursive_NotAllowed: {
+ /*
+ * Where a recursive seize of the mutex is not allowed.
+ */
+ if ( ctx->tq_ctx->recursive == TQ_MTX_RECURSIVE_ALLOWED ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Recursive_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSurrender_Pre_OwnerCheck_Prepare(
+ ScoreMtxReqSurrender_Context *ctx,
+ ScoreMtxReqSurrender_Pre_OwnerCheck state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSurrender_Pre_OwnerCheck_Yes: {
+ /*
+ * Where the surrender checks that the mutex owner is the calling thread.
+ */
+ if ( ctx->tq_ctx->owner_check != TQ_MTX_CHECKS_OWNER ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_OwnerCheck_No: {
+ /*
+ * Where the surrender does not check that the mutex owner is the calling
+ * thread.
+ */
+ if ( ctx->tq_ctx->owner_check != TQ_MTX_NO_OWNER_CHECK ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_OwnerCheck_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSurrender_Pre_Owner_Prepare(
+ ScoreMtxReqSurrender_Context *ctx,
+ ScoreMtxReqSurrender_Pre_Owner state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSurrender_Pre_Owner_None: {
+ /*
+ * While the mutex has no owner.
+ */
+ ctx->owner_caller = false;
+ ctx->owner_other = false;
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Owner_Caller: {
+ /*
+ * While the owner of the mutex is the calling thread.
+ */
+ ctx->owner_caller = true;
+ ctx->owner_other = false;
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Owner_Other: {
+ /*
+ * While the owner of the mutex is a thread other than the calling
+ * thread.
+ */
+ ctx->owner_caller = false;
+ ctx->owner_other = true;
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Owner_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSurrender_Pre_Nested_Prepare(
+ ScoreMtxReqSurrender_Context *ctx,
+ ScoreMtxReqSurrender_Pre_Nested state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSurrender_Pre_Nested_Yes: {
+ /*
+ * While calling thread seized the mutex recursively.
+ */
+ ctx->nested = true;
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Nested_No: {
+ /*
+ * While calling thread seized the mutex not recursively.
+ */
+ ctx->nested = false;
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Nested_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSurrender_Pre_Blocked_Prepare(
+ ScoreMtxReqSurrender_Context *ctx,
+ ScoreMtxReqSurrender_Pre_Blocked state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSurrender_Pre_Blocked_Yes: {
+ /*
+ * While the mutex has threads blocked on the mutex.
+ */
+ ctx->blocked = true;
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Blocked_No: {
+ /*
+ * While no threads are blocked on the mutex.
+ */
+ ctx->blocked = false;
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Blocked_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSurrender_Pre_Priority_Prepare(
+ ScoreMtxReqSurrender_Context *ctx,
+ ScoreMtxReqSurrender_Pre_Priority state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSurrender_Pre_Priority_High: {
+ /*
+ * While the current priority of the calling thread without the
+ * priorities available through the mutex would be higher than the
+ * highest priority of the priorities available through the mutex.
+ */
+ ctx->priority_real = PRIO_ULTRA_HIGH;
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Priority_Equal: {
+ /*
+ * While the current priority of the calling thread without the
+ * priorities available through the mutex would be equal to the highest
+ * priority of the priorities available through the mutex.
+ */
+ ctx->priority_real = PRIO_VERY_HIGH;
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Priority_Low: {
+ /*
+ * While the current priority of the calling thread without the
+ * priorities available through the mutex would be lower than the highest
+ * priority of the priorities available through the mutex.
+ */
+ ctx->priority_real = PRIO_HIGH;
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Pre_Priority_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSurrender_Post_Status_Check(
+ ScoreMtxReqSurrender_Context *ctx,
+ ScoreMtxReqSurrender_Post_Status state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSurrender_Post_Status_Ok: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_SUCCESSFUL.
+ */
+ T_eq_int( ctx->status, Status( ctx, STATUS_SUCCESSFUL ) );
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Post_Status_NotOwner: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_NOT_OWNER.
+ */
+ T_eq_int( ctx->status, Status( ctx, STATUS_NOT_OWNER ) );
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Post_Status_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSurrender_Post_Owner_Check(
+ ScoreMtxReqSurrender_Context *ctx,
+ ScoreMtxReqSurrender_Post_Owner state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSurrender_Post_Owner_None: {
+ /*
+ * The mutex shall have no owner.
+ */
+ T_null( ctx->owner_after );
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Post_Owner_Caller: {
+ /*
+ * The owner of the mutex shall be the calling thread.
+ */
+ T_eq_ptr(
+ ctx->owner_after,
+ ctx->tq_ctx->base.runner_tcb
+ );
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Post_Owner_Other: {
+ /*
+ * The owner of the mutex shall not be modified.
+ */
+ T_eq_ptr(
+ ctx->owner_after,
+ ctx->tq_ctx->base.worker_tcb[ TQ_HELPER_A ]
+ );
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Post_Owner_First: {
+ /*
+ * The owner of the mutex shall be dequeued thread.
+ */
+ T_eq_ptr(
+ ctx->owner_after,
+ ctx->tq_ctx->base.worker_tcb[ TQ_BLOCKER_A ]
+ );
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Post_Owner_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSurrender_Post_Surrender_Check(
+ ScoreMtxReqSurrender_Context *ctx,
+ ScoreMtxReqSurrender_Post_Surrender state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSurrender_Post_Surrender_Nop: {
+ /*
+ * The thread queue of the mutex shall not be surrendered to a thread.
+ */
+ T_eq_u32( ctx->counter, 0 );
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Post_Surrender_FIFO: {
+ /*
+ * The thread queue of the mutex shall be surrendered in FIFO order.
+ */
+ T_eq_u32( ctx->counter, 1 );
+ ScoreTqReqSurrender_Run( &ctx->tq_ctx->base );
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Post_Surrender_Priority: {
+ /*
+ * The thread queue of the mutex shall be surrendered in priority order.
+ */
+ T_eq_u32( ctx->counter, 1 );
+ ScoreTqReqSurrender_Run( &ctx->tq_ctx->base );
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Post_Surrender_PriorityInherit: {
+ /*
+ * The thread queue of the mutex shall be surrendered in priority order
+ * with priority inheritance.
+ */
+ T_eq_u32( ctx->counter, 1 );
+ ScoreTqReqSurrenderPriorityInherit_Run( &ctx->tq_ctx->base );
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Post_Surrender_MrsP: {
+ /*
+ * The thread queue of the mutex shall be surrendered in priority order
+ * with MrsP.
+ */
+ #if defined(RTEMS_SMP)
+ T_eq_u32( ctx->counter, 1 );
+ ScoreTqReqSurrenderMrsp_Run( &ctx->tq_ctx->base );
+ #else
+ T_unreachable();
+ #endif
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Post_Surrender_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSurrender_Post_Priority_Check(
+ ScoreMtxReqSurrender_Context *ctx,
+ ScoreMtxReqSurrender_Post_Priority state
+)
+{
+ switch ( state ) {
+ case ScoreMtxReqSurrender_Post_Priority_Nop: {
+ /*
+ * The current priority of the calling thread shall be not be modified.
+ */
+ T_eq_u32( ctx->priority_after, ctx->priority_before );
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Post_Priority_Low: {
+ /*
+ * The current priority of the calling thread shall be lowered to reflect
+ * the removal of the priorities available through the mutex.
+ */
+ T_eq_u32( ctx->priority_after, ctx->priority_real );
+ break;
+ }
+
+ case ScoreMtxReqSurrender_Post_Priority_NA:
+ break;
+ }
+}
+
+static void ScoreMtxReqSurrender_Prepare( ScoreMtxReqSurrender_Context *ctx )
+{
+ ctx->owner_caller = false;
+ ctx->owner_other = false;
+ ctx->nested = false;
+ ctx->blocked = false;
+
+ if ( ctx->tq_ctx->base.enqueue_variant == TQ_ENQUEUE_STICKY ) {
+ ctx->priority_real = PRIO_ULTRA_HIGH;
+ } else {
+ ctx->priority_real = PRIO_NORMAL;
+ }
+}
+
+static void ScoreMtxReqSurrender_Action( ScoreMtxReqSurrender_Context *ctx )
+{
+ if ( ctx->tq_ctx->base.enqueue_variant == TQ_ENQUEUE_STICKY ) {
+ ActionSticky( ctx );
+ } else {
+ Action( ctx );
+ }
+}
+
+static const ScoreMtxReqSurrender_Entry
+ScoreMtxReqSurrender_Entries[] = {
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_NA,
+ ScoreMtxReqSurrender_Post_Owner_NA, ScoreMtxReqSurrender_Post_Surrender_NA,
+ ScoreMtxReqSurrender_Post_Priority_NA },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_NA,
+ ScoreMtxReqSurrender_Post_Owner_NA, ScoreMtxReqSurrender_Post_Surrender_NA,
+ ScoreMtxReqSurrender_Post_Priority_NA },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_NA,
+ ScoreMtxReqSurrender_Post_Owner_NA, ScoreMtxReqSurrender_Post_Surrender_NA,
+ ScoreMtxReqSurrender_Post_Priority_NA },
+ { 0, 0, 0, 0, 0, 0, 1, 0, 1, ScoreMtxReqSurrender_Post_Status_NotOwner,
+ ScoreMtxReqSurrender_Post_Owner_Other,
+ ScoreMtxReqSurrender_Post_Surrender_Nop,
+ ScoreMtxReqSurrender_Post_Priority_Nop },
+ { 1, 0, 0, 0, 0, 0, 1, 0, 1, ScoreMtxReqSurrender_Post_Status_NA,
+ ScoreMtxReqSurrender_Post_Owner_NA, ScoreMtxReqSurrender_Post_Surrender_NA,
+ ScoreMtxReqSurrender_Post_Priority_NA },
+ { 0, 0, 0, 0, 0, 0, 1, 0, 1, ScoreMtxReqSurrender_Post_Status_NotOwner,
+ ScoreMtxReqSurrender_Post_Owner_None,
+ ScoreMtxReqSurrender_Post_Surrender_Nop,
+ ScoreMtxReqSurrender_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSurrender_Post_Status_Ok,
+ ScoreMtxReqSurrender_Post_Owner_None,
+ ScoreMtxReqSurrender_Post_Surrender_Nop,
+ ScoreMtxReqSurrender_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSurrender_Post_Status_Ok,
+ ScoreMtxReqSurrender_Post_Owner_Caller,
+ ScoreMtxReqSurrender_Post_Surrender_Nop,
+ ScoreMtxReqSurrender_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
+ ScoreMtxReqSurrender_Post_Owner_Caller,
+ ScoreMtxReqSurrender_Post_Surrender_Nop,
+ ScoreMtxReqSurrender_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
+ ScoreMtxReqSurrender_Post_Owner_None,
+ ScoreMtxReqSurrender_Post_Surrender_Nop,
+ ScoreMtxReqSurrender_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSurrender_Post_Status_Ok,
+ ScoreMtxReqSurrender_Post_Owner_First,
+ ScoreMtxReqSurrender_Post_Surrender_FIFO,
+ ScoreMtxReqSurrender_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 1, ScoreMtxReqSurrender_Post_Status_Ok,
+ ScoreMtxReqSurrender_Post_Owner_First,
+ ScoreMtxReqSurrender_Post_Surrender_Priority,
+ ScoreMtxReqSurrender_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
+ ScoreMtxReqSurrender_Post_Owner_First,
+ ScoreMtxReqSurrender_Post_Surrender_PriorityInherit,
+ ScoreMtxReqSurrender_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
+ ScoreMtxReqSurrender_Post_Owner_First,
+ ScoreMtxReqSurrender_Post_Surrender_Priority,
+ ScoreMtxReqSurrender_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
+ ScoreMtxReqSurrender_Post_Owner_None,
+ ScoreMtxReqSurrender_Post_Surrender_Nop,
+ ScoreMtxReqSurrender_Post_Priority_Low },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
+ ScoreMtxReqSurrender_Post_Owner_First,
+ ScoreMtxReqSurrender_Post_Surrender_MrsP,
+ ScoreMtxReqSurrender_Post_Priority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
+ ScoreMtxReqSurrender_Post_Owner_First,
+ ScoreMtxReqSurrender_Post_Surrender_PriorityInherit,
+ ScoreMtxReqSurrender_Post_Priority_Low },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
+ ScoreMtxReqSurrender_Post_Owner_First,
+ ScoreMtxReqSurrender_Post_Surrender_Priority,
+ ScoreMtxReqSurrender_Post_Priority_Low },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, ScoreMtxReqSurrender_Post_Status_Ok,
+ ScoreMtxReqSurrender_Post_Owner_First,
+ ScoreMtxReqSurrender_Post_Surrender_MrsP,
+ ScoreMtxReqSurrender_Post_Priority_Low }
+};
+
+static const uint8_t
+ScoreMtxReqSurrender_Map[] = {
+ 4, 4, 4, 5, 5, 5, 4, 4, 4, 5, 5, 5, 7, 7, 7, 7, 7, 7, 10, 10, 10, 6, 6, 6, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7, 7,
+ 7, 7, 7, 10, 10, 10, 6, 6, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
+ 2, 2, 4, 4, 4, 5, 5, 5, 2, 2, 2, 2, 2, 2, 10, 10, 10, 6, 6, 6, 2, 2, 2, 2, 2,
+ 2, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2,
+ 10, 10, 10, 6, 6, 6, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 4, 4, 4, 5, 5, 5, 4,
+ 4, 4, 5, 5, 5, 7, 7, 7, 7, 7, 7, 11, 11, 11, 6, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7, 7, 7, 7, 7, 11, 11, 11,
+ 6, 6, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 4, 4, 4, 5, 5,
+ 5, 2, 2, 2, 2, 2, 2, 11, 11, 11, 6, 6, 6, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
+ 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 11, 11, 11, 6, 6, 6, 2,
+ 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4,
+ 4, 4, 5, 5, 5, 4, 4, 4, 5, 5, 5, 8, 8, 8, 7, 7, 7, 12, 12, 16, 6, 6, 6, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 7,
+ 7, 7, 12, 12, 16, 6, 6, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2,
+ 2, 4, 4, 4, 5, 5, 5, 2, 2, 2, 2, 2, 2, 12, 12, 16, 6, 6, 6, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 12,
+ 12, 16, 6, 6, 6, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 4, 4, 4, 5, 5, 5, 4, 4, 4, 5, 5, 5, 8, 8, 8, 8, 8, 8, 13,
+ 13, 17, 9, 9, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 8, 8, 8, 8, 8, 8, 13, 13, 17, 9, 9, 14, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 4, 4, 4, 5, 5, 5, 2, 2, 2, 2, 2, 2, 13, 13, 17,
+ 9, 9, 14, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
+ 1, 1, 2, 2, 2, 2, 2, 2, 13, 13, 17, 9, 9, 14, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1,
+ 1, 1, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 5, 5, 5, 4, 4, 4, 5,
+ 5, 5, 8, 8, 8, 8, 8, 8, 15, 15, 18, 9, 9, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 8, 8, 8, 8, 8, 15, 15, 18, 9, 9,
+ 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 4, 4, 4, 5, 5, 5,
+ 2, 2, 2, 2, 2, 2, 15, 15, 18, 9, 9, 14, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3,
+ 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 15, 15, 18, 9, 9, 14,
+ 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1
+};
+
+static size_t ScoreMtxReqSurrender_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreMtxReqSurrender_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( ScoreMtxReqSurrender_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreMtxReqSurrender_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = ScoreMtxReqSurrender_Scope,
+ .initial_context = &ScoreMtxReqSurrender_Instance
+};
+
+static const uint16_t ScoreMtxReqSurrender_Weights[] = {
+ 288, 144, 72, 36, 12, 6, 3, 1
+};
+
+static void ScoreMtxReqSurrender_Skip(
+ ScoreMtxReqSurrender_Context *ctx,
+ size_t index
+)
+{
+ switch ( index + 1 ) {
+ case 1:
+ ctx->Map.pci[ 1 ] = ScoreMtxReqSurrender_Pre_Discipline_NA - 1;
+ /* Fall through */
+ case 2:
+ ctx->Map.pci[ 2 ] = ScoreMtxReqSurrender_Pre_Recursive_NA - 1;
+ /* Fall through */
+ case 3:
+ ctx->Map.pci[ 3 ] = ScoreMtxReqSurrender_Pre_OwnerCheck_NA - 1;
+ /* Fall through */
+ case 4:
+ ctx->Map.pci[ 4 ] = ScoreMtxReqSurrender_Pre_Owner_NA - 1;
+ /* Fall through */
+ case 5:
+ ctx->Map.pci[ 5 ] = ScoreMtxReqSurrender_Pre_Nested_NA - 1;
+ /* Fall through */
+ case 6:
+ ctx->Map.pci[ 6 ] = ScoreMtxReqSurrender_Pre_Blocked_NA - 1;
+ /* Fall through */
+ case 7:
+ ctx->Map.pci[ 7 ] = ScoreMtxReqSurrender_Pre_Priority_NA - 1;
+ break;
+ }
+}
+
+static inline ScoreMtxReqSurrender_Entry ScoreMtxReqSurrender_PopEntry(
+ ScoreMtxReqSurrender_Context *ctx
+)
+{
+ size_t index;
+
+ if ( ctx->Map.skip ) {
+ size_t i;
+
+ ctx->Map.skip = false;
+ index = 0;
+
+ for ( i = 0; i < 8; ++i ) {
+ index += ScoreMtxReqSurrender_Weights[ i ] * ctx->Map.pci[ i ];
+ }
+ } else {
+ index = ctx->Map.index;
+ }
+
+ ctx->Map.index = index + 1;
+
+ return ScoreMtxReqSurrender_Entries[
+ ScoreMtxReqSurrender_Map[ index ]
+ ];
+}
+
+static void ScoreMtxReqSurrender_SetPreConditionStates(
+ ScoreMtxReqSurrender_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+
+ if ( ctx->Map.entry.Pre_Nested_NA ) {
+ ctx->Map.pcs[ 5 ] = ScoreMtxReqSurrender_Pre_Nested_NA;
+ } else {
+ ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
+ }
+
+ ctx->Map.pcs[ 6 ] = ctx->Map.pci[ 6 ];
+
+ if ( ctx->Map.entry.Pre_Priority_NA ) {
+ ctx->Map.pcs[ 7 ] = ScoreMtxReqSurrender_Pre_Priority_NA;
+ } else {
+ ctx->Map.pcs[ 7 ] = ctx->Map.pci[ 7 ];
+ }
+}
+
+static void ScoreMtxReqSurrender_TestVariant(
+ ScoreMtxReqSurrender_Context *ctx
+)
+{
+ ScoreMtxReqSurrender_Pre_Protocol_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+
+ if ( ctx->Map.skip ) {
+ ScoreMtxReqSurrender_Skip( ctx, 0 );
+ return;
+ }
+
+ ScoreMtxReqSurrender_Pre_Discipline_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+
+ if ( ctx->Map.skip ) {
+ ScoreMtxReqSurrender_Skip( ctx, 1 );
+ return;
+ }
+
+ ScoreMtxReqSurrender_Pre_Recursive_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+
+ if ( ctx->Map.skip ) {
+ ScoreMtxReqSurrender_Skip( ctx, 2 );
+ return;
+ }
+
+ ScoreMtxReqSurrender_Pre_OwnerCheck_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+
+ if ( ctx->Map.skip ) {
+ ScoreMtxReqSurrender_Skip( ctx, 3 );
+ return;
+ }
+
+ ScoreMtxReqSurrender_Pre_Owner_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ ScoreMtxReqSurrender_Pre_Nested_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ ScoreMtxReqSurrender_Pre_Blocked_Prepare( ctx, ctx->Map.pcs[ 6 ] );
+ ScoreMtxReqSurrender_Pre_Priority_Prepare( ctx, ctx->Map.pcs[ 7 ] );
+ ScoreMtxReqSurrender_Action( ctx );
+ ScoreMtxReqSurrender_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ ScoreMtxReqSurrender_Post_Owner_Check( ctx, ctx->Map.entry.Post_Owner );
+ ScoreMtxReqSurrender_Post_Surrender_Check(
+ ctx,
+ ctx->Map.entry.Post_Surrender
+ );
+ ScoreMtxReqSurrender_Post_Priority_Check(
+ ctx,
+ ctx->Map.entry.Post_Priority
+ );
+}
+
+static T_fixture_node ScoreMtxReqSurrender_Node;
+
+static T_remark ScoreMtxReqSurrender_Remark = {
+ .next = NULL,
+ .remark = "ScoreMtxReqSurrender"
+};
+
+void ScoreMtxReqSurrender_Run( TQMtxContext *tq_ctx )
+{
+ ScoreMtxReqSurrender_Context *ctx;
+
+ ctx = &ScoreMtxReqSurrender_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreMtxReqSurrender_Node,
+ &ScoreMtxReqSurrender_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+ ctx->Map.skip = false;
+
+ for (
+ ctx->Map.pci[ 0 ] = ScoreMtxReqSurrender_Pre_Protocol_None;
+ ctx->Map.pci[ 0 ] < ScoreMtxReqSurrender_Pre_Protocol_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = ScoreMtxReqSurrender_Pre_Discipline_FIFO;
+ ctx->Map.pci[ 1 ] < ScoreMtxReqSurrender_Pre_Discipline_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = ScoreMtxReqSurrender_Pre_Recursive_Allowed;
+ ctx->Map.pci[ 2 ] < ScoreMtxReqSurrender_Pre_Recursive_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = ScoreMtxReqSurrender_Pre_OwnerCheck_Yes;
+ ctx->Map.pci[ 3 ] < ScoreMtxReqSurrender_Pre_OwnerCheck_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ for (
+ ctx->Map.pci[ 4 ] = ScoreMtxReqSurrender_Pre_Owner_None;
+ ctx->Map.pci[ 4 ] < ScoreMtxReqSurrender_Pre_Owner_NA;
+ ++ctx->Map.pci[ 4 ]
+ ) {
+ for (
+ ctx->Map.pci[ 5 ] = ScoreMtxReqSurrender_Pre_Nested_Yes;
+ ctx->Map.pci[ 5 ] < ScoreMtxReqSurrender_Pre_Nested_NA;
+ ++ctx->Map.pci[ 5 ]
+ ) {
+ for (
+ ctx->Map.pci[ 6 ] = ScoreMtxReqSurrender_Pre_Blocked_Yes;
+ ctx->Map.pci[ 6 ] < ScoreMtxReqSurrender_Pre_Blocked_NA;
+ ++ctx->Map.pci[ 6 ]
+ ) {
+ for (
+ ctx->Map.pci[ 7 ] = ScoreMtxReqSurrender_Pre_Priority_High;
+ ctx->Map.pci[ 7 ] < ScoreMtxReqSurrender_Pre_Priority_NA;
+ ++ctx->Map.pci[ 7 ]
+ ) {
+ ctx->Map.entry = ScoreMtxReqSurrender_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ ScoreMtxReqSurrender_SetPreConditionStates( ctx );
+ ScoreMtxReqSurrender_Prepare( ctx );
+ ScoreMtxReqSurrender_TestVariant( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ T_add_remark( &ScoreMtxReqSurrender_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-mtx-surrender.h b/testsuites/validation/tr-mtx-surrender.h
new file mode 100644
index 0000000000..1b732d5e73
--- /dev/null
+++ b/testsuites/validation/tr-mtx-surrender.h
@@ -0,0 +1,160 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreMtxReqSurrender
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_MTX_SURRENDER_H
+#define _TR_MTX_SURRENDER_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreMtxReqSurrender
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreMtxReqSurrender_Pre_Protocol_None,
+ ScoreMtxReqSurrender_Pre_Protocol_Inherit,
+ ScoreMtxReqSurrender_Pre_Protocol_Ceiling,
+ ScoreMtxReqSurrender_Pre_Protocol_MrsP,
+ ScoreMtxReqSurrender_Pre_Protocol_NA
+} ScoreMtxReqSurrender_Pre_Protocol;
+
+typedef enum {
+ ScoreMtxReqSurrender_Pre_Discipline_FIFO,
+ ScoreMtxReqSurrender_Pre_Discipline_Priority,
+ ScoreMtxReqSurrender_Pre_Discipline_NA
+} ScoreMtxReqSurrender_Pre_Discipline;
+
+typedef enum {
+ ScoreMtxReqSurrender_Pre_Recursive_Allowed,
+ ScoreMtxReqSurrender_Pre_Recursive_NotAllowed,
+ ScoreMtxReqSurrender_Pre_Recursive_NA
+} ScoreMtxReqSurrender_Pre_Recursive;
+
+typedef enum {
+ ScoreMtxReqSurrender_Pre_OwnerCheck_Yes,
+ ScoreMtxReqSurrender_Pre_OwnerCheck_No,
+ ScoreMtxReqSurrender_Pre_OwnerCheck_NA
+} ScoreMtxReqSurrender_Pre_OwnerCheck;
+
+typedef enum {
+ ScoreMtxReqSurrender_Pre_Owner_None,
+ ScoreMtxReqSurrender_Pre_Owner_Caller,
+ ScoreMtxReqSurrender_Pre_Owner_Other,
+ ScoreMtxReqSurrender_Pre_Owner_NA
+} ScoreMtxReqSurrender_Pre_Owner;
+
+typedef enum {
+ ScoreMtxReqSurrender_Pre_Nested_Yes,
+ ScoreMtxReqSurrender_Pre_Nested_No,
+ ScoreMtxReqSurrender_Pre_Nested_NA
+} ScoreMtxReqSurrender_Pre_Nested;
+
+typedef enum {
+ ScoreMtxReqSurrender_Pre_Blocked_Yes,
+ ScoreMtxReqSurrender_Pre_Blocked_No,
+ ScoreMtxReqSurrender_Pre_Blocked_NA
+} ScoreMtxReqSurrender_Pre_Blocked;
+
+typedef enum {
+ ScoreMtxReqSurrender_Pre_Priority_High,
+ ScoreMtxReqSurrender_Pre_Priority_Equal,
+ ScoreMtxReqSurrender_Pre_Priority_Low,
+ ScoreMtxReqSurrender_Pre_Priority_NA
+} ScoreMtxReqSurrender_Pre_Priority;
+
+typedef enum {
+ ScoreMtxReqSurrender_Post_Status_Ok,
+ ScoreMtxReqSurrender_Post_Status_NotOwner,
+ ScoreMtxReqSurrender_Post_Status_NA
+} ScoreMtxReqSurrender_Post_Status;
+
+typedef enum {
+ ScoreMtxReqSurrender_Post_Owner_None,
+ ScoreMtxReqSurrender_Post_Owner_Caller,
+ ScoreMtxReqSurrender_Post_Owner_Other,
+ ScoreMtxReqSurrender_Post_Owner_First,
+ ScoreMtxReqSurrender_Post_Owner_NA
+} ScoreMtxReqSurrender_Post_Owner;
+
+typedef enum {
+ ScoreMtxReqSurrender_Post_Surrender_Nop,
+ ScoreMtxReqSurrender_Post_Surrender_FIFO,
+ ScoreMtxReqSurrender_Post_Surrender_Priority,
+ ScoreMtxReqSurrender_Post_Surrender_PriorityInherit,
+ ScoreMtxReqSurrender_Post_Surrender_MrsP,
+ ScoreMtxReqSurrender_Post_Surrender_NA
+} ScoreMtxReqSurrender_Post_Surrender;
+
+typedef enum {
+ ScoreMtxReqSurrender_Post_Priority_Nop,
+ ScoreMtxReqSurrender_Post_Priority_Low,
+ ScoreMtxReqSurrender_Post_Priority_NA
+} ScoreMtxReqSurrender_Post_Priority;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue context.
+ */
+void ScoreMtxReqSurrender_Run( TQMtxContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_MTX_SURRENDER_H */
diff --git a/testsuites/validation/tr-object-ident-local.c b/testsuites/validation/tr-object-ident-local.c
new file mode 100644
index 0000000000..5cf521fbd6
--- /dev/null
+++ b/testsuites/validation/tr-object-ident-local.c
@@ -0,0 +1,394 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsReqIdentLocal
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-object-ident-local.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsReqIdentLocal spec:/rtems/req/ident-local
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Name_NA : 1;
+ uint8_t Pre_Id_NA : 1;
+ uint8_t Post_Status : 2;
+ uint8_t Post_Id : 2;
+} RtemsReqIdentLocal_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/req/ident-local test case.
+ */
+typedef struct {
+ rtems_status_code status;
+
+ rtems_name name;
+
+ rtems_id *id;
+
+ rtems_id id_value;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * RtemsReqIdentLocal_Run() parameter.
+ */
+ rtems_id id_local_object;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * RtemsReqIdentLocal_Run() parameter.
+ */
+ rtems_name name_local_object;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * RtemsReqIdentLocal_Run() parameter.
+ */
+ rtems_status_code ( *action )( rtems_name, rtems_id * );
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsReqIdentLocal_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsReqIdentLocal_Context;
+
+static RtemsReqIdentLocal_Context
+ RtemsReqIdentLocal_Instance;
+
+static const char * const RtemsReqIdentLocal_PreDesc_Name[] = {
+ "Invalid",
+ "Valid",
+ "NA"
+};
+
+static const char * const RtemsReqIdentLocal_PreDesc_Id[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsReqIdentLocal_PreDesc[] = {
+ RtemsReqIdentLocal_PreDesc_Name,
+ RtemsReqIdentLocal_PreDesc_Id,
+ NULL
+};
+
+static void RtemsReqIdentLocal_Pre_Name_Prepare(
+ RtemsReqIdentLocal_Context *ctx,
+ RtemsReqIdentLocal_Pre_Name state
+)
+{
+ switch ( state ) {
+ case RtemsReqIdentLocal_Pre_Name_Invalid: {
+ /*
+ * While the ``name`` parameter is not associated with an active object
+ * of the specified class .
+ */
+ ctx->name = 1;
+ break;
+ }
+
+ case RtemsReqIdentLocal_Pre_Name_Valid: {
+ /*
+ * While the ``name`` parameter is associated with an active object of
+ * the specified class .
+ */
+ ctx->name = ctx->name_local_object;
+ break;
+ }
+
+ case RtemsReqIdentLocal_Pre_Name_NA:
+ break;
+ }
+}
+
+static void RtemsReqIdentLocal_Pre_Id_Prepare(
+ RtemsReqIdentLocal_Context *ctx,
+ RtemsReqIdentLocal_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsReqIdentLocal_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter references an object of type rtems_id.
+ */
+ ctx->id_value = 0xffffffff;
+ ctx->id = &ctx->id_value;
+ break;
+ }
+
+ case RtemsReqIdentLocal_Pre_Id_Null: {
+ /*
+ * While the ``id`` parameter is NULL.
+ */
+ ctx->id = NULL;
+ break;
+ }
+
+ case RtemsReqIdentLocal_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsReqIdentLocal_Post_Status_Check(
+ RtemsReqIdentLocal_Context *ctx,
+ RtemsReqIdentLocal_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsReqIdentLocal_Post_Status_Ok: {
+ /*
+ * The return status shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc( ctx->status, RTEMS_SUCCESSFUL );
+ break;
+ }
+
+ case RtemsReqIdentLocal_Post_Status_InvAddr: {
+ /*
+ * The return status shall be RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
+ break;
+ }
+
+ case RtemsReqIdentLocal_Post_Status_InvName: {
+ /*
+ * The return status shall be RTEMS_INVALID_NAME.
+ */
+ T_rsc( ctx->status, RTEMS_INVALID_NAME );
+ break;
+ }
+
+ case RtemsReqIdentLocal_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsReqIdentLocal_Post_Id_Check(
+ RtemsReqIdentLocal_Context *ctx,
+ RtemsReqIdentLocal_Post_Id state
+)
+{
+ switch ( state ) {
+ case RtemsReqIdentLocal_Post_Id_Nop: {
+ /*
+ * The value of the object identifier referenced by the id parameter
+ * shall be the value before the action.
+ */
+ T_eq_ptr( ctx->id, &ctx->id_value );
+ T_eq_u32( ctx->id_value, 0xffffffff );
+ break;
+ }
+
+ case RtemsReqIdentLocal_Post_Id_Null: {
+ /*
+ * While the id is NULL.
+ */
+ T_null( ctx->id )
+ break;
+ }
+
+ case RtemsReqIdentLocal_Post_Id_Id: {
+ /*
+ * The value of the object identifier referenced by the id parameter
+ * shall be the identifier of a local object of the specified class with
+ * a name equal to the name parameter. If more than one local object of
+ * the specified class with such a name exists, then it shall be the
+ * identifier of the object with the lowest object index.
+ */
+ T_eq_ptr( ctx->id, &ctx->id_value );
+ T_eq_u32( ctx->id_value, ctx->id_local_object );
+ break;
+ }
+
+ case RtemsReqIdentLocal_Post_Id_NA:
+ break;
+ }
+}
+
+static void RtemsReqIdentLocal_Action( RtemsReqIdentLocal_Context *ctx )
+{
+ ctx->status = ( *ctx->action )( ctx->name, ctx->id );
+}
+
+static const RtemsReqIdentLocal_Entry
+RtemsReqIdentLocal_Entries[] = {
+ { 0, 0, 0, RtemsReqIdentLocal_Post_Status_InvAddr,
+ RtemsReqIdentLocal_Post_Id_Null },
+ { 0, 0, 0, RtemsReqIdentLocal_Post_Status_InvName,
+ RtemsReqIdentLocal_Post_Id_Nop },
+ { 0, 0, 0, RtemsReqIdentLocal_Post_Status_Ok, RtemsReqIdentLocal_Post_Id_Id }
+};
+
+static const uint8_t
+RtemsReqIdentLocal_Map[] = {
+ 1, 0, 2, 0
+};
+
+static size_t RtemsReqIdentLocal_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsReqIdentLocal_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsReqIdentLocal_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsReqIdentLocal_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsReqIdentLocal_Scope,
+ .initial_context = &RtemsReqIdentLocal_Instance
+};
+
+static inline RtemsReqIdentLocal_Entry RtemsReqIdentLocal_PopEntry(
+ RtemsReqIdentLocal_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsReqIdentLocal_Entries[
+ RtemsReqIdentLocal_Map[ index ]
+ ];
+}
+
+static void RtemsReqIdentLocal_TestVariant( RtemsReqIdentLocal_Context *ctx )
+{
+ RtemsReqIdentLocal_Pre_Name_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsReqIdentLocal_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsReqIdentLocal_Action( ctx );
+ RtemsReqIdentLocal_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsReqIdentLocal_Post_Id_Check( ctx, ctx->Map.entry.Post_Id );
+}
+
+static T_fixture_node RtemsReqIdentLocal_Node;
+
+static T_remark RtemsReqIdentLocal_Remark = {
+ .next = NULL,
+ .remark = "RtemsReqIdentLocal"
+};
+
+void RtemsReqIdentLocal_Run(
+ rtems_id id_local_object,
+ rtems_name name_local_object,
+ rtems_status_code ( *action )( rtems_name, rtems_id * )
+)
+{
+ RtemsReqIdentLocal_Context *ctx;
+
+ ctx = &RtemsReqIdentLocal_Instance;
+ ctx->id_local_object = id_local_object;
+ ctx->name_local_object = name_local_object;
+ ctx->action = action;
+
+ ctx = T_push_fixture( &RtemsReqIdentLocal_Node, &RtemsReqIdentLocal_Fixture );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsReqIdentLocal_Pre_Name_Invalid;
+ ctx->Map.pcs[ 0 ] < RtemsReqIdentLocal_Pre_Name_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsReqIdentLocal_Pre_Id_Valid;
+ ctx->Map.pcs[ 1 ] < RtemsReqIdentLocal_Pre_Id_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ ctx->Map.entry = RtemsReqIdentLocal_PopEntry( ctx );
+ RtemsReqIdentLocal_TestVariant( ctx );
+ }
+ }
+
+ T_add_remark( &RtemsReqIdentLocal_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-object-ident-local.h b/testsuites/validation/tr-object-ident-local.h
new file mode 100644
index 0000000000..d3cf1c307a
--- /dev/null
+++ b/testsuites/validation/tr-object-ident-local.h
@@ -0,0 +1,115 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsReqIdentLocal
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_OBJECT_IDENT_LOCAL_H
+#define _TR_OBJECT_IDENT_LOCAL_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup RtemsReqIdentLocal
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsReqIdentLocal_Pre_Name_Invalid,
+ RtemsReqIdentLocal_Pre_Name_Valid,
+ RtemsReqIdentLocal_Pre_Name_NA
+} RtemsReqIdentLocal_Pre_Name;
+
+typedef enum {
+ RtemsReqIdentLocal_Pre_Id_Valid,
+ RtemsReqIdentLocal_Pre_Id_Null,
+ RtemsReqIdentLocal_Pre_Id_NA
+} RtemsReqIdentLocal_Pre_Id;
+
+typedef enum {
+ RtemsReqIdentLocal_Post_Status_Ok,
+ RtemsReqIdentLocal_Post_Status_InvAddr,
+ RtemsReqIdentLocal_Post_Status_InvName,
+ RtemsReqIdentLocal_Post_Status_NA
+} RtemsReqIdentLocal_Post_Status;
+
+typedef enum {
+ RtemsReqIdentLocal_Post_Id_Nop,
+ RtemsReqIdentLocal_Post_Id_Null,
+ RtemsReqIdentLocal_Post_Id_Id,
+ RtemsReqIdentLocal_Post_Id_NA
+} RtemsReqIdentLocal_Post_Id;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param id_local_object is the identifier of an active object of the class
+ * under test.
+ *
+ * @param name_local_object is the name of the active object of the class under
+ * test.
+ *
+ * @param action is the action handler.
+ */
+void RtemsReqIdentLocal_Run(
+ rtems_id id_local_object,
+ rtems_name name_local_object,
+ rtems_status_code ( *action )( rtems_name, rtems_id * )
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_OBJECT_IDENT_LOCAL_H */
diff --git a/testsuites/validation/tr-object-ident.c b/testsuites/validation/tr-object-ident.c
new file mode 100644
index 0000000000..df66d51437
--- /dev/null
+++ b/testsuites/validation/tr-object-ident.c
@@ -0,0 +1,504 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsReqIdent
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-object-ident.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsReqIdent spec:/rtems/req/ident
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Name_NA : 1;
+ uint16_t Pre_Node_NA : 1;
+ uint16_t Pre_Id_NA : 1;
+ uint16_t Post_Status : 3;
+ uint16_t Post_Id : 3;
+} RtemsReqIdent_Entry;
+
+/**
+ * @brief Test context for spec:/rtems/req/ident test case.
+ */
+typedef struct {
+ rtems_status_code status;
+
+ rtems_name name;
+
+ uint32_t node;
+
+ rtems_id *id;
+
+ rtems_id id_value;
+
+ rtems_id id_remote_object;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * RtemsReqIdent_Run() parameter.
+ */
+ rtems_id id_local_object;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * RtemsReqIdent_Run() parameter.
+ */
+ rtems_name name_local_object;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * RtemsReqIdent_Run() parameter.
+ */
+ rtems_status_code ( *action )( rtems_name, uint32_t, rtems_id * );
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ RtemsReqIdent_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} RtemsReqIdent_Context;
+
+static RtemsReqIdent_Context
+ RtemsReqIdent_Instance;
+
+static const char * const RtemsReqIdent_PreDesc_Name[] = {
+ "Invalid",
+ "Valid",
+ "NA"
+};
+
+static const char * const RtemsReqIdent_PreDesc_Node[] = {
+ "Local",
+ "Remote",
+ "Invalid",
+ "SearchAll",
+ "SearchOther",
+ "SearchLocal",
+ "NA"
+};
+
+static const char * const RtemsReqIdent_PreDesc_Id[] = {
+ "Valid",
+ "Null",
+ "NA"
+};
+
+static const char * const * const RtemsReqIdent_PreDesc[] = {
+ RtemsReqIdent_PreDesc_Name,
+ RtemsReqIdent_PreDesc_Node,
+ RtemsReqIdent_PreDesc_Id,
+ NULL
+};
+
+static void RtemsReqIdent_Pre_Name_Prepare(
+ RtemsReqIdent_Context *ctx,
+ RtemsReqIdent_Pre_Name state
+)
+{
+ switch ( state ) {
+ case RtemsReqIdent_Pre_Name_Invalid: {
+ /*
+ * While the ``name`` parameter is not associated with an active object
+ * of the specified class .
+ */
+ ctx->name = 1;
+ break;
+ }
+
+ case RtemsReqIdent_Pre_Name_Valid: {
+ /*
+ * While the ``name`` parameter is associated with an active object of
+ * the specified class .
+ */
+ ctx->name = ctx->name_local_object;
+ break;
+ }
+
+ case RtemsReqIdent_Pre_Name_NA:
+ break;
+ }
+}
+
+static void RtemsReqIdent_Pre_Node_Prepare(
+ RtemsReqIdent_Context *ctx,
+ RtemsReqIdent_Pre_Node state
+)
+{
+ switch ( state ) {
+ case RtemsReqIdent_Pre_Node_Local: {
+ /*
+ * While the ``node`` parameter is the local node number.
+ */
+ ctx->node = 1;
+ break;
+ }
+
+ case RtemsReqIdent_Pre_Node_Remote: {
+ /*
+ * While the ``node`` parameter is a remote node number.
+ */
+ ctx->node = 2;
+ break;
+ }
+
+ case RtemsReqIdent_Pre_Node_Invalid: {
+ /*
+ * While the ``node`` parameter is an invalid node number.
+ */
+ ctx->node = 256;
+ break;
+ }
+
+ case RtemsReqIdent_Pre_Node_SearchAll: {
+ /*
+ * While the ``node`` parameter is RTEMS_SEARCH_ALL_NODES.
+ */
+ ctx->node = RTEMS_SEARCH_ALL_NODES;
+ break;
+ }
+
+ case RtemsReqIdent_Pre_Node_SearchOther: {
+ /*
+ * While the ``node`` parameter is RTEMS_SEARCH_OTHER_NODES.
+ */
+ ctx->node = RTEMS_SEARCH_OTHER_NODES;
+ break;
+ }
+
+ case RtemsReqIdent_Pre_Node_SearchLocal: {
+ /*
+ * While the ``node`` parameter is RTEMS_SEARCH_LOCAL_NODE.
+ */
+ ctx->node = RTEMS_SEARCH_LOCAL_NODE;
+ break;
+ }
+
+ case RtemsReqIdent_Pre_Node_NA:
+ break;
+ }
+}
+
+static void RtemsReqIdent_Pre_Id_Prepare(
+ RtemsReqIdent_Context *ctx,
+ RtemsReqIdent_Pre_Id state
+)
+{
+ switch ( state ) {
+ case RtemsReqIdent_Pre_Id_Valid: {
+ /*
+ * While the ``id`` parameter references an object of type rtems_id.
+ */
+ ctx->id_value = 0xffffffff;
+ ctx->id = &ctx->id_value;
+ break;
+ }
+
+ case RtemsReqIdent_Pre_Id_Null: {
+ /*
+ * While the ``id`` parameter is NULL.
+ */
+ ctx->id = NULL;
+ break;
+ }
+
+ case RtemsReqIdent_Pre_Id_NA:
+ break;
+ }
+}
+
+static void RtemsReqIdent_Post_Status_Check(
+ RtemsReqIdent_Context *ctx,
+ RtemsReqIdent_Post_Status state
+)
+{
+ switch ( state ) {
+ case RtemsReqIdent_Post_Status_Ok: {
+ /*
+ * The return status shall be RTEMS_SUCCESSFUL.
+ */
+ T_rsc(ctx->status, RTEMS_SUCCESSFUL);
+ break;
+ }
+
+ case RtemsReqIdent_Post_Status_InvAddr: {
+ /*
+ * The return status shall be RTEMS_INVALID_ADDRESS.
+ */
+ T_rsc(ctx->status, RTEMS_INVALID_ADDRESS);
+ break;
+ }
+
+ case RtemsReqIdent_Post_Status_InvName: {
+ /*
+ * The return status shall be RTEMS_INVALID_NAME.
+ */
+ T_rsc(ctx->status, RTEMS_INVALID_NAME);
+ break;
+ }
+
+ case RtemsReqIdent_Post_Status_InvNode: {
+ /*
+ * The return status shall be RTEMS_INVALID_NODE.
+ */
+ T_rsc(ctx->status, RTEMS_INVALID_NODE);
+ break;
+ }
+
+ case RtemsReqIdent_Post_Status_NA:
+ break;
+ }
+}
+
+static void RtemsReqIdent_Post_Id_Check(
+ RtemsReqIdent_Context *ctx,
+ RtemsReqIdent_Post_Id state
+)
+{
+ switch ( state ) {
+ case RtemsReqIdent_Post_Id_Nop: {
+ /*
+ * The value of the object identifier referenced by the id parameter
+ * shall be the value before the action.
+ */
+ T_eq_ptr(ctx->id, &ctx->id_value);
+ T_eq_u32(ctx->id_value, 0xffffffff);
+ break;
+ }
+
+ case RtemsReqIdent_Post_Id_Null: {
+ /*
+ * While the id is NULL.
+ */
+ T_null(ctx->id)
+ break;
+ }
+
+ case RtemsReqIdent_Post_Id_LocalObj: {
+ /*
+ * The value of the object identifier referenced by the id parameter
+ * shall be the identifier of a local object of the specified class with
+ * a name equal to the name parameter. If more than one local object of
+ * the specified class with such a name exists, then it shall be the
+ * identifier of the object with the lowest object index.
+ */
+ T_eq_ptr(ctx->id, &ctx->id_value);
+ T_eq_u32(ctx->id_value, ctx->id_local_object);
+ break;
+ }
+
+ case RtemsReqIdent_Post_Id_RemoteObj: {
+ /*
+ * The value of the object identifier referenced by the id parameter
+ * shall be the identifier of a remote object of the specified class on a
+ * eligible node defined by the node parameter with a name equal to the
+ * name parameter. If more than one local object of the specified class
+ * with such a name exists, then it shall be the identifier of the object
+ * with the lowest object index. Otherwise, if more than one object of
+ * the specified class with such a name exists on remote eligible nodes,
+ * then it shall be the identifier of the object with the lowest node
+ * index and the lowest object index on this node.
+ */
+ T_eq_ptr(ctx->id, &ctx->id_value);
+ T_eq_u32(ctx->id_value, ctx->id_remote_object);
+ break;
+ }
+
+ case RtemsReqIdent_Post_Id_NA:
+ break;
+ }
+}
+
+static void RtemsReqIdent_Action( RtemsReqIdent_Context *ctx )
+{
+ ctx->status = ( *ctx->action )( ctx->name, ctx->node, ctx->id );
+}
+
+static const RtemsReqIdent_Entry
+RtemsReqIdent_Entries[] = {
+ { 0, 0, 0, 0, RtemsReqIdent_Post_Status_InvAddr, RtemsReqIdent_Post_Id_Null },
+ { 0, 0, 0, 0, RtemsReqIdent_Post_Status_InvName, RtemsReqIdent_Post_Id_Nop },
+ { 0, 0, 0, 0, RtemsReqIdent_Post_Status_Ok, RtemsReqIdent_Post_Id_LocalObj },
+#if defined(RTEMS_MULTIPROCESSING)
+ { 0, 0, 0, 0, RtemsReqIdent_Post_Status_Ok, RtemsReqIdent_Post_Id_RemoteObj }
+#else
+ { 0, 0, 0, 0, RtemsReqIdent_Post_Status_InvName, RtemsReqIdent_Post_Id_Nop }
+#endif
+};
+
+static const uint8_t
+RtemsReqIdent_Map[] = {
+ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 2, 0, 3, 0, 1, 0, 2, 0, 3, 0, 2, 0
+};
+
+static size_t RtemsReqIdent_Scope( void *arg, char *buf, size_t n )
+{
+ RtemsReqIdent_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( RtemsReqIdent_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture RtemsReqIdent_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = RtemsReqIdent_Scope,
+ .initial_context = &RtemsReqIdent_Instance
+};
+
+static inline RtemsReqIdent_Entry RtemsReqIdent_PopEntry(
+ RtemsReqIdent_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return RtemsReqIdent_Entries[
+ RtemsReqIdent_Map[ index ]
+ ];
+}
+
+static void RtemsReqIdent_TestVariant( RtemsReqIdent_Context *ctx )
+{
+ RtemsReqIdent_Pre_Name_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ RtemsReqIdent_Pre_Node_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ RtemsReqIdent_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ RtemsReqIdent_Action( ctx );
+ RtemsReqIdent_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ RtemsReqIdent_Post_Id_Check( ctx, ctx->Map.entry.Post_Id );
+}
+
+static T_fixture_node RtemsReqIdent_Node;
+
+static T_remark RtemsReqIdent_Remark = {
+ .next = NULL,
+ .remark = "RtemsReqIdent"
+};
+
+void RtemsReqIdent_Run(
+ rtems_id id_local_object,
+ rtems_name name_local_object,
+ rtems_status_code ( *action )( rtems_name, uint32_t, rtems_id * )
+)
+{
+ RtemsReqIdent_Context *ctx;
+
+ ctx = &RtemsReqIdent_Instance;
+ ctx->id_local_object = id_local_object;
+ ctx->name_local_object = name_local_object;
+ ctx->action = action;
+
+ ctx = T_push_fixture( &RtemsReqIdent_Node, &RtemsReqIdent_Fixture );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = RtemsReqIdent_Pre_Name_Invalid;
+ ctx->Map.pcs[ 0 ] < RtemsReqIdent_Pre_Name_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = RtemsReqIdent_Pre_Node_Local;
+ ctx->Map.pcs[ 1 ] < RtemsReqIdent_Pre_Node_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = RtemsReqIdent_Pre_Id_Valid;
+ ctx->Map.pcs[ 2 ] < RtemsReqIdent_Pre_Id_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ ctx->Map.entry = RtemsReqIdent_PopEntry( ctx );
+ RtemsReqIdent_TestVariant( ctx );
+ }
+ }
+ }
+
+ T_add_remark( &RtemsReqIdent_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-object-ident.h b/testsuites/validation/tr-object-ident.h
new file mode 100644
index 0000000000..404d56c707
--- /dev/null
+++ b/testsuites/validation/tr-object-ident.h
@@ -0,0 +1,127 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsReqIdent
+ */
+
+/*
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_OBJECT_IDENT_H
+#define _TR_OBJECT_IDENT_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup RtemsReqIdent
+ *
+ * @{
+ */
+
+typedef enum {
+ RtemsReqIdent_Pre_Name_Invalid,
+ RtemsReqIdent_Pre_Name_Valid,
+ RtemsReqIdent_Pre_Name_NA
+} RtemsReqIdent_Pre_Name;
+
+typedef enum {
+ RtemsReqIdent_Pre_Node_Local,
+ RtemsReqIdent_Pre_Node_Remote,
+ RtemsReqIdent_Pre_Node_Invalid,
+ RtemsReqIdent_Pre_Node_SearchAll,
+ RtemsReqIdent_Pre_Node_SearchOther,
+ RtemsReqIdent_Pre_Node_SearchLocal,
+ RtemsReqIdent_Pre_Node_NA
+} RtemsReqIdent_Pre_Node;
+
+typedef enum {
+ RtemsReqIdent_Pre_Id_Valid,
+ RtemsReqIdent_Pre_Id_Null,
+ RtemsReqIdent_Pre_Id_NA
+} RtemsReqIdent_Pre_Id;
+
+typedef enum {
+ RtemsReqIdent_Post_Status_Ok,
+ RtemsReqIdent_Post_Status_InvAddr,
+ RtemsReqIdent_Post_Status_InvName,
+ RtemsReqIdent_Post_Status_InvNode,
+ RtemsReqIdent_Post_Status_NA
+} RtemsReqIdent_Post_Status;
+
+typedef enum {
+ RtemsReqIdent_Post_Id_Nop,
+ RtemsReqIdent_Post_Id_Null,
+ RtemsReqIdent_Post_Id_LocalObj,
+ RtemsReqIdent_Post_Id_RemoteObj,
+ RtemsReqIdent_Post_Id_NA
+} RtemsReqIdent_Post_Id;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param id_local_object is the identifier of an active object of the class
+ * under test.
+ *
+ * @param name_local_object is the name of the active object of the class under
+ * test.
+ *
+ * @param action is the action handler.
+ */
+void RtemsReqIdent_Run(
+ rtems_id id_local_object,
+ rtems_name name_local_object,
+ rtems_status_code ( *action )( rtems_name, uint32_t, rtems_id * )
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_OBJECT_IDENT_H */
diff --git a/testsuites/validation/tr-sem-seize-try.c b/testsuites/validation/tr-sem-seize-try.c
new file mode 100644
index 0000000000..3470f832fd
--- /dev/null
+++ b/testsuites/validation/tr-sem-seize-try.c
@@ -0,0 +1,329 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSemReqSeizeTry
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-sem-seize-try.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreSemReqSeizeTry spec:/score/sem/req/seize-try
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Count_NA : 1;
+ uint8_t Post_Status : 2;
+ uint8_t Post_Count : 2;
+} ScoreSemReqSeizeTry_Entry;
+
+/**
+ * @brief Test context for spec:/score/sem/req/seize-try test case.
+ */
+typedef struct {
+ /**
+ * @brief This member specifies the semaphore count before the directive
+ * call.
+ */
+ uint32_t count_before;
+
+ /**
+ * @brief This member contains the return status of the directive call.
+ */
+ Status_Control status;
+
+ /**
+ * @brief This member contains the semaphore count after the directive call.
+ */
+ uint32_t count_after;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreSemReqSeizeTry_Run() parameter.
+ */
+ TQSemContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreSemReqSeizeTry_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreSemReqSeizeTry_Context;
+
+static ScoreSemReqSeizeTry_Context
+ ScoreSemReqSeizeTry_Instance;
+
+static const char * const ScoreSemReqSeizeTry_PreDesc_Count[] = {
+ "Zero",
+ "Positive",
+ "NA"
+};
+
+static const char * const * const ScoreSemReqSeizeTry_PreDesc[] = {
+ ScoreSemReqSeizeTry_PreDesc_Count,
+ NULL
+};
+
+typedef ScoreSemReqSeizeTry_Context Context;
+
+static Status_Control Status( const Context *ctx, Status_Control status )
+{
+ return TQConvertStatus( &ctx->tq_ctx->base, status );
+}
+
+static void ScoreSemReqSeizeTry_Pre_Count_Prepare(
+ ScoreSemReqSeizeTry_Context *ctx,
+ ScoreSemReqSeizeTry_Pre_Count state
+)
+{
+ switch ( state ) {
+ case ScoreSemReqSeizeTry_Pre_Count_Zero: {
+ /*
+ * While the count of the semaphore is zero.
+ */
+ ctx->count_before = 0;
+ break;
+ }
+
+ case ScoreSemReqSeizeTry_Pre_Count_Positive: {
+ /*
+ * While the count of the semaphore is greater than zero.
+ */
+ ctx->count_before = 1;
+ break;
+ }
+
+ case ScoreSemReqSeizeTry_Pre_Count_NA:
+ break;
+ }
+}
+
+static void ScoreSemReqSeizeTry_Post_Status_Check(
+ ScoreSemReqSeizeTry_Context *ctx,
+ ScoreSemReqSeizeTry_Post_Status state
+)
+{
+ switch ( state ) {
+ case ScoreSemReqSeizeTry_Post_Status_Ok: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_SUCCESSFUL.
+ */
+ T_eq_int( ctx->status, Status( ctx, STATUS_SUCCESSFUL ) );
+ break;
+ }
+
+ case ScoreSemReqSeizeTry_Post_Status_Unsat: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_UNSATISFIED.
+ */
+ T_eq_int( ctx->status, Status( ctx, STATUS_UNSATISFIED ) );
+ break;
+ }
+
+ case ScoreSemReqSeizeTry_Post_Status_NA:
+ break;
+ }
+}
+
+static void ScoreSemReqSeizeTry_Post_Count_Check(
+ ScoreSemReqSeizeTry_Context *ctx,
+ ScoreSemReqSeizeTry_Post_Count state
+)
+{
+ switch ( state ) {
+ case ScoreSemReqSeizeTry_Post_Count_Nop: {
+ /*
+ * The count of the semaphore shall not be modified.
+ */
+ T_eq_u32( ctx->count_after, ctx->count_before );
+ break;
+ }
+
+ case ScoreSemReqSeizeTry_Post_Count_MinusOne: {
+ /*
+ * The count of the semaphore shall be decremented by one.
+ */
+ T_eq_u32( ctx->count_after, ctx->count_before - 1 );
+ break;
+ }
+
+ case ScoreSemReqSeizeTry_Post_Count_NA:
+ break;
+ }
+}
+
+static void ScoreSemReqSeizeTry_Action( ScoreSemReqSeizeTry_Context *ctx )
+{
+ TQSemSetCount( ctx->tq_ctx, ctx->count_before );
+ ctx->status = TQEnqueue( &ctx->tq_ctx->base, TQ_NO_WAIT );
+ ctx->count_after = TQSemGetCount( ctx->tq_ctx );
+}
+
+static const ScoreSemReqSeizeTry_Entry
+ScoreSemReqSeizeTry_Entries[] = {
+ { 0, 0, ScoreSemReqSeizeTry_Post_Status_Unsat,
+ ScoreSemReqSeizeTry_Post_Count_Nop },
+ { 0, 0, ScoreSemReqSeizeTry_Post_Status_Ok,
+ ScoreSemReqSeizeTry_Post_Count_MinusOne }
+};
+
+static const uint8_t
+ScoreSemReqSeizeTry_Map[] = {
+ 0, 1
+};
+
+static size_t ScoreSemReqSeizeTry_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreSemReqSeizeTry_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( ScoreSemReqSeizeTry_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreSemReqSeizeTry_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = ScoreSemReqSeizeTry_Scope,
+ .initial_context = &ScoreSemReqSeizeTry_Instance
+};
+
+static inline ScoreSemReqSeizeTry_Entry ScoreSemReqSeizeTry_PopEntry(
+ ScoreSemReqSeizeTry_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return ScoreSemReqSeizeTry_Entries[
+ ScoreSemReqSeizeTry_Map[ index ]
+ ];
+}
+
+static void ScoreSemReqSeizeTry_TestVariant( ScoreSemReqSeizeTry_Context *ctx )
+{
+ ScoreSemReqSeizeTry_Pre_Count_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ ScoreSemReqSeizeTry_Action( ctx );
+ ScoreSemReqSeizeTry_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ ScoreSemReqSeizeTry_Post_Count_Check( ctx, ctx->Map.entry.Post_Count );
+}
+
+static T_fixture_node ScoreSemReqSeizeTry_Node;
+
+static T_remark ScoreSemReqSeizeTry_Remark = {
+ .next = NULL,
+ .remark = "ScoreSemReqSeizeTry"
+};
+
+void ScoreSemReqSeizeTry_Run( TQSemContext *tq_ctx )
+{
+ ScoreSemReqSeizeTry_Context *ctx;
+
+ ctx = &ScoreSemReqSeizeTry_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreSemReqSeizeTry_Node,
+ &ScoreSemReqSeizeTry_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = ScoreSemReqSeizeTry_Pre_Count_Zero;
+ ctx->Map.pcs[ 0 ] < ScoreSemReqSeizeTry_Pre_Count_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = ScoreSemReqSeizeTry_PopEntry( ctx );
+ ScoreSemReqSeizeTry_TestVariant( ctx );
+ }
+
+ T_add_remark( &ScoreSemReqSeizeTry_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-sem-seize-try.h b/testsuites/validation/tr-sem-seize-try.h
new file mode 100644
index 0000000000..347c8aa61d
--- /dev/null
+++ b/testsuites/validation/tr-sem-seize-try.h
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSemReqSeizeTry
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_SEM_SEIZE_TRY_H
+#define _TR_SEM_SEIZE_TRY_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreSemReqSeizeTry
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreSemReqSeizeTry_Pre_Count_Zero,
+ ScoreSemReqSeizeTry_Pre_Count_Positive,
+ ScoreSemReqSeizeTry_Pre_Count_NA
+} ScoreSemReqSeizeTry_Pre_Count;
+
+typedef enum {
+ ScoreSemReqSeizeTry_Post_Status_Ok,
+ ScoreSemReqSeizeTry_Post_Status_Unsat,
+ ScoreSemReqSeizeTry_Post_Status_NA
+} ScoreSemReqSeizeTry_Post_Status;
+
+typedef enum {
+ ScoreSemReqSeizeTry_Post_Count_Nop,
+ ScoreSemReqSeizeTry_Post_Count_MinusOne,
+ ScoreSemReqSeizeTry_Post_Count_NA
+} ScoreSemReqSeizeTry_Post_Count;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue context.
+ */
+void ScoreSemReqSeizeTry_Run( TQSemContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_SEM_SEIZE_TRY_H */
diff --git a/testsuites/validation/tr-sem-seize-wait.c b/testsuites/validation/tr-sem-seize-wait.c
new file mode 100644
index 0000000000..bbc1cfd252
--- /dev/null
+++ b/testsuites/validation/tr-sem-seize-wait.c
@@ -0,0 +1,404 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSemReqSeizeWait
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/statesimpl.h>
+
+#include "tr-sem-seize-wait.h"
+#include "tr-tq-enqueue-fifo.h"
+#include "tr-tq-enqueue-priority.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreSemReqSeizeWait spec:/score/sem/req/seize-wait
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Count_NA : 1;
+ uint8_t Post_Status : 2;
+ uint8_t Post_Count : 2;
+ uint8_t Post_Timer : 2;
+} ScoreSemReqSeizeWait_Entry;
+
+/**
+ * @brief Test context for spec:/score/sem/req/seize-wait test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreSemReqSeizeWait_Run() parameter.
+ */
+ TQSemContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreSemReqSeizeWait_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreSemReqSeizeWait_Context;
+
+static ScoreSemReqSeizeWait_Context
+ ScoreSemReqSeizeWait_Instance;
+
+static const char * const ScoreSemReqSeizeWait_PreDesc_Count[] = {
+ "Zero",
+ "Positive",
+ "NA"
+};
+
+static const char * const * const ScoreSemReqSeizeWait_PreDesc[] = {
+ ScoreSemReqSeizeWait_PreDesc_Count,
+ NULL
+};
+
+typedef ScoreSemReqSeizeWait_Context Context;
+
+static Status_Control Status( const Context *ctx, Status_Control status )
+{
+ return TQConvertStatus( &ctx->tq_ctx->base, status );
+}
+
+static void GetProperties( TQContext *base, TQWorkerKind enqueued_worker )
+{
+ TQSemContext *ctx;
+ T_thread_timer_state timer_state;
+
+ ctx = (TQSemContext *) base;
+ T_eq_u32(
+ ctx->base.worker_tcb[ enqueued_worker ]->current_state,
+ STATES_WAITING_FOR_SEMAPHORE
+ );
+
+ timer_state = T_get_thread_timer_state(
+ ctx->base.worker_id[ enqueued_worker ]
+ );
+
+ if ( base->wait == TQ_WAIT_TIMED ) {
+ T_eq_int( timer_state, T_THREAD_TIMER_SCHEDULED );
+ } else {
+ T_eq_int( timer_state, T_THREAD_TIMER_INACTIVE );
+ }
+
+ T_eq_u32( TQSemGetCount( ctx ), 0 );
+}
+
+static void ScoreSemReqSeizeWait_Pre_Count_Prepare(
+ ScoreSemReqSeizeWait_Context *ctx,
+ ScoreSemReqSeizeWait_Pre_Count state
+)
+{
+ switch ( state ) {
+ case ScoreSemReqSeizeWait_Pre_Count_Zero: {
+ /*
+ * While the count of the semaphore is zero.
+ */
+ /* Done by TQEnqueuePrepareDefault() */
+ break;
+ }
+
+ case ScoreSemReqSeizeWait_Pre_Count_Positive: {
+ /*
+ * While the count of the semaphore is greater than zero.
+ */
+ TQSemSetCount( ctx->tq_ctx, 1 );
+ break;
+ }
+
+ case ScoreSemReqSeizeWait_Pre_Count_NA:
+ break;
+ }
+}
+
+static void ScoreSemReqSeizeWait_Post_Status_Check(
+ ScoreSemReqSeizeWait_Context *ctx,
+ ScoreSemReqSeizeWait_Post_Status state
+)
+{
+ Status_Control status;
+
+ switch ( state ) {
+ case ScoreSemReqSeizeWait_Post_Status_Ok: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_SUCCESSFUL.
+ */
+ status = TQEnqueue( &ctx->tq_ctx->base, ctx->tq_ctx->base.wait );
+ T_eq_int( status, Status( ctx, STATUS_SUCCESSFUL ) );
+ break;
+ }
+
+ case ScoreSemReqSeizeWait_Post_Status_Enqueued: {
+ /*
+ * Where the thread queue uses the FIFO discipline, the calling thread
+ * shall be enqueued in FIFO order.
+ *
+ * Where the thread queue uses the priority discipline, the calling
+ * thread shall be enqueued in priority order.
+ */
+ switch ( ctx->tq_ctx->base.discipline ) {
+ case TQ_FIFO:
+ ScoreTqReqEnqueueFifo_Run( &ctx->tq_ctx->base );
+ break;
+ case TQ_PRIORITY:
+ ScoreTqReqEnqueuePriority_Run( &ctx->tq_ctx->base );
+ break;
+ default:
+ T_unreachable();
+ break;
+ }
+ break;
+ }
+
+ case ScoreSemReqSeizeWait_Post_Status_NA:
+ break;
+ }
+}
+
+static void ScoreSemReqSeizeWait_Post_Count_Check(
+ ScoreSemReqSeizeWait_Context *ctx,
+ ScoreSemReqSeizeWait_Post_Count state
+)
+{
+ switch ( state ) {
+ case ScoreSemReqSeizeWait_Post_Count_Nop: {
+ /*
+ * The count of the semaphore shall not be modified.
+ */
+ /* Checked by GetProperties() */
+ break;
+ }
+
+ case ScoreSemReqSeizeWait_Post_Count_MinusOne: {
+ /*
+ * The count of the semaphore shall be decremented by one.
+ */
+ T_eq_u32( TQSemGetCount( ctx->tq_ctx ), 0 );
+ break;
+ }
+
+ case ScoreSemReqSeizeWait_Post_Count_NA:
+ break;
+ }
+}
+
+static void ScoreSemReqSeizeWait_Post_Timer_Check(
+ ScoreSemReqSeizeWait_Context *ctx,
+ ScoreSemReqSeizeWait_Post_Timer state
+)
+{
+ switch ( state ) {
+ case ScoreSemReqSeizeWait_Post_Timer_Optional: {
+ /*
+ * Where the directive was called with a timeout in clock ticks, the
+ * thread timer of the calling task shall fire after the specified clock
+ * ticks.
+ *
+ * Where the directive was called without a timeout, the thread timer of
+ * the calling task shall be inactive.
+ */
+ /* Checked by GetProperties() */
+ break;
+ }
+
+ case ScoreSemReqSeizeWait_Post_Timer_No: {
+ /*
+ * The thread timer of the calling task shall be inactive.
+ */
+ T_eq_int(
+ T_get_thread_timer_state( RTEMS_SELF ),
+ T_THREAD_TIMER_INACTIVE
+ );
+ break;
+ }
+
+ case ScoreSemReqSeizeWait_Post_Timer_NA:
+ break;
+ }
+}
+
+static void ScoreSemReqSeizeWait_Prepare( ScoreSemReqSeizeWait_Context *ctx )
+{
+ ctx->tq_ctx->base.enqueue_prepare = TQEnqueuePrepareDefault;
+ ctx->tq_ctx->base.enqueue_done = TQEnqueueDoneDefault;
+ ctx->tq_ctx->base.get_properties = GetProperties;
+}
+
+static void ScoreSemReqSeizeWait_Action( ScoreSemReqSeizeWait_Context *ctx )
+{
+ /* Action performed by Status post-condition */
+}
+
+static const ScoreSemReqSeizeWait_Entry
+ScoreSemReqSeizeWait_Entries[] = {
+ { 0, 0, ScoreSemReqSeizeWait_Post_Status_Enqueued,
+ ScoreSemReqSeizeWait_Post_Count_Nop,
+ ScoreSemReqSeizeWait_Post_Timer_Optional },
+ { 0, 0, ScoreSemReqSeizeWait_Post_Status_Ok,
+ ScoreSemReqSeizeWait_Post_Count_MinusOne,
+ ScoreSemReqSeizeWait_Post_Timer_No }
+};
+
+static const uint8_t
+ScoreSemReqSeizeWait_Map[] = {
+ 0, 1
+};
+
+static size_t ScoreSemReqSeizeWait_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreSemReqSeizeWait_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( ScoreSemReqSeizeWait_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreSemReqSeizeWait_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = ScoreSemReqSeizeWait_Scope,
+ .initial_context = &ScoreSemReqSeizeWait_Instance
+};
+
+static inline ScoreSemReqSeizeWait_Entry ScoreSemReqSeizeWait_PopEntry(
+ ScoreSemReqSeizeWait_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return ScoreSemReqSeizeWait_Entries[
+ ScoreSemReqSeizeWait_Map[ index ]
+ ];
+}
+
+static void ScoreSemReqSeizeWait_TestVariant(
+ ScoreSemReqSeizeWait_Context *ctx
+)
+{
+ ScoreSemReqSeizeWait_Pre_Count_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ ScoreSemReqSeizeWait_Action( ctx );
+ ScoreSemReqSeizeWait_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ ScoreSemReqSeizeWait_Post_Count_Check( ctx, ctx->Map.entry.Post_Count );
+ ScoreSemReqSeizeWait_Post_Timer_Check( ctx, ctx->Map.entry.Post_Timer );
+}
+
+static T_fixture_node ScoreSemReqSeizeWait_Node;
+
+static T_remark ScoreSemReqSeizeWait_Remark = {
+ .next = NULL,
+ .remark = "ScoreSemReqSeizeWait"
+};
+
+void ScoreSemReqSeizeWait_Run( TQSemContext *tq_ctx )
+{
+ ScoreSemReqSeizeWait_Context *ctx;
+
+ ctx = &ScoreSemReqSeizeWait_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreSemReqSeizeWait_Node,
+ &ScoreSemReqSeizeWait_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = ScoreSemReqSeizeWait_Pre_Count_Zero;
+ ctx->Map.pcs[ 0 ] < ScoreSemReqSeizeWait_Pre_Count_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = ScoreSemReqSeizeWait_PopEntry( ctx );
+ ScoreSemReqSeizeWait_Prepare( ctx );
+ ScoreSemReqSeizeWait_TestVariant( ctx );
+ }
+
+ T_add_remark( &ScoreSemReqSeizeWait_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-sem-seize-wait.h b/testsuites/validation/tr-sem-seize-wait.h
new file mode 100644
index 0000000000..68156abbc7
--- /dev/null
+++ b/testsuites/validation/tr-sem-seize-wait.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSemReqSeizeWait
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_SEM_SEIZE_WAIT_H
+#define _TR_SEM_SEIZE_WAIT_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreSemReqSeizeWait
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreSemReqSeizeWait_Pre_Count_Zero,
+ ScoreSemReqSeizeWait_Pre_Count_Positive,
+ ScoreSemReqSeizeWait_Pre_Count_NA
+} ScoreSemReqSeizeWait_Pre_Count;
+
+typedef enum {
+ ScoreSemReqSeizeWait_Post_Status_Ok,
+ ScoreSemReqSeizeWait_Post_Status_Enqueued,
+ ScoreSemReqSeizeWait_Post_Status_NA
+} ScoreSemReqSeizeWait_Post_Status;
+
+typedef enum {
+ ScoreSemReqSeizeWait_Post_Count_Nop,
+ ScoreSemReqSeizeWait_Post_Count_MinusOne,
+ ScoreSemReqSeizeWait_Post_Count_NA
+} ScoreSemReqSeizeWait_Post_Count;
+
+typedef enum {
+ ScoreSemReqSeizeWait_Post_Timer_Optional,
+ ScoreSemReqSeizeWait_Post_Timer_No,
+ ScoreSemReqSeizeWait_Post_Timer_NA
+} ScoreSemReqSeizeWait_Post_Timer;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the semaphore thread queue context.
+ */
+void ScoreSemReqSeizeWait_Run( TQSemContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_SEM_SEIZE_WAIT_H */
diff --git a/testsuites/validation/tr-sem-surrender.c b/testsuites/validation/tr-sem-surrender.c
new file mode 100644
index 0000000000..d554a33dd2
--- /dev/null
+++ b/testsuites/validation/tr-sem-surrender.c
@@ -0,0 +1,576 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSemReqSurrender
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-sem-surrender.h"
+#include "tr-tq-surrender.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreSemReqSurrender spec:/score/sem/req/surrender
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint16_t Skip : 1;
+ uint16_t Pre_Variant_NA : 1;
+ uint16_t Pre_Discipline_NA : 1;
+ uint16_t Pre_Count_NA : 1;
+ uint16_t Post_Status : 2;
+ uint16_t Post_Surrender : 2;
+ uint16_t Post_Count : 3;
+} ScoreSemReqSurrender_Entry;
+
+/**
+ * @brief Test context for spec:/score/sem/req/surrender test case.
+ */
+typedef struct {
+ /**
+ * @brief This member specifies the semaphore count before the directive
+ * call.
+ */
+ uint32_t count_before;
+
+ /**
+ * @brief This member contains the return status of the directive call.
+ */
+ Status_Control status;
+
+ /**
+ * @brief This member contains the semaphore count after the directive call.
+ */
+ uint32_t count_after;
+
+ /**
+ * @brief If this member is true, then there shall be threads blocked on the
+ * semaphore.
+ */
+ bool blocked;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreSemReqSurrender_Run() parameter.
+ */
+ TQSemContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreSemReqSurrender_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreSemReqSurrender_Context;
+
+static ScoreSemReqSurrender_Context
+ ScoreSemReqSurrender_Instance;
+
+static const char * const ScoreSemReqSurrender_PreDesc_Variant[] = {
+ "Binary",
+ "Counting",
+ "NA"
+};
+
+static const char * const ScoreSemReqSurrender_PreDesc_Discipline[] = {
+ "FIFO",
+ "Priority",
+ "NA"
+};
+
+static const char * const ScoreSemReqSurrender_PreDesc_Count[] = {
+ "LessMax",
+ "Max",
+ "Blocked",
+ "NA"
+};
+
+static const char * const * const ScoreSemReqSurrender_PreDesc[] = {
+ ScoreSemReqSurrender_PreDesc_Variant,
+ ScoreSemReqSurrender_PreDesc_Discipline,
+ ScoreSemReqSurrender_PreDesc_Count,
+ NULL
+};
+
+typedef ScoreSemReqSurrender_Context Context;
+
+static Status_Control Status( const Context *ctx, Status_Control status )
+{
+ return TQConvertStatus( &ctx->tq_ctx->base, status );
+}
+
+static void ScoreSemReqSurrender_Pre_Variant_Prepare(
+ ScoreSemReqSurrender_Context *ctx,
+ ScoreSemReqSurrender_Pre_Variant state
+)
+{
+ switch ( state ) {
+ case ScoreSemReqSurrender_Pre_Variant_Binary: {
+ /*
+ * Where the semaphore is a binary semaphore.
+ */
+ if ( ctx->tq_ctx->variant != TQ_SEM_BINARY ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreSemReqSurrender_Pre_Variant_Counting: {
+ /*
+ * Where the semaphore is a counting semaphore.
+ */
+ if ( ctx->tq_ctx->variant != TQ_SEM_COUNTING ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreSemReqSurrender_Pre_Variant_NA:
+ break;
+ }
+}
+
+static void ScoreSemReqSurrender_Pre_Discipline_Prepare(
+ ScoreSemReqSurrender_Context *ctx,
+ ScoreSemReqSurrender_Pre_Discipline state
+)
+{
+ switch ( state ) {
+ case ScoreSemReqSurrender_Pre_Discipline_FIFO: {
+ /*
+ * Where the thread queue of the semaphore uses the FIFO discipline.
+ */
+ if ( ctx->tq_ctx->base.discipline != TQ_FIFO ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreSemReqSurrender_Pre_Discipline_Priority: {
+ /*
+ * Where the thread queue of the semaphore uses the priority discipline.
+ */
+ if ( ctx->tq_ctx->base.discipline != TQ_PRIORITY ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreSemReqSurrender_Pre_Discipline_NA:
+ break;
+ }
+}
+
+static void ScoreSemReqSurrender_Pre_Count_Prepare(
+ ScoreSemReqSurrender_Context *ctx,
+ ScoreSemReqSurrender_Pre_Count state
+)
+{
+ switch ( state ) {
+ case ScoreSemReqSurrender_Pre_Count_LessMax: {
+ /*
+ * While the count of the semaphore is less than the maximum count.
+ */
+ ctx->blocked = false;
+
+ if ( ctx->tq_ctx->variant == TQ_SEM_BINARY ) {
+ ctx->count_before = 0;
+ } else {
+ ctx->count_before = UINT32_MAX - 1;
+ }
+ break;
+ }
+
+ case ScoreSemReqSurrender_Pre_Count_Max: {
+ /*
+ * While the count of the semaphore is equal to the maximum count.
+ */
+ ctx->blocked = false;
+
+ if ( ctx->tq_ctx->variant == TQ_SEM_BINARY ) {
+ ctx->count_before = 1;
+ } else {
+ ctx->count_before = UINT32_MAX;
+ }
+ break;
+ }
+
+ case ScoreSemReqSurrender_Pre_Count_Blocked: {
+ /*
+ * While the semaphore has threads blocked on the semaphore.
+ */
+ ctx->blocked = true;
+ ctx->count_before = 0;
+ break;
+ }
+
+ case ScoreSemReqSurrender_Pre_Count_NA:
+ break;
+ }
+}
+
+static void ScoreSemReqSurrender_Post_Status_Check(
+ ScoreSemReqSurrender_Context *ctx,
+ ScoreSemReqSurrender_Post_Status state
+)
+{
+ switch ( state ) {
+ case ScoreSemReqSurrender_Post_Status_Ok: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_SUCCESSFUL.
+ */
+ T_eq_int( ctx->status, Status( ctx, STATUS_SUCCESSFUL ) );
+ break;
+ }
+
+ case ScoreSemReqSurrender_Post_Status_MaxCountExceeded: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_MAXIMUM_COUNT_EXCEEDED.
+ */
+ T_eq_int( ctx->status, Status( ctx, STATUS_MAXIMUM_COUNT_EXCEEDED ) );
+ break;
+ }
+
+ case ScoreSemReqSurrender_Post_Status_NA:
+ break;
+ }
+}
+
+static void ScoreSemReqSurrender_Post_Surrender_Check(
+ ScoreSemReqSurrender_Context *ctx,
+ ScoreSemReqSurrender_Post_Surrender state
+)
+{
+ switch ( state ) {
+ case ScoreSemReqSurrender_Post_Surrender_FIFO: {
+ /*
+ * The thread queue of the semaphore shall be surrendered in FIFO order.
+ */
+ ScoreTqReqSurrender_Run( &ctx->tq_ctx->base );
+ break;
+ }
+
+ case ScoreSemReqSurrender_Post_Surrender_Priority: {
+ /*
+ * The thread queue of the semaphore shall be surrendered in priority
+ * order.
+ */
+ ScoreTqReqSurrender_Run( &ctx->tq_ctx->base );
+ break;
+ }
+
+ case ScoreSemReqSurrender_Post_Surrender_NA:
+ break;
+ }
+}
+
+static void ScoreSemReqSurrender_Post_Count_Check(
+ ScoreSemReqSurrender_Context *ctx,
+ ScoreSemReqSurrender_Post_Count state
+)
+{
+ switch ( state ) {
+ case ScoreSemReqSurrender_Post_Count_Zero: {
+ /*
+ * The count of the semaphore shall be zero.
+ */
+ T_eq_u32( ctx->count_after, 0 );
+ break;
+ }
+
+ case ScoreSemReqSurrender_Post_Count_One: {
+ /*
+ * The count of the semaphore shall be one.
+ */
+ T_eq_u32( ctx->count_after, 1 );
+ break;
+ }
+
+ case ScoreSemReqSurrender_Post_Count_PlusOne: {
+ /*
+ * The count of the semaphore shall be incremented by one.
+ */
+ T_eq_u32( ctx->count_after, ctx->count_before + 1 );
+ break;
+ }
+
+ case ScoreSemReqSurrender_Post_Count_Nop: {
+ /*
+ * The count of the semaphore shall not be modified.
+ */
+ T_eq_u32( ctx->count_after, ctx->count_before );
+ break;
+ }
+
+ case ScoreSemReqSurrender_Post_Count_NA:
+ break;
+ }
+}
+
+static void ScoreSemReqSurrender_Setup( ScoreSemReqSurrender_Context *ctx )
+{
+ ctx->tq_ctx->base.wait = TQ_WAIT_FOREVER;
+ TQReset( &ctx->tq_ctx->base );
+}
+
+static void ScoreSemReqSurrender_Setup_Wrap( void *arg )
+{
+ ScoreSemReqSurrender_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreSemReqSurrender_Setup( ctx );
+}
+
+static void ScoreSemReqSurrender_Action( ScoreSemReqSurrender_Context *ctx )
+{
+ TQSemSetCount( ctx->tq_ctx, ctx->count_before );
+
+ if ( ctx->blocked ) {
+ TQSend( &ctx->tq_ctx->base, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
+ }
+
+ ctx->status = TQSurrender( &ctx->tq_ctx->base );
+ ctx->count_after = TQSemGetCount( ctx->tq_ctx );
+ TQSemSetCount( ctx->tq_ctx, 1 );
+}
+
+static const ScoreSemReqSurrender_Entry
+ScoreSemReqSurrender_Entries[] = {
+ { 0, 0, 0, 0, ScoreSemReqSurrender_Post_Status_Ok,
+ ScoreSemReqSurrender_Post_Surrender_NA, ScoreSemReqSurrender_Post_Count_One },
+ { 0, 0, 0, 0, ScoreSemReqSurrender_Post_Status_Ok,
+ ScoreSemReqSurrender_Post_Surrender_FIFO,
+ ScoreSemReqSurrender_Post_Count_Zero },
+ { 0, 0, 0, 0, ScoreSemReqSurrender_Post_Status_Ok,
+ ScoreSemReqSurrender_Post_Surrender_Priority,
+ ScoreSemReqSurrender_Post_Count_Zero },
+ { 0, 0, 0, 0, ScoreSemReqSurrender_Post_Status_Ok,
+ ScoreSemReqSurrender_Post_Surrender_NA,
+ ScoreSemReqSurrender_Post_Count_PlusOne },
+ { 0, 0, 0, 0, ScoreSemReqSurrender_Post_Status_MaxCountExceeded,
+ ScoreSemReqSurrender_Post_Surrender_NA, ScoreSemReqSurrender_Post_Count_Nop }
+};
+
+static const uint8_t
+ScoreSemReqSurrender_Map[] = {
+ 0, 0, 1, 0, 0, 2, 3, 4, 1, 3, 4, 2
+};
+
+static size_t ScoreSemReqSurrender_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreSemReqSurrender_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( ScoreSemReqSurrender_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreSemReqSurrender_Fixture = {
+ .setup = ScoreSemReqSurrender_Setup_Wrap,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = ScoreSemReqSurrender_Scope,
+ .initial_context = &ScoreSemReqSurrender_Instance
+};
+
+static const uint8_t ScoreSemReqSurrender_Weights[] = {
+ 6, 3, 1
+};
+
+static void ScoreSemReqSurrender_Skip(
+ ScoreSemReqSurrender_Context *ctx,
+ size_t index
+)
+{
+ switch ( index + 1 ) {
+ case 1:
+ ctx->Map.pcs[ 1 ] = ScoreSemReqSurrender_Pre_Discipline_NA - 1;
+ /* Fall through */
+ case 2:
+ ctx->Map.pcs[ 2 ] = ScoreSemReqSurrender_Pre_Count_NA - 1;
+ break;
+ }
+}
+
+static inline ScoreSemReqSurrender_Entry ScoreSemReqSurrender_PopEntry(
+ ScoreSemReqSurrender_Context *ctx
+)
+{
+ size_t index;
+
+ if ( ctx->Map.skip ) {
+ size_t i;
+
+ ctx->Map.skip = false;
+ index = 0;
+
+ for ( i = 0; i < 3; ++i ) {
+ index += ScoreSemReqSurrender_Weights[ i ] * ctx->Map.pcs[ i ];
+ }
+ } else {
+ index = ctx->Map.index;
+ }
+
+ ctx->Map.index = index + 1;
+
+ return ScoreSemReqSurrender_Entries[
+ ScoreSemReqSurrender_Map[ index ]
+ ];
+}
+
+static void ScoreSemReqSurrender_TestVariant(
+ ScoreSemReqSurrender_Context *ctx
+)
+{
+ ScoreSemReqSurrender_Pre_Variant_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+
+ if ( ctx->Map.skip ) {
+ ScoreSemReqSurrender_Skip( ctx, 0 );
+ return;
+ }
+
+ ScoreSemReqSurrender_Pre_Discipline_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+
+ if ( ctx->Map.skip ) {
+ ScoreSemReqSurrender_Skip( ctx, 1 );
+ return;
+ }
+
+ ScoreSemReqSurrender_Pre_Count_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ ScoreSemReqSurrender_Action( ctx );
+ ScoreSemReqSurrender_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ ScoreSemReqSurrender_Post_Surrender_Check(
+ ctx,
+ ctx->Map.entry.Post_Surrender
+ );
+ ScoreSemReqSurrender_Post_Count_Check( ctx, ctx->Map.entry.Post_Count );
+}
+
+static T_fixture_node ScoreSemReqSurrender_Node;
+
+static T_remark ScoreSemReqSurrender_Remark = {
+ .next = NULL,
+ .remark = "ScoreSemReqSurrender"
+};
+
+void ScoreSemReqSurrender_Run( TQSemContext *tq_ctx )
+{
+ ScoreSemReqSurrender_Context *ctx;
+
+ ctx = &ScoreSemReqSurrender_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreSemReqSurrender_Node,
+ &ScoreSemReqSurrender_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+ ctx->Map.skip = false;
+
+ for (
+ ctx->Map.pcs[ 0 ] = ScoreSemReqSurrender_Pre_Variant_Binary;
+ ctx->Map.pcs[ 0 ] < ScoreSemReqSurrender_Pre_Variant_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = ScoreSemReqSurrender_Pre_Discipline_FIFO;
+ ctx->Map.pcs[ 1 ] < ScoreSemReqSurrender_Pre_Discipline_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = ScoreSemReqSurrender_Pre_Count_LessMax;
+ ctx->Map.pcs[ 2 ] < ScoreSemReqSurrender_Pre_Count_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ ctx->Map.entry = ScoreSemReqSurrender_PopEntry( ctx );
+ ScoreSemReqSurrender_TestVariant( ctx );
+ }
+ }
+ }
+
+ T_add_remark( &ScoreSemReqSurrender_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-sem-surrender.h b/testsuites/validation/tr-sem-surrender.h
new file mode 100644
index 0000000000..d03fe56b54
--- /dev/null
+++ b/testsuites/validation/tr-sem-surrender.h
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreSemReqSurrender
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_SEM_SURRENDER_H
+#define _TR_SEM_SURRENDER_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreSemReqSurrender
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreSemReqSurrender_Pre_Variant_Binary,
+ ScoreSemReqSurrender_Pre_Variant_Counting,
+ ScoreSemReqSurrender_Pre_Variant_NA
+} ScoreSemReqSurrender_Pre_Variant;
+
+typedef enum {
+ ScoreSemReqSurrender_Pre_Discipline_FIFO,
+ ScoreSemReqSurrender_Pre_Discipline_Priority,
+ ScoreSemReqSurrender_Pre_Discipline_NA
+} ScoreSemReqSurrender_Pre_Discipline;
+
+typedef enum {
+ ScoreSemReqSurrender_Pre_Count_LessMax,
+ ScoreSemReqSurrender_Pre_Count_Max,
+ ScoreSemReqSurrender_Pre_Count_Blocked,
+ ScoreSemReqSurrender_Pre_Count_NA
+} ScoreSemReqSurrender_Pre_Count;
+
+typedef enum {
+ ScoreSemReqSurrender_Post_Status_Ok,
+ ScoreSemReqSurrender_Post_Status_MaxCountExceeded,
+ ScoreSemReqSurrender_Post_Status_NA
+} ScoreSemReqSurrender_Post_Status;
+
+typedef enum {
+ ScoreSemReqSurrender_Post_Surrender_FIFO,
+ ScoreSemReqSurrender_Post_Surrender_Priority,
+ ScoreSemReqSurrender_Post_Surrender_NA
+} ScoreSemReqSurrender_Post_Surrender;
+
+typedef enum {
+ ScoreSemReqSurrender_Post_Count_Zero,
+ ScoreSemReqSurrender_Post_Count_One,
+ ScoreSemReqSurrender_Post_Count_PlusOne,
+ ScoreSemReqSurrender_Post_Count_Nop,
+ ScoreSemReqSurrender_Post_Count_NA
+} ScoreSemReqSurrender_Post_Count;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue context.
+ */
+void ScoreSemReqSurrender_Run( TQSemContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_SEM_SURRENDER_H */
diff --git a/testsuites/validation/tr-signal-constant.c b/testsuites/validation/tr-signal-constant.c
new file mode 100644
index 0000000000..c8aeb463fd
--- /dev/null
+++ b/testsuites/validation/tr-signal-constant.c
@@ -0,0 +1,206 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSignalValSignalConstant
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems.h>
+
+#include "tr-signal-constant.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup RtemsSignalValSignalConstant \
+ * spec:/rtems/signal/val/signal-constant
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @brief Tests a signal constant of the @ref RTEMSAPIClassicSignal using the
+ * signal set of the executing task.
+ *
+ * This test case performs the following actions:
+ *
+ * - Validate the signal constant.
+ *
+ * - Check that the signal constant is equal to the integer representation of
+ * the signal in the signal set.
+ *
+ * - Validate the signal delivery.
+ *
+ * - Check that the caught signal set represents exactly the sent signal.
+ *
+ * @{
+ */
+
+/**
+ * @brief Test context for spec:/rtems/signal/val/signal-constant test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the caught signal set.
+ */
+ rtems_signal_set signal_set;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * RtemsSignalValSignalConstant_Run() parameter.
+ */
+ rtems_signal_set signal;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * RtemsSignalValSignalConstant_Run() parameter.
+ */
+ int number;
+} RtemsSignalValSignalConstant_Context;
+
+static RtemsSignalValSignalConstant_Context
+ RtemsSignalValSignalConstant_Instance;
+
+typedef RtemsSignalValSignalConstant_Context Context;
+
+static void SignalHandler( rtems_signal_set signal_set )
+{
+ Context *ctx;
+
+ ctx = T_fixture_context();
+ ctx->signal_set = signal_set;
+}
+
+static T_fixture RtemsSignalValSignalConstant_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = NULL,
+ .initial_context = &RtemsSignalValSignalConstant_Instance
+};
+
+/**
+ * @brief Validate the signal constant.
+ */
+static void RtemsSignalValSignalConstant_Action_0(
+ RtemsSignalValSignalConstant_Context *ctx
+)
+{
+ /* No action */
+
+ /*
+ * Check that the signal constant is equal to the integer representation of
+ * the signal in the signal set.
+ */
+ T_step_eq_u32(
+ 0,
+ ctx->signal,
+ ( (rtems_signal_set) 1 ) << ctx->number
+ );
+}
+
+/**
+ * @brief Validate the signal delivery.
+ */
+static void RtemsSignalValSignalConstant_Action_1(
+ RtemsSignalValSignalConstant_Context *ctx
+)
+{
+ rtems_status_code sc;
+
+ ctx->signal_set = 0;
+
+ sc = rtems_signal_catch( NULL, RTEMS_DEFAULT_MODES );
+ T_step_rsc_success( 1, sc );
+
+ sc = rtems_signal_catch( SignalHandler, RTEMS_NO_ASR );
+ T_step_rsc_success( 2, sc );
+
+ sc = rtems_signal_send( RTEMS_SELF, ctx->signal );
+ T_step_rsc_success( 3, sc );
+
+ /*
+ * Check that the caught signal set represents exactly the sent signal.
+ */
+ T_step_eq_u32(
+ 4,
+ ctx->signal_set,
+ ctx->signal
+ );
+}
+
+static T_fixture_node RtemsSignalValSignalConstant_Node;
+
+static T_remark RtemsSignalValSignalConstant_Remark = {
+ .next = NULL,
+ .remark = "RtemsSignalValSignalConstant"
+};
+
+void RtemsSignalValSignalConstant_Run( rtems_signal_set signal, int number )
+{
+ RtemsSignalValSignalConstant_Context *ctx;
+
+ ctx = &RtemsSignalValSignalConstant_Instance;
+ ctx->signal = signal;
+ ctx->number = number;
+
+ ctx = T_push_fixture(
+ &RtemsSignalValSignalConstant_Node,
+ &RtemsSignalValSignalConstant_Fixture
+ );
+
+ T_plan( 5 );
+
+ RtemsSignalValSignalConstant_Action_0( ctx );
+ RtemsSignalValSignalConstant_Action_1( ctx );
+
+ T_add_remark( &RtemsSignalValSignalConstant_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-signal-constant.h b/testsuites/validation/tr-signal-constant.h
new file mode 100644
index 0000000000..a957426213
--- /dev/null
+++ b/testsuites/validation/tr-signal-constant.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RtemsSignalValSignalConstant
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_SIGNAL_CONSTANT_H
+#define _TR_SIGNAL_CONSTANT_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup RtemsSignalValSignalConstant
+ *
+ * @{
+ */
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param signal is the signal constant.
+ *
+ * @param number is the signal number.
+ */
+void RtemsSignalValSignalConstant_Run( rtems_signal_set signal, int number );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_SIGNAL_CONSTANT_H */
diff --git a/testsuites/validation/tr-tq-enqueue-ceiling.c b/testsuites/validation/tr-tq-enqueue-ceiling.c
new file mode 100644
index 0000000000..a0b4077689
--- /dev/null
+++ b/testsuites/validation/tr-tq-enqueue-ceiling.c
@@ -0,0 +1,693 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqEnqueueCeiling
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-tq-enqueue-ceiling.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTqReqEnqueueCeiling spec:/score/tq/req/enqueue-ceiling
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_EligibleScheduler_NA : 1;
+ uint8_t Pre_QueueEligible_NA : 1;
+ uint8_t Pre_QueueIneligible_NA : 1;
+ uint8_t Post_Position : 3;
+} ScoreTqReqEnqueueCeiling_Entry;
+
+/**
+ * @brief Test context for spec:/score/tq/req/enqueue-ceiling test case.
+ */
+typedef struct {
+ /**
+ * @brief This this member is true, then the enqueueing thread shall have at
+ * least one helping scheduler.
+ */
+ bool helping;
+
+ /**
+ * @brief This member specifies the priority of a thread with an eligible
+ * scheduler equal to an eligible scheduler of the enqueueing thread.
+ */
+ rtems_task_priority priority;
+
+ /**
+ * @brief If this member is true, then a thread those eligible schedulers are
+ * ineligible scheduler to the enqueueing task should be enqueued before a
+ * thread with an eligible scheduler equal to an eligible scheduler of the
+ * enqueueing thread.
+ */
+ size_t other_before;
+
+ /**
+ * @brief If this member is true, then a thread those eligible schedulers are
+ * ineligible scheduler to the enqueueing task should be enqueued after a
+ * thread with an eligible scheduler equal to an eligible scheduler of the
+ * enqueueing thread.
+ */
+ size_t other_after;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreTqReqEnqueueCeiling_Run() parameter.
+ */
+ TQContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreTqReqEnqueueCeiling_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreTqReqEnqueueCeiling_Context;
+
+static ScoreTqReqEnqueueCeiling_Context
+ ScoreTqReqEnqueueCeiling_Instance;
+
+static const char * const ScoreTqReqEnqueueCeiling_PreDesc_EligibleScheduler[] = {
+ "Home",
+ "Helping",
+ "NA"
+};
+
+static const char * const ScoreTqReqEnqueueCeiling_PreDesc_QueueEligible[] = {
+ "None",
+ "Equal",
+ "Low",
+ "NA"
+};
+
+static const char * const ScoreTqReqEnqueueCeiling_PreDesc_QueueIneligible[] = {
+ "None",
+ "Before",
+ "After",
+ "NA"
+};
+
+static const char * const * const ScoreTqReqEnqueueCeiling_PreDesc[] = {
+ ScoreTqReqEnqueueCeiling_PreDesc_EligibleScheduler,
+ ScoreTqReqEnqueueCeiling_PreDesc_QueueEligible,
+ ScoreTqReqEnqueueCeiling_PreDesc_QueueIneligible,
+ NULL
+};
+
+typedef ScoreTqReqEnqueueCeiling_Context Context;
+
+static const rtems_tcb *GetUnblock( Context *ctx, size_t *index )
+{
+ const rtems_tcb *thread;
+
+ do {
+ thread = TQGetNextUnblock( ctx->tq_ctx, index )->thread;
+ } while ( thread == ctx->tq_ctx->runner_tcb );
+
+ return thread;
+}
+
+static const rtems_tcb *GetTCB( Context *ctx, TQWorkerKind worker )
+{
+ return ctx->tq_ctx->worker_tcb[ worker ];
+}
+
+static void AddHelper( TQContext *tq_ctx, rtems_id scheduler_id )
+{
+ TQSend( tq_ctx, TQ_BLOCKER_C, TQ_EVENT_MUTEX_A_OBTAIN );
+ TQSetScheduler( tq_ctx, TQ_BLOCKER_E, scheduler_id, PRIO_LOW );
+ TQSendAndWaitForExecutionStop(
+ tq_ctx,
+ TQ_BLOCKER_E,
+ TQ_EVENT_MUTEX_A_OBTAIN | TQ_EVENT_MUTEX_A_RELEASE
+ );
+}
+
+static void RemoveHelper( TQContext *tq_ctx )
+{
+ TQSend( tq_ctx, TQ_BLOCKER_C, TQ_EVENT_MUTEX_A_RELEASE );
+ TQMutexObtain( tq_ctx, TQ_MUTEX_A );
+ TQMutexRelease( tq_ctx, TQ_MUTEX_A );
+}
+
+static void ScoreTqReqEnqueueCeiling_Pre_EligibleScheduler_Prepare(
+ ScoreTqReqEnqueueCeiling_Context *ctx,
+ ScoreTqReqEnqueueCeiling_Pre_EligibleScheduler state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueueCeiling_Pre_EligibleScheduler_Home: {
+ /*
+ * While the enqueueing thread has no helping scheduler.
+ */
+ ctx->helping = false;
+ break;
+ }
+
+ case ScoreTqReqEnqueueCeiling_Pre_EligibleScheduler_Helping: {
+ /*
+ * While the enqueueing thread has at least one helping scheduler.
+ */
+ ctx->helping = true;
+ break;
+ }
+
+ case ScoreTqReqEnqueueCeiling_Pre_EligibleScheduler_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueueCeiling_Pre_QueueEligible_Prepare(
+ ScoreTqReqEnqueueCeiling_Context *ctx,
+ ScoreTqReqEnqueueCeiling_Pre_QueueEligible state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueueCeiling_Pre_QueueEligible_None: {
+ /*
+ * While all priority queues of the thread queue associated with eligible
+ * schedulers of the enqueueing thread are empty.
+ */
+ /* This is the default */
+ break;
+ }
+
+ case ScoreTqReqEnqueueCeiling_Pre_QueueEligible_Equal: {
+ /*
+ * While a priority queue of the thread queue associated with an eligible
+ * scheduler of the enqueueing thread is non-empty, while the highest
+ * priority of the priority queue is equal to the priority of the
+ * enqueueing thread with respect to the eligible scheduler.
+ */
+ ctx->priority = PRIO_VERY_HIGH;
+ break;
+ }
+
+ case ScoreTqReqEnqueueCeiling_Pre_QueueEligible_Low: {
+ /*
+ * While a priority queue of the thread queue associated with an eligible
+ * scheduler of the enqueueing thread is non-empty, while the highest
+ * priority of the priority queue is lower than the priority of the
+ * enqueueing thread with respect to the eligible scheduler.
+ */
+ ctx->priority = PRIO_HIGH;
+ break;
+ }
+
+ case ScoreTqReqEnqueueCeiling_Pre_QueueEligible_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueueCeiling_Pre_QueueIneligible_Prepare(
+ ScoreTqReqEnqueueCeiling_Context *ctx,
+ ScoreTqReqEnqueueCeiling_Pre_QueueIneligible state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueueCeiling_Pre_QueueIneligible_None: {
+ /*
+ * While no priority queue of the thread queue exists which is not
+ * associated with an eligible scheduler of the enqueueing thread.
+ */
+ /* This is the default */
+ break;
+ }
+
+ case ScoreTqReqEnqueueCeiling_Pre_QueueIneligible_Before: {
+ /*
+ * While a priority queue of the thread queue exists which is not
+ * associated with an eligible scheduler of the enqueueing thread, while
+ * this priority queue is positioned before all priority queues which are
+ * associated with eligible schedulers of the enqueueing thread.
+ */
+ ctx->other_before = true;
+ break;
+ }
+
+ case ScoreTqReqEnqueueCeiling_Pre_QueueIneligible_After: {
+ /*
+ * While a priority queue of the thread queue exists which is not
+ * associated with an eligible scheduler of the enqueueing thread, while
+ * this priority queue is positioned after all priority queues which are
+ * associated with eligible schedulers of the enqueueing thread.
+ */
+ ctx->other_after = true;
+ break;
+ }
+
+ case ScoreTqReqEnqueueCeiling_Pre_QueueIneligible_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueueCeiling_Post_Position_Check(
+ ScoreTqReqEnqueueCeiling_Context *ctx,
+ ScoreTqReqEnqueueCeiling_Post_Position state
+)
+{
+ size_t i;
+
+ i = 0;
+
+ /* Event receives */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+
+ switch ( state ) {
+ case ScoreTqReqEnqueueCeiling_Post_Position_InitialFirst: {
+ /*
+ * A priority queue associated with the scheduler which contains exactly
+ * the enqueueing thread shall be created as the first priority queue of
+ * the thread queue.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueueCeiling_Post_Position_First: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueueCeiling_Post_Position_Second: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueueCeiling_Post_Position_FirstFirst: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ *
+ * The position of the priority queue in the thread queue shall not
+ * change.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueueCeiling_Post_Position_SecondFirst: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ *
+ * The position of the priority queue in the thread queue shall not
+ * change.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueueCeiling_Post_Position_SecondQueue: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ *
+ * The position of the priority queue in the thread queue shall not
+ * change.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueueCeiling_Post_Position_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueueCeiling_Setup(
+ ScoreTqReqEnqueueCeiling_Context *ctx
+)
+{
+ rtems_id scheduler_id;
+
+ scheduler_id = SCHEDULER_A_ID;
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_A, scheduler_id, PRIO_VERY_HIGH );
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_B, scheduler_id, PRIO_VERY_HIGH );
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_C, scheduler_id, PRIO_VERY_HIGH );
+ #if defined( RTEMS_SMP )
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_D, SCHEDULER_B_ID, PRIO_LOW );
+ #endif
+}
+
+static void ScoreTqReqEnqueueCeiling_Setup_Wrap( void *arg )
+{
+ ScoreTqReqEnqueueCeiling_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqEnqueueCeiling_Setup( ctx );
+}
+
+static void ScoreTqReqEnqueueCeiling_Teardown(
+ ScoreTqReqEnqueueCeiling_Context *ctx
+)
+{
+ TQReset( ctx->tq_ctx );
+}
+
+static void ScoreTqReqEnqueueCeiling_Teardown_Wrap( void *arg )
+{
+ ScoreTqReqEnqueueCeiling_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqEnqueueCeiling_Teardown( ctx );
+}
+
+static void ScoreTqReqEnqueueCeiling_Prepare(
+ ScoreTqReqEnqueueCeiling_Context *ctx
+)
+{
+ ctx->priority = PRIO_PSEUDO_ISR;
+ ctx->other_before = false;
+ ctx->other_after = false;
+}
+
+static void ScoreTqReqEnqueueCeiling_Action(
+ ScoreTqReqEnqueueCeiling_Context *ctx
+)
+{
+ Status_Control status;
+
+ if ( ctx->priority == PRIO_PSEUDO_ISR ) {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
+ } else {
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_B , ctx->priority );
+
+ if ( ctx->other_before || ctx->other_after ) {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_B, TQ_EVENT_MUTEX_B_OBTAIN );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_BLOCKER_D,
+ TQ_EVENT_MUTEX_B_OBTAIN | TQ_EVENT_MUTEX_B_RELEASE |
+ TQ_EVENT_RUNNER_SYNC
+ );
+
+ if ( ctx->other_before ) {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_C, TQ_EVENT_ENQUEUE );
+ }
+
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
+ TQSend(
+ ctx->tq_ctx,
+ TQ_BLOCKER_B,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
+ );
+
+ if ( ctx->other_before ) {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_C, TQ_EVENT_SURRENDER );
+ }
+ } else {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
+ TQSend(
+ ctx->tq_ctx,
+ TQ_BLOCKER_B,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
+ );
+ }
+ }
+
+ if ( ctx->helping ) {
+ if ( ctx->other_before || ctx->other_after ) {
+ if ( rtems_scheduler_get_processor_maximum() > 2 ) {
+ AddHelper( ctx->tq_ctx, SCHEDULER_C_ID );
+ }
+ } else {
+ AddHelper( ctx->tq_ctx, SCHEDULER_B_ID );
+ }
+ }
+
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_C, TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_SURRENDER );
+ status = TQEnqueue( ctx->tq_ctx, TQ_WAIT_FOREVER );
+ T_eq_int( status, TQConvertStatus( ctx->tq_ctx, STATUS_SUCCESSFUL ) );
+ TQSchedulerRecordStop( ctx->tq_ctx );
+ status = TQSurrender( ctx->tq_ctx );
+ T_eq_int( status, TQConvertStatus( ctx->tq_ctx, STATUS_SUCCESSFUL ) );
+
+ if (
+ ctx->priority != PRIO_PSEUDO_ISR &&
+ ( ctx->other_before || ctx->other_after )
+ ) {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_B, TQ_EVENT_MUTEX_B_RELEASE );
+ TQSynchronizeRunner();
+ }
+
+ if ( ctx->helping ) {
+ if ( ctx->other_before || ctx->other_after ) {
+ if ( rtems_scheduler_get_processor_maximum() > 2 ) {
+ RemoveHelper( ctx->tq_ctx );
+ }
+ } else {
+ RemoveHelper( ctx->tq_ctx );
+ }
+ }
+}
+
+static const ScoreTqReqEnqueueCeiling_Entry
+ScoreTqReqEnqueueCeiling_Entries[] = {
+ { 1, 0, 0, 0, ScoreTqReqEnqueueCeiling_Post_Position_NA },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, ScoreTqReqEnqueueCeiling_Post_Position_SecondQueue },
+#else
+ { 1, 0, 0, 0, ScoreTqReqEnqueueCeiling_Post_Position_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, ScoreTqReqEnqueueCeiling_Post_Position_SecondFirst },
+#else
+ { 1, 0, 0, 0, ScoreTqReqEnqueueCeiling_Post_Position_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, ScoreTqReqEnqueueCeiling_Post_Position_FirstFirst },
+#else
+ { 1, 0, 0, 0, ScoreTqReqEnqueueCeiling_Post_Position_NA },
+#endif
+ { 0, 0, 0, 0, ScoreTqReqEnqueueCeiling_Post_Position_InitialFirst },
+ { 0, 0, 0, 0, ScoreTqReqEnqueueCeiling_Post_Position_Second },
+ { 0, 0, 0, 0, ScoreTqReqEnqueueCeiling_Post_Position_First },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, ScoreTqReqEnqueueCeiling_Post_Position_InitialFirst },
+#else
+ { 1, 0, 0, 0, ScoreTqReqEnqueueCeiling_Post_Position_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, ScoreTqReqEnqueueCeiling_Post_Position_Second },
+#else
+ { 1, 0, 0, 0, ScoreTqReqEnqueueCeiling_Post_Position_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, ScoreTqReqEnqueueCeiling_Post_Position_First }
+#else
+ { 1, 0, 0, 0, ScoreTqReqEnqueueCeiling_Post_Position_NA }
+#endif
+};
+
+static const uint8_t
+ScoreTqReqEnqueueCeiling_Map[] = {
+ 4, 0, 0, 5, 1, 2, 6, 1, 3, 7, 0, 0, 8, 1, 2, 9, 1, 3
+};
+
+static size_t ScoreTqReqEnqueueCeiling_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreTqReqEnqueueCeiling_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ ScoreTqReqEnqueueCeiling_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreTqReqEnqueueCeiling_Fixture = {
+ .setup = ScoreTqReqEnqueueCeiling_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreTqReqEnqueueCeiling_Teardown_Wrap,
+ .scope = ScoreTqReqEnqueueCeiling_Scope,
+ .initial_context = &ScoreTqReqEnqueueCeiling_Instance
+};
+
+static inline ScoreTqReqEnqueueCeiling_Entry ScoreTqReqEnqueueCeiling_PopEntry(
+ ScoreTqReqEnqueueCeiling_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return ScoreTqReqEnqueueCeiling_Entries[
+ ScoreTqReqEnqueueCeiling_Map[ index ]
+ ];
+}
+
+static void ScoreTqReqEnqueueCeiling_TestVariant(
+ ScoreTqReqEnqueueCeiling_Context *ctx
+)
+{
+ ScoreTqReqEnqueueCeiling_Pre_EligibleScheduler_Prepare(
+ ctx,
+ ctx->Map.pcs[ 0 ]
+ );
+ ScoreTqReqEnqueueCeiling_Pre_QueueEligible_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ ScoreTqReqEnqueueCeiling_Pre_QueueIneligible_Prepare(
+ ctx,
+ ctx->Map.pcs[ 2 ]
+ );
+ ScoreTqReqEnqueueCeiling_Action( ctx );
+ ScoreTqReqEnqueueCeiling_Post_Position_Check(
+ ctx,
+ ctx->Map.entry.Post_Position
+ );
+}
+
+static T_fixture_node ScoreTqReqEnqueueCeiling_Node;
+
+static T_remark ScoreTqReqEnqueueCeiling_Remark = {
+ .next = NULL,
+ .remark = "ScoreTqReqEnqueueCeiling"
+};
+
+void ScoreTqReqEnqueueCeiling_Run( TQContext *tq_ctx )
+{
+ ScoreTqReqEnqueueCeiling_Context *ctx;
+
+ ctx = &ScoreTqReqEnqueueCeiling_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreTqReqEnqueueCeiling_Node,
+ &ScoreTqReqEnqueueCeiling_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = ScoreTqReqEnqueueCeiling_Pre_EligibleScheduler_Home;
+ ctx->Map.pcs[ 0 ] < ScoreTqReqEnqueueCeiling_Pre_EligibleScheduler_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = ScoreTqReqEnqueueCeiling_Pre_QueueEligible_None;
+ ctx->Map.pcs[ 1 ] < ScoreTqReqEnqueueCeiling_Pre_QueueEligible_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = ScoreTqReqEnqueueCeiling_Pre_QueueIneligible_None;
+ ctx->Map.pcs[ 2 ] < ScoreTqReqEnqueueCeiling_Pre_QueueIneligible_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ ctx->Map.entry = ScoreTqReqEnqueueCeiling_PopEntry( ctx );
+ ScoreTqReqEnqueueCeiling_Prepare( ctx );
+ ScoreTqReqEnqueueCeiling_TestVariant( ctx );
+ }
+ }
+ }
+
+ T_add_remark( &ScoreTqReqEnqueueCeiling_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-tq-enqueue-ceiling.h b/testsuites/validation/tr-tq-enqueue-ceiling.h
new file mode 100644
index 0000000000..3f61865791
--- /dev/null
+++ b/testsuites/validation/tr-tq-enqueue-ceiling.h
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqEnqueueCeiling
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_TQ_ENQUEUE_CEILING_H
+#define _TR_TQ_ENQUEUE_CEILING_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreTqReqEnqueueCeiling
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreTqReqEnqueueCeiling_Pre_EligibleScheduler_Home,
+ ScoreTqReqEnqueueCeiling_Pre_EligibleScheduler_Helping,
+ ScoreTqReqEnqueueCeiling_Pre_EligibleScheduler_NA
+} ScoreTqReqEnqueueCeiling_Pre_EligibleScheduler;
+
+typedef enum {
+ ScoreTqReqEnqueueCeiling_Pre_QueueEligible_None,
+ ScoreTqReqEnqueueCeiling_Pre_QueueEligible_Equal,
+ ScoreTqReqEnqueueCeiling_Pre_QueueEligible_Low,
+ ScoreTqReqEnqueueCeiling_Pre_QueueEligible_NA
+} ScoreTqReqEnqueueCeiling_Pre_QueueEligible;
+
+typedef enum {
+ ScoreTqReqEnqueueCeiling_Pre_QueueIneligible_None,
+ ScoreTqReqEnqueueCeiling_Pre_QueueIneligible_Before,
+ ScoreTqReqEnqueueCeiling_Pre_QueueIneligible_After,
+ ScoreTqReqEnqueueCeiling_Pre_QueueIneligible_NA
+} ScoreTqReqEnqueueCeiling_Pre_QueueIneligible;
+
+typedef enum {
+ ScoreTqReqEnqueueCeiling_Post_Position_InitialFirst,
+ ScoreTqReqEnqueueCeiling_Post_Position_First,
+ ScoreTqReqEnqueueCeiling_Post_Position_Second,
+ ScoreTqReqEnqueueCeiling_Post_Position_FirstFirst,
+ ScoreTqReqEnqueueCeiling_Post_Position_SecondFirst,
+ ScoreTqReqEnqueueCeiling_Post_Position_SecondQueue,
+ ScoreTqReqEnqueueCeiling_Post_Position_NA
+} ScoreTqReqEnqueueCeiling_Post_Position;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue context.
+ */
+void ScoreTqReqEnqueueCeiling_Run( TQContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_TQ_ENQUEUE_CEILING_H */
diff --git a/testsuites/validation/tr-tq-enqueue-deadlock.c b/testsuites/validation/tr-tq-enqueue-deadlock.c
new file mode 100644
index 0000000000..7f61cbc444
--- /dev/null
+++ b/testsuites/validation/tr-tq-enqueue-deadlock.c
@@ -0,0 +1,447 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqEnqueueDeadlock
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-tq-enqueue-deadlock.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTqReqEnqueueDeadlock spec:/score/tq/req/enqueue-deadlock
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Notification_NA : 1;
+ uint8_t Pre_Deadlock_NA : 1;
+ uint8_t Post_Result : 2;
+} ScoreTqReqEnqueueDeadlock_Entry;
+
+/**
+ * @brief Test context for spec:/score/tq/req/enqueue-deadlock test case.
+ */
+typedef struct {
+ /**
+ * @brief If this member is true, then more than one mutex shall be used for
+ * the deadlock scenario.
+ */
+ bool more;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreTqReqEnqueueDeadlock_Run() parameter.
+ */
+ TQContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreTqReqEnqueueDeadlock_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreTqReqEnqueueDeadlock_Context;
+
+static ScoreTqReqEnqueueDeadlock_Context
+ ScoreTqReqEnqueueDeadlock_Instance;
+
+static const char * const ScoreTqReqEnqueueDeadlock_PreDesc_Notification[] = {
+ "Status",
+ "Fatal",
+ "NA"
+};
+
+static const char * const ScoreTqReqEnqueueDeadlock_PreDesc_Deadlock[] = {
+ "One",
+ "More",
+ "NA"
+};
+
+static const char * const * const ScoreTqReqEnqueueDeadlock_PreDesc[] = {
+ ScoreTqReqEnqueueDeadlock_PreDesc_Notification,
+ ScoreTqReqEnqueueDeadlock_PreDesc_Deadlock,
+ NULL
+};
+
+static void ScoreTqReqEnqueueDeadlock_Pre_Notification_Prepare(
+ ScoreTqReqEnqueueDeadlock_Context *ctx,
+ ScoreTqReqEnqueueDeadlock_Pre_Notification state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueueDeadlock_Pre_Notification_Status: {
+ /*
+ * Where a detected deadlock results in a return with a status code.
+ */
+ if ( ctx->tq_ctx->deadlock != TQ_DEADLOCK_STATUS ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreTqReqEnqueueDeadlock_Pre_Notification_Fatal: {
+ /*
+ * Where a detected deadlock results in a fatal error.
+ */
+ if ( ctx->tq_ctx->deadlock != TQ_DEADLOCK_FATAL ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreTqReqEnqueueDeadlock_Pre_Notification_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueueDeadlock_Pre_Deadlock_Prepare(
+ ScoreTqReqEnqueueDeadlock_Context *ctx,
+ ScoreTqReqEnqueueDeadlock_Pre_Deadlock state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueueDeadlock_Pre_Deadlock_One: {
+ /*
+ * While the owner of the thread queue is enqueued on another thread
+ * queue owned by the calling thread.
+ */
+ ctx->more = false;
+ break;
+ }
+
+ case ScoreTqReqEnqueueDeadlock_Pre_Deadlock_More: {
+ /*
+ * While the owner of the thread queue is enqueued on another thread
+ * queue owned by a thread other than the calling thread, and so on,
+ * while the owner of the last thread queue of this dependency chain is
+ * enqueued on a thread queue owned by the calling thread.
+ */
+ ctx->more = true;
+ break;
+ }
+
+ case ScoreTqReqEnqueueDeadlock_Pre_Deadlock_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueueDeadlock_Post_Result_Check(
+ ScoreTqReqEnqueueDeadlock_Context *ctx,
+ ScoreTqReqEnqueueDeadlock_Post_Result state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueueDeadlock_Post_Result_Status: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_DEADLOCK.
+ */
+ /* Checked by action */
+ break;
+ }
+
+ case ScoreTqReqEnqueueDeadlock_Post_Result_Fatal: {
+ /*
+ * The system shall terminate with the INTERNAL_ERROR_CORE fatal source
+ * and the INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK fatal code.
+ */
+ /* Checked by action */
+ break;
+ }
+
+ case ScoreTqReqEnqueueDeadlock_Post_Result_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueueDeadlock_Action(
+ ScoreTqReqEnqueueDeadlock_Context *ctx
+)
+{
+ Status_Control status;
+
+ if ( ctx->tq_ctx->enqueue_variant == TQ_ENQUEUE_STICKY ) {
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_A, SCHEDULER_B_ID, PRIO_NORMAL );
+ } else {
+ TQSetScheduler(
+ ctx->tq_ctx,
+ TQ_BLOCKER_A,
+ SCHEDULER_A_ID,
+ PRIO_VERY_HIGH
+ );
+ }
+
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_B, SCHEDULER_A_ID, PRIO_HIGH );
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_C, SCHEDULER_A_ID, PRIO_HIGH );
+
+ TQSortMutexesByID( ctx->tq_ctx );
+ TQMutexObtain( ctx->tq_ctx, TQ_MUTEX_C );
+ TQSendAndWaitForExecutionStop( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
+
+ if ( ctx->more ) {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_B, TQ_EVENT_MUTEX_A_OBTAIN );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_B, TQ_EVENT_MUTEX_C_OBTAIN );
+ Yield();
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_C, TQ_EVENT_MUTEX_B_OBTAIN );
+ Yield();
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_C, TQ_EVENT_MUTEX_A_OBTAIN );
+ Yield();
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_BLOCKER_A,
+ TQ_EVENT_MUTEX_B_OBTAIN
+ );
+ } else {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_BLOCKER_A,
+ TQ_EVENT_MUTEX_C_OBTAIN
+ );
+ }
+
+ if ( ctx->tq_ctx->deadlock == TQ_DEADLOCK_FATAL ) {
+ status = TQEnqueueFatal( ctx->tq_ctx );
+ T_eq_int( status, STATUS_DEADLOCK );
+ } else {
+ status = TQEnqueue( ctx->tq_ctx, TQ_WAIT_FOREVER );
+ T_eq_int( status, TQConvertStatus( ctx->tq_ctx, STATUS_DEADLOCK ) );
+ }
+
+ TQMutexRelease( ctx->tq_ctx, TQ_MUTEX_C );
+
+ if ( ctx->more ) {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_B, TQ_EVENT_MUTEX_C_RELEASE );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_B, TQ_EVENT_MUTEX_A_RELEASE );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_C, TQ_EVENT_MUTEX_A_RELEASE );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_C, TQ_EVENT_MUTEX_B_RELEASE );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_MUTEX_B_RELEASE );
+ } else {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_MUTEX_C_RELEASE );
+ }
+
+ if ( ctx->tq_ctx->enqueue_variant == TQ_ENQUEUE_STICKY ) {
+ TQSend(
+ ctx->tq_ctx,
+ TQ_BLOCKER_A,
+ TQ_EVENT_SURRENDER | TQ_EVENT_RUNNER_SYNC
+ );
+ TQSynchronizeRunner();
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_A, SCHEDULER_A_ID, PRIO_HIGH );
+ } else {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_SURRENDER );
+ }
+}
+
+static const ScoreTqReqEnqueueDeadlock_Entry
+ScoreTqReqEnqueueDeadlock_Entries[] = {
+ { 0, 0, 0, ScoreTqReqEnqueueDeadlock_Post_Result_Status },
+ { 0, 0, 0, ScoreTqReqEnqueueDeadlock_Post_Result_Fatal }
+};
+
+static const uint8_t
+ScoreTqReqEnqueueDeadlock_Map[] = {
+ 0, 0, 1, 1
+};
+
+static size_t ScoreTqReqEnqueueDeadlock_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreTqReqEnqueueDeadlock_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ ScoreTqReqEnqueueDeadlock_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreTqReqEnqueueDeadlock_Fixture = {
+ .setup = NULL,
+ .stop = NULL,
+ .teardown = NULL,
+ .scope = ScoreTqReqEnqueueDeadlock_Scope,
+ .initial_context = &ScoreTqReqEnqueueDeadlock_Instance
+};
+
+static const uint8_t ScoreTqReqEnqueueDeadlock_Weights[] = {
+ 2, 1
+};
+
+static void ScoreTqReqEnqueueDeadlock_Skip(
+ ScoreTqReqEnqueueDeadlock_Context *ctx,
+ size_t index
+)
+{
+ switch ( index + 1 ) {
+ case 1:
+ ctx->Map.pcs[ 1 ] = ScoreTqReqEnqueueDeadlock_Pre_Deadlock_NA - 1;
+ break;
+ }
+}
+
+static inline ScoreTqReqEnqueueDeadlock_Entry
+ScoreTqReqEnqueueDeadlock_PopEntry( ScoreTqReqEnqueueDeadlock_Context *ctx )
+{
+ size_t index;
+
+ if ( ctx->Map.skip ) {
+ size_t i;
+
+ ctx->Map.skip = false;
+ index = 0;
+
+ for ( i = 0; i < 2; ++i ) {
+ index += ScoreTqReqEnqueueDeadlock_Weights[ i ] * ctx->Map.pcs[ i ];
+ }
+ } else {
+ index = ctx->Map.index;
+ }
+
+ ctx->Map.index = index + 1;
+
+ return ScoreTqReqEnqueueDeadlock_Entries[
+ ScoreTqReqEnqueueDeadlock_Map[ index ]
+ ];
+}
+
+static void ScoreTqReqEnqueueDeadlock_TestVariant(
+ ScoreTqReqEnqueueDeadlock_Context *ctx
+)
+{
+ ScoreTqReqEnqueueDeadlock_Pre_Notification_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+
+ if ( ctx->Map.skip ) {
+ ScoreTqReqEnqueueDeadlock_Skip( ctx, 0 );
+ return;
+ }
+
+ ScoreTqReqEnqueueDeadlock_Pre_Deadlock_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ ScoreTqReqEnqueueDeadlock_Action( ctx );
+ ScoreTqReqEnqueueDeadlock_Post_Result_Check(
+ ctx,
+ ctx->Map.entry.Post_Result
+ );
+}
+
+static T_fixture_node ScoreTqReqEnqueueDeadlock_Node;
+
+static T_remark ScoreTqReqEnqueueDeadlock_Remark = {
+ .next = NULL,
+ .remark = "ScoreTqReqEnqueueDeadlock"
+};
+
+void ScoreTqReqEnqueueDeadlock_Run( TQContext *tq_ctx )
+{
+ ScoreTqReqEnqueueDeadlock_Context *ctx;
+
+ ctx = &ScoreTqReqEnqueueDeadlock_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreTqReqEnqueueDeadlock_Node,
+ &ScoreTqReqEnqueueDeadlock_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+ ctx->Map.skip = false;
+
+ for (
+ ctx->Map.pcs[ 0 ] = ScoreTqReqEnqueueDeadlock_Pre_Notification_Status;
+ ctx->Map.pcs[ 0 ] < ScoreTqReqEnqueueDeadlock_Pre_Notification_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = ScoreTqReqEnqueueDeadlock_Pre_Deadlock_One;
+ ctx->Map.pcs[ 1 ] < ScoreTqReqEnqueueDeadlock_Pre_Deadlock_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ ctx->Map.entry = ScoreTqReqEnqueueDeadlock_PopEntry( ctx );
+ ScoreTqReqEnqueueDeadlock_TestVariant( ctx );
+ }
+ }
+
+ T_add_remark( &ScoreTqReqEnqueueDeadlock_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-tq-enqueue-deadlock.h b/testsuites/validation/tr-tq-enqueue-deadlock.h
new file mode 100644
index 0000000000..1fe580a19c
--- /dev/null
+++ b/testsuites/validation/tr-tq-enqueue-deadlock.h
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqEnqueueDeadlock
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_TQ_ENQUEUE_DEADLOCK_H
+#define _TR_TQ_ENQUEUE_DEADLOCK_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreTqReqEnqueueDeadlock
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreTqReqEnqueueDeadlock_Pre_Notification_Status,
+ ScoreTqReqEnqueueDeadlock_Pre_Notification_Fatal,
+ ScoreTqReqEnqueueDeadlock_Pre_Notification_NA
+} ScoreTqReqEnqueueDeadlock_Pre_Notification;
+
+typedef enum {
+ ScoreTqReqEnqueueDeadlock_Pre_Deadlock_One,
+ ScoreTqReqEnqueueDeadlock_Pre_Deadlock_More,
+ ScoreTqReqEnqueueDeadlock_Pre_Deadlock_NA
+} ScoreTqReqEnqueueDeadlock_Pre_Deadlock;
+
+typedef enum {
+ ScoreTqReqEnqueueDeadlock_Post_Result_Status,
+ ScoreTqReqEnqueueDeadlock_Post_Result_Fatal,
+ ScoreTqReqEnqueueDeadlock_Post_Result_NA
+} ScoreTqReqEnqueueDeadlock_Post_Result;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue context.
+ */
+void ScoreTqReqEnqueueDeadlock_Run( TQContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_TQ_ENQUEUE_DEADLOCK_H */
diff --git a/testsuites/validation/tr-tq-enqueue-fifo.c b/testsuites/validation/tr-tq-enqueue-fifo.c
new file mode 100644
index 0000000000..27ac064797
--- /dev/null
+++ b/testsuites/validation/tr-tq-enqueue-fifo.c
@@ -0,0 +1,340 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqEnqueueFifo
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-tq-enqueue-fifo.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTqReqEnqueueFifo spec:/score/tq/req/enqueue-fifo
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Queue_NA : 1;
+ uint8_t Post_Position : 2;
+} ScoreTqReqEnqueueFifo_Entry;
+
+/**
+ * @brief Test context for spec:/score/tq/req/enqueue-fifo test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreTqReqEnqueueFifo_Run() parameter.
+ */
+ TQContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreTqReqEnqueueFifo_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreTqReqEnqueueFifo_Context;
+
+static ScoreTqReqEnqueueFifo_Context
+ ScoreTqReqEnqueueFifo_Instance;
+
+static const char * const ScoreTqReqEnqueueFifo_PreDesc_Queue[] = {
+ "Empty",
+ "NonEmpty",
+ "NA"
+};
+
+static const char * const * const ScoreTqReqEnqueueFifo_PreDesc[] = {
+ ScoreTqReqEnqueueFifo_PreDesc_Queue,
+ NULL
+};
+
+typedef ScoreTqReqEnqueueFifo_Context Context;
+
+static const rtems_tcb *GetUnblock( Context *ctx, size_t *index )
+{
+ return TQGetNextUnblock( ctx->tq_ctx, index )->thread;
+}
+
+static const rtems_tcb *GetTCB( Context *ctx, TQWorkerKind worker )
+{
+ return ctx->tq_ctx->worker_tcb[ worker ];
+}
+
+static void ScoreTqReqEnqueueFifo_Pre_Queue_Prepare(
+ ScoreTqReqEnqueueFifo_Context *ctx,
+ ScoreTqReqEnqueueFifo_Pre_Queue state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueueFifo_Pre_Queue_Empty: {
+ /*
+ * While the queue is empty.
+ */
+ ctx->tq_ctx->how_many = 1;
+ break;
+ }
+
+ case ScoreTqReqEnqueueFifo_Pre_Queue_NonEmpty: {
+ /*
+ * While the queue is non-empty.
+ */
+ ctx->tq_ctx->how_many = 2;
+ break;
+ }
+
+ case ScoreTqReqEnqueueFifo_Pre_Queue_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueueFifo_Post_Position_Check(
+ ScoreTqReqEnqueueFifo_Context *ctx,
+ ScoreTqReqEnqueueFifo_Post_Position state
+)
+{
+ size_t i;
+
+ i = 0;
+
+ /* Event receives */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+
+ switch ( state ) {
+ case ScoreTqReqEnqueueFifo_Post_Position_First: {
+ /*
+ * The thread shall be the first thread in the queue.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueueFifo_Post_Position_Last: {
+ /*
+ * The thread shall be the last thread in the queue.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueueFifo_Post_Position_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueueFifo_Setup( ScoreTqReqEnqueueFifo_Context *ctx )
+{
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_A, PRIO_HIGH );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_B, PRIO_VERY_HIGH );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_C, PRIO_ULTRA_HIGH );
+}
+
+static void ScoreTqReqEnqueueFifo_Setup_Wrap( void *arg )
+{
+ ScoreTqReqEnqueueFifo_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqEnqueueFifo_Setup( ctx );
+}
+
+static void ScoreTqReqEnqueueFifo_Teardown(
+ ScoreTqReqEnqueueFifo_Context *ctx
+)
+{
+ TQReset( ctx->tq_ctx );
+}
+
+static void ScoreTqReqEnqueueFifo_Teardown_Wrap( void *arg )
+{
+ ScoreTqReqEnqueueFifo_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqEnqueueFifo_Teardown( ctx );
+}
+
+static void ScoreTqReqEnqueueFifo_Action( ScoreTqReqEnqueueFifo_Context *ctx )
+{
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE_PREPARE );
+
+ if ( ctx->tq_ctx->how_many >= 2 ) {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_B, TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER );
+ }
+
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_C, TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE_DONE );
+ TQSchedulerRecordStop( ctx->tq_ctx );
+}
+
+static const ScoreTqReqEnqueueFifo_Entry
+ScoreTqReqEnqueueFifo_Entries[] = {
+ { 0, 0, ScoreTqReqEnqueueFifo_Post_Position_First },
+ { 0, 0, ScoreTqReqEnqueueFifo_Post_Position_Last }
+};
+
+static const uint8_t
+ScoreTqReqEnqueueFifo_Map[] = {
+ 0, 1
+};
+
+static size_t ScoreTqReqEnqueueFifo_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreTqReqEnqueueFifo_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( ScoreTqReqEnqueueFifo_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreTqReqEnqueueFifo_Fixture = {
+ .setup = ScoreTqReqEnqueueFifo_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreTqReqEnqueueFifo_Teardown_Wrap,
+ .scope = ScoreTqReqEnqueueFifo_Scope,
+ .initial_context = &ScoreTqReqEnqueueFifo_Instance
+};
+
+static inline ScoreTqReqEnqueueFifo_Entry ScoreTqReqEnqueueFifo_PopEntry(
+ ScoreTqReqEnqueueFifo_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return ScoreTqReqEnqueueFifo_Entries[
+ ScoreTqReqEnqueueFifo_Map[ index ]
+ ];
+}
+
+static void ScoreTqReqEnqueueFifo_TestVariant(
+ ScoreTqReqEnqueueFifo_Context *ctx
+)
+{
+ ScoreTqReqEnqueueFifo_Pre_Queue_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ ScoreTqReqEnqueueFifo_Action( ctx );
+ ScoreTqReqEnqueueFifo_Post_Position_Check(
+ ctx,
+ ctx->Map.entry.Post_Position
+ );
+}
+
+static T_fixture_node ScoreTqReqEnqueueFifo_Node;
+
+static T_remark ScoreTqReqEnqueueFifo_Remark = {
+ .next = NULL,
+ .remark = "ScoreTqReqEnqueueFifo"
+};
+
+void ScoreTqReqEnqueueFifo_Run( TQContext *tq_ctx )
+{
+ ScoreTqReqEnqueueFifo_Context *ctx;
+
+ ctx = &ScoreTqReqEnqueueFifo_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreTqReqEnqueueFifo_Node,
+ &ScoreTqReqEnqueueFifo_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = ScoreTqReqEnqueueFifo_Pre_Queue_Empty;
+ ctx->Map.pcs[ 0 ] < ScoreTqReqEnqueueFifo_Pre_Queue_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = ScoreTqReqEnqueueFifo_PopEntry( ctx );
+ ScoreTqReqEnqueueFifo_TestVariant( ctx );
+ }
+
+ T_add_remark( &ScoreTqReqEnqueueFifo_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-tq-enqueue-fifo.h b/testsuites/validation/tr-tq-enqueue-fifo.h
new file mode 100644
index 0000000000..16a37ecf2b
--- /dev/null
+++ b/testsuites/validation/tr-tq-enqueue-fifo.h
@@ -0,0 +1,91 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqEnqueueFifo
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_TQ_ENQUEUE_FIFO_H
+#define _TR_TQ_ENQUEUE_FIFO_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreTqReqEnqueueFifo
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreTqReqEnqueueFifo_Pre_Queue_Empty,
+ ScoreTqReqEnqueueFifo_Pre_Queue_NonEmpty,
+ ScoreTqReqEnqueueFifo_Pre_Queue_NA
+} ScoreTqReqEnqueueFifo_Pre_Queue;
+
+typedef enum {
+ ScoreTqReqEnqueueFifo_Post_Position_First,
+ ScoreTqReqEnqueueFifo_Post_Position_Last,
+ ScoreTqReqEnqueueFifo_Post_Position_NA
+} ScoreTqReqEnqueueFifo_Post_Position;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue test context.
+ */
+void ScoreTqReqEnqueueFifo_Run( TQContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_TQ_ENQUEUE_FIFO_H */
diff --git a/testsuites/validation/tr-tq-enqueue-mrsp.c b/testsuites/validation/tr-tq-enqueue-mrsp.c
new file mode 100644
index 0000000000..14f1f17713
--- /dev/null
+++ b/testsuites/validation/tr-tq-enqueue-mrsp.c
@@ -0,0 +1,658 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqEnqueueMrsp
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-tq-enqueue-mrsp.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTqReqEnqueueMrsp spec:/score/tq/req/enqueue-mrsp
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_EligibleScheduler_NA : 1;
+ uint8_t Pre_QueueEligible_NA : 1;
+ uint8_t Pre_QueueIneligible_NA : 1;
+ uint8_t Post_Position : 3;
+} ScoreTqReqEnqueueMrsp_Entry;
+
+/**
+ * @brief Test context for spec:/score/tq/req/enqueue-mrsp test case.
+ */
+typedef struct {
+ /**
+ * @brief This this member is true, then the enqueueing thread shall have at
+ * least one helping scheduler which is an ineligible scheduler for the
+ * already enqueued threads.
+ */
+ bool helping;
+
+ /**
+ * @brief This member specifies the priority of an already enqueued thread
+ * with an eligible scheduler equal to an eligible scheduler of the
+ * enqueueing thread.
+ */
+ rtems_task_priority priority;
+
+ /**
+ * @brief If this member is true, then a thread those eligible schedulers are
+ * ineligible scheduler to the enqueueing task should be enqueued before a
+ * thread with an eligible scheduler equal to an eligible scheduler of the
+ * enqueueing thread.
+ */
+ size_t other_before;
+
+ /**
+ * @brief If this member is true, then a thread those eligible schedulers are
+ * ineligible scheduler to the enqueueing task should be enqueued after a
+ * thread with an eligible scheduler equal to an eligible scheduler of the
+ * enqueueing thread.
+ */
+ size_t other_after;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreTqReqEnqueueMrsp_Run() parameter.
+ */
+ TQContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreTqReqEnqueueMrsp_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreTqReqEnqueueMrsp_Context;
+
+static ScoreTqReqEnqueueMrsp_Context
+ ScoreTqReqEnqueueMrsp_Instance;
+
+static const char * const ScoreTqReqEnqueueMrsp_PreDesc_EligibleScheduler[] = {
+ "Home",
+ "Helping",
+ "NA"
+};
+
+static const char * const ScoreTqReqEnqueueMrsp_PreDesc_QueueEligible[] = {
+ "None",
+ "Equal",
+ "Low",
+ "NA"
+};
+
+static const char * const ScoreTqReqEnqueueMrsp_PreDesc_QueueIneligible[] = {
+ "None",
+ "Only",
+ "Before",
+ "After",
+ "NA"
+};
+
+static const char * const * const ScoreTqReqEnqueueMrsp_PreDesc[] = {
+ ScoreTqReqEnqueueMrsp_PreDesc_EligibleScheduler,
+ ScoreTqReqEnqueueMrsp_PreDesc_QueueEligible,
+ ScoreTqReqEnqueueMrsp_PreDesc_QueueIneligible,
+ NULL
+};
+
+/*
+ * The MrsP locking protocol uses a sticky thread queue enqueue. This means
+ * that threads waiting for the mutex ownership perform a busy wait and thus
+ * occupy the processor. For a full validation we need at least four
+ * processors.
+ */
+static bool CanDoFullValidation( void )
+{
+ return rtems_scheduler_get_processor_maximum() >= 4;
+}
+
+static void ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_Prepare(
+ ScoreTqReqEnqueueMrsp_Context *ctx,
+ ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_Home: {
+ /*
+ * While the enqueueing thread has no helping scheduler.
+ */
+ ctx->helping = false;
+ break;
+ }
+
+ case ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_Helping: {
+ /*
+ * While the enqueueing thread has at least one helping scheduler.
+ */
+ ctx->helping = true;
+ break;
+ }
+
+ case ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueueMrsp_Pre_QueueEligible_Prepare(
+ ScoreTqReqEnqueueMrsp_Context *ctx,
+ ScoreTqReqEnqueueMrsp_Pre_QueueEligible state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueueMrsp_Pre_QueueEligible_None: {
+ /*
+ * While all priority queues of the thread queue associated with eligible
+ * schedulers of the enqueueing thread are empty.
+ */
+ ctx->priority = PRIO_PSEUDO_ISR;
+ break;
+ }
+
+ case ScoreTqReqEnqueueMrsp_Pre_QueueEligible_Equal: {
+ /*
+ * While a priority queue of the thread queue associated with an eligible
+ * scheduler of the enqueueing thread is non-empty, while the highest
+ * priority of the priority queue is equal to the priority of the
+ * enqueueing thread with respect to the eligible scheduler.
+ */
+ ctx->priority = PRIO_VERY_HIGH;
+ break;
+ }
+
+ case ScoreTqReqEnqueueMrsp_Pre_QueueEligible_Low: {
+ /*
+ * While a priority queue of the thread queue associated with an eligible
+ * scheduler of the enqueueing thread is non-empty, while the highest
+ * priority of the priority queue is lower than the priority of the
+ * enqueueing thread with respect to the eligible scheduler.
+ */
+ ctx->priority = PRIO_HIGH;
+ break;
+ }
+
+ case ScoreTqReqEnqueueMrsp_Pre_QueueEligible_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_Prepare(
+ ScoreTqReqEnqueueMrsp_Context *ctx,
+ ScoreTqReqEnqueueMrsp_Pre_QueueIneligible state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_None: {
+ /*
+ * While no priority queue of the thread queue exists which is not
+ * associated with an eligible scheduler of the enqueueing thread.
+ */
+ ctx->other_before = false;
+ ctx->other_after = false;
+ break;
+ }
+
+ case ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_Only: {
+ /*
+ * While exactly one priority queue of the thread queue exists which is
+ * not associated with an eligible scheduler of the enqueueing thread.
+ */
+ ctx->other_before = true;
+ ctx->other_after = false;
+ break;
+ }
+
+ case ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_Before: {
+ /*
+ * While a priority queue of the thread queue exists which is not
+ * associated with an eligible scheduler of the enqueueing thread, while
+ * this priority queue is positioned before all priority queues which are
+ * associated with eligible schedulers of the enqueueing thread.
+ */
+ ctx->other_before = true;
+ ctx->other_after = false;
+ break;
+ }
+
+ case ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_After: {
+ /*
+ * While a priority queue of the thread queue exists which is not
+ * associated with an eligible scheduler of the enqueueing thread, while
+ * this priority queue is positioned after all priority queues which are
+ * associated with eligible schedulers of the enqueueing thread.
+ */
+ ctx->other_before = false;
+ ctx->other_after = true;
+ break;
+ }
+
+ case ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueueMrsp_Post_Position_Check(
+ ScoreTqReqEnqueueMrsp_Context *ctx,
+ ScoreTqReqEnqueueMrsp_Post_Position state
+)
+{
+ size_t i;
+
+ i = 0;
+
+ /* The enqueue is sticky, so no enqueued thread is blocked by the scheduler */
+ T_null( TQGetNextUnblock( ctx->tq_ctx, &i )->thread );
+
+ switch ( state ) {
+ case ScoreTqReqEnqueueMrsp_Post_Position_InitialFirst: {
+ /*
+ * A priority queue associated with the scheduler which contains exactly
+ * the enqueueing thread shall be created as the first priority queue of
+ * the thread queue.
+ */
+ T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
+ T_eq_u32( 1, TQGetCounter( ctx->tq_ctx ) );
+ break;
+ }
+
+ case ScoreTqReqEnqueueMrsp_Post_Position_InitialLast: {
+ /*
+ * A priority queue associated with the scheduler which contains exactly
+ * the enqueueing thread shall be created as the last priority queue of
+ * the thread queue.
+ */
+ if ( CanDoFullValidation() ) {
+ T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_C ) );
+ T_eq_u32( 2, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
+ T_eq_u32( 2, TQGetCounter( ctx->tq_ctx ) );
+ } else {
+ T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
+ T_eq_u32( 1, TQGetCounter( ctx->tq_ctx ) );
+ }
+ break;
+ }
+
+ case ScoreTqReqEnqueueMrsp_Post_Position_Second: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ */
+ if ( CanDoFullValidation() ) {
+ T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_B ) );
+ T_eq_u32( 2, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
+ T_eq_u32( 2, TQGetCounter( ctx->tq_ctx ) );
+ } else {
+ T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
+ T_eq_u32( 1, TQGetCounter( ctx->tq_ctx ) );
+ }
+ break;
+ }
+
+ case ScoreTqReqEnqueueMrsp_Post_Position_SecondFirst: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ *
+ * The position of the priority queue in the thread queue shall not
+ * change.
+ */
+ if ( CanDoFullValidation() ) {
+ T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_B ) );
+ T_eq_u32( 2, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_C ) );
+ T_eq_u32( 3, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
+ T_eq_u32( 3, TQGetCounter( ctx->tq_ctx ) );
+ } else {
+ T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
+ T_eq_u32( 1, TQGetCounter( ctx->tq_ctx ) );
+ }
+ break;
+ }
+
+ case ScoreTqReqEnqueueMrsp_Post_Position_SecondLast: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ *
+ * The position of the priority queue in the thread queue shall not
+ * change.
+ */
+ if ( CanDoFullValidation() ) {
+ T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_C ) );
+ T_eq_u32( 2, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_B ) );
+ T_eq_u32( 3, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
+ T_eq_u32( 3, TQGetCounter( ctx->tq_ctx ) );
+ } else {
+ T_eq_u32( 1, TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ) );
+ T_eq_u32( 1, TQGetCounter( ctx->tq_ctx ) );
+ }
+ break;
+ }
+
+ case ScoreTqReqEnqueueMrsp_Post_Position_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueueMrsp_Setup( ScoreTqReqEnqueueMrsp_Context *ctx )
+{
+ if ( CanDoFullValidation() ) {
+ RemoveProcessor( SCHEDULER_C_ID, 2 );
+ AddProcessor( SCHEDULER_B_ID, 2 );
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_C, SCHEDULER_C_ID, PRIO_LOW );
+ }
+
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_A, SCHEDULER_B_ID, PRIO_LOW );
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_B, SCHEDULER_B_ID, PRIO_LOW );
+ TQSetScheduler(
+ ctx->tq_ctx,
+ TQ_BLOCKER_D,
+ SCHEDULER_A_ID,
+ PRIO_ULTRA_HIGH
+ );
+}
+
+static void ScoreTqReqEnqueueMrsp_Setup_Wrap( void *arg )
+{
+ ScoreTqReqEnqueueMrsp_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqEnqueueMrsp_Setup( ctx );
+}
+
+static void ScoreTqReqEnqueueMrsp_Teardown(
+ ScoreTqReqEnqueueMrsp_Context *ctx
+)
+{
+ if ( CanDoFullValidation() ) {
+ RemoveProcessor( SCHEDULER_B_ID, 2 );
+ AddProcessor( SCHEDULER_C_ID, 2 );
+ }
+
+ TQReset( ctx->tq_ctx );
+}
+
+static void ScoreTqReqEnqueueMrsp_Teardown_Wrap( void *arg )
+{
+ ScoreTqReqEnqueueMrsp_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqEnqueueMrsp_Teardown( ctx );
+}
+
+static void ScoreTqReqEnqueueMrsp_Action( ScoreTqReqEnqueueMrsp_Context *ctx )
+{
+ Status_Control status;
+
+ TQResetCounter( ctx->tq_ctx );
+ TQClearDone( ctx->tq_ctx, TQ_BLOCKER_A );
+ TQClearDone( ctx->tq_ctx, TQ_BLOCKER_B );
+ TQClearDone( ctx->tq_ctx, TQ_BLOCKER_C );
+
+ status = TQEnqueue( ctx->tq_ctx, TQ_WAIT_FOREVER );
+ T_eq_int( status, TQConvertStatus( ctx->tq_ctx, STATUS_SUCCESSFUL ) );
+
+ if ( ctx->helping ) {
+ TQSend(
+ ctx->tq_ctx,
+ TQ_BLOCKER_A,
+ TQ_EVENT_MUTEX_A_OBTAIN | TQ_EVENT_RUNNER_SYNC
+ );
+ TQSynchronizeRunner();
+ TQSend(
+ ctx->tq_ctx,
+ TQ_BLOCKER_D,
+ TQ_EVENT_MUTEX_A_OBTAIN | TQ_EVENT_MUTEX_A_RELEASE |
+ TQ_EVENT_RUNNER_SYNC_2
+ );
+ }
+
+ if ( CanDoFullValidation() ) {
+ if ( ctx->other_before ) {
+ TQSendAndWaitForIntendToBlock(
+ ctx->tq_ctx,
+ TQ_BLOCKER_C,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
+ );
+ }
+
+ if ( ctx->priority != PRIO_PSEUDO_ISR ) {
+ TQSendAndWaitForIntendToBlock(
+ ctx->tq_ctx,
+ TQ_BLOCKER_B,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
+ );
+ }
+
+ if ( ctx->other_after ) {
+ TQSendAndWaitForIntendToBlock(
+ ctx->tq_ctx,
+ TQ_BLOCKER_C,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
+ );
+ }
+ }
+
+ TQSendAndWaitForIntendToBlock(
+ ctx->tq_ctx,
+ TQ_BLOCKER_A,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
+ );
+
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ status = TQSurrender( ctx->tq_ctx );
+ T_eq_int( status, TQConvertStatus( ctx->tq_ctx, STATUS_SUCCESSFUL ) );
+ TQWaitForDone( ctx->tq_ctx, TQ_BLOCKER_A );
+
+ if ( CanDoFullValidation() ) {
+ if ( ctx->priority != PRIO_PSEUDO_ISR ) {
+ TQWaitForDone( ctx->tq_ctx, TQ_BLOCKER_B );
+ }
+
+ if ( ctx->other_before || ctx->other_after ) {
+ TQWaitForDone( ctx->tq_ctx, TQ_BLOCKER_C );
+ }
+ }
+
+ TQSchedulerRecordStop( ctx->tq_ctx );
+
+ if ( ctx->helping ) {
+ TQSend(
+ ctx->tq_ctx,
+ TQ_BLOCKER_A,
+ TQ_EVENT_MUTEX_A_RELEASE | TQ_EVENT_RUNNER_SYNC
+ );
+ TQSynchronizeRunner2();
+ }
+}
+
+static const ScoreTqReqEnqueueMrsp_Entry
+ScoreTqReqEnqueueMrsp_Entries[] = {
+ { 1, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_NA },
+ { 0, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_Second },
+ { 0, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_SecondLast },
+ { 0, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_SecondFirst },
+ { 0, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_InitialFirst },
+ { 0, 0, 0, 0, ScoreTqReqEnqueueMrsp_Post_Position_InitialLast }
+};
+
+static const uint8_t
+ScoreTqReqEnqueueMrsp_Map[] = {
+ 4, 5, 0, 0, 1, 0, 2, 3, 1, 0, 2, 3, 4, 5, 0, 0, 1, 0, 2, 3, 1, 0, 2, 3
+};
+
+static size_t ScoreTqReqEnqueueMrsp_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreTqReqEnqueueMrsp_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( ScoreTqReqEnqueueMrsp_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreTqReqEnqueueMrsp_Fixture = {
+ .setup = ScoreTqReqEnqueueMrsp_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreTqReqEnqueueMrsp_Teardown_Wrap,
+ .scope = ScoreTqReqEnqueueMrsp_Scope,
+ .initial_context = &ScoreTqReqEnqueueMrsp_Instance
+};
+
+static inline ScoreTqReqEnqueueMrsp_Entry ScoreTqReqEnqueueMrsp_PopEntry(
+ ScoreTqReqEnqueueMrsp_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return ScoreTqReqEnqueueMrsp_Entries[
+ ScoreTqReqEnqueueMrsp_Map[ index ]
+ ];
+}
+
+static void ScoreTqReqEnqueueMrsp_TestVariant(
+ ScoreTqReqEnqueueMrsp_Context *ctx
+)
+{
+ ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_Prepare(
+ ctx,
+ ctx->Map.pcs[ 0 ]
+ );
+ ScoreTqReqEnqueueMrsp_Pre_QueueEligible_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ ScoreTqReqEnqueueMrsp_Action( ctx );
+ ScoreTqReqEnqueueMrsp_Post_Position_Check(
+ ctx,
+ ctx->Map.entry.Post_Position
+ );
+}
+
+static T_fixture_node ScoreTqReqEnqueueMrsp_Node;
+
+static T_remark ScoreTqReqEnqueueMrsp_Remark = {
+ .next = NULL,
+ .remark = "ScoreTqReqEnqueueMrsp"
+};
+
+void ScoreTqReqEnqueueMrsp_Run( TQContext *tq_ctx )
+{
+ ScoreTqReqEnqueueMrsp_Context *ctx;
+
+ ctx = &ScoreTqReqEnqueueMrsp_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreTqReqEnqueueMrsp_Node,
+ &ScoreTqReqEnqueueMrsp_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_Home;
+ ctx->Map.pcs[ 0 ] < ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = ScoreTqReqEnqueueMrsp_Pre_QueueEligible_None;
+ ctx->Map.pcs[ 1 ] < ScoreTqReqEnqueueMrsp_Pre_QueueEligible_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_None;
+ ctx->Map.pcs[ 2 ] < ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ ctx->Map.entry = ScoreTqReqEnqueueMrsp_PopEntry( ctx );
+ ScoreTqReqEnqueueMrsp_TestVariant( ctx );
+ }
+ }
+ }
+
+ T_add_remark( &ScoreTqReqEnqueueMrsp_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-tq-enqueue-mrsp.h b/testsuites/validation/tr-tq-enqueue-mrsp.h
new file mode 100644
index 0000000000..1c38b4b238
--- /dev/null
+++ b/testsuites/validation/tr-tq-enqueue-mrsp.h
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqEnqueueMrsp
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_TQ_ENQUEUE_MRSP_H
+#define _TR_TQ_ENQUEUE_MRSP_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreTqReqEnqueueMrsp
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_Home,
+ ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_Helping,
+ ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler_NA
+} ScoreTqReqEnqueueMrsp_Pre_EligibleScheduler;
+
+typedef enum {
+ ScoreTqReqEnqueueMrsp_Pre_QueueEligible_None,
+ ScoreTqReqEnqueueMrsp_Pre_QueueEligible_Equal,
+ ScoreTqReqEnqueueMrsp_Pre_QueueEligible_Low,
+ ScoreTqReqEnqueueMrsp_Pre_QueueEligible_NA
+} ScoreTqReqEnqueueMrsp_Pre_QueueEligible;
+
+typedef enum {
+ ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_None,
+ ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_Only,
+ ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_Before,
+ ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_After,
+ ScoreTqReqEnqueueMrsp_Pre_QueueIneligible_NA
+} ScoreTqReqEnqueueMrsp_Pre_QueueIneligible;
+
+typedef enum {
+ ScoreTqReqEnqueueMrsp_Post_Position_InitialFirst,
+ ScoreTqReqEnqueueMrsp_Post_Position_InitialLast,
+ ScoreTqReqEnqueueMrsp_Post_Position_Second,
+ ScoreTqReqEnqueueMrsp_Post_Position_SecondFirst,
+ ScoreTqReqEnqueueMrsp_Post_Position_SecondLast,
+ ScoreTqReqEnqueueMrsp_Post_Position_NA
+} ScoreTqReqEnqueueMrsp_Post_Position;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue test context.
+ */
+void ScoreTqReqEnqueueMrsp_Run( TQContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_TQ_ENQUEUE_MRSP_H */
diff --git a/testsuites/validation/tr-tq-enqueue-priority-inherit.c b/testsuites/validation/tr-tq-enqueue-priority-inherit.c
new file mode 100644
index 0000000000..160e2d7825
--- /dev/null
+++ b/testsuites/validation/tr-tq-enqueue-priority-inherit.c
@@ -0,0 +1,1742 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqEnqueuePriorityInherit
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-tq-enqueue-priority-inherit.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTqReqEnqueuePriorityInherit \
+ * spec:/score/tq/req/enqueue-priority-inherit
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_Scheduler_NA : 1;
+ uint32_t Pre_QueueEligible_NA : 1;
+ uint32_t Pre_QueueIneligible_NA : 1;
+ uint32_t Pre_PriorityForOwner_NA : 1;
+ uint32_t Pre_SchedulerForOwner_NA : 1;
+ uint32_t Pre_OwnerState_NA : 1;
+ uint32_t Post_Position : 4;
+ uint32_t Post_OwnerPriority : 2;
+ uint32_t Post_OwnerScheduler : 2;
+ uint32_t Post_OwnerOwnerPriority : 2;
+ uint32_t Post_OwnerOwnerScheduler : 2;
+} ScoreTqReqEnqueuePriorityInherit_Entry;
+
+/**
+ * @brief Test context for spec:/score/tq/req/enqueue-priority-inherit test
+ * case.
+ */
+typedef struct {
+ /**
+ * @brief This member specifies the priority of a thread on the thread queue
+ * with an eligible scheduler equal to an eligible scheduler of the
+ * enqueueing thread.
+ */
+ rtems_task_priority queue_priority;
+
+ /**
+ * @brief If this member is true, then a thread those eligible schedulers are
+ * ineligible scheduler to the enqueueing task should be enqueued before a
+ * thread with an eligible scheduler equal to an eligible scheduler of the
+ * enqueueing thread.
+ */
+ size_t other_before;
+
+ /**
+ * @brief If this member is true, then a thread those eligible schedulers are
+ * ineligible scheduler to the enqueueing task should be enqueued after a
+ * thread with an eligible scheduler equal to an eligible scheduler of the
+ * enqueueing thread.
+ */
+ size_t other_after;
+
+ /**
+ * @brief This this member is true, then the priorities of the enqueueing
+ * thread shall be dispensable for the owner of the thread queue.
+ */
+ bool vital_priority;
+
+ /**
+ * @brief This this member is true, then the eligible scheduler of the
+ * enqueueing thread shall be dispensable for the owner of the thread
+ * queue.
+ */
+ bool vital_scheduler;
+
+ /**
+ * @brief This member contains the priorities of the thread queue owner after
+ * the enqueue.
+ */
+ rtems_task_priority owner_priority[ 4 ];
+
+ /**
+ * @brief This member contains the priorities of the owner of the thread
+ * queue on which the thread queue owner is blocked after the enqueue.
+ */
+ rtems_task_priority owner_owner_priority[ 4 ];
+
+ /**
+ * @brief This member specifies which mutex obtain event shall be used to
+ * block the thread queue owner.
+ */
+ rtems_event_set owner_obtain;
+
+ /**
+ * @brief This member specifies which mutex release event shall be used to
+ * unblock the thread queue owner.
+ */
+ rtems_event_set owner_release;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreTqReqEnqueuePriorityInherit_Run() parameter.
+ */
+ TQContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 6 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreTqReqEnqueuePriorityInherit_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreTqReqEnqueuePriorityInherit_Context;
+
+static ScoreTqReqEnqueuePriorityInherit_Context
+ ScoreTqReqEnqueuePriorityInherit_Instance;
+
+static const char * const ScoreTqReqEnqueuePriorityInherit_PreDesc_Scheduler[] = {
+ "One",
+ "Two",
+ "Three",
+ "More",
+ "NA"
+};
+
+static const char * const ScoreTqReqEnqueuePriorityInherit_PreDesc_QueueEligible[] = {
+ "None",
+ "High",
+ "Equal",
+ "Low",
+ "NA"
+};
+
+static const char * const ScoreTqReqEnqueuePriorityInherit_PreDesc_QueueIneligible[] = {
+ "None",
+ "Only",
+ "Before",
+ "After",
+ "NA"
+};
+
+static const char * const ScoreTqReqEnqueuePriorityInherit_PreDesc_PriorityForOwner[] = {
+ "Vital",
+ "Dispensable",
+ "NA"
+};
+
+static const char * const ScoreTqReqEnqueuePriorityInherit_PreDesc_SchedulerForOwner[] = {
+ "Vital",
+ "Dispensable",
+ "NA"
+};
+
+static const char * const ScoreTqReqEnqueuePriorityInherit_PreDesc_OwnerState[] = {
+ "NotEnqueued",
+ "FIFO",
+ "Priority",
+ "PriorityInherit",
+ "NA"
+};
+
+static const char * const * const ScoreTqReqEnqueuePriorityInherit_PreDesc[] = {
+ ScoreTqReqEnqueuePriorityInherit_PreDesc_Scheduler,
+ ScoreTqReqEnqueuePriorityInherit_PreDesc_QueueEligible,
+ ScoreTqReqEnqueuePriorityInherit_PreDesc_QueueIneligible,
+ ScoreTqReqEnqueuePriorityInherit_PreDesc_PriorityForOwner,
+ ScoreTqReqEnqueuePriorityInherit_PreDesc_SchedulerForOwner,
+ ScoreTqReqEnqueuePriorityInherit_PreDesc_OwnerState,
+ NULL
+};
+
+typedef ScoreTqReqEnqueuePriorityInherit_Context Context;
+
+static const rtems_tcb *GetUnblock( Context *ctx, size_t *index )
+{
+ const rtems_tcb *thread;
+
+ do {
+ thread = TQGetNextUnblock( ctx->tq_ctx, index )->thread;
+ } while ( thread == ctx->tq_ctx->runner_tcb );
+
+ return thread;
+}
+
+static const rtems_tcb *GetTCB( Context *ctx, TQWorkerKind worker )
+{
+ return ctx->tq_ctx->worker_tcb[ worker ];
+}
+
+static void CheckPriorityRaise(
+ const Context *ctx,
+ const rtems_task_priority *priority
+)
+{
+ if ( ctx->queue_priority == PRIO_ULTRA_HIGH ) {
+ T_eq_u32( priority[ 0 ], PRIO_ULTRA_HIGH );
+ } else {
+ T_eq_u32( priority[ 0 ], PRIO_VERY_HIGH );
+ }
+
+ if (
+ ctx->queue_priority == PRIO_VERY_HIGH ||
+ ctx->queue_priority == PRIO_ULTRA_HIGH
+ ) {
+ if ( ctx->other_before || ctx->other_after ) {
+ T_eq_u32( priority[ 1 ], PRIO_ULTRA_LOW );
+ T_eq_u32( priority[ 2 ], PRIO_NORMAL );
+ } else {
+ T_eq_u32( priority[ 1 ], PRIO_NORMAL );
+ }
+ }
+}
+
+static void CheckPriorityNop(
+ const Context *ctx,
+ const rtems_task_priority *priority
+)
+{
+ if ( ctx->queue_priority == PRIO_ULTRA_HIGH ) {
+ T_eq_u32( priority[ 0 ], PRIO_ULTRA_HIGH );
+ } else {
+ T_eq_u32( priority[ 0 ], PRIO_VERY_HIGH );
+ }
+}
+
+static void CheckSchedulerNewHelper(
+ const Context *ctx,
+ const rtems_task_priority *priority
+)
+{
+ if (
+ ctx->vital_priority &&
+ ( ctx->queue_priority == PRIO_VERY_HIGH ||
+ ctx->queue_priority == PRIO_ULTRA_HIGH )
+ ) {
+ if ( ctx->other_before || ctx->other_after ) {
+ T_eq_u32( priority[ 3 ], PRIO_VERY_LOW );
+ } else {
+ T_eq_u32( priority[ 2 ], PRIO_VERY_LOW );
+ T_eq_u32( priority[ 3 ], PRIO_INVALID );
+ }
+ } else {
+ if ( ctx->other_before || ctx->other_after ) {
+ T_eq_u32( priority[ 1 ], PRIO_ULTRA_LOW );
+ T_eq_u32( priority[ 2 ], PRIO_VERY_LOW );
+ } else {
+ T_eq_u32( priority[ 1 ], PRIO_VERY_LOW );
+ T_eq_u32( priority[ 2 ], PRIO_INVALID );
+ }
+
+ T_eq_u32( priority[ 3 ], PRIO_INVALID );
+ }
+}
+
+static void CheckSchedulerNop(
+ const Context *ctx,
+ const rtems_task_priority *priority
+)
+{
+ if (
+ ctx->vital_priority &&
+ ( ctx->queue_priority == PRIO_VERY_HIGH ||
+ ctx->queue_priority == PRIO_ULTRA_HIGH )
+ ) {
+ if ( !ctx->other_before && !ctx->other_after ) {
+ T_eq_u32( priority[ 2 ], PRIO_INVALID );
+ }
+
+ T_eq_u32( priority[ 3 ], PRIO_INVALID );
+ } else {
+ if ( ctx->other_before || ctx->other_after ) {
+ T_eq_u32( priority[ 1 ], PRIO_ULTRA_LOW );
+ } else {
+ T_eq_u32( priority[ 1 ], PRIO_INVALID );
+ }
+
+ T_eq_u32( priority[ 2 ], PRIO_INVALID );
+ T_eq_u32( priority[ 3 ], PRIO_INVALID );
+ }
+}
+
+static void GetPriorities(
+ const Context *ctx,
+ TQWorkerKind worker,
+ rtems_task_priority *priority
+)
+{
+ priority[ 0 ] = GetPriorityByScheduler(
+ ctx->tq_ctx->worker_id[ worker ],
+ SCHEDULER_A_ID
+ );
+ priority[ 1 ] = GetPriorityByScheduler(
+ ctx->tq_ctx->worker_id[ worker ],
+ SCHEDULER_B_ID
+ );
+ priority[ 2 ] = GetPriorityByScheduler(
+ ctx->tq_ctx->worker_id[ worker ],
+ SCHEDULER_C_ID
+ );
+ priority[ 3 ] = GetPriorityByScheduler(
+ ctx->tq_ctx->worker_id[ worker ],
+ SCHEDULER_D_ID
+ );
+}
+
+static void AddVitalPriority( Context *ctx, rtems_id scheduler_id )
+{
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_D, scheduler_id, PRIO_NORMAL );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_BLOCKER_D,
+ TQ_EVENT_MUTEX_A_OBTAIN | TQ_EVENT_MUTEX_A_RELEASE
+ );
+}
+
+static void AddVitalPriorityHelper( Context *ctx, rtems_id scheduler_id )
+{
+ TQSetScheduler( ctx->tq_ctx, TQ_HELPER_B, scheduler_id, PRIO_LOW );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_HELPER_B,
+ TQ_EVENT_MUTEX_B_OBTAIN | TQ_EVENT_MUTEX_B_RELEASE
+ );
+}
+
+static void AddVitalScheduler( Context *ctx, rtems_id scheduler_id )
+{
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_E, scheduler_id, PRIO_VERY_LOW );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_BLOCKER_E,
+ TQ_EVENT_MUTEX_A_OBTAIN | TQ_EVENT_MUTEX_A_RELEASE
+ );
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_Pre_Scheduler_Prepare(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx,
+ ScoreTqReqEnqueuePriorityInherit_Pre_Scheduler state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueuePriorityInherit_Pre_Scheduler_One: {
+ /*
+ * Where the system has exactly one schedulers.
+ */
+ if ( rtems_scheduler_get_processor_maximum() != 1 ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_Scheduler_Two: {
+ /*
+ * Where the system has exactly two schedulers.
+ */
+ if ( rtems_scheduler_get_processor_maximum() != 2 ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_Scheduler_Three: {
+ /*
+ * Where the system has exactly three schedulers.
+ */
+ if ( rtems_scheduler_get_processor_maximum() != 3 ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_Scheduler_More: {
+ /*
+ * Where the system has at least three schedulers.
+ */
+ if ( rtems_scheduler_get_processor_maximum() < 4 ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_Scheduler_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_Pre_QueueEligible_Prepare(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx,
+ ScoreTqReqEnqueuePriorityInherit_Pre_QueueEligible state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueuePriorityInherit_Pre_QueueEligible_None: {
+ /*
+ * While all priority queues of the thread queue associated with eligible
+ * schedulers of the enqueueing thread are empty.
+ */
+ ctx->queue_priority = PRIO_INVALID;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_QueueEligible_High: {
+ /*
+ * While a priority queue of the thread queue associated with an eligible
+ * scheduler of the enqueueing thread is non-empty, while the highest
+ * priority of the priority queue is higher than the priority of the
+ * enqueueing thread with respect to the eligible scheduler.
+ */
+ ++ctx->tq_ctx->how_many;
+ ctx->queue_priority = PRIO_ULTRA_HIGH;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_QueueEligible_Equal: {
+ /*
+ * While a priority queue of the thread queue associated with an eligible
+ * scheduler of the enqueueing thread is non-empty, while the highest
+ * priority of the priority queue is equal to the priority of the
+ * enqueueing thread with respect to the eligible scheduler.
+ */
+ ++ctx->tq_ctx->how_many;
+ ctx->queue_priority = PRIO_VERY_HIGH;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_QueueEligible_Low: {
+ /*
+ * While a priority queue of the thread queue associated with an eligible
+ * scheduler of the enqueueing thread is non-empty, while the highest
+ * priority of the priority queue is lower than the priority of the
+ * enqueueing thread with respect to the eligible scheduler.
+ */
+ ++ctx->tq_ctx->how_many;
+ ctx->queue_priority = PRIO_HIGH;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_QueueEligible_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_Pre_QueueIneligible_Prepare(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx,
+ ScoreTqReqEnqueuePriorityInherit_Pre_QueueIneligible state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueuePriorityInherit_Pre_QueueIneligible_None: {
+ /*
+ * While each priority queue of the thread queue is associated with an
+ * eligible scheduler of the enqueueing thread.
+ */
+ ctx->other_before = false;
+ ctx->other_after = false;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_QueueIneligible_Only: {
+ /*
+ * While exactly one priority queue of the thread queue exists which is
+ * not associated with an eligible scheduler of the enqueueing thread.
+ */
+ ++ctx->tq_ctx->how_many;
+ ctx->other_before = true;
+ ctx->other_after = false;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_QueueIneligible_Before: {
+ /*
+ * While a priority queue of the thread queue exists which is not
+ * associated with an eligible scheduler of the enqueueing thread, while
+ * the priority queue is positioned before all priority queues which are
+ * associated with eligible schedulers of the enqueueing thread.
+ */
+ ++ctx->tq_ctx->how_many;
+ ctx->other_before = true;
+ ctx->other_after = false;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_QueueIneligible_After: {
+ /*
+ * While a priority queue of the thread queue exists which is not
+ * associated with an eligible scheduler of the enqueueing thread, while
+ * the priority queue is positioned after all priority queues which are
+ * associated with eligible schedulers of the enqueueing thread.
+ */
+ ++ctx->tq_ctx->how_many;
+ ctx->other_before = false;
+ ctx->other_after = true;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_QueueIneligible_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_Pre_PriorityForOwner_Prepare(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx,
+ ScoreTqReqEnqueuePriorityInherit_Pre_PriorityForOwner state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueuePriorityInherit_Pre_PriorityForOwner_Vital: {
+ /*
+ * While at least one priority of the enqueueing thread is higher than
+ * the highest priority of the owner of the thread queue.
+ */
+ ctx->vital_priority = true;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_PriorityForOwner_Dispensable: {
+ /*
+ * While all priorities of the enqueueing thread are lower than or equal
+ * to the highest priority of the owner of the thread queue.
+ */
+ ctx->vital_priority = false;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_PriorityForOwner_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_Pre_SchedulerForOwner_Prepare(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx,
+ ScoreTqReqEnqueuePriorityInherit_Pre_SchedulerForOwner state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueuePriorityInherit_Pre_SchedulerForOwner_Vital: {
+ /*
+ * While at least one eligible scheduler of the enqueueing thread is not
+ * an eligible scheduler of the owner of the thread queue.
+ */
+ ctx->vital_scheduler = true;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_SchedulerForOwner_Dispensable: {
+ /*
+ * While all eligible schedulers of the enqueueing thread are an eligible
+ * scheduler of the owner of the thread queue.
+ */
+ ctx->vital_scheduler = false;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_SchedulerForOwner_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_Pre_OwnerState_Prepare(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx,
+ ScoreTqReqEnqueuePriorityInherit_Pre_OwnerState state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueuePriorityInherit_Pre_OwnerState_NotEnqueued: {
+ /*
+ * While the owner of the thread queue is not enqueued on a thread queue.
+ */
+ ctx->owner_obtain = 0;
+ ctx->owner_release = 0;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_OwnerState_FIFO: {
+ /*
+ * While the owner of the thread queue is enqueued on a thread queue in
+ * FIFO order.
+ */
+ ctx->owner_obtain = TQ_EVENT_MUTEX_FIFO_OBTAIN;
+ ctx->owner_release = TQ_EVENT_MUTEX_FIFO_RELEASE;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_OwnerState_Priority: {
+ /*
+ * While the owner of the thread queue is enqueued on a thread queue in
+ * priority order.
+ */
+ ctx->owner_obtain = TQ_EVENT_MUTEX_NO_PROTOCOL_OBTAIN;
+ ctx->owner_release = TQ_EVENT_MUTEX_NO_PROTOCOL_RELEASE;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_OwnerState_PriorityInherit: {
+ /*
+ * While the owner of the thread queue is enqueued on a thread queue in
+ * priority order with priority inheritance.
+ */
+ ctx->owner_obtain = TQ_EVENT_MUTEX_C_OBTAIN;
+ ctx->owner_release = TQ_EVENT_MUTEX_C_RELEASE;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Pre_OwnerState_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_Post_Position_Check(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position state
+)
+{
+ size_t i;
+
+ i = 0;
+
+ /* Event receive */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_HELPER_A ) );
+
+ switch ( state ) {
+ case ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialFirst: {
+ /*
+ * A priority queue associated with the scheduler which contains exactly
+ * the enqueueing thread shall be created as the first priority queue of
+ * the thread queue.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialLast: {
+ /*
+ * A priority queue associated with the scheduler which contains exactly
+ * the enqueueing thread shall be created as the last priority queue of
+ * the thread queue.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Post_Position_First: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Post_Position_Second: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstFirst: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ *
+ * The position of the priority queue in the thread queue shall not
+ * change.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondFirst: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ *
+ * The position of the priority queue in the thread queue shall not
+ * change.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstLast: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ *
+ * The position of the priority queue in the thread queue shall not
+ * change.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondLast: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ *
+ * The position of the priority queue in the thread queue shall not
+ * change.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Post_Position_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Check(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise: {
+ /*
+ * Each priority of the enqueueing thread which is higher than the
+ * highest priority of the owner of the thread queue shall be made the
+ * highest priority of the owner.
+ */
+ CheckPriorityRaise( ctx, ctx->owner_priority );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop: {
+ /*
+ * The priorities of the owner of the thread queue shall not change.
+ */
+ CheckPriorityNop( ctx, ctx->owner_priority );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Check(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper: {
+ /*
+ * Each eligible scheduler of the enqueueing thread which is not an
+ * eligible scheduler of the owner of the thread queue shall be made a
+ * helping scheduler of the owner with the priority of the enqueueing
+ * thread.
+ */
+ CheckSchedulerNewHelper( ctx, ctx->owner_priority );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop: {
+ /*
+ * The set of eligible schedulers of the owner of the thread queue shall
+ * not change.
+ */
+ CheckSchedulerNop( ctx, ctx->owner_priority );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Check(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise: {
+ /*
+ * Each priority of the enqueueing thread which is higher than the
+ * highest priority of the owner of the thread queue on which the owner
+ * of the thread queue is enqueued shall be made the highest priority of
+ * the owner.
+ */
+ CheckPriorityRaise( ctx, ctx->owner_owner_priority );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop: {
+ /*
+ * The priorities of the owner of the thread queue on which the owner of
+ * the thread queue is enqueued shall not change.
+ */
+ if ( ctx->owner_obtain == TQ_EVENT_MUTEX_C_OBTAIN ) {
+ CheckPriorityNop( ctx, ctx->owner_owner_priority );
+ } else {
+ if ( ctx->vital_priority ) {
+ T_eq_u32( ctx->owner_owner_priority[ 0 ], PRIO_HIGH );
+ } else {
+ T_eq_u32( ctx->owner_owner_priority[ 0 ], PRIO_VERY_HIGH );
+ }
+ }
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Check(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper: {
+ /*
+ * Each eligible scheduler of the enqueueing thread which is not an
+ * eligible scheduler of the owner of the thread queue on which the owner
+ * of the thread queue is enqueued shall be made a helping scheduler of
+ * the owner with the priority of the enqueueing thread.
+ */
+ CheckSchedulerNewHelper( ctx, ctx->owner_owner_priority );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop: {
+ /*
+ * The set of eligible schedulers of the owner of the thread queue on
+ * which the owner of the thread queue is enqueued shall not change.
+ */
+ if ( ctx->owner_obtain == TQ_EVENT_MUTEX_C_OBTAIN ) {
+ CheckSchedulerNop( ctx, ctx->owner_owner_priority );
+ } else {
+ T_eq_u32( ctx->owner_owner_priority[ 1 ], PRIO_INVALID );
+ T_eq_u32( ctx->owner_owner_priority[ 2 ], PRIO_INVALID );
+ T_eq_u32( ctx->owner_owner_priority[ 3 ], PRIO_INVALID );
+ }
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_Setup(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx
+)
+{
+ TQReset( ctx->tq_ctx );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_A, PRIO_VERY_HIGH );
+ TQSetPriority( ctx->tq_ctx, TQ_HELPER_C, PRIO_HIGH );
+
+ #if defined( RTEMS_SMP )
+ TQSetScheduler(
+ ctx->tq_ctx,
+ TQ_BLOCKER_C,
+ SCHEDULER_B_ID,
+ PRIO_ULTRA_LOW
+ );
+
+ if ( rtems_scheduler_get_processor_maximum() > 3 ) {
+ RemoveProcessor( SCHEDULER_C_ID, 3 );
+ AddProcessor( SCHEDULER_D_ID, 3 );
+ }
+ #endif
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_Setup_Wrap( void *arg )
+{
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqEnqueuePriorityInherit_Setup( ctx );
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_Teardown(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx
+)
+{
+ TQReset( ctx->tq_ctx );
+
+ #if defined( RTEMS_SMP )
+ if ( rtems_scheduler_get_processor_maximum() > 3 ) {
+ RemoveProcessor( SCHEDULER_D_ID, 3 );
+ AddProcessor( SCHEDULER_C_ID, 3 );
+ }
+ #endif
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_Teardown_Wrap( void *arg )
+{
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqEnqueuePriorityInherit_Teardown( ctx );
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_Prepare(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx
+)
+{
+ ctx->tq_ctx->how_many = 1;
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_Action(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx
+)
+{
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_MUTEX_A_OBTAIN );
+ TQSend(
+ ctx->tq_ctx,
+ TQ_HELPER_A,
+ TQ_EVENT_MUTEX_B_OBTAIN | TQ_EVENT_ENQUEUE_PREPARE
+ );
+
+ if ( ctx->owner_obtain != 0 ) {
+ TQSend( ctx->tq_ctx, TQ_HELPER_C, ctx->owner_obtain );
+ }
+
+ if ( ctx->other_before ) {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_BLOCKER_C,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER | TQ_EVENT_RUNNER_SYNC_2
+ );
+ }
+
+ if ( ctx->queue_priority != PRIO_INVALID ) {
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_B , ctx->queue_priority );
+ TQSend(
+ ctx->tq_ctx,
+ TQ_BLOCKER_B,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
+ );
+ }
+
+ if ( ctx->other_after ) {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_BLOCKER_C,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER | TQ_EVENT_RUNNER_SYNC_2
+ );
+ }
+
+ if ( ctx->vital_priority ) {
+ TQSetPriority( ctx->tq_ctx, TQ_HELPER_A, PRIO_HIGH );
+ TQSetPriority( ctx->tq_ctx, TQ_HELPER_C, PRIO_HIGH );
+
+ if (
+ ctx->queue_priority == PRIO_VERY_HIGH ||
+ ctx->queue_priority == PRIO_ULTRA_HIGH
+ ) {
+ if ( ctx->other_before || ctx->other_after ) {
+ AddVitalPriority( ctx, SCHEDULER_C_ID );
+ AddVitalPriorityHelper( ctx, SCHEDULER_C_ID );
+
+ if ( ctx->vital_scheduler ) {
+ AddVitalScheduler( ctx, SCHEDULER_D_ID );
+ }
+ } else {
+ AddVitalPriority( ctx, SCHEDULER_B_ID );
+ AddVitalPriorityHelper( ctx, SCHEDULER_B_ID );
+
+ if ( ctx->vital_scheduler ) {
+ AddVitalScheduler( ctx, SCHEDULER_C_ID );
+ }
+ }
+ } else {
+ if ( ctx->vital_scheduler ) {
+ if ( ctx->other_before || ctx->other_after ) {
+ AddVitalScheduler( ctx, SCHEDULER_C_ID );
+ } else {
+ AddVitalScheduler( ctx, SCHEDULER_B_ID );
+ }
+ }
+ }
+ } else {
+ TQSetPriority( ctx->tq_ctx, TQ_HELPER_A, PRIO_VERY_HIGH );
+ TQSetPriority( ctx->tq_ctx, TQ_HELPER_C, PRIO_VERY_HIGH );
+
+ if ( ctx->vital_scheduler ) {
+ if ( ctx->other_before || ctx->other_after ) {
+ AddVitalScheduler( ctx, SCHEDULER_C_ID );
+ } else {
+ AddVitalScheduler( ctx, SCHEDULER_B_ID );
+ }
+ }
+ }
+
+ if ( ctx->owner_obtain != 0 ) {
+ TQClearDone( ctx->tq_ctx, TQ_HELPER_A );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_HELPER_A,
+ ctx->owner_obtain | ctx->owner_release
+ );
+ }
+
+ TQSend(
+ ctx->tq_ctx,
+ TQ_BLOCKER_A,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER | TQ_EVENT_RUNNER_SYNC
+ );
+
+ GetPriorities( ctx, TQ_HELPER_A, ctx->owner_priority );
+ GetPriorities( ctx, TQ_HELPER_C, ctx->owner_owner_priority );
+
+ if ( ctx->owner_obtain != 0 ) {
+ TQSend( ctx->tq_ctx, TQ_HELPER_C, ctx->owner_release );
+ TQWaitForDone( ctx->tq_ctx, TQ_HELPER_A );
+ TQWaitForExecutionStop( ctx->tq_ctx, TQ_HELPER_A );
+ }
+
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ TQSend( ctx->tq_ctx, TQ_HELPER_A, TQ_EVENT_ENQUEUE_DONE );
+
+ if ( ctx->other_before || ctx->other_after ) {
+ TQSynchronizeRunner2();
+ } else {
+ TQSynchronizeRunner();
+ }
+
+ TQSchedulerRecordStop( ctx->tq_ctx );
+
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_MUTEX_A_RELEASE );
+ TQMutexObtain( ctx->tq_ctx, TQ_MUTEX_A );
+ TQMutexRelease( ctx->tq_ctx, TQ_MUTEX_A );
+
+ TQSend( ctx->tq_ctx, TQ_HELPER_A, TQ_EVENT_MUTEX_B_RELEASE );
+ TQMutexObtain( ctx->tq_ctx, TQ_MUTEX_B );
+ TQMutexRelease( ctx->tq_ctx, TQ_MUTEX_B );
+}
+
+static const ScoreTqReqEnqueuePriorityInherit_Entry
+ScoreTqReqEnqueuePriorityInherit_Entries[] = {
+ { 1, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NA },
+ { 1, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NA },
+ { 1, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NA },
+ { 1, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NA },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_Second,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 1, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_NA,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NA },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_Second,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_Second,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_First,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_First,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_Second,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_First,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_First,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_Second,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_Second,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_First,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_Second,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_First,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqEnqueuePriorityInherit_Post_Position_First,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper },
+ { 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper }
+};
+
+static const uint8_t
+ScoreTqReqEnqueuePriorityInherit_Map[] = {
+ 0, 0, 0, 0, 12, 12, 12, 39, 0, 0, 0, 0, 10, 10, 10, 10, 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, 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, 5, 5, 5, 5, 0, 0, 0,
+ 0, 4, 4, 4, 4, 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, 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, 5, 5, 5, 5, 0, 0, 0, 0, 4, 4, 4, 4, 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, 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, 13, 13, 13, 40, 0, 0, 0,
+ 0, 11, 11, 11, 11, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 22, 22, 22, 46, 12, 12, 12, 39, 23, 23, 23, 47, 10, 10, 10, 10, 3,
+ 3, 3, 3, 24, 24, 24, 48, 3, 3, 3, 3, 14, 14, 14, 14, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3,
+ 3, 3, 8, 8, 8, 29, 9, 9, 9, 30, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 3, 3, 3, 3, 5, 5, 5, 5, 3, 3, 3, 3, 6, 6, 6, 6, 3, 3, 3, 3, 5,
+ 5, 5, 5, 3, 3, 3, 3, 7, 7, 7, 7, 3, 3, 3, 3, 8, 8, 8, 29, 9, 9, 9, 30, 4, 4,
+ 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 5, 5, 5, 5,
+ 3, 3, 3, 3, 6, 6, 6, 6, 3, 3, 3, 3, 5, 5, 5, 5, 3, 3, 3, 3, 7, 7, 7, 7, 25,
+ 25, 25, 49, 13, 13, 13, 40, 26, 26, 26, 50, 11, 11, 11, 11, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 27, 27, 27, 51, 3, 3, 3, 3, 15, 15,
+ 15, 15, 3, 3, 3, 3, 28, 28, 28, 52, 3, 3, 3, 3, 16, 16, 16, 16, 22, 22, 22,
+ 46, 12, 12, 12, 39, 23, 23, 23, 47, 10, 10, 10, 10, 31, 31, 31, 53, 24, 24,
+ 24, 48, 32, 32, 32, 54, 14, 14, 14, 14, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 17, 17, 41,
+ 8, 8, 8, 29, 9, 9, 9, 30, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 3, 3, 3, 3, 18, 18, 18, 42, 19, 19, 19, 43, 6, 6, 6, 6, 3, 3, 3, 3,
+ 20, 20, 20, 44, 21, 21, 21, 45, 7, 7, 7, 7, 17, 17, 17, 41, 8, 8, 8, 29, 9,
+ 9, 9, 30, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3,
+ 3, 3, 18, 18, 18, 42, 19, 19, 19, 43, 6, 6, 6, 6, 3, 3, 3, 3, 20, 20, 20, 44,
+ 21, 21, 21, 45, 7, 7, 7, 7, 25, 25, 25, 49, 13, 13, 13, 40, 26, 26, 26, 50,
+ 11, 11, 11, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 33, 33, 33,
+ 55, 27, 27, 27, 51, 34, 34, 34, 56, 15, 15, 15, 15, 35, 35, 35, 57, 28, 28,
+ 28, 52, 36, 36, 36, 58, 16, 16, 16, 16, 22, 22, 22, 46, 12, 12, 12, 39, 23,
+ 23, 23, 47, 10, 10, 10, 10, 31, 31, 31, 53, 24, 24, 24, 48, 32, 32, 32, 54,
+ 14, 14, 14, 14, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 17, 17, 41, 8, 8, 8, 29, 9, 9, 9, 30,
+ 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 37, 37, 37, 59,
+ 18, 18, 18, 42, 19, 19, 19, 43, 6, 6, 6, 6, 38, 38, 38, 60, 20, 20, 20, 44,
+ 21, 21, 21, 45, 7, 7, 7, 7, 17, 17, 17, 41, 8, 8, 8, 29, 9, 9, 9, 30, 4, 4,
+ 4, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 37, 37, 37, 59, 18, 18,
+ 18, 42, 19, 19, 19, 43, 6, 6, 6, 6, 38, 38, 38, 60, 20, 20, 20, 44, 21, 21,
+ 21, 45, 7, 7, 7, 7, 25, 25, 25, 49, 13, 13, 13, 40, 26, 26, 26, 50, 11, 11,
+ 11, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 33, 33, 33, 55, 27,
+ 27, 27, 51, 34, 34, 34, 56, 15, 15, 15, 15, 35, 35, 35, 57, 28, 28, 28, 52,
+ 36, 36, 36, 58, 16, 16, 16, 16
+};
+
+static size_t ScoreTqReqEnqueuePriorityInherit_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ ScoreTqReqEnqueuePriorityInherit_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreTqReqEnqueuePriorityInherit_Fixture = {
+ .setup = ScoreTqReqEnqueuePriorityInherit_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreTqReqEnqueuePriorityInherit_Teardown_Wrap,
+ .scope = ScoreTqReqEnqueuePriorityInherit_Scope,
+ .initial_context = &ScoreTqReqEnqueuePriorityInherit_Instance
+};
+
+static const uint16_t ScoreTqReqEnqueuePriorityInherit_Weights[] = {
+ 256, 64, 16, 8, 4, 1
+};
+
+static void ScoreTqReqEnqueuePriorityInherit_Skip(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx,
+ size_t index
+)
+{
+ switch ( index + 1 ) {
+ case 1:
+ ctx->Map.pcs[ 1 ] = ScoreTqReqEnqueuePriorityInherit_Pre_QueueEligible_NA - 1;
+ /* Fall through */
+ case 2:
+ ctx->Map.pcs[ 2 ] = ScoreTqReqEnqueuePriorityInherit_Pre_QueueIneligible_NA - 1;
+ /* Fall through */
+ case 3:
+ ctx->Map.pcs[ 3 ] = ScoreTqReqEnqueuePriorityInherit_Pre_PriorityForOwner_NA - 1;
+ /* Fall through */
+ case 4:
+ ctx->Map.pcs[ 4 ] = ScoreTqReqEnqueuePriorityInherit_Pre_SchedulerForOwner_NA - 1;
+ /* Fall through */
+ case 5:
+ ctx->Map.pcs[ 5 ] = ScoreTqReqEnqueuePriorityInherit_Pre_OwnerState_NA - 1;
+ break;
+ }
+}
+
+static inline ScoreTqReqEnqueuePriorityInherit_Entry
+ScoreTqReqEnqueuePriorityInherit_PopEntry(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx
+)
+{
+ size_t index;
+
+ if ( ctx->Map.skip ) {
+ size_t i;
+
+ ctx->Map.skip = false;
+ index = 0;
+
+ for ( i = 0; i < 6; ++i ) {
+ index += ScoreTqReqEnqueuePriorityInherit_Weights[ i ] * ctx->Map.pcs[ i ];
+ }
+ } else {
+ index = ctx->Map.index;
+ }
+
+ ctx->Map.index = index + 1;
+
+ return ScoreTqReqEnqueuePriorityInherit_Entries[
+ ScoreTqReqEnqueuePriorityInherit_Map[ index ]
+ ];
+}
+
+static void ScoreTqReqEnqueuePriorityInherit_TestVariant(
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx
+)
+{
+ ScoreTqReqEnqueuePriorityInherit_Pre_Scheduler_Prepare(
+ ctx,
+ ctx->Map.pcs[ 0 ]
+ );
+
+ if ( ctx->Map.skip ) {
+ ScoreTqReqEnqueuePriorityInherit_Skip( ctx, 0 );
+ return;
+ }
+
+ ScoreTqReqEnqueuePriorityInherit_Pre_QueueEligible_Prepare(
+ ctx,
+ ctx->Map.pcs[ 1 ]
+ );
+ ScoreTqReqEnqueuePriorityInherit_Pre_QueueIneligible_Prepare(
+ ctx,
+ ctx->Map.pcs[ 2 ]
+ );
+ ScoreTqReqEnqueuePriorityInherit_Pre_PriorityForOwner_Prepare(
+ ctx,
+ ctx->Map.pcs[ 3 ]
+ );
+ ScoreTqReqEnqueuePriorityInherit_Pre_SchedulerForOwner_Prepare(
+ ctx,
+ ctx->Map.pcs[ 4 ]
+ );
+ ScoreTqReqEnqueuePriorityInherit_Pre_OwnerState_Prepare(
+ ctx,
+ ctx->Map.pcs[ 5 ]
+ );
+ ScoreTqReqEnqueuePriorityInherit_Action( ctx );
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_Check(
+ ctx,
+ ctx->Map.entry.Post_Position
+ );
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Check(
+ ctx,
+ ctx->Map.entry.Post_OwnerPriority
+ );
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Check(
+ ctx,
+ ctx->Map.entry.Post_OwnerScheduler
+ );
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Check(
+ ctx,
+ ctx->Map.entry.Post_OwnerOwnerPriority
+ );
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Check(
+ ctx,
+ ctx->Map.entry.Post_OwnerOwnerScheduler
+ );
+}
+
+static T_fixture_node ScoreTqReqEnqueuePriorityInherit_Node;
+
+static T_remark ScoreTqReqEnqueuePriorityInherit_Remark = {
+ .next = NULL,
+ .remark = "ScoreTqReqEnqueuePriorityInherit"
+};
+
+void ScoreTqReqEnqueuePriorityInherit_Run( TQContext *tq_ctx )
+{
+ ScoreTqReqEnqueuePriorityInherit_Context *ctx;
+
+ ctx = &ScoreTqReqEnqueuePriorityInherit_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreTqReqEnqueuePriorityInherit_Node,
+ &ScoreTqReqEnqueuePriorityInherit_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+ ctx->Map.skip = false;
+
+ for (
+ ctx->Map.pcs[ 0 ] = ScoreTqReqEnqueuePriorityInherit_Pre_Scheduler_One;
+ ctx->Map.pcs[ 0 ] < ScoreTqReqEnqueuePriorityInherit_Pre_Scheduler_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = ScoreTqReqEnqueuePriorityInherit_Pre_QueueEligible_None;
+ ctx->Map.pcs[ 1 ] < ScoreTqReqEnqueuePriorityInherit_Pre_QueueEligible_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = ScoreTqReqEnqueuePriorityInherit_Pre_QueueIneligible_None;
+ ctx->Map.pcs[ 2 ] < ScoreTqReqEnqueuePriorityInherit_Pre_QueueIneligible_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = ScoreTqReqEnqueuePriorityInherit_Pre_PriorityForOwner_Vital;
+ ctx->Map.pcs[ 3 ] < ScoreTqReqEnqueuePriorityInherit_Pre_PriorityForOwner_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = ScoreTqReqEnqueuePriorityInherit_Pre_SchedulerForOwner_Vital;
+ ctx->Map.pcs[ 4 ] < ScoreTqReqEnqueuePriorityInherit_Pre_SchedulerForOwner_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 5 ] = ScoreTqReqEnqueuePriorityInherit_Pre_OwnerState_NotEnqueued;
+ ctx->Map.pcs[ 5 ] < ScoreTqReqEnqueuePriorityInherit_Pre_OwnerState_NA;
+ ++ctx->Map.pcs[ 5 ]
+ ) {
+ ctx->Map.entry = ScoreTqReqEnqueuePriorityInherit_PopEntry(
+ ctx
+ );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ ScoreTqReqEnqueuePriorityInherit_Prepare( ctx );
+ ScoreTqReqEnqueuePriorityInherit_TestVariant( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ T_add_remark( &ScoreTqReqEnqueuePriorityInherit_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-tq-enqueue-priority-inherit.h b/testsuites/validation/tr-tq-enqueue-priority-inherit.h
new file mode 100644
index 0000000000..c2ffa59902
--- /dev/null
+++ b/testsuites/validation/tr-tq-enqueue-priority-inherit.h
@@ -0,0 +1,159 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqEnqueuePriorityInherit
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_TQ_ENQUEUE_PRIORITY_INHERIT_H
+#define _TR_TQ_ENQUEUE_PRIORITY_INHERIT_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreTqReqEnqueuePriorityInherit
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreTqReqEnqueuePriorityInherit_Pre_Scheduler_One,
+ ScoreTqReqEnqueuePriorityInherit_Pre_Scheduler_Two,
+ ScoreTqReqEnqueuePriorityInherit_Pre_Scheduler_Three,
+ ScoreTqReqEnqueuePriorityInherit_Pre_Scheduler_More,
+ ScoreTqReqEnqueuePriorityInherit_Pre_Scheduler_NA
+} ScoreTqReqEnqueuePriorityInherit_Pre_Scheduler;
+
+typedef enum {
+ ScoreTqReqEnqueuePriorityInherit_Pre_QueueEligible_None,
+ ScoreTqReqEnqueuePriorityInherit_Pre_QueueEligible_High,
+ ScoreTqReqEnqueuePriorityInherit_Pre_QueueEligible_Equal,
+ ScoreTqReqEnqueuePriorityInherit_Pre_QueueEligible_Low,
+ ScoreTqReqEnqueuePriorityInherit_Pre_QueueEligible_NA
+} ScoreTqReqEnqueuePriorityInherit_Pre_QueueEligible;
+
+typedef enum {
+ ScoreTqReqEnqueuePriorityInherit_Pre_QueueIneligible_None,
+ ScoreTqReqEnqueuePriorityInherit_Pre_QueueIneligible_Only,
+ ScoreTqReqEnqueuePriorityInherit_Pre_QueueIneligible_Before,
+ ScoreTqReqEnqueuePriorityInherit_Pre_QueueIneligible_After,
+ ScoreTqReqEnqueuePriorityInherit_Pre_QueueIneligible_NA
+} ScoreTqReqEnqueuePriorityInherit_Pre_QueueIneligible;
+
+typedef enum {
+ ScoreTqReqEnqueuePriorityInherit_Pre_PriorityForOwner_Vital,
+ ScoreTqReqEnqueuePriorityInherit_Pre_PriorityForOwner_Dispensable,
+ ScoreTqReqEnqueuePriorityInherit_Pre_PriorityForOwner_NA
+} ScoreTqReqEnqueuePriorityInherit_Pre_PriorityForOwner;
+
+typedef enum {
+ ScoreTqReqEnqueuePriorityInherit_Pre_SchedulerForOwner_Vital,
+ ScoreTqReqEnqueuePriorityInherit_Pre_SchedulerForOwner_Dispensable,
+ ScoreTqReqEnqueuePriorityInherit_Pre_SchedulerForOwner_NA
+} ScoreTqReqEnqueuePriorityInherit_Pre_SchedulerForOwner;
+
+typedef enum {
+ ScoreTqReqEnqueuePriorityInherit_Pre_OwnerState_NotEnqueued,
+ ScoreTqReqEnqueuePriorityInherit_Pre_OwnerState_FIFO,
+ ScoreTqReqEnqueuePriorityInherit_Pre_OwnerState_Priority,
+ ScoreTqReqEnqueuePriorityInherit_Pre_OwnerState_PriorityInherit,
+ ScoreTqReqEnqueuePriorityInherit_Pre_OwnerState_NA
+} ScoreTqReqEnqueuePriorityInherit_Pre_OwnerState;
+
+typedef enum {
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_InitialLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_First,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_Second,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondFirst,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_FirstLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_SecondLast,
+ ScoreTqReqEnqueuePriorityInherit_Post_Position_NA
+} ScoreTqReqEnqueuePriorityInherit_Post_Position;
+
+typedef enum {
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority_NA
+} ScoreTqReqEnqueuePriorityInherit_Post_OwnerPriority;
+
+typedef enum {
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler_NA
+} ScoreTqReqEnqueuePriorityInherit_Post_OwnerScheduler;
+
+typedef enum {
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Raise,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority_NA
+} ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerPriority;
+
+typedef enum {
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NewHelper,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_Nop,
+ ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler_NA
+} ScoreTqReqEnqueuePriorityInherit_Post_OwnerOwnerScheduler;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue context.
+ */
+void ScoreTqReqEnqueuePriorityInherit_Run( TQContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_TQ_ENQUEUE_PRIORITY_INHERIT_H */
diff --git a/testsuites/validation/tr-tq-enqueue-priority.c b/testsuites/validation/tr-tq-enqueue-priority.c
new file mode 100644
index 0000000000..18818e34cd
--- /dev/null
+++ b/testsuites/validation/tr-tq-enqueue-priority.c
@@ -0,0 +1,751 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqEnqueuePriority
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-tq-enqueue-priority.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTqReqEnqueuePriority spec:/score/tq/req/enqueue-priority
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_EligibleScheduler_NA : 1;
+ uint8_t Pre_QueueEligible_NA : 1;
+ uint8_t Pre_QueueIneligible_NA : 1;
+ uint8_t Post_Position : 4;
+} ScoreTqReqEnqueuePriority_Entry;
+
+/**
+ * @brief Test context for spec:/score/tq/req/enqueue-priority test case.
+ */
+typedef struct {
+ /**
+ * @brief This this member is true, then the enqueueing thread shall have at
+ * least one helping scheduler.
+ */
+ bool helping;
+
+ /**
+ * @brief This member specifies the priority of a thread with an eligible
+ * scheduler equal to an eligible scheduler of the enqueueing thread.
+ */
+ rtems_task_priority priority;
+
+ /**
+ * @brief If this member is true, then a thread those eligible schedulers are
+ * ineligible scheduler to the enqueueing task should be enqueued before a
+ * thread with an eligible scheduler equal to an eligible scheduler of the
+ * enqueueing thread.
+ */
+ size_t other_before;
+
+ /**
+ * @brief If this member is true, then a thread those eligible schedulers are
+ * ineligible scheduler to the enqueueing task should be enqueued after a
+ * thread with an eligible scheduler equal to an eligible scheduler of the
+ * enqueueing thread.
+ */
+ size_t other_after;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreTqReqEnqueuePriority_Run() parameter.
+ */
+ TQContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreTqReqEnqueuePriority_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreTqReqEnqueuePriority_Context;
+
+static ScoreTqReqEnqueuePriority_Context
+ ScoreTqReqEnqueuePriority_Instance;
+
+static const char * const ScoreTqReqEnqueuePriority_PreDesc_EligibleScheduler[] = {
+ "Home",
+ "Helping",
+ "NA"
+};
+
+static const char * const ScoreTqReqEnqueuePriority_PreDesc_QueueEligible[] = {
+ "None",
+ "High",
+ "Equal",
+ "Low",
+ "NA"
+};
+
+static const char * const ScoreTqReqEnqueuePriority_PreDesc_QueueIneligible[] = {
+ "None",
+ "Only",
+ "Before",
+ "After",
+ "NA"
+};
+
+static const char * const * const ScoreTqReqEnqueuePriority_PreDesc[] = {
+ ScoreTqReqEnqueuePriority_PreDesc_EligibleScheduler,
+ ScoreTqReqEnqueuePriority_PreDesc_QueueEligible,
+ ScoreTqReqEnqueuePriority_PreDesc_QueueIneligible,
+ NULL
+};
+
+typedef ScoreTqReqEnqueuePriority_Context Context;
+
+static const rtems_tcb *GetUnblock( Context *ctx, size_t *index )
+{
+ const rtems_tcb *thread;
+
+ do {
+ thread = TQGetNextUnblock( ctx->tq_ctx, index )->thread;
+ } while ( thread == ctx->tq_ctx->runner_tcb );
+
+ return thread;
+}
+
+static const rtems_tcb *GetTCB( Context *ctx, TQWorkerKind worker )
+{
+ return ctx->tq_ctx->worker_tcb[ worker ];
+}
+
+static void AddHelper( TQContext *tq_ctx, rtems_id scheduler_id )
+{
+ TQSend( tq_ctx, TQ_BLOCKER_C, TQ_EVENT_MUTEX_A_OBTAIN );
+ TQSetScheduler( tq_ctx, TQ_BLOCKER_E, scheduler_id, PRIO_LOW );
+ TQSendAndWaitForExecutionStop(
+ tq_ctx,
+ TQ_BLOCKER_E,
+ TQ_EVENT_MUTEX_A_OBTAIN | TQ_EVENT_MUTEX_A_RELEASE
+ );
+}
+
+static void RemoveHelper( TQContext *tq_ctx )
+{
+ TQSend( tq_ctx, TQ_BLOCKER_C, TQ_EVENT_MUTEX_A_RELEASE );
+ TQMutexObtain( tq_ctx, TQ_MUTEX_A );
+ TQMutexRelease( tq_ctx, TQ_MUTEX_A );
+}
+
+static void ScoreTqReqEnqueuePriority_Pre_EligibleScheduler_Prepare(
+ ScoreTqReqEnqueuePriority_Context *ctx,
+ ScoreTqReqEnqueuePriority_Pre_EligibleScheduler state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueuePriority_Pre_EligibleScheduler_Home: {
+ /*
+ * While the enqueueing thread has no helping scheduler.
+ */
+ ctx->helping = false;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Pre_EligibleScheduler_Helping: {
+ /*
+ * While the enqueueing thread has at least one helping scheduler.
+ */
+ ctx->helping = true;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Pre_EligibleScheduler_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueuePriority_Pre_QueueEligible_Prepare(
+ ScoreTqReqEnqueuePriority_Context *ctx,
+ ScoreTqReqEnqueuePriority_Pre_QueueEligible state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueuePriority_Pre_QueueEligible_None: {
+ /*
+ * While all priority queues of the thread queue associated with eligible
+ * schedulers of the enqueueing thread are empty.
+ */
+ ctx->priority = PRIO_PSEUDO_ISR;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Pre_QueueEligible_High: {
+ /*
+ * While a priority queue of the thread queue associated with an eligible
+ * scheduler of the enqueueing thread is non-empty, while the highest
+ * priority of the priority queue is higher than the priority of the
+ * enqueueing thread with respect to the eligible scheduler.
+ */
+ ++ctx->tq_ctx->how_many;
+ ctx->priority = PRIO_ULTRA_HIGH;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Pre_QueueEligible_Equal: {
+ /*
+ * While a priority queue of the thread queue associated with an eligible
+ * scheduler of the enqueueing thread is non-empty, while the highest
+ * priority of the priority queue is equal to the priority of the
+ * enqueueing thread with respect to the eligible scheduler.
+ */
+ ++ctx->tq_ctx->how_many;
+ ctx->priority = PRIO_VERY_HIGH;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Pre_QueueEligible_Low: {
+ /*
+ * While a priority queue of the thread queue associated with an eligible
+ * scheduler of the enqueueing thread is non-empty, while the highest
+ * priority of the priority queue is lower than the priority of the
+ * enqueueing thread with respect to the eligible scheduler.
+ */
+ ++ctx->tq_ctx->how_many;
+ ctx->priority = PRIO_HIGH;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Pre_QueueEligible_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueuePriority_Pre_QueueIneligible_Prepare(
+ ScoreTqReqEnqueuePriority_Context *ctx,
+ ScoreTqReqEnqueuePriority_Pre_QueueIneligible state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqEnqueuePriority_Pre_QueueIneligible_None: {
+ /*
+ * While no priority queue of the thread queue exists which is not
+ * associated with an eligible scheduler of the enqueueing thread.
+ */
+ ctx->other_before = false;
+ ctx->other_after = false;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Pre_QueueIneligible_Only: {
+ /*
+ * While exactly one priority queue of the thread queue exists which is
+ * not associated with an eligible scheduler of the enqueueing thread.
+ */
+ ++ctx->tq_ctx->how_many;
+ ctx->other_before = true;
+ ctx->other_after = false;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Pre_QueueIneligible_Before: {
+ /*
+ * While a priority queue of the thread queue exists which is not
+ * associated with an eligible scheduler of the enqueueing thread, while
+ * this priority queue is positioned before all priority queues which are
+ * associated with eligible schedulers of the enqueueing thread.
+ */
+ ++ctx->tq_ctx->how_many;
+ ctx->other_before = true;
+ ctx->other_after = false;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Pre_QueueIneligible_After: {
+ /*
+ * While a priority queue of the thread queue exists which is not
+ * associated with an eligible scheduler of the enqueueing thread, while
+ * this priority queue is positioned after all priority queues which are
+ * associated with eligible schedulers of the enqueueing thread.
+ */
+ ++ctx->tq_ctx->how_many;
+ ctx->other_before = false;
+ ctx->other_after = true;
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Pre_QueueIneligible_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueuePriority_Post_Position_Check(
+ ScoreTqReqEnqueuePriority_Context *ctx,
+ ScoreTqReqEnqueuePriority_Post_Position state
+)
+{
+ size_t i;
+
+ i = 0;
+
+ /* Event receives */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+
+ switch ( state ) {
+ case ScoreTqReqEnqueuePriority_Post_Position_InitialFirst: {
+ /*
+ * A priority queue associated with the scheduler which contains exactly
+ * the enqueueing thread shall be created as the first priority queue of
+ * the thread queue.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Post_Position_InitialLast: {
+ /*
+ * A priority queue associated with the scheduler which contains exactly
+ * the enqueueing thread shall be created as the last priority queue of
+ * the thread queue.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_D ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Post_Position_First: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Post_Position_Second: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Post_Position_FirstFirst: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ *
+ * The position of the priority queue in the thread queue shall not
+ * change.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_D ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Post_Position_SecondFirst: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ *
+ * The position of the priority queue in the thread queue shall not
+ * change.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_D ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Post_Position_FirstLast: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ *
+ * The position of the priority queue in the thread queue shall not
+ * change.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_D ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Post_Position_SecondLast: {
+ /*
+ * The enqueueing thread shall be enqueued in the priority queue
+ * associated with the scheduler.
+ *
+ * The position of the priority queue in the thread queue shall not
+ * change.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_D ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_C ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqEnqueuePriority_Post_Position_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqEnqueuePriority_Setup(
+ ScoreTqReqEnqueuePriority_Context *ctx
+)
+{
+ TQReset( ctx->tq_ctx );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_A, PRIO_ULTRA_HIGH );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_B, PRIO_LOW );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_C, PRIO_VERY_HIGH );
+
+ #if defined( RTEMS_SMP )
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_D, SCHEDULER_B_ID, PRIO_LOW );
+ #endif
+}
+
+static void ScoreTqReqEnqueuePriority_Setup_Wrap( void *arg )
+{
+ ScoreTqReqEnqueuePriority_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqEnqueuePriority_Setup( ctx );
+}
+
+static void ScoreTqReqEnqueuePriority_Teardown(
+ ScoreTqReqEnqueuePriority_Context *ctx
+)
+{
+ TQReset( ctx->tq_ctx );
+}
+
+static void ScoreTqReqEnqueuePriority_Teardown_Wrap( void *arg )
+{
+ ScoreTqReqEnqueuePriority_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqEnqueuePriority_Teardown( ctx );
+}
+
+static void ScoreTqReqEnqueuePriority_Prepare(
+ ScoreTqReqEnqueuePriority_Context *ctx
+)
+{
+ ctx->tq_ctx->how_many = 1;
+}
+
+static void ScoreTqReqEnqueuePriority_Action(
+ ScoreTqReqEnqueuePriority_Context *ctx
+)
+{
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE_PREPARE );
+
+ if ( ctx->other_before ) {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_BLOCKER_D,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER | TQ_EVENT_RUNNER_SYNC_2
+ );
+ }
+
+ if ( ctx->priority != PRIO_PSEUDO_ISR ) {
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_B , ctx->priority );
+ TQSend(
+ ctx->tq_ctx,
+ TQ_BLOCKER_B,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER
+ );
+ }
+
+ if ( ctx->other_after ) {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_BLOCKER_D,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER | TQ_EVENT_RUNNER_SYNC_2
+ );
+ }
+
+ if ( ctx->helping ) {
+ if ( ctx->other_before || ctx->other_after ) {
+ if ( rtems_scheduler_get_processor_maximum() > 2 ) {
+ AddHelper( ctx->tq_ctx, SCHEDULER_C_ID );
+ }
+ } else {
+ AddHelper( ctx->tq_ctx, SCHEDULER_B_ID );
+ }
+ }
+
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ TQSend(
+ ctx->tq_ctx,
+ TQ_BLOCKER_C,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_SURRENDER | TQ_EVENT_RUNNER_SYNC
+ );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE_DONE );
+
+ if ( ctx->other_before || ctx->other_after ) {
+ TQSynchronizeRunner2();
+ } else {
+ TQSynchronizeRunner();
+ }
+
+ TQSchedulerRecordStop( ctx->tq_ctx );
+
+ if ( ctx->helping ) {
+ if ( ctx->other_before || ctx->other_after ) {
+ if ( rtems_scheduler_get_processor_maximum() > 2 ) {
+ RemoveHelper( ctx->tq_ctx );
+ }
+ } else {
+ RemoveHelper( ctx->tq_ctx );
+ }
+ }
+}
+
+static const ScoreTqReqEnqueuePriority_Entry
+ScoreTqReqEnqueuePriority_Entries[] = {
+ { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_SecondLast },
+#else
+ { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_SecondFirst },
+#else
+ { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_InitialLast },
+#else
+ { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA },
+#endif
+ { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_Second },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_FirstLast },
+#else
+ { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_FirstFirst },
+#else
+ { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_Second },
+#else
+ { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA },
+#endif
+ { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_InitialFirst },
+ { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_First },
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_InitialFirst },
+#else
+ { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA },
+#endif
+#if defined(RTEMS_SMP)
+ { 0, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_First }
+#else
+ { 1, 0, 0, 0, ScoreTqReqEnqueuePriority_Post_Position_NA }
+#endif
+};
+
+static const uint8_t
+ScoreTqReqEnqueuePriority_Map[] = {
+ 8, 3, 0, 0, 4, 0, 1, 2, 4, 0, 1, 2, 9, 0, 5, 6, 10, 3, 0, 0, 7, 0, 1, 2, 7,
+ 0, 1, 2, 11, 0, 5, 6
+};
+
+static size_t ScoreTqReqEnqueuePriority_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreTqReqEnqueuePriority_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ ScoreTqReqEnqueuePriority_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreTqReqEnqueuePriority_Fixture = {
+ .setup = ScoreTqReqEnqueuePriority_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreTqReqEnqueuePriority_Teardown_Wrap,
+ .scope = ScoreTqReqEnqueuePriority_Scope,
+ .initial_context = &ScoreTqReqEnqueuePriority_Instance
+};
+
+static inline ScoreTqReqEnqueuePriority_Entry
+ScoreTqReqEnqueuePriority_PopEntry( ScoreTqReqEnqueuePriority_Context *ctx )
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return ScoreTqReqEnqueuePriority_Entries[
+ ScoreTqReqEnqueuePriority_Map[ index ]
+ ];
+}
+
+static void ScoreTqReqEnqueuePriority_TestVariant(
+ ScoreTqReqEnqueuePriority_Context *ctx
+)
+{
+ ScoreTqReqEnqueuePriority_Pre_EligibleScheduler_Prepare(
+ ctx,
+ ctx->Map.pcs[ 0 ]
+ );
+ ScoreTqReqEnqueuePriority_Pre_QueueEligible_Prepare(
+ ctx,
+ ctx->Map.pcs[ 1 ]
+ );
+ ScoreTqReqEnqueuePriority_Pre_QueueIneligible_Prepare(
+ ctx,
+ ctx->Map.pcs[ 2 ]
+ );
+ ScoreTqReqEnqueuePriority_Action( ctx );
+ ScoreTqReqEnqueuePriority_Post_Position_Check(
+ ctx,
+ ctx->Map.entry.Post_Position
+ );
+}
+
+static T_fixture_node ScoreTqReqEnqueuePriority_Node;
+
+static T_remark ScoreTqReqEnqueuePriority_Remark = {
+ .next = NULL,
+ .remark = "ScoreTqReqEnqueuePriority"
+};
+
+void ScoreTqReqEnqueuePriority_Run( TQContext *tq_ctx )
+{
+ ScoreTqReqEnqueuePriority_Context *ctx;
+
+ ctx = &ScoreTqReqEnqueuePriority_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreTqReqEnqueuePriority_Node,
+ &ScoreTqReqEnqueuePriority_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = ScoreTqReqEnqueuePriority_Pre_EligibleScheduler_Home;
+ ctx->Map.pcs[ 0 ] < ScoreTqReqEnqueuePriority_Pre_EligibleScheduler_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = ScoreTqReqEnqueuePriority_Pre_QueueEligible_None;
+ ctx->Map.pcs[ 1 ] < ScoreTqReqEnqueuePriority_Pre_QueueEligible_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = ScoreTqReqEnqueuePriority_Pre_QueueIneligible_None;
+ ctx->Map.pcs[ 2 ] < ScoreTqReqEnqueuePriority_Pre_QueueIneligible_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ ctx->Map.entry = ScoreTqReqEnqueuePriority_PopEntry( ctx );
+ ScoreTqReqEnqueuePriority_Prepare( ctx );
+ ScoreTqReqEnqueuePriority_TestVariant( ctx );
+ }
+ }
+ }
+
+ T_add_remark( &ScoreTqReqEnqueuePriority_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-tq-enqueue-priority.h b/testsuites/validation/tr-tq-enqueue-priority.h
new file mode 100644
index 0000000000..141c8a122c
--- /dev/null
+++ b/testsuites/validation/tr-tq-enqueue-priority.h
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqEnqueuePriority
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_TQ_ENQUEUE_PRIORITY_H
+#define _TR_TQ_ENQUEUE_PRIORITY_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreTqReqEnqueuePriority
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreTqReqEnqueuePriority_Pre_EligibleScheduler_Home,
+ ScoreTqReqEnqueuePriority_Pre_EligibleScheduler_Helping,
+ ScoreTqReqEnqueuePriority_Pre_EligibleScheduler_NA
+} ScoreTqReqEnqueuePriority_Pre_EligibleScheduler;
+
+typedef enum {
+ ScoreTqReqEnqueuePriority_Pre_QueueEligible_None,
+ ScoreTqReqEnqueuePriority_Pre_QueueEligible_High,
+ ScoreTqReqEnqueuePriority_Pre_QueueEligible_Equal,
+ ScoreTqReqEnqueuePriority_Pre_QueueEligible_Low,
+ ScoreTqReqEnqueuePriority_Pre_QueueEligible_NA
+} ScoreTqReqEnqueuePriority_Pre_QueueEligible;
+
+typedef enum {
+ ScoreTqReqEnqueuePriority_Pre_QueueIneligible_None,
+ ScoreTqReqEnqueuePriority_Pre_QueueIneligible_Only,
+ ScoreTqReqEnqueuePriority_Pre_QueueIneligible_Before,
+ ScoreTqReqEnqueuePriority_Pre_QueueIneligible_After,
+ ScoreTqReqEnqueuePriority_Pre_QueueIneligible_NA
+} ScoreTqReqEnqueuePriority_Pre_QueueIneligible;
+
+typedef enum {
+ ScoreTqReqEnqueuePriority_Post_Position_InitialFirst,
+ ScoreTqReqEnqueuePriority_Post_Position_InitialLast,
+ ScoreTqReqEnqueuePriority_Post_Position_First,
+ ScoreTqReqEnqueuePriority_Post_Position_Second,
+ ScoreTqReqEnqueuePriority_Post_Position_FirstFirst,
+ ScoreTqReqEnqueuePriority_Post_Position_SecondFirst,
+ ScoreTqReqEnqueuePriority_Post_Position_FirstLast,
+ ScoreTqReqEnqueuePriority_Post_Position_SecondLast,
+ ScoreTqReqEnqueuePriority_Post_Position_NA
+} ScoreTqReqEnqueuePriority_Post_Position;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue context.
+ */
+void ScoreTqReqEnqueuePriority_Run( TQContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_TQ_ENQUEUE_PRIORITY_H */
diff --git a/testsuites/validation/tr-tq-flush-fifo.c b/testsuites/validation/tr-tq-flush-fifo.c
new file mode 100644
index 0000000000..785d7b37a1
--- /dev/null
+++ b/testsuites/validation/tr-tq-flush-fifo.c
@@ -0,0 +1,694 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqFlushFifo
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-tq-flush-fifo.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTqReqFlushFifo spec:/score/tq/req/flush-fifo
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_MayStop_NA : 1;
+ uint8_t Pre_QueueEmpty_NA : 1;
+ uint8_t Pre_Stop_NA : 1;
+ uint8_t Pre_WaitState_NA : 1;
+ uint8_t Post_Operation : 2;
+} ScoreTqReqFlushFifo_Entry;
+
+/**
+ * @brief Test context for spec:/score/tq/req/flush-fifo test case.
+ */
+typedef struct {
+ /**
+ * @brief If this member is true, then the flush filter shall return NULL.
+ */
+ bool stop;
+
+ /**
+ * @brief If this member is true, then the least recently enqueued thread
+ * shall be in the intend to block wait state.
+ */
+ bool intend_to_block;
+
+ /**
+ * @brief This member contains the call within ISR request.
+ */
+ CallWithinISRRequest request;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreTqReqFlushFifo_Run() parameter.
+ */
+ TQContext *tq_ctx;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreTqReqFlushFifo_Run() parameter.
+ */
+ bool may_stop;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 4 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 4 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreTqReqFlushFifo_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreTqReqFlushFifo_Context;
+
+static ScoreTqReqFlushFifo_Context
+ ScoreTqReqFlushFifo_Instance;
+
+static const char * const ScoreTqReqFlushFifo_PreDesc_MayStop[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const ScoreTqReqFlushFifo_PreDesc_QueueEmpty[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const ScoreTqReqFlushFifo_PreDesc_Stop[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const ScoreTqReqFlushFifo_PreDesc_WaitState[] = {
+ "Blocked",
+ "IntendToBlock",
+ "NA"
+};
+
+static const char * const * const ScoreTqReqFlushFifo_PreDesc[] = {
+ ScoreTqReqFlushFifo_PreDesc_MayStop,
+ ScoreTqReqFlushFifo_PreDesc_QueueEmpty,
+ ScoreTqReqFlushFifo_PreDesc_Stop,
+ ScoreTqReqFlushFifo_PreDesc_WaitState,
+ NULL
+};
+
+typedef ScoreTqReqFlushFifo_Context Context;
+
+static const T_scheduler_event *GetUnblock( Context *ctx, size_t *index )
+{
+ return TQGetNextUnblock( ctx->tq_ctx, index );
+}
+
+static const rtems_tcb *GetTCB( Context *ctx, TQWorkerKind worker )
+{
+ return ctx->tq_ctx->worker_tcb[ worker ];
+}
+
+static void BlockerAFlush( Context *ctx )
+{
+ TQSchedulerRecordStart( ctx->tq_ctx );
+
+ if ( ctx->stop ) {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_FLUSH_PARTIAL );
+ } else {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_FLUSH_ALL );
+ }
+}
+
+static void InterruptFlush( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ TQFlush( ctx->tq_ctx, !ctx->stop );
+}
+
+static void SchedulerEvent(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ if (
+ when == T_SCHEDULER_BEFORE &&
+ event->operation == T_SCHEDULER_BLOCK
+ ) {
+ T_scheduler_set_event_handler( NULL, NULL );
+ ctx->request.handler = InterruptFlush;
+ CallWithinISRSubmit( &ctx->request );
+ }
+}
+
+static uint32_t CheckExtractions( Context *ctx )
+{
+ uint32_t extracted_threads;
+ size_t i;
+ const T_scheduler_event *event;
+
+ extracted_threads = 0;
+ i = 0;
+
+ if ( !ctx->intend_to_block ) {
+ /* Event receive */
+ T_eq_ptr( GetUnblock( ctx, &i )->thread, GetTCB( ctx, TQ_BLOCKER_A ) );
+ }
+
+ event = GetUnblock( ctx, &i );
+
+ if ( event != &T_scheduler_event_null ) {
+ if ( ctx->intend_to_block ) {
+ T_eq_ptr( event->executing, NULL );
+ } else {
+ T_eq_ptr( event->executing, GetTCB( ctx, TQ_BLOCKER_A ) );
+ }
+
+ T_eq_ptr( event->thread, GetTCB( ctx, TQ_BLOCKER_B ) );
+ ++extracted_threads;
+ }
+
+ event = GetUnblock( ctx, &i );
+
+ if ( event != &T_scheduler_event_null ) {
+ if ( ctx->intend_to_block ) {
+ T_eq_ptr( event->executing, NULL );
+ } else {
+ T_eq_ptr( event->executing, GetTCB( ctx, TQ_BLOCKER_A ) );
+ }
+
+ T_eq_ptr( event->thread, GetTCB( ctx, TQ_BLOCKER_C ) );
+ ++extracted_threads;
+ }
+
+ event = GetUnblock( ctx, &i );
+
+ if ( event != &T_scheduler_event_null ) {
+ if ( ctx->intend_to_block ) {
+ T_eq_ptr( event->executing, GetTCB( ctx, TQ_BLOCKER_D ) );
+ } else {
+ T_eq_ptr( event->executing, GetTCB( ctx, TQ_BLOCKER_A ) );
+ }
+
+ T_eq_ptr( event->thread, GetTCB( ctx, TQ_BLOCKER_D ) );
+ ++extracted_threads;
+ }
+
+ T_eq_ptr( GetUnblock( ctx, &i ), &T_scheduler_event_null );
+ T_eq_u32( extracted_threads, ctx->tq_ctx->flush_count );
+
+ return extracted_threads;
+}
+
+static void ScoreTqReqFlushFifo_Pre_MayStop_Prepare(
+ ScoreTqReqFlushFifo_Context *ctx,
+ ScoreTqReqFlushFifo_Pre_MayStop state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqFlushFifo_Pre_MayStop_Yes: {
+ /*
+ * Where the flush filter may return NULL.
+ */
+ if ( !ctx->may_stop ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreTqReqFlushFifo_Pre_MayStop_No: {
+ /*
+ * Where the flush filter does not return NULL.
+ */
+ if ( ctx->may_stop ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreTqReqFlushFifo_Pre_MayStop_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqFlushFifo_Pre_QueueEmpty_Prepare(
+ ScoreTqReqFlushFifo_Context *ctx,
+ ScoreTqReqFlushFifo_Pre_QueueEmpty state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqFlushFifo_Pre_QueueEmpty_Yes: {
+ /*
+ * While the thread queue is empty.
+ */
+ ctx->tq_ctx->how_many = 0;
+ break;
+ }
+
+ case ScoreTqReqFlushFifo_Pre_QueueEmpty_No: {
+ /*
+ * While the thread queue has at least one enqueued thread.
+ */
+ ctx->tq_ctx->how_many = 3;
+ break;
+ }
+
+ case ScoreTqReqFlushFifo_Pre_QueueEmpty_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqFlushFifo_Pre_Stop_Prepare(
+ ScoreTqReqFlushFifo_Context *ctx,
+ ScoreTqReqFlushFifo_Pre_Stop state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqFlushFifo_Pre_Stop_Yes: {
+ /*
+ * While the flush filter returns NULL for an enqueued thread.
+ */
+ ctx->stop = true;
+ break;
+ }
+
+ case ScoreTqReqFlushFifo_Pre_Stop_No: {
+ /*
+ * While the flush filter does not return NULL for an enqueued thread.
+ */
+ ctx->stop = false;
+ break;
+ }
+
+ case ScoreTqReqFlushFifo_Pre_Stop_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqFlushFifo_Pre_WaitState_Prepare(
+ ScoreTqReqFlushFifo_Context *ctx,
+ ScoreTqReqFlushFifo_Pre_WaitState state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqFlushFifo_Pre_WaitState_Blocked: {
+ /*
+ * While the least recently enqueued thread on the thread queue is in the
+ * blocked wait state.
+ */
+ ctx->intend_to_block = false;
+ break;
+ }
+
+ case ScoreTqReqFlushFifo_Pre_WaitState_IntendToBlock: {
+ /*
+ * While the least recently enqueued thread on the thread queue is in the
+ * intend to block wait state.
+ */
+ ctx->intend_to_block = true;
+ break;
+ }
+
+ case ScoreTqReqFlushFifo_Pre_WaitState_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqFlushFifo_Post_Operation_Check(
+ ScoreTqReqFlushFifo_Context *ctx,
+ ScoreTqReqFlushFifo_Post_Operation state
+)
+{
+ size_t i;
+ uint32_t extracted_threads;
+
+ switch ( state ) {
+ case ScoreTqReqFlushFifo_Post_Operation_Nop: {
+ /*
+ * No thread queue extraction operation shall be performed.
+ */
+ /* Event receive */
+ i = 0;
+ T_eq_ptr( GetUnblock( ctx, &i )->thread, GetTCB( ctx, TQ_BLOCKER_A ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), &T_scheduler_event_null );
+ break;
+ }
+
+ case ScoreTqReqFlushFifo_Post_Operation_ExtractAll: {
+ /*
+ * The enqueued threads shall be extracted from the thread queue in FIFO
+ * order.
+ */
+ extracted_threads = CheckExtractions( ctx );
+ T_eq_sz( extracted_threads, ctx->tq_ctx->how_many );
+ break;
+ }
+
+ case ScoreTqReqFlushFifo_Post_Operation_ExtractPartial: {
+ /*
+ * The enqueued threads which precede in FIFO order the enqueued thread
+ * for which the flush filter returned NULL shall be extracted from the
+ * thread queue in FIFO order.
+ */
+ extracted_threads = CheckExtractions( ctx );
+ T_lt_sz( extracted_threads, ctx->tq_ctx->how_many );
+ break;
+ }
+
+ case ScoreTqReqFlushFifo_Post_Operation_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqFlushFifo_Setup( ScoreTqReqFlushFifo_Context *ctx )
+{
+ ctx->request.arg = ctx;
+ TQReset( ctx->tq_ctx );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_A, PRIO_ULTRA_HIGH );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_B, PRIO_VERY_HIGH );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_C, PRIO_HIGH );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_D, PRIO_HIGH );
+}
+
+static void ScoreTqReqFlushFifo_Setup_Wrap( void *arg )
+{
+ ScoreTqReqFlushFifo_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqFlushFifo_Setup( ctx );
+}
+
+static void ScoreTqReqFlushFifo_Teardown( ScoreTqReqFlushFifo_Context *ctx )
+{
+ TQReset( ctx->tq_ctx );
+}
+
+static void ScoreTqReqFlushFifo_Teardown_Wrap( void *arg )
+{
+ ScoreTqReqFlushFifo_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqFlushFifo_Teardown( ctx );
+}
+
+static void ScoreTqReqFlushFifo_Action( ScoreTqReqFlushFifo_Context *ctx )
+{
+ uint32_t flush_count;
+
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE_PREPARE );
+
+ if ( ctx->tq_ctx->how_many > 0 ) {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_B, TQ_EVENT_ENQUEUE );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_C, TQ_EVENT_ENQUEUE );
+
+ if ( ctx->intend_to_block ) {
+ T_scheduler_set_event_handler( SchedulerEvent, ctx );
+ }
+
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_D, TQ_EVENT_ENQUEUE );
+
+ if ( !ctx->intend_to_block ) {
+ BlockerAFlush( ctx );
+ }
+ } else {
+ BlockerAFlush( ctx );
+ }
+
+ flush_count = ctx->tq_ctx->flush_count;
+ TQSchedulerRecordStop( ctx->tq_ctx );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_FLUSH_ALL );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE_DONE );
+ ctx->tq_ctx->flush_count = flush_count;
+}
+
+static const ScoreTqReqFlushFifo_Entry
+ScoreTqReqFlushFifo_Entries[] = {
+ { 0, 0, 0, 1, 1, ScoreTqReqFlushFifo_Post_Operation_Nop },
+ { 0, 0, 0, 0, 0, ScoreTqReqFlushFifo_Post_Operation_ExtractAll },
+ { 0, 0, 0, 0, 0, ScoreTqReqFlushFifo_Post_Operation_ExtractPartial },
+ { 1, 0, 0, 0, 0, ScoreTqReqFlushFifo_Post_Operation_NA }
+};
+
+static const uint8_t
+ScoreTqReqFlushFifo_Map[] = {
+ 0, 0, 0, 0, 2, 2, 1, 1, 0, 0, 0, 0, 3, 3, 1, 1
+};
+
+static size_t ScoreTqReqFlushFifo_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreTqReqFlushFifo_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( ScoreTqReqFlushFifo_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreTqReqFlushFifo_Fixture = {
+ .setup = ScoreTqReqFlushFifo_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreTqReqFlushFifo_Teardown_Wrap,
+ .scope = ScoreTqReqFlushFifo_Scope,
+ .initial_context = &ScoreTqReqFlushFifo_Instance
+};
+
+static const uint8_t ScoreTqReqFlushFifo_Weights[] = {
+ 8, 4, 2, 1
+};
+
+static void ScoreTqReqFlushFifo_Skip(
+ ScoreTqReqFlushFifo_Context *ctx,
+ size_t index
+)
+{
+ switch ( index + 1 ) {
+ case 1:
+ ctx->Map.pci[ 1 ] = ScoreTqReqFlushFifo_Pre_QueueEmpty_NA - 1;
+ /* Fall through */
+ case 2:
+ ctx->Map.pci[ 2 ] = ScoreTqReqFlushFifo_Pre_Stop_NA - 1;
+ /* Fall through */
+ case 3:
+ ctx->Map.pci[ 3 ] = ScoreTqReqFlushFifo_Pre_WaitState_NA - 1;
+ break;
+ }
+}
+
+static inline ScoreTqReqFlushFifo_Entry ScoreTqReqFlushFifo_PopEntry(
+ ScoreTqReqFlushFifo_Context *ctx
+)
+{
+ size_t index;
+
+ if ( ctx->Map.skip ) {
+ size_t i;
+
+ ctx->Map.skip = false;
+ index = 0;
+
+ for ( i = 0; i < 4; ++i ) {
+ index += ScoreTqReqFlushFifo_Weights[ i ] * ctx->Map.pci[ i ];
+ }
+ } else {
+ index = ctx->Map.index;
+ }
+
+ ctx->Map.index = index + 1;
+
+ return ScoreTqReqFlushFifo_Entries[
+ ScoreTqReqFlushFifo_Map[ index ]
+ ];
+}
+
+static void ScoreTqReqFlushFifo_SetPreConditionStates(
+ ScoreTqReqFlushFifo_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+
+ if ( ctx->Map.entry.Pre_Stop_NA ) {
+ ctx->Map.pcs[ 2 ] = ScoreTqReqFlushFifo_Pre_Stop_NA;
+ } else {
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ }
+
+ if ( ctx->Map.entry.Pre_WaitState_NA ) {
+ ctx->Map.pcs[ 3 ] = ScoreTqReqFlushFifo_Pre_WaitState_NA;
+ } else {
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ }
+}
+
+static void ScoreTqReqFlushFifo_TestVariant( ScoreTqReqFlushFifo_Context *ctx )
+{
+ ScoreTqReqFlushFifo_Pre_MayStop_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+
+ if ( ctx->Map.skip ) {
+ ScoreTqReqFlushFifo_Skip( ctx, 0 );
+ return;
+ }
+
+ ScoreTqReqFlushFifo_Pre_QueueEmpty_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ ScoreTqReqFlushFifo_Pre_Stop_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ ScoreTqReqFlushFifo_Pre_WaitState_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ ScoreTqReqFlushFifo_Action( ctx );
+ ScoreTqReqFlushFifo_Post_Operation_Check(
+ ctx,
+ ctx->Map.entry.Post_Operation
+ );
+}
+
+static T_fixture_node ScoreTqReqFlushFifo_Node;
+
+static T_remark ScoreTqReqFlushFifo_Remark = {
+ .next = NULL,
+ .remark = "ScoreTqReqFlushFifo"
+};
+
+void ScoreTqReqFlushFifo_Run( TQContext *tq_ctx, bool may_stop )
+{
+ ScoreTqReqFlushFifo_Context *ctx;
+
+ ctx = &ScoreTqReqFlushFifo_Instance;
+ ctx->tq_ctx = tq_ctx;
+ ctx->may_stop = may_stop;
+
+ ctx = T_push_fixture(
+ &ScoreTqReqFlushFifo_Node,
+ &ScoreTqReqFlushFifo_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+ ctx->Map.skip = false;
+
+ for (
+ ctx->Map.pci[ 0 ] = ScoreTqReqFlushFifo_Pre_MayStop_Yes;
+ ctx->Map.pci[ 0 ] < ScoreTqReqFlushFifo_Pre_MayStop_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = ScoreTqReqFlushFifo_Pre_QueueEmpty_Yes;
+ ctx->Map.pci[ 1 ] < ScoreTqReqFlushFifo_Pre_QueueEmpty_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = ScoreTqReqFlushFifo_Pre_Stop_Yes;
+ ctx->Map.pci[ 2 ] < ScoreTqReqFlushFifo_Pre_Stop_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = ScoreTqReqFlushFifo_Pre_WaitState_Blocked;
+ ctx->Map.pci[ 3 ] < ScoreTqReqFlushFifo_Pre_WaitState_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ ctx->Map.entry = ScoreTqReqFlushFifo_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ ScoreTqReqFlushFifo_SetPreConditionStates( ctx );
+ ScoreTqReqFlushFifo_TestVariant( ctx );
+ }
+ }
+ }
+ }
+
+ T_add_remark( &ScoreTqReqFlushFifo_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-tq-flush-fifo.h b/testsuites/validation/tr-tq-flush-fifo.h
new file mode 100644
index 0000000000..8d5bb8b8d6
--- /dev/null
+++ b/testsuites/validation/tr-tq-flush-fifo.h
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqFlushFifo
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_TQ_FLUSH_FIFO_H
+#define _TR_TQ_FLUSH_FIFO_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreTqReqFlushFifo
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreTqReqFlushFifo_Pre_MayStop_Yes,
+ ScoreTqReqFlushFifo_Pre_MayStop_No,
+ ScoreTqReqFlushFifo_Pre_MayStop_NA
+} ScoreTqReqFlushFifo_Pre_MayStop;
+
+typedef enum {
+ ScoreTqReqFlushFifo_Pre_QueueEmpty_Yes,
+ ScoreTqReqFlushFifo_Pre_QueueEmpty_No,
+ ScoreTqReqFlushFifo_Pre_QueueEmpty_NA
+} ScoreTqReqFlushFifo_Pre_QueueEmpty;
+
+typedef enum {
+ ScoreTqReqFlushFifo_Pre_Stop_Yes,
+ ScoreTqReqFlushFifo_Pre_Stop_No,
+ ScoreTqReqFlushFifo_Pre_Stop_NA
+} ScoreTqReqFlushFifo_Pre_Stop;
+
+typedef enum {
+ ScoreTqReqFlushFifo_Pre_WaitState_Blocked,
+ ScoreTqReqFlushFifo_Pre_WaitState_IntendToBlock,
+ ScoreTqReqFlushFifo_Pre_WaitState_NA
+} ScoreTqReqFlushFifo_Pre_WaitState;
+
+typedef enum {
+ ScoreTqReqFlushFifo_Post_Operation_Nop,
+ ScoreTqReqFlushFifo_Post_Operation_ExtractAll,
+ ScoreTqReqFlushFifo_Post_Operation_ExtractPartial,
+ ScoreTqReqFlushFifo_Post_Operation_NA
+} ScoreTqReqFlushFifo_Post_Operation;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue test context.
+ *
+ * @param may_stop is true, if a partial flush is supported.
+ */
+void ScoreTqReqFlushFifo_Run( TQContext *tq_ctx, bool may_stop );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_TQ_FLUSH_FIFO_H */
diff --git a/testsuites/validation/tr-tq-flush-priority-inherit.c b/testsuites/validation/tr-tq-flush-priority-inherit.c
new file mode 100644
index 0000000000..903dc20cf2
--- /dev/null
+++ b/testsuites/validation/tr-tq-flush-priority-inherit.c
@@ -0,0 +1,577 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqFlushPriorityInherit
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-tq-flush-priority-inherit.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTqReqFlushPriorityInherit \
+ * spec:/score/tq/req/flush-priority-inherit
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Priority_NA : 1;
+ uint8_t Pre_Queue_NA : 1;
+ uint8_t Post_Extract : 2;
+ uint8_t Post_PriorityUpdate : 2;
+} ScoreTqReqFlushPriorityInherit_Entry;
+
+/**
+ * @brief Test context for spec:/score/tq/req/flush-priority-inherit test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the call within ISR request.
+ */
+ CallWithinISRRequest request;
+
+ /**
+ * @brief If this member is true, then a minimum priority of the owner of the
+ * thread queue shall be inherited from a thread enqueued on the thread
+ * queue.
+ */
+ bool minimum;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreTqReqFlushPriorityInherit_Run() parameter.
+ */
+ TQContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 2 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreTqReqFlushPriorityInherit_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreTqReqFlushPriorityInherit_Context;
+
+static ScoreTqReqFlushPriorityInherit_Context
+ ScoreTqReqFlushPriorityInherit_Instance;
+
+static const char * const ScoreTqReqFlushPriorityInherit_PreDesc_Priority[] = {
+ "Minimum",
+ "NotMinimum",
+ "NA"
+};
+
+static const char * const ScoreTqReqFlushPriorityInherit_PreDesc_Queue[] = {
+ "Empty",
+ "NonEmpty",
+ "NA"
+};
+
+static const char * const * const ScoreTqReqFlushPriorityInherit_PreDesc[] = {
+ ScoreTqReqFlushPriorityInherit_PreDesc_Priority,
+ ScoreTqReqFlushPriorityInherit_PreDesc_Queue,
+ NULL
+};
+
+typedef ScoreTqReqFlushPriorityInherit_Context Context;
+
+static const T_scheduler_event *GetUnblock( Context *ctx, size_t *index )
+{
+ return TQGetNextUnblock( ctx->tq_ctx, index );
+}
+
+static const T_scheduler_event *GetPriorityUpdate( Context *ctx, size_t *index )
+{
+ return T_scheduler_next(
+ &ctx->tq_ctx->scheduler_log.header,
+ T_SCHEDULER_UPDATE_PRIORITY,
+ index
+ );
+}
+
+static const rtems_tcb *GetTCB( Context *ctx, TQWorkerKind worker )
+{
+ return ctx->tq_ctx->worker_tcb[ worker ];
+}
+
+static void Flush( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ TQFlush( ctx->tq_ctx, true );
+}
+
+static void SchedulerEvent(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ if (
+ when == T_SCHEDULER_BEFORE &&
+ event->operation == T_SCHEDULER_BLOCK
+ ) {
+ ctx->request.handler = Flush;
+ ctx->request.arg = ctx;
+ CallWithinISRSubmit( &ctx->request );
+ T_scheduler_set_event_handler( NULL, NULL );
+ }
+}
+
+static void ScoreTqReqFlushPriorityInherit_Pre_Priority_Prepare(
+ ScoreTqReqFlushPriorityInherit_Context *ctx,
+ ScoreTqReqFlushPriorityInherit_Pre_Priority state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqFlushPriorityInherit_Pre_Priority_Minimum: {
+ /*
+ * While a minimum priority of the owner of the thread queue is inherited
+ * from a thread enqueued on the thread queue.
+ */
+ ctx->minimum = true;
+ break;
+ }
+
+ case ScoreTqReqFlushPriorityInherit_Pre_Priority_NotMinimum: {
+ /*
+ * While no minimum priority of the owner of the thread queue is
+ * inherited from a thread enqueued on the thread queue.
+ */
+ ctx->minimum = false;
+ break;
+ }
+
+ case ScoreTqReqFlushPriorityInherit_Pre_Priority_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqFlushPriorityInherit_Pre_Queue_Prepare(
+ ScoreTqReqFlushPriorityInherit_Context *ctx,
+ ScoreTqReqFlushPriorityInherit_Pre_Queue state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqFlushPriorityInherit_Pre_Queue_Empty: {
+ /*
+ * While the thread queue is empty.
+ */
+ ctx->tq_ctx->how_many = 0;
+ break;
+ }
+
+ case ScoreTqReqFlushPriorityInherit_Pre_Queue_NonEmpty: {
+ /*
+ * While the thread queue has at least one enqueued thread.
+ */
+ ctx->tq_ctx->how_many = 3;
+ break;
+ }
+
+ case ScoreTqReqFlushPriorityInherit_Pre_Queue_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqFlushPriorityInherit_Post_Extract_Check(
+ ScoreTqReqFlushPriorityInherit_Context *ctx,
+ ScoreTqReqFlushPriorityInherit_Post_Extract state
+)
+{
+ size_t i;
+ const T_scheduler_event *event;
+
+ i = 0;
+
+ switch ( state ) {
+ case ScoreTqReqFlushPriorityInherit_Post_Extract_Nop: {
+ /*
+ * No operation shall be performed.
+ */
+ /* Event receive */
+ T_eq_ptr( GetUnblock( ctx, &i )->thread, GetTCB( ctx, TQ_BLOCKER_A ) );
+ T_eq_ptr( GetPriorityUpdate( ctx, &i ), &T_scheduler_event_null );
+ break;
+ }
+
+ case ScoreTqReqFlushPriorityInherit_Post_Extract_All: {
+ /*
+ * The enqueued threads of the thread queue shall be extracted in
+ * priority order for each priority queue associated with a scheduler.
+ * The priority queues of the thread queue shall be accessed in FIFO
+ * order.
+ */
+ event = GetUnblock( ctx, &i );
+ T_eq_ptr( event->executing, NULL );
+ T_eq_ptr( event->thread, GetTCB( ctx, TQ_BLOCKER_D ) );
+
+ event = GetUnblock( ctx, &i );
+ T_eq_ptr( event->executing, NULL );
+ T_eq_ptr( event->thread, GetTCB( ctx, TQ_BLOCKER_C ) );
+
+ if ( ctx->minimum ) {
+ /*
+ * This priority update is carried out by
+ * _Thread_queue_Flush_critical().
+ */
+ event = GetPriorityUpdate( ctx, &i );
+ T_eq_ptr( event->executing, NULL );
+ T_eq_ptr( event->thread, GetTCB( ctx, TQ_BLOCKER_A ) );
+ }
+
+ event = GetUnblock( ctx, &i );
+ T_eq_ptr( event->executing, GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( event->thread, GetTCB( ctx, TQ_BLOCKER_B ) );
+
+ if ( ctx->minimum && rtems_configuration_get_maximum_processors() > 1 ) {
+ /*
+ * This superfluous priority update is carried out by
+ * _Thread_queue_Enqueue() since TQ_BLOCKER_B would have inherited its
+ * priority for scheduler B to TQ_BLOCKER_A if it were not flushed from
+ * the thread queue.
+ */
+ event = GetPriorityUpdate( ctx, &i );
+ T_eq_ptr( event->executing, GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( event->thread, GetTCB( ctx, TQ_BLOCKER_A ) );
+ }
+
+ event = GetPriorityUpdate( ctx, &i );
+ T_eq_ptr( event, &T_scheduler_event_null );
+
+ T_eq_u32(
+ GetPriority( ctx->tq_ctx->worker_id[ TQ_BLOCKER_A ] ),
+ PRIO_HIGH
+ );
+ break;
+ }
+
+ case ScoreTqReqFlushPriorityInherit_Post_Extract_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqFlushPriorityInherit_Post_PriorityUpdate_Check(
+ ScoreTqReqFlushPriorityInherit_Context *ctx,
+ ScoreTqReqFlushPriorityInherit_Post_PriorityUpdate state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqFlushPriorityInherit_Post_PriorityUpdate_No: {
+ /*
+ * The current priority of the owner of the thread queue shall not be
+ * updated by the thread queue flush operation.
+ */
+ /* Checked by ``Extract`` post-condition state ``Nop`` */
+ break;
+ }
+
+ case ScoreTqReqFlushPriorityInherit_Post_PriorityUpdate_Yes: {
+ /*
+ * The current priority of the owner of the thread queue shall be updated
+ * by the thread queue flush operation to reflect the loss of inherited
+ * priorities of the flushed threads.
+ */
+ /* Checked by ``Extract`` post-condition state ``All`` */
+ break;
+ }
+
+ case ScoreTqReqFlushPriorityInherit_Post_PriorityUpdate_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqFlushPriorityInherit_Setup(
+ ScoreTqReqFlushPriorityInherit_Context *ctx
+)
+{
+ TQReset( ctx->tq_ctx );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_A, PRIO_HIGH );
+}
+
+static void ScoreTqReqFlushPriorityInherit_Setup_Wrap( void *arg )
+{
+ ScoreTqReqFlushPriorityInherit_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqFlushPriorityInherit_Setup( ctx );
+}
+
+static void ScoreTqReqFlushPriorityInherit_Teardown(
+ ScoreTqReqFlushPriorityInherit_Context *ctx
+)
+{
+ TQReset( ctx->tq_ctx );
+}
+
+static void ScoreTqReqFlushPriorityInherit_Teardown_Wrap( void *arg )
+{
+ ScoreTqReqFlushPriorityInherit_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqFlushPriorityInherit_Teardown( ctx );
+}
+
+static void ScoreTqReqFlushPriorityInherit_Action(
+ ScoreTqReqFlushPriorityInherit_Context *ctx
+)
+{
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE_PREPARE );
+
+ if ( ctx->tq_ctx->how_many > 0 ) {
+ if ( ctx->minimum ) {
+ if ( rtems_configuration_get_maximum_processors() > 1 ) {
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_B, SCHEDULER_B_ID, PRIO_HIGH );
+ } else {
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_B, SCHEDULER_A_ID, PRIO_HIGH );
+ }
+
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_C, PRIO_VERY_HIGH );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_D, PRIO_ULTRA_HIGH );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_C, TQ_EVENT_ENQUEUE );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_D, TQ_EVENT_ENQUEUE );
+ } else {
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_B, SCHEDULER_A_ID, PRIO_HIGH );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_C, PRIO_HIGH );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_D, PRIO_HIGH );
+
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_D, TQ_EVENT_ENQUEUE );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_C, TQ_EVENT_ENQUEUE );
+ }
+
+ T_scheduler_set_event_handler( SchedulerEvent, ctx );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_BLOCKER_B,
+ TQ_EVENT_ENQUEUE
+ );
+ } else {
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_FLUSH_ALL );
+ }
+
+ TQSchedulerRecordStop( ctx->tq_ctx );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE_DONE );
+}
+
+static const ScoreTqReqFlushPriorityInherit_Entry
+ScoreTqReqFlushPriorityInherit_Entries[] = {
+ { 0, 1, 0, ScoreTqReqFlushPriorityInherit_Post_Extract_Nop,
+ ScoreTqReqFlushPriorityInherit_Post_PriorityUpdate_No },
+ { 0, 0, 0, ScoreTqReqFlushPriorityInherit_Post_Extract_All,
+ ScoreTqReqFlushPriorityInherit_Post_PriorityUpdate_Yes },
+ { 0, 0, 0, ScoreTqReqFlushPriorityInherit_Post_Extract_All,
+ ScoreTqReqFlushPriorityInherit_Post_PriorityUpdate_No }
+};
+
+static const uint8_t
+ScoreTqReqFlushPriorityInherit_Map[] = {
+ 0, 1, 0, 2
+};
+
+static size_t ScoreTqReqFlushPriorityInherit_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ ScoreTqReqFlushPriorityInherit_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ ScoreTqReqFlushPriorityInherit_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreTqReqFlushPriorityInherit_Fixture = {
+ .setup = ScoreTqReqFlushPriorityInherit_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreTqReqFlushPriorityInherit_Teardown_Wrap,
+ .scope = ScoreTqReqFlushPriorityInherit_Scope,
+ .initial_context = &ScoreTqReqFlushPriorityInherit_Instance
+};
+
+static inline ScoreTqReqFlushPriorityInherit_Entry
+ScoreTqReqFlushPriorityInherit_PopEntry(
+ ScoreTqReqFlushPriorityInherit_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return ScoreTqReqFlushPriorityInherit_Entries[
+ ScoreTqReqFlushPriorityInherit_Map[ index ]
+ ];
+}
+
+static void ScoreTqReqFlushPriorityInherit_SetPreConditionStates(
+ ScoreTqReqFlushPriorityInherit_Context *ctx
+)
+{
+ if ( ctx->Map.entry.Pre_Priority_NA ) {
+ ctx->Map.pcs[ 0 ] = ScoreTqReqFlushPriorityInherit_Pre_Priority_NA;
+ } else {
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ }
+
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+}
+
+static void ScoreTqReqFlushPriorityInherit_TestVariant(
+ ScoreTqReqFlushPriorityInherit_Context *ctx
+)
+{
+ ScoreTqReqFlushPriorityInherit_Pre_Priority_Prepare(
+ ctx,
+ ctx->Map.pcs[ 0 ]
+ );
+ ScoreTqReqFlushPriorityInherit_Pre_Queue_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ ScoreTqReqFlushPriorityInherit_Action( ctx );
+ ScoreTqReqFlushPriorityInherit_Post_Extract_Check(
+ ctx,
+ ctx->Map.entry.Post_Extract
+ );
+ ScoreTqReqFlushPriorityInherit_Post_PriorityUpdate_Check(
+ ctx,
+ ctx->Map.entry.Post_PriorityUpdate
+ );
+}
+
+static T_fixture_node ScoreTqReqFlushPriorityInherit_Node;
+
+static T_remark ScoreTqReqFlushPriorityInherit_Remark = {
+ .next = NULL,
+ .remark = "ScoreTqReqFlushPriorityInherit"
+};
+
+void ScoreTqReqFlushPriorityInherit_Run( TQContext *tq_ctx )
+{
+ ScoreTqReqFlushPriorityInherit_Context *ctx;
+
+ ctx = &ScoreTqReqFlushPriorityInherit_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreTqReqFlushPriorityInherit_Node,
+ &ScoreTqReqFlushPriorityInherit_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = ScoreTqReqFlushPriorityInherit_Pre_Priority_Minimum;
+ ctx->Map.pci[ 0 ] < ScoreTqReqFlushPriorityInherit_Pre_Priority_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = ScoreTqReqFlushPriorityInherit_Pre_Queue_Empty;
+ ctx->Map.pci[ 1 ] < ScoreTqReqFlushPriorityInherit_Pre_Queue_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ ctx->Map.entry = ScoreTqReqFlushPriorityInherit_PopEntry( ctx );
+ ScoreTqReqFlushPriorityInherit_SetPreConditionStates( ctx );
+ ScoreTqReqFlushPriorityInherit_TestVariant( ctx );
+ }
+ }
+
+ T_add_remark( &ScoreTqReqFlushPriorityInherit_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-tq-flush-priority-inherit.h b/testsuites/validation/tr-tq-flush-priority-inherit.h
new file mode 100644
index 0000000000..277084244c
--- /dev/null
+++ b/testsuites/validation/tr-tq-flush-priority-inherit.h
@@ -0,0 +1,103 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqFlushPriorityInherit
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_TQ_FLUSH_PRIORITY_INHERIT_H
+#define _TR_TQ_FLUSH_PRIORITY_INHERIT_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreTqReqFlushPriorityInherit
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreTqReqFlushPriorityInherit_Pre_Priority_Minimum,
+ ScoreTqReqFlushPriorityInherit_Pre_Priority_NotMinimum,
+ ScoreTqReqFlushPriorityInherit_Pre_Priority_NA
+} ScoreTqReqFlushPriorityInherit_Pre_Priority;
+
+typedef enum {
+ ScoreTqReqFlushPriorityInherit_Pre_Queue_Empty,
+ ScoreTqReqFlushPriorityInherit_Pre_Queue_NonEmpty,
+ ScoreTqReqFlushPriorityInherit_Pre_Queue_NA
+} ScoreTqReqFlushPriorityInherit_Pre_Queue;
+
+typedef enum {
+ ScoreTqReqFlushPriorityInherit_Post_Extract_Nop,
+ ScoreTqReqFlushPriorityInherit_Post_Extract_All,
+ ScoreTqReqFlushPriorityInherit_Post_Extract_NA
+} ScoreTqReqFlushPriorityInherit_Post_Extract;
+
+typedef enum {
+ ScoreTqReqFlushPriorityInherit_Post_PriorityUpdate_No,
+ ScoreTqReqFlushPriorityInherit_Post_PriorityUpdate_Yes,
+ ScoreTqReqFlushPriorityInherit_Post_PriorityUpdate_NA
+} ScoreTqReqFlushPriorityInherit_Post_PriorityUpdate;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue test context.
+ */
+void ScoreTqReqFlushPriorityInherit_Run( TQContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_TQ_FLUSH_PRIORITY_INHERIT_H */
diff --git a/testsuites/validation/tr-tq-flush-priority.c b/testsuites/validation/tr-tq-flush-priority.c
new file mode 100644
index 0000000000..b8a06c2340
--- /dev/null
+++ b/testsuites/validation/tr-tq-flush-priority.c
@@ -0,0 +1,424 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqFlushPriority
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-tq-flush-priority.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTqReqFlushPriority spec:/score/tq/req/flush-priority
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Queue_NA : 1;
+ uint8_t Post_Operation : 2;
+} ScoreTqReqFlushPriority_Entry;
+
+/**
+ * @brief Test context for spec:/score/tq/req/flush-priority test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the call within ISR request.
+ */
+ CallWithinISRRequest request;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreTqReqFlushPriority_Run() parameter.
+ */
+ TQContext *tq_ctx;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreTqReqFlushPriority_Run() parameter.
+ */
+ bool supports_multiple_priority_queues;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreTqReqFlushPriority_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreTqReqFlushPriority_Context;
+
+static ScoreTqReqFlushPriority_Context
+ ScoreTqReqFlushPriority_Instance;
+
+static const char * const ScoreTqReqFlushPriority_PreDesc_Queue[] = {
+ "Empty",
+ "NonEmpty",
+ "NA"
+};
+
+static const char * const * const ScoreTqReqFlushPriority_PreDesc[] = {
+ ScoreTqReqFlushPriority_PreDesc_Queue,
+ NULL
+};
+
+typedef ScoreTqReqFlushPriority_Context Context;
+
+static const T_scheduler_event *GetUnblock( Context *ctx, size_t *index )
+{
+ return TQGetNextUnblock( ctx->tq_ctx, index );
+}
+
+static const rtems_tcb *GetTCB( Context *ctx, TQWorkerKind worker )
+{
+ return ctx->tq_ctx->worker_tcb[ worker ];
+}
+
+static void Flush( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ TQFlush( ctx->tq_ctx, true );
+}
+
+static void SchedulerEvent(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ if (
+ when == T_SCHEDULER_BEFORE &&
+ event->operation == T_SCHEDULER_BLOCK
+ ) {
+ ctx->request.handler = Flush;
+ ctx->request.arg = ctx;
+ CallWithinISRSubmit( &ctx->request );
+ T_scheduler_set_event_handler( NULL, NULL );
+ }
+}
+
+static void ScoreTqReqFlushPriority_Pre_Queue_Prepare(
+ ScoreTqReqFlushPriority_Context *ctx,
+ ScoreTqReqFlushPriority_Pre_Queue state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqFlushPriority_Pre_Queue_Empty: {
+ /*
+ * While the thread queue is empty.
+ */
+ ctx->tq_ctx->how_many = 0;
+ break;
+ }
+
+ case ScoreTqReqFlushPriority_Pre_Queue_NonEmpty: {
+ /*
+ * While the thread queue has at least one enqueued thread.
+ */
+ ctx->tq_ctx->how_many = 3;
+ break;
+ }
+
+ case ScoreTqReqFlushPriority_Pre_Queue_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqFlushPriority_Post_Operation_Check(
+ ScoreTqReqFlushPriority_Context *ctx,
+ ScoreTqReqFlushPriority_Post_Operation state
+)
+{
+ size_t i;
+ const T_scheduler_event *event;
+
+ i = 0;
+
+ switch ( state ) {
+ case ScoreTqReqFlushPriority_Post_Operation_Nop: {
+ /*
+ * No operation shall be performed.
+ */
+ /* Event receive */
+ T_eq_ptr( GetUnblock( ctx, &i )->thread, GetTCB( ctx, TQ_BLOCKER_A ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), &T_scheduler_event_null );
+ break;
+ }
+
+ case ScoreTqReqFlushPriority_Post_Operation_TryExtract: {
+ /*
+ * The enqueued threads of the thread queue may be extracted in priority
+ * order for each priority queue associated with a scheduler. The
+ * priority queues of the thread queue shall be accessed in FIFO order.
+ */
+ event = GetUnblock( ctx, &i );
+ T_eq_ptr( event->executing, NULL );
+ T_eq_ptr( event->thread, GetTCB( ctx, TQ_BLOCKER_D ) );
+
+ event = GetUnblock( ctx, &i );
+ T_eq_ptr( event->executing, NULL );
+ T_eq_ptr( event->thread, GetTCB( ctx, TQ_BLOCKER_C ) );
+
+ event = GetUnblock( ctx, &i );
+ T_eq_ptr( event->executing, GetTCB( ctx, TQ_BLOCKER_B ) );
+ T_eq_ptr( event->thread, GetTCB( ctx, TQ_BLOCKER_B ) );
+
+ T_eq_ptr( GetUnblock( ctx, &i ), &T_scheduler_event_null );
+ break;
+ }
+
+ case ScoreTqReqFlushPriority_Post_Operation_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqFlushPriority_Setup(
+ ScoreTqReqFlushPriority_Context *ctx
+)
+{
+ TQReset( ctx->tq_ctx );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_A, PRIO_ULTRA_HIGH );
+
+ if (
+ ctx->supports_multiple_priority_queues &&
+ rtems_configuration_get_maximum_processors() > 1
+ ) {
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_B, SCHEDULER_B_ID, PRIO_HIGH );
+ } else {
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_B, PRIO_HIGH );
+ }
+
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_C, PRIO_VERY_HIGH );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_D, PRIO_ULTRA_HIGH );
+}
+
+static void ScoreTqReqFlushPriority_Setup_Wrap( void *arg )
+{
+ ScoreTqReqFlushPriority_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqFlushPriority_Setup( ctx );
+}
+
+static void ScoreTqReqFlushPriority_Teardown(
+ ScoreTqReqFlushPriority_Context *ctx
+)
+{
+ TQReset( ctx->tq_ctx );
+}
+
+static void ScoreTqReqFlushPriority_Teardown_Wrap( void *arg )
+{
+ ScoreTqReqFlushPriority_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqFlushPriority_Teardown( ctx );
+}
+
+static void ScoreTqReqFlushPriority_Action(
+ ScoreTqReqFlushPriority_Context *ctx
+)
+{
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE_PREPARE );
+
+ if ( ctx->tq_ctx->how_many > 0 ) {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_C, TQ_EVENT_ENQUEUE );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_D, TQ_EVENT_ENQUEUE );
+ T_scheduler_set_event_handler( SchedulerEvent, ctx );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_BLOCKER_B,
+ TQ_EVENT_ENQUEUE
+ );
+ } else {
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_FLUSH_ALL );
+ }
+
+ TQSchedulerRecordStop( ctx->tq_ctx );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE_DONE );
+}
+
+static const ScoreTqReqFlushPriority_Entry
+ScoreTqReqFlushPriority_Entries[] = {
+ { 0, 0, ScoreTqReqFlushPriority_Post_Operation_Nop },
+ { 0, 0, ScoreTqReqFlushPriority_Post_Operation_TryExtract }
+};
+
+static const uint8_t
+ScoreTqReqFlushPriority_Map[] = {
+ 0, 1
+};
+
+static size_t ScoreTqReqFlushPriority_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreTqReqFlushPriority_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ ScoreTqReqFlushPriority_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreTqReqFlushPriority_Fixture = {
+ .setup = ScoreTqReqFlushPriority_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreTqReqFlushPriority_Teardown_Wrap,
+ .scope = ScoreTqReqFlushPriority_Scope,
+ .initial_context = &ScoreTqReqFlushPriority_Instance
+};
+
+static inline ScoreTqReqFlushPriority_Entry ScoreTqReqFlushPriority_PopEntry(
+ ScoreTqReqFlushPriority_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return ScoreTqReqFlushPriority_Entries[
+ ScoreTqReqFlushPriority_Map[ index ]
+ ];
+}
+
+static void ScoreTqReqFlushPriority_TestVariant(
+ ScoreTqReqFlushPriority_Context *ctx
+)
+{
+ ScoreTqReqFlushPriority_Pre_Queue_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ ScoreTqReqFlushPriority_Action( ctx );
+ ScoreTqReqFlushPriority_Post_Operation_Check(
+ ctx,
+ ctx->Map.entry.Post_Operation
+ );
+}
+
+static T_fixture_node ScoreTqReqFlushPriority_Node;
+
+static T_remark ScoreTqReqFlushPriority_Remark = {
+ .next = NULL,
+ .remark = "ScoreTqReqFlushPriority"
+};
+
+void ScoreTqReqFlushPriority_Run(
+ TQContext *tq_ctx,
+ bool supports_multiple_priority_queues
+)
+{
+ ScoreTqReqFlushPriority_Context *ctx;
+
+ ctx = &ScoreTqReqFlushPriority_Instance;
+ ctx->tq_ctx = tq_ctx;
+ ctx->supports_multiple_priority_queues = supports_multiple_priority_queues;
+
+ ctx = T_push_fixture(
+ &ScoreTqReqFlushPriority_Node,
+ &ScoreTqReqFlushPriority_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = ScoreTqReqFlushPriority_Pre_Queue_Empty;
+ ctx->Map.pcs[ 0 ] < ScoreTqReqFlushPriority_Pre_Queue_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = ScoreTqReqFlushPriority_PopEntry( ctx );
+ ScoreTqReqFlushPriority_TestVariant( ctx );
+ }
+
+ T_add_remark( &ScoreTqReqFlushPriority_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-tq-flush-priority.h b/testsuites/validation/tr-tq-flush-priority.h
new file mode 100644
index 0000000000..ae700ca192
--- /dev/null
+++ b/testsuites/validation/tr-tq-flush-priority.h
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqFlushPriority
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_TQ_FLUSH_PRIORITY_H
+#define _TR_TQ_FLUSH_PRIORITY_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreTqReqFlushPriority
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreTqReqFlushPriority_Pre_Queue_Empty,
+ ScoreTqReqFlushPriority_Pre_Queue_NonEmpty,
+ ScoreTqReqFlushPriority_Pre_Queue_NA
+} ScoreTqReqFlushPriority_Pre_Queue;
+
+typedef enum {
+ ScoreTqReqFlushPriority_Post_Operation_Nop,
+ ScoreTqReqFlushPriority_Post_Operation_TryExtract,
+ ScoreTqReqFlushPriority_Post_Operation_NA
+} ScoreTqReqFlushPriority_Post_Operation;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue test context.
+ *
+ * @param supports_multiple_priority_queues is true, if the object using the
+ * thread queue supports multiple priority queues, otherwise it is false.
+ */
+void ScoreTqReqFlushPriority_Run(
+ TQContext *tq_ctx,
+ bool supports_multiple_priority_queues
+);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_TQ_FLUSH_PRIORITY_H */
diff --git a/testsuites/validation/tr-tq-surrender-mrsp.c b/testsuites/validation/tr-tq-surrender-mrsp.c
new file mode 100644
index 0000000000..903146ccbe
--- /dev/null
+++ b/testsuites/validation/tr-tq-surrender-mrsp.c
@@ -0,0 +1,1041 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqSurrenderMrsp
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/threadimpl.h>
+
+#include "tr-tq-surrender-mrsp.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTqReqSurrenderMrsp spec:/score/tq/req/surrender-mrsp
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_InheritedPriority_NA : 1;
+ uint32_t Pre_PreviousHelping_NA : 1;
+ uint32_t Pre_Scheduler_NA : 1;
+ uint32_t Pre_NewHelping_NA : 1;
+ uint32_t Pre_Suspended_NA : 1;
+ uint32_t Pre_WaitState_NA : 1;
+ uint32_t Post_Dequeue : 1;
+ uint32_t Post_Unblock : 1;
+ uint32_t Post_PreviousOwnerPriority : 2;
+ uint32_t Post_RemoveHelper : 2;
+ uint32_t Post_AddHelper : 2;
+ uint32_t Post_Suspended : 2;
+} ScoreTqReqSurrenderMrsp_Entry;
+
+/**
+ * @brief Test context for spec:/score/tq/req/surrender-mrsp test case.
+ */
+typedef struct {
+ /**
+ * @brief If this member is true, then all priorities of the previous owner
+ * inherited from the thread queue thread shall be dispensable.
+ */
+ bool inherited_priorities_are_dispensible;
+
+ /**
+ * @brief If this member is true, then all helping schedulers of the previous
+ * owner thread gained through the thread queue shall be dispensable.
+ */
+ bool helping_schedules_are_dispensible;
+
+ /**
+ * @brief If this member is true, then the previous owner thread shall use
+ * helping scheduler.
+ */
+ bool use_helping_scheduler;
+
+ /**
+ * @brief If this member is true, then the new owner thread shall gain a
+ * vital helping scheduler.
+ */
+ bool gains_new_helping_scheduler;
+
+ /**
+ * @brief If this member is true, then the new owner thread shall be
+ * suspended.
+ */
+ bool suspended;
+
+ /**
+ * @brief If this member is true, then the new owner thread shall be in the
+ * intend to block wait state.
+ */
+ bool intend_to_block;
+
+ /**
+ * @brief This member contains the current priority of the previous owner
+ * thread before the thread queue surrender operation.
+ */
+ rtems_task_priority priority_before;
+
+ /**
+ * @brief This member contains the current priority of the previous owner
+ * thread after the thread queue surrender operation.
+ */
+ rtems_task_priority priority_after;
+
+ /**
+ * @brief This member contains the identifier of the previous owner thread.
+ */
+ rtems_id previous_owner;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreTqReqSurrenderMrsp_Run() parameter.
+ */
+ TQContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 6 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreTqReqSurrenderMrsp_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreTqReqSurrenderMrsp_Context;
+
+static ScoreTqReqSurrenderMrsp_Context
+ ScoreTqReqSurrenderMrsp_Instance;
+
+static const char * const ScoreTqReqSurrenderMrsp_PreDesc_InheritedPriority[] = {
+ "Vital",
+ "Dispensable",
+ "NA"
+};
+
+static const char * const ScoreTqReqSurrenderMrsp_PreDesc_PreviousHelping[] = {
+ "Vital",
+ "Dispensable",
+ "NA"
+};
+
+static const char * const ScoreTqReqSurrenderMrsp_PreDesc_Scheduler[] = {
+ "Home",
+ "Helping",
+ "NA"
+};
+
+static const char * const ScoreTqReqSurrenderMrsp_PreDesc_NewHelping[] = {
+ "Vital",
+ "Dispensable",
+ "NA"
+};
+
+static const char * const ScoreTqReqSurrenderMrsp_PreDesc_Suspended[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const ScoreTqReqSurrenderMrsp_PreDesc_WaitState[] = {
+ "IntendToBlock",
+ "NA"
+};
+
+static const char * const * const ScoreTqReqSurrenderMrsp_PreDesc[] = {
+ ScoreTqReqSurrenderMrsp_PreDesc_InheritedPriority,
+ ScoreTqReqSurrenderMrsp_PreDesc_PreviousHelping,
+ ScoreTqReqSurrenderMrsp_PreDesc_Scheduler,
+ ScoreTqReqSurrenderMrsp_PreDesc_NewHelping,
+ ScoreTqReqSurrenderMrsp_PreDesc_Suspended,
+ ScoreTqReqSurrenderMrsp_PreDesc_WaitState,
+ NULL
+};
+
+typedef ScoreTqReqSurrenderMrsp_Context Context;
+
+static const rtems_tcb *GetUnblock( Context *ctx, size_t *index )
+{
+ return TQGetNextUnblock( ctx->tq_ctx, index )->thread;
+}
+
+static void ScoreTqReqSurrenderMrsp_Pre_InheritedPriority_Prepare(
+ ScoreTqReqSurrenderMrsp_Context *ctx,
+ ScoreTqReqSurrenderMrsp_Pre_InheritedPriority state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderMrsp_Pre_InheritedPriority_Vital: {
+ /*
+ * While at least one priority inherited through the thread queue for the
+ * previous owner is the highest priority of the previous owner.
+ */
+ ctx->inherited_priorities_are_dispensible = false;
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Pre_InheritedPriority_Dispensable: {
+ /*
+ * While all priorities inherited through the thread queue for the
+ * previous owner are not the highest priority of the previous owner.
+ */
+ ctx->inherited_priorities_are_dispensible = true;
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Pre_InheritedPriority_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderMrsp_Pre_PreviousHelping_Prepare(
+ ScoreTqReqSurrenderMrsp_Context *ctx,
+ ScoreTqReqSurrenderMrsp_Pre_PreviousHelping state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderMrsp_Pre_PreviousHelping_Vital: {
+ /*
+ * While at least one helping scheduler of the previous owner is only
+ * available due to a priority inherited through the thread queue.
+ */
+ ctx->helping_schedules_are_dispensible = false;
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Pre_PreviousHelping_Dispensable: {
+ /*
+ * While all helping scheduler of the previous owner are not only
+ * available due to a priority inherited through the thread queue.
+ */
+ ctx->helping_schedules_are_dispensible = true;
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Pre_PreviousHelping_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderMrsp_Pre_Scheduler_Prepare(
+ ScoreTqReqSurrenderMrsp_Context *ctx,
+ ScoreTqReqSurrenderMrsp_Pre_Scheduler state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderMrsp_Pre_Scheduler_Home: {
+ /*
+ * While the previous owner executes in its home scheduler.
+ */
+ ctx->use_helping_scheduler = false;
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Pre_Scheduler_Helping: {
+ /*
+ * While the previous owner executes in a helping scheduler which is
+ * available due to a priority inherited through the thread queue.
+ */
+ ctx->use_helping_scheduler = true;
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Pre_Scheduler_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderMrsp_Pre_NewHelping_Prepare(
+ ScoreTqReqSurrenderMrsp_Context *ctx,
+ ScoreTqReqSurrenderMrsp_Pre_NewHelping state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderMrsp_Pre_NewHelping_Vital: {
+ /*
+ * While at least one helping scheduler of the new owner is only
+ * available due to a priority inherited through the thread queue.
+ */
+ ctx->gains_new_helping_scheduler = true;
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Pre_NewHelping_Dispensable: {
+ /*
+ * While all helping scheduler of the new owner are not only available
+ * due to a priority inherited through the thread queue.
+ */
+ ctx->gains_new_helping_scheduler = false;
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Pre_NewHelping_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderMrsp_Pre_Suspended_Prepare(
+ ScoreTqReqSurrenderMrsp_Context *ctx,
+ ScoreTqReqSurrenderMrsp_Pre_Suspended state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderMrsp_Pre_Suspended_Yes: {
+ /*
+ * While the new owner is suspended.
+ */
+ ctx->suspended = true;
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Pre_Suspended_No: {
+ /*
+ * While the new owner is not suspended.
+ */
+ ctx->suspended = false;
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Pre_Suspended_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderMrsp_Pre_WaitState_Prepare(
+ ScoreTqReqSurrenderMrsp_Context *ctx,
+ ScoreTqReqSurrenderMrsp_Pre_WaitState state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderMrsp_Pre_WaitState_IntendToBlock: {
+ /*
+ * While the new owner is in the intend to block wait state.
+ */
+ ctx->intend_to_block = true;
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Pre_WaitState_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderMrsp_Post_Dequeue_Check(
+ ScoreTqReqSurrenderMrsp_Context *ctx,
+ ScoreTqReqSurrenderMrsp_Post_Dequeue state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority: {
+ /*
+ * The first thread in priority order shall be dequeued from the thread
+ * queue.
+ */
+ /* Validation is done by spec:/score/tq/req/enqueue-priority */
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Post_Dequeue_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderMrsp_Post_Unblock_Check(
+ ScoreTqReqSurrenderMrsp_Context *ctx,
+ ScoreTqReqSurrenderMrsp_Post_Unblock state
+)
+{
+ size_t i;
+
+ i = 0;
+
+ switch ( state ) {
+ case ScoreTqReqSurrenderMrsp_Post_Unblock_No: {
+ /*
+ * The dequeued thread shall not be unblocked by the thread queue
+ * surrender operation.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Post_Unblock_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Check(
+ ScoreTqReqSurrenderMrsp_Context *ctx,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Drop: {
+ /*
+ * Each eligible priority of the previous owner which had the highest
+ * priority inherited through the thread queue shall be updated.
+ */
+ T_eq_u32( ctx->priority_after, PRIO_NORMAL );
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Nop: {
+ /*
+ * No eligible priority of the previous owner shall be updated.
+ */
+ T_eq_u32( ctx->priority_after, ctx->priority_before );
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderMrsp_Post_RemoveHelper_Check(
+ ScoreTqReqSurrenderMrsp_Context *ctx,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper state
+)
+{
+ rtems_status_code sc;
+ rtems_task_priority priority;
+
+ switch ( state ) {
+ case ScoreTqReqSurrenderMrsp_Post_RemoveHelper_Yes: {
+ /*
+ * Each helping scheduler of the previous owner which was only available
+ * due to a priority inherited through the thread queue shall be removed
+ * from the previous owner.
+ */
+ sc = rtems_task_get_priority(
+ ctx->previous_owner,
+ SCHEDULER_B_ID,
+ &priority
+ );
+ T_rsc( sc, RTEMS_NOT_DEFINED );
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Post_RemoveHelper_No: {
+ /*
+ * No helping scheduler shall be removed from the previous owner.
+ */
+ sc = rtems_task_get_priority(
+ ctx->previous_owner,
+ SCHEDULER_B_ID,
+ &priority
+ );
+ #if defined(RTEMS_SMP)
+ T_rsc_success( sc );
+
+ if ( ctx->tq_ctx->enqueue_variant == TQ_ENQUEUE_STICKY ) {
+ T_eq_u32( priority, PRIO_LOW );
+ } else {
+ T_eq_u32( priority, PRIO_HIGH );
+ }
+ #else
+ T_rsc( sc, RTEMS_INVALID_ID );
+ #endif
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Post_RemoveHelper_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderMrsp_Post_AddHelper_Check(
+ ScoreTqReqSurrenderMrsp_Context *ctx,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper state
+)
+{
+ rtems_status_code sc;
+ rtems_task_priority priority;
+
+ switch ( state ) {
+ case ScoreTqReqSurrenderMrsp_Post_AddHelper_Yes: {
+ /*
+ * Each helping scheduler of the new owner which is only available due to
+ * a priority inherited through the thread queue shall be added to the
+ * new owner.
+ */
+ sc = rtems_task_get_priority(
+ ctx->tq_ctx->worker_id[ TQ_BLOCKER_A ],
+ SCHEDULER_A_ID,
+ &priority
+ );
+ T_rsc_success( sc );
+
+ if ( ctx->tq_ctx->enqueue_variant == TQ_ENQUEUE_STICKY ) {
+ T_eq_u32( priority, PRIO_VERY_HIGH );
+ } else {
+ T_eq_u32( priority, PRIO_LOW );
+ }
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Post_AddHelper_No: {
+ /*
+ * No helping scheduler shall added to the new owner.
+ */
+ sc = rtems_task_get_priority(
+ ctx->tq_ctx->worker_id[ TQ_BLOCKER_A ],
+ SCHEDULER_A_ID,
+ &priority
+ );
+ #if defined(RTEMS_SMP)
+ T_rsc( sc, RTEMS_NOT_DEFINED );
+ #else
+ T_rsc_success( sc );
+ T_eq_u32( priority, PRIO_HIGH );
+ #endif
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Post_AddHelper_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderMrsp_Post_Suspended_Check(
+ ScoreTqReqSurrenderMrsp_Context *ctx,
+ ScoreTqReqSurrenderMrsp_Post_Suspended state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderMrsp_Post_Suspended_Yes: {
+ /*
+ * The new owner shall be suspended.
+ */
+ T_true( IsTaskSuspended( ctx->tq_ctx->worker_id[ TQ_BLOCKER_A ] ) );
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Post_Suspended_No: {
+ /*
+ * The new owner shall be not suspended.
+ */
+ T_false( IsTaskSuspended( ctx->tq_ctx->worker_id[ TQ_BLOCKER_A ] ) );
+ break;
+ }
+
+ case ScoreTqReqSurrenderMrsp_Post_Suspended_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderMrsp_Setup(
+ ScoreTqReqSurrenderMrsp_Context *ctx
+)
+{
+ TQReset( ctx->tq_ctx );
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_A, SCHEDULER_B_ID, PRIO_NORMAL );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_B, PRIO_VERY_HIGH );
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_C, SCHEDULER_B_ID, PRIO_LOW );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_D, PRIO_VERY_HIGH );
+ TQSetPriority( ctx->tq_ctx, TQ_HELPER_A, PRIO_NORMAL );
+}
+
+static void ScoreTqReqSurrenderMrsp_Setup_Wrap( void *arg )
+{
+ ScoreTqReqSurrenderMrsp_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqSurrenderMrsp_Setup( ctx );
+}
+
+static void ScoreTqReqSurrenderMrsp_Teardown(
+ ScoreTqReqSurrenderMrsp_Context *ctx
+)
+{
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_NORMAL );
+}
+
+static void ScoreTqReqSurrenderMrsp_Teardown_Wrap( void *arg )
+{
+ ScoreTqReqSurrenderMrsp_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqSurrenderMrsp_Teardown( ctx );
+}
+
+static void ScoreTqReqSurrenderMrsp_Prepare(
+ ScoreTqReqSurrenderMrsp_Context *ctx
+)
+{
+ ctx->inherited_priorities_are_dispensible = true;
+ ctx->helping_schedules_are_dispensible = true;
+ ctx->use_helping_scheduler = false;
+ ctx->gains_new_helping_scheduler = false;
+ ctx->intend_to_block = false;
+}
+
+static void ScoreTqReqSurrenderMrsp_Action(
+ ScoreTqReqSurrenderMrsp_Context *ctx
+)
+{
+ ctx->previous_owner = ctx->tq_ctx->worker_id[ TQ_HELPER_A ];
+
+ SetSelfPriority( PRIO_LOW );
+
+ if (
+ ctx->inherited_priorities_are_dispensible ||
+ ctx->helping_schedules_are_dispensible
+ ) {
+ TQSend( ctx->tq_ctx, TQ_HELPER_A, TQ_EVENT_MUTEX_A_OBTAIN );
+
+ if ( ctx->inherited_priorities_are_dispensible ) {
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_B, TQ_EVENT_MUTEX_A_OBTAIN );
+ }
+
+ if ( ctx->helping_schedules_are_dispensible ) {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_BLOCKER_C,
+ TQ_EVENT_MUTEX_A_OBTAIN
+ );
+ }
+ }
+
+ /*
+ * Take only the priorities into account which are inherited from the
+ * priority inheritance mutex. This avoids having to deal with the ceiling
+ * priority.
+ */
+ ctx->priority_before = TQGetPriority( ctx->tq_ctx, TQ_HELPER_A );
+
+ SetSelfScheduler( SCHEDULER_B_ID, PRIO_ULTRA_HIGH );
+ ctx->tq_ctx->busy_wait[ TQ_HELPER_A ] = true;
+ TQSendAndSynchronizeRunner(
+ ctx->tq_ctx,
+ TQ_HELPER_A,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_BUSY_WAIT
+ );
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_ULTRA_HIGH );
+
+ TQSendAndWaitForIntendToBlock(
+ ctx->tq_ctx,
+ TQ_BLOCKER_A,
+ TQ_EVENT_ENQUEUE
+ );
+
+ SetSelfScheduler( SCHEDULER_B_ID, PRIO_ULTRA_HIGH );
+
+ if ( ctx->gains_new_helping_scheduler ) {
+ TQSend(
+ ctx->tq_ctx,
+ TQ_BLOCKER_D,
+ TQ_EVENT_ENQUEUE
+ );
+ YieldTask( ctx->tq_ctx->worker_id[ TQ_HELPER_A ] );
+ TQWaitForEventsReceived( ctx->tq_ctx, TQ_BLOCKER_D );
+ TQWaitForIntendToBlock( ctx->tq_ctx, TQ_BLOCKER_D );
+ YieldTask( ctx->tq_ctx->worker_id[ TQ_BLOCKER_D ] );
+ }
+
+ if ( ctx->use_helping_scheduler ) {
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_ULTRA_HIGH );
+ WaitForHeir( 1, ctx->tq_ctx->worker_id[ TQ_HELPER_A ] );
+ }
+
+ if ( ctx->suspended ) {
+ SuspendTask( ctx->tq_ctx->worker_id[ TQ_BLOCKER_A ] );
+ }
+
+ ctx->tq_ctx->busy_wait[ TQ_HELPER_A ] = false;
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_HELPER_A,
+ TQ_EVENT_SCHEDULER_RECORD_START |
+ TQ_EVENT_SURRENDER
+ );
+ TQSchedulerRecordStop( ctx->tq_ctx );
+ T_eq_ptr(
+ TQGetOwner( ctx->tq_ctx ),
+ ctx->tq_ctx->worker_tcb[ TQ_BLOCKER_A ]
+ );
+ ctx->priority_after = TQGetPriority( ctx->tq_ctx, TQ_HELPER_A );
+}
+
+static void ScoreTqReqSurrenderMrsp_Cleanup(
+ ScoreTqReqSurrenderMrsp_Context *ctx
+)
+{
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_ULTRA_HIGH );
+
+ if ( ctx->suspended ) {
+ ResumeTask( ctx->tq_ctx->worker_id[ TQ_BLOCKER_A ] );
+ }
+
+ TQSendAndSynchronizeRunner(
+ ctx->tq_ctx,
+ TQ_BLOCKER_A,
+ TQ_EVENT_SURRENDER
+ );
+
+ if ( ctx->gains_new_helping_scheduler ) {
+ TQSendAndSynchronizeRunner(
+ ctx->tq_ctx,
+ TQ_BLOCKER_D,
+ TQ_EVENT_SURRENDER
+ );
+ }
+
+ if (
+ ctx->inherited_priorities_are_dispensible ||
+ ctx->helping_schedules_are_dispensible
+ ) {
+ TQSendAndSynchronizeRunner(
+ ctx->tq_ctx,
+ TQ_HELPER_A,
+ TQ_EVENT_MUTEX_A_RELEASE
+ );
+
+ if ( ctx->inherited_priorities_are_dispensible ) {
+ TQSendAndSynchronizeRunner(
+ ctx->tq_ctx,
+ TQ_BLOCKER_B,
+ TQ_EVENT_MUTEX_A_RELEASE
+ );
+ }
+
+ if ( ctx->helping_schedules_are_dispensible ) {
+ TQSendAndSynchronizeRunner(
+ ctx->tq_ctx,
+ TQ_BLOCKER_C,
+ TQ_EVENT_MUTEX_A_RELEASE
+ );
+ }
+ }
+
+ T_eq_u32( rtems_scheduler_get_processor(), 0 );
+}
+
+static const ScoreTqReqSurrenderMrsp_Entry
+ScoreTqReqSurrenderMrsp_Entries[] = {
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderMrsp_Post_Unblock_No,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_Yes },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderMrsp_Post_Unblock_No,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_No },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderMrsp_Post_Unblock_No,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_Yes },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderMrsp_Post_Unblock_No,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_No },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderMrsp_Post_Unblock_No,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_Yes },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderMrsp_Post_Unblock_No,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_No },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderMrsp_Post_Unblock_No,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_Yes },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderMrsp_Post_Unblock_No,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_No },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderMrsp_Post_Unblock_No,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_Yes },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderMrsp_Post_Unblock_No,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_No },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderMrsp_Post_Unblock_No,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_Yes },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderMrsp_Post_Unblock_No,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_No },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderMrsp_Post_Unblock_No,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_Yes },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderMrsp_Post_Unblock_No,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_No },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderMrsp_Post_Unblock_No,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_Yes },
+ { 0, 0, 0, 0, 0, 0, 0, ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderMrsp_Post_Unblock_No,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_No }
+};
+
+static const uint8_t
+ScoreTqReqSurrenderMrsp_Map[] = {
+ 0, 1, 2, 3, 0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 8, 9, 10, 11, 8, 9, 10, 11,
+ 12, 13, 14, 15, 12, 13, 14, 15
+};
+
+static size_t ScoreTqReqSurrenderMrsp_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreTqReqSurrenderMrsp_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ ScoreTqReqSurrenderMrsp_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreTqReqSurrenderMrsp_Fixture = {
+ .setup = ScoreTqReqSurrenderMrsp_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreTqReqSurrenderMrsp_Teardown_Wrap,
+ .scope = ScoreTqReqSurrenderMrsp_Scope,
+ .initial_context = &ScoreTqReqSurrenderMrsp_Instance
+};
+
+static inline ScoreTqReqSurrenderMrsp_Entry ScoreTqReqSurrenderMrsp_PopEntry(
+ ScoreTqReqSurrenderMrsp_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return ScoreTqReqSurrenderMrsp_Entries[
+ ScoreTqReqSurrenderMrsp_Map[ index ]
+ ];
+}
+
+static void ScoreTqReqSurrenderMrsp_TestVariant(
+ ScoreTqReqSurrenderMrsp_Context *ctx
+)
+{
+ ScoreTqReqSurrenderMrsp_Pre_InheritedPriority_Prepare(
+ ctx,
+ ctx->Map.pcs[ 0 ]
+ );
+ ScoreTqReqSurrenderMrsp_Pre_PreviousHelping_Prepare(
+ ctx,
+ ctx->Map.pcs[ 1 ]
+ );
+ ScoreTqReqSurrenderMrsp_Pre_Scheduler_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ ScoreTqReqSurrenderMrsp_Pre_NewHelping_Prepare( ctx, ctx->Map.pcs[ 3 ] );
+ ScoreTqReqSurrenderMrsp_Pre_Suspended_Prepare( ctx, ctx->Map.pcs[ 4 ] );
+ ScoreTqReqSurrenderMrsp_Pre_WaitState_Prepare( ctx, ctx->Map.pcs[ 5 ] );
+ ScoreTqReqSurrenderMrsp_Action( ctx );
+ ScoreTqReqSurrenderMrsp_Post_Dequeue_Check(
+ ctx,
+ ctx->Map.entry.Post_Dequeue
+ );
+ ScoreTqReqSurrenderMrsp_Post_Unblock_Check(
+ ctx,
+ ctx->Map.entry.Post_Unblock
+ );
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Check(
+ ctx,
+ ctx->Map.entry.Post_PreviousOwnerPriority
+ );
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_Check(
+ ctx,
+ ctx->Map.entry.Post_RemoveHelper
+ );
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_Check(
+ ctx,
+ ctx->Map.entry.Post_AddHelper
+ );
+ ScoreTqReqSurrenderMrsp_Post_Suspended_Check(
+ ctx,
+ ctx->Map.entry.Post_Suspended
+ );
+}
+
+static T_fixture_node ScoreTqReqSurrenderMrsp_Node;
+
+static T_remark ScoreTqReqSurrenderMrsp_Remark = {
+ .next = NULL,
+ .remark = "ScoreTqReqSurrenderMrsp"
+};
+
+void ScoreTqReqSurrenderMrsp_Run( TQContext *tq_ctx )
+{
+ ScoreTqReqSurrenderMrsp_Context *ctx;
+
+ ctx = &ScoreTqReqSurrenderMrsp_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreTqReqSurrenderMrsp_Node,
+ &ScoreTqReqSurrenderMrsp_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = ScoreTqReqSurrenderMrsp_Pre_InheritedPriority_Vital;
+ ctx->Map.pcs[ 0 ] < ScoreTqReqSurrenderMrsp_Pre_InheritedPriority_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = ScoreTqReqSurrenderMrsp_Pre_PreviousHelping_Vital;
+ ctx->Map.pcs[ 1 ] < ScoreTqReqSurrenderMrsp_Pre_PreviousHelping_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = ScoreTqReqSurrenderMrsp_Pre_Scheduler_Home;
+ ctx->Map.pcs[ 2 ] < ScoreTqReqSurrenderMrsp_Pre_Scheduler_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = ScoreTqReqSurrenderMrsp_Pre_NewHelping_Vital;
+ ctx->Map.pcs[ 3 ] < ScoreTqReqSurrenderMrsp_Pre_NewHelping_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = ScoreTqReqSurrenderMrsp_Pre_Suspended_Yes;
+ ctx->Map.pcs[ 4 ] < ScoreTqReqSurrenderMrsp_Pre_Suspended_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 5 ] = ScoreTqReqSurrenderMrsp_Pre_WaitState_IntendToBlock;
+ ctx->Map.pcs[ 5 ] < ScoreTqReqSurrenderMrsp_Pre_WaitState_NA;
+ ++ctx->Map.pcs[ 5 ]
+ ) {
+ ctx->Map.entry = ScoreTqReqSurrenderMrsp_PopEntry( ctx );
+ ScoreTqReqSurrenderMrsp_Prepare( ctx );
+ ScoreTqReqSurrenderMrsp_TestVariant( ctx );
+ ScoreTqReqSurrenderMrsp_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+
+ T_add_remark( &ScoreTqReqSurrenderMrsp_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-tq-surrender-mrsp.h b/testsuites/validation/tr-tq-surrender-mrsp.h
new file mode 100644
index 0000000000..eff865e612
--- /dev/null
+++ b/testsuites/validation/tr-tq-surrender-mrsp.h
@@ -0,0 +1,148 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqSurrenderMrsp
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_TQ_SURRENDER_MRSP_H
+#define _TR_TQ_SURRENDER_MRSP_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreTqReqSurrenderMrsp
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreTqReqSurrenderMrsp_Pre_InheritedPriority_Vital,
+ ScoreTqReqSurrenderMrsp_Pre_InheritedPriority_Dispensable,
+ ScoreTqReqSurrenderMrsp_Pre_InheritedPriority_NA
+} ScoreTqReqSurrenderMrsp_Pre_InheritedPriority;
+
+typedef enum {
+ ScoreTqReqSurrenderMrsp_Pre_PreviousHelping_Vital,
+ ScoreTqReqSurrenderMrsp_Pre_PreviousHelping_Dispensable,
+ ScoreTqReqSurrenderMrsp_Pre_PreviousHelping_NA
+} ScoreTqReqSurrenderMrsp_Pre_PreviousHelping;
+
+typedef enum {
+ ScoreTqReqSurrenderMrsp_Pre_Scheduler_Home,
+ ScoreTqReqSurrenderMrsp_Pre_Scheduler_Helping,
+ ScoreTqReqSurrenderMrsp_Pre_Scheduler_NA
+} ScoreTqReqSurrenderMrsp_Pre_Scheduler;
+
+typedef enum {
+ ScoreTqReqSurrenderMrsp_Pre_NewHelping_Vital,
+ ScoreTqReqSurrenderMrsp_Pre_NewHelping_Dispensable,
+ ScoreTqReqSurrenderMrsp_Pre_NewHelping_NA
+} ScoreTqReqSurrenderMrsp_Pre_NewHelping;
+
+typedef enum {
+ ScoreTqReqSurrenderMrsp_Pre_Suspended_Yes,
+ ScoreTqReqSurrenderMrsp_Pre_Suspended_No,
+ ScoreTqReqSurrenderMrsp_Pre_Suspended_NA
+} ScoreTqReqSurrenderMrsp_Pre_Suspended;
+
+typedef enum {
+ ScoreTqReqSurrenderMrsp_Pre_WaitState_IntendToBlock,
+ ScoreTqReqSurrenderMrsp_Pre_WaitState_NA
+} ScoreTqReqSurrenderMrsp_Pre_WaitState;
+
+typedef enum {
+ ScoreTqReqSurrenderMrsp_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderMrsp_Post_Dequeue_NA
+} ScoreTqReqSurrenderMrsp_Post_Dequeue;
+
+typedef enum {
+ ScoreTqReqSurrenderMrsp_Post_Unblock_No,
+ ScoreTqReqSurrenderMrsp_Post_Unblock_NA
+} ScoreTqReqSurrenderMrsp_Post_Unblock;
+
+typedef enum {
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority_NA
+} ScoreTqReqSurrenderMrsp_Post_PreviousOwnerPriority;
+
+typedef enum {
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_RemoveHelper_NA
+} ScoreTqReqSurrenderMrsp_Post_RemoveHelper;
+
+typedef enum {
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_No,
+ ScoreTqReqSurrenderMrsp_Post_AddHelper_NA
+} ScoreTqReqSurrenderMrsp_Post_AddHelper;
+
+typedef enum {
+ ScoreTqReqSurrenderMrsp_Post_Suspended_Yes,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_No,
+ ScoreTqReqSurrenderMrsp_Post_Suspended_NA
+} ScoreTqReqSurrenderMrsp_Post_Suspended;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue test context.
+ */
+void ScoreTqReqSurrenderMrsp_Run( TQContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_TQ_SURRENDER_MRSP_H */
diff --git a/testsuites/validation/tr-tq-surrender-priority-inherit.c b/testsuites/validation/tr-tq-surrender-priority-inherit.c
new file mode 100644
index 0000000000..d0a580f988
--- /dev/null
+++ b/testsuites/validation/tr-tq-surrender-priority-inherit.c
@@ -0,0 +1,2522 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqSurrenderPriorityInherit
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/smpbarrier.h>
+#include <rtems/score/threadimpl.h>
+
+#include "tr-tq-surrender-priority-inherit.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTqReqSurrenderPriorityInherit \
+ * spec:/score/tq/req/surrender-priority-inherit
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_SchedulerCount_NA : 1;
+ uint32_t Pre_InheritedPriority_NA : 1;
+ uint32_t Pre_PreviousHelping_NA : 1;
+ uint32_t Pre_UsedScheduler_NA : 1;
+ uint32_t Pre_NewPriority_NA : 1;
+ uint32_t Pre_NewHelping_NA : 1;
+ uint32_t Pre_Suspended_NA : 1;
+ uint32_t Pre_WaitState_NA : 1;
+ uint32_t Post_Dequeue : 1;
+ uint32_t Post_Unblock : 2;
+ uint32_t Post_PreviousOwnerPriority : 2;
+ uint32_t Post_NewPriority : 2;
+ uint32_t Post_RemoveHelper : 2;
+ uint32_t Post_AddHelper : 2;
+ uint32_t Post_Suspended : 2;
+} ScoreTqReqSurrenderPriorityInherit_Entry;
+
+/**
+ * @brief Test context for spec:/score/tq/req/surrender-priority-inherit test
+ * case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the call within ISR request.
+ */
+ CallWithinISRRequest request;
+
+ /**
+ * @brief This member contains the barrier to synchronize the runner and the
+ * worker.
+ */
+ SMP_barrier_Control barrier;
+
+ /**
+ * @brief If this member is true, then all priorities of the previous owner
+ * inherited from the thread queue thread shall be dispensable.
+ */
+ bool inherited_priorities_are_dispensible;
+
+ /**
+ * @brief If this member is true, then all helping schedulers of the previous
+ * owner thread gained through the thread queue shall be dispensable.
+ */
+ bool helping_schedules_are_dispensible;
+
+ /**
+ * @brief If this member is true, then the previous owner thread shall use
+ * helping scheduler.
+ */
+ bool use_helping_scheduler;
+
+ /**
+ * @brief If this member is true, then the new owner thread shall gain a
+ * vital priority.
+ */
+ bool gains_new_priority;
+
+ /**
+ * @brief If this member is true, then the new owner thread shall gain a
+ * vital helping scheduler.
+ */
+ bool gains_new_helping_scheduler;
+
+ /**
+ * @brief If this member is true, then the new owner thread shall be
+ * suspended.
+ */
+ bool suspended;
+
+ /**
+ * @brief If this member is true, then the new owner thread shall be in the
+ * intend to block wait state.
+ */
+ bool intend_to_block;
+
+ /**
+ * @brief If this member is true, then the action was performed.
+ */
+ bool action_performed;
+
+ /**
+ * @brief This member contains the current priority of the previous owner
+ * thread before the thread queue surrender operation.
+ */
+ rtems_task_priority priority_before;
+
+ /**
+ * @brief This member contains the current priority of the previous owner
+ * thread after the thread queue surrender operation.
+ */
+ rtems_task_priority priority_after;
+
+ /**
+ * @brief This member contains the identifier of the previous owner thread.
+ */
+ rtems_id previous_owner;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreTqReqSurrenderPriorityInherit_Run() parameter.
+ */
+ TQContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 8 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreTqReqSurrenderPriorityInherit_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreTqReqSurrenderPriorityInherit_Context;
+
+static ScoreTqReqSurrenderPriorityInherit_Context
+ ScoreTqReqSurrenderPriorityInherit_Instance;
+
+static const char * const ScoreTqReqSurrenderPriorityInherit_PreDesc_SchedulerCount[] = {
+ "One",
+ "Two",
+ "More",
+ "NA"
+};
+
+static const char * const ScoreTqReqSurrenderPriorityInherit_PreDesc_InheritedPriority[] = {
+ "Vital",
+ "Dispensable",
+ "NA"
+};
+
+static const char * const ScoreTqReqSurrenderPriorityInherit_PreDesc_PreviousHelping[] = {
+ "Vital",
+ "Dispensable",
+ "NA"
+};
+
+static const char * const ScoreTqReqSurrenderPriorityInherit_PreDesc_UsedScheduler[] = {
+ "Home",
+ "Helping",
+ "NA"
+};
+
+static const char * const ScoreTqReqSurrenderPriorityInherit_PreDesc_NewPriority[] = {
+ "Vital",
+ "Dispensable",
+ "NA"
+};
+
+static const char * const ScoreTqReqSurrenderPriorityInherit_PreDesc_NewHelping[] = {
+ "Vital",
+ "Dispensable",
+ "NA"
+};
+
+static const char * const ScoreTqReqSurrenderPriorityInherit_PreDesc_Suspended[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const ScoreTqReqSurrenderPriorityInherit_PreDesc_WaitState[] = {
+ "Blocked",
+ "IntendToBlock",
+ "NA"
+};
+
+static const char * const * const ScoreTqReqSurrenderPriorityInherit_PreDesc[] = {
+ ScoreTqReqSurrenderPriorityInherit_PreDesc_SchedulerCount,
+ ScoreTqReqSurrenderPriorityInherit_PreDesc_InheritedPriority,
+ ScoreTqReqSurrenderPriorityInherit_PreDesc_PreviousHelping,
+ ScoreTqReqSurrenderPriorityInherit_PreDesc_UsedScheduler,
+ ScoreTqReqSurrenderPriorityInherit_PreDesc_NewPriority,
+ ScoreTqReqSurrenderPriorityInherit_PreDesc_NewHelping,
+ ScoreTqReqSurrenderPriorityInherit_PreDesc_Suspended,
+ ScoreTqReqSurrenderPriorityInherit_PreDesc_WaitState,
+ NULL
+};
+
+typedef ScoreTqReqSurrenderPriorityInherit_Context Context;
+
+#define NEW_OWNER TQ_BLOCKER_A
+
+#define PREV_OWNER_HELPER_A TQ_BLOCKER_B
+
+#define PREV_OWNER_HELPER_B TQ_BLOCKER_C
+
+#define PREV_OWNER_HELPER_C TQ_BLOCKER_D
+
+#define NEW_OWNER_NEW_HELPER TQ_BLOCKER_E
+
+#define NEW_OWNER_NEW_PRIORITY TQ_WORKER_F
+
+#define NEW_OWNER_OLD_PRIORITY TQ_HELPER_C
+
+#define PREV_OWNER_MOVER TQ_HELPER_A
+
+#define PREV_OWNER TQ_HELPER_A
+
+static const rtems_tcb *GetUnblock( Context *ctx, size_t *index )
+{
+ return TQGetNextUnblock( ctx->tq_ctx, index )->thread;
+}
+
+static const rtems_tcb *GetTCB( Context *ctx, TQWorkerKind worker )
+{
+ return ctx->tq_ctx->worker_tcb[ worker ];
+}
+
+static void Surrender( Context *ctx )
+{
+ Status_Control status;
+
+ if ( ctx->suspended ) {
+ SuspendTask( ctx->tq_ctx->worker_id[ NEW_OWNER ] );
+ }
+
+ ctx->priority_before = GetSelfPriority();
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ status = TQSurrender( ctx->tq_ctx );
+ T_eq_int( status, TQConvertStatus( ctx->tq_ctx, STATUS_SUCCESSFUL ) );
+ TQSchedulerRecordStop( ctx->tq_ctx );
+ T_eq_ptr( TQGetOwner( ctx->tq_ctx ), ctx->tq_ctx->worker_tcb[ NEW_OWNER ] );
+ ctx->priority_after = GetSelfPriority();
+}
+
+#if defined(RTEMS_SMP)
+static void Delay( void *arg )
+{
+ Context *ctx;
+ SMP_barrier_State state;
+
+ ctx = arg;
+ _SMP_barrier_State_initialize( &state );
+
+ /* B0 */
+ _SMP_barrier_Wait( &ctx->barrier, &state, 2 );
+
+ /* B1 */
+ _SMP_barrier_Wait( &ctx->barrier, &state, 2 );
+}
+
+static void SchedulerBlock(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ if (
+ when == T_SCHEDULER_BEFORE &&
+ event->operation == T_SCHEDULER_BLOCK
+ ) {
+ T_scheduler_set_event_handler( NULL, NULL );
+ ctx->request.handler = Delay;
+ CallWithinISRSubmit( &ctx->request );
+ }
+}
+#endif
+
+static void Setup( Context *ctx )
+{
+#if defined(RTEMS_SMP)
+ TQSetScheduler( ctx->tq_ctx, NEW_OWNER, SCHEDULER_B_ID, PRIO_NORMAL );
+ TQSetPriority( ctx->tq_ctx, PREV_OWNER_HELPER_A, PRIO_VERY_HIGH );
+ TQSetScheduler(
+ ctx->tq_ctx,
+ PREV_OWNER_HELPER_B,
+ SCHEDULER_B_ID,
+ PRIO_HIGH
+ );
+ TQSetPriority( ctx->tq_ctx, NEW_OWNER_OLD_PRIORITY, PRIO_VERY_LOW );
+ TQSetPriority( ctx->tq_ctx, NEW_OWNER_NEW_PRIORITY, PRIO_LOW );
+
+ TQSetPriority( ctx->tq_ctx, PREV_OWNER_MOVER, PRIO_ULTRA_HIGH );
+
+ if ( rtems_scheduler_get_processor_maximum() >= 3 ) {
+ TQSetScheduler(
+ ctx->tq_ctx,
+ PREV_OWNER_HELPER_C,
+ SCHEDULER_C_ID,
+ PRIO_HIGH
+ );
+ }
+#else
+ TQSetPriority( ctx->tq_ctx, NEW_OWNER, PRIO_HIGH );
+ TQSetPriority( ctx->tq_ctx, PREV_OWNER_HELPER_A, PRIO_HIGH );
+#endif
+
+ TQSetPriority( ctx->tq_ctx, TQ_HELPER_B, PRIO_ULTRA_LOW );
+}
+
+static void Action( Context *ctx )
+{
+ Status_Control status;
+#if defined(RTEMS_SMP)
+ SMP_barrier_State state;
+#endif
+
+ ctx->action_performed = true;
+ ctx->previous_owner = ctx->tq_ctx->runner_id;
+ TQMutexObtain( ctx->tq_ctx, TQ_MUTEX_A );
+#if defined(RTEMS_SMP)
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ NEW_OWNER,
+ TQ_EVENT_MUTEX_B_OBTAIN
+ );
+#endif
+
+ if ( ctx->inherited_priorities_are_dispensible ) {
+ TQSend(
+ ctx->tq_ctx,
+ PREV_OWNER_HELPER_A,
+ TQ_EVENT_MUTEX_A_OBTAIN | TQ_EVENT_MUTEX_A_RELEASE
+ );
+ }
+
+#if defined(RTEMS_SMP)
+ if ( ctx->helping_schedules_are_dispensible ) {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ PREV_OWNER_HELPER_B,
+ TQ_EVENT_MUTEX_A_OBTAIN | TQ_EVENT_MUTEX_A_RELEASE
+ );
+
+ if ( ctx->gains_new_priority && ctx->gains_new_helping_scheduler ) {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ PREV_OWNER_HELPER_C,
+ TQ_EVENT_MUTEX_A_OBTAIN | TQ_EVENT_MUTEX_A_RELEASE
+ );
+ }
+ }
+#endif
+
+ status = TQEnqueue( ctx->tq_ctx, TQ_NO_WAIT );
+ T_eq_int( status, TQConvertStatus( ctx->tq_ctx, STATUS_SUCCESSFUL ) );
+
+#if defined(RTEMS_SMP)
+ if ( ctx->intend_to_block ) {
+ _SMP_barrier_Control_initialize( &ctx->barrier );
+ _SMP_barrier_State_initialize( &state );
+
+ T_scheduler_set_event_handler( SchedulerBlock, ctx );
+ TQSend( ctx->tq_ctx, NEW_OWNER, TQ_EVENT_ENQUEUE );
+
+ /* B0 */
+ _SMP_barrier_Wait( &ctx->barrier, &state, 2 );
+ } else {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ NEW_OWNER,
+ TQ_EVENT_ENQUEUE
+ );
+ }
+
+ if ( ctx->gains_new_priority ) {
+ TQSend(
+ ctx->tq_ctx,
+ NEW_OWNER_OLD_PRIORITY,
+ TQ_EVENT_HELPER_B_SYNC | TQ_EVENT_MUTEX_B_OBTAIN
+ );
+ TQSynchronizeRunner();
+ TQSend(
+ ctx->tq_ctx,
+ NEW_OWNER_NEW_PRIORITY,
+ TQ_EVENT_HELPER_B_SYNC | TQ_EVENT_ENQUEUE
+ );
+ TQSynchronizeRunner();
+
+ if ( ctx->gains_new_helping_scheduler ) {
+ TQSetScheduler(
+ ctx->tq_ctx,
+ NEW_OWNER_NEW_HELPER,
+ SCHEDULER_C_ID,
+ PRIO_LOW
+ );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ NEW_OWNER_NEW_HELPER,
+ TQ_EVENT_ENQUEUE
+ );
+ }
+ } else if ( ctx->gains_new_helping_scheduler ) {
+ TQSetScheduler(
+ ctx->tq_ctx,
+ NEW_OWNER_NEW_HELPER,
+ SCHEDULER_A_ID,
+ PRIO_LOW
+ );
+ TQSend(
+ ctx->tq_ctx,
+ NEW_OWNER_NEW_HELPER,
+ TQ_EVENT_HELPER_B_SYNC | TQ_EVENT_ENQUEUE
+ );
+ TQSynchronizeRunner();
+ }
+
+ /*
+ * In order to run the validation test variant also for the intend to block
+ * wait state, we would need at least three processors. Skip it for now.
+ */
+ if ( ctx->use_helping_scheduler && !ctx->intend_to_block ) {
+ ctx->tq_ctx->busy_wait[ PREV_OWNER_MOVER ] = true;
+ TQSend( ctx->tq_ctx, PREV_OWNER_MOVER, TQ_EVENT_BUSY_WAIT );
+
+ while ( rtems_scheduler_get_processor() != 1 ) {
+ /* Wait */
+ }
+
+ ctx->tq_ctx->busy_wait[ PREV_OWNER_MOVER ] = false;
+ }
+#else
+ TQSend(
+ ctx->tq_ctx,
+ NEW_OWNER,
+ TQ_EVENT_HELPER_B_SYNC | TQ_EVENT_ENQUEUE
+ );
+ TQSynchronizeRunner();
+#endif
+
+ Surrender( ctx );
+
+#if defined(RTEMS_SMP)
+ if ( ctx->intend_to_block ) {
+ /* B1 */
+ _SMP_barrier_Wait( &ctx->barrier, &state, 2 );
+ }
+#endif
+}
+
+static void Cleanup( Context *ctx )
+{
+ if ( ctx->suspended ) {
+ ResumeTask( ctx->tq_ctx->worker_id[ NEW_OWNER ] );
+ }
+
+ TQSendAndSynchronizeRunner(
+ ctx->tq_ctx,
+ NEW_OWNER,
+ TQ_EVENT_SURRENDER
+ );
+ TQWaitForExecutionStop( ctx->tq_ctx, NEW_OWNER );
+
+#if defined(RTEMS_SMP)
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ NEW_OWNER,
+ TQ_EVENT_MUTEX_B_RELEASE
+ );
+
+ if ( ctx->gains_new_priority ) {
+ TQSendAndSynchronizeRunner(
+ ctx->tq_ctx,
+ NEW_OWNER_OLD_PRIORITY,
+ TQ_EVENT_MUTEX_B_RELEASE
+ );
+ TQSendAndSynchronizeRunner(
+ ctx->tq_ctx,
+ NEW_OWNER_NEW_PRIORITY,
+ TQ_EVENT_SURRENDER
+ );
+ }
+
+ if ( ctx->gains_new_helping_scheduler ) {
+ TQSendAndSynchronizeRunner(
+ ctx->tq_ctx,
+ NEW_OWNER_NEW_HELPER,
+ TQ_EVENT_SURRENDER
+ );
+ }
+#endif
+
+ TQMutexRelease( ctx->tq_ctx, TQ_MUTEX_A );
+ TQMutexObtain( ctx->tq_ctx, TQ_MUTEX_A );
+ TQMutexRelease( ctx->tq_ctx, TQ_MUTEX_A );
+
+ T_eq_u32( rtems_scheduler_get_processor(), 0 );
+}
+
+static void SetupSticky( Context *ctx )
+{
+#if defined(RTEMS_SMP)
+ TQSetScheduler( ctx->tq_ctx, NEW_OWNER, SCHEDULER_B_ID, PRIO_NORMAL );
+ TQSetPriority( ctx->tq_ctx, PREV_OWNER_HELPER_A, PRIO_VERY_HIGH );
+ TQSetScheduler( ctx->tq_ctx,
+ PREV_OWNER_HELPER_B,
+ SCHEDULER_B_ID,
+ PRIO_LOW
+ );
+ TQSetPriority( ctx->tq_ctx, NEW_OWNER_NEW_HELPER, PRIO_VERY_HIGH );
+ TQSetPriority( ctx->tq_ctx, PREV_OWNER, PRIO_NORMAL );
+#endif
+}
+
+static void ActionSticky( Context *ctx )
+{
+#if defined(RTEMS_SMP)
+ ctx->action_performed = true;
+ ctx->previous_owner = ctx->tq_ctx->worker_id[ PREV_OWNER ];
+
+ SetSelfPriority( PRIO_LOW );
+
+ if (
+ ctx->inherited_priorities_are_dispensible ||
+ ctx->helping_schedules_are_dispensible
+ ) {
+ TQSend( ctx->tq_ctx, PREV_OWNER, TQ_EVENT_MUTEX_A_OBTAIN );
+
+ if ( ctx->inherited_priorities_are_dispensible ) {
+ TQSend( ctx->tq_ctx, PREV_OWNER_HELPER_A, TQ_EVENT_MUTEX_A_OBTAIN );
+ }
+
+ if ( ctx->helping_schedules_are_dispensible ) {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ PREV_OWNER_HELPER_B,
+ TQ_EVENT_MUTEX_A_OBTAIN
+ );
+ }
+ }
+
+ /*
+ * Take only the priorities into account which are inherited from the
+ * priority inheritance mutex. This avoids having to deal with the ceiling
+ * priority.
+ */
+ ctx->priority_before = TQGetPriority( ctx->tq_ctx, PREV_OWNER );
+
+ SetSelfScheduler( SCHEDULER_B_ID, PRIO_ULTRA_HIGH );
+ ctx->tq_ctx->busy_wait[ PREV_OWNER ] = true;
+ TQSendAndSynchronizeRunner(
+ ctx->tq_ctx,
+ PREV_OWNER,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_BUSY_WAIT
+ );
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_ULTRA_HIGH );
+
+ TQSendAndWaitForIntendToBlock(
+ ctx->tq_ctx,
+ NEW_OWNER,
+ TQ_EVENT_ENQUEUE
+ );
+
+ SetSelfScheduler( SCHEDULER_B_ID, PRIO_ULTRA_HIGH );
+
+ if ( ctx->gains_new_helping_scheduler ) {
+ TQSend(
+ ctx->tq_ctx,
+ NEW_OWNER_NEW_HELPER,
+ TQ_EVENT_ENQUEUE
+ );
+ YieldTask( ctx->tq_ctx->worker_id[ PREV_OWNER ] );
+ TQWaitForEventsReceived( ctx->tq_ctx, NEW_OWNER_NEW_HELPER );
+ TQWaitForIntendToBlock( ctx->tq_ctx, NEW_OWNER_NEW_HELPER );
+ YieldTask( ctx->tq_ctx->worker_id[ NEW_OWNER_NEW_HELPER ] );
+ }
+
+ if ( ctx->use_helping_scheduler ) {
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_ULTRA_HIGH );
+ }
+
+ if ( ctx->suspended ) {
+ SuspendTask( ctx->tq_ctx->worker_id[ NEW_OWNER ] );
+ }
+
+ ctx->tq_ctx->busy_wait[ PREV_OWNER ] = false;
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ PREV_OWNER,
+ TQ_EVENT_SCHEDULER_RECORD_START |
+ TQ_EVENT_SURRENDER
+ );
+ TQSchedulerRecordStop( ctx->tq_ctx );
+ T_eq_ptr(
+ TQGetOwner( ctx->tq_ctx ),
+ ctx->tq_ctx->worker_tcb[ NEW_OWNER ]
+ );
+ ctx->priority_after = TQGetPriority( ctx->tq_ctx, PREV_OWNER );
+#endif
+}
+
+static void CleanupSticky( Context *ctx )
+{
+#if defined(RTEMS_SMP)
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_ULTRA_HIGH );
+
+ if ( ctx->suspended ) {
+ ResumeTask( ctx->tq_ctx->worker_id[ NEW_OWNER ] );
+ }
+
+ TQSendAndSynchronizeRunner(
+ ctx->tq_ctx,
+ NEW_OWNER,
+ TQ_EVENT_SURRENDER
+ );
+
+ if ( ctx->gains_new_helping_scheduler ) {
+ TQSendAndSynchronizeRunner(
+ ctx->tq_ctx,
+ NEW_OWNER_NEW_HELPER,
+ TQ_EVENT_SURRENDER
+ );
+ }
+
+ if (
+ ctx->inherited_priorities_are_dispensible ||
+ ctx->helping_schedules_are_dispensible
+ ) {
+ TQSendAndSynchronizeRunner(
+ ctx->tq_ctx,
+ PREV_OWNER,
+ TQ_EVENT_MUTEX_A_RELEASE
+ );
+
+ if ( ctx->inherited_priorities_are_dispensible ) {
+ TQSendAndSynchronizeRunner(
+ ctx->tq_ctx,
+ PREV_OWNER_HELPER_A,
+ TQ_EVENT_MUTEX_A_RELEASE
+ );
+ }
+
+ if ( ctx->helping_schedules_are_dispensible ) {
+ TQSendAndSynchronizeRunner(
+ ctx->tq_ctx,
+ PREV_OWNER_HELPER_B,
+ TQ_EVENT_MUTEX_A_RELEASE
+ );
+ }
+ }
+
+ T_eq_u32( rtems_scheduler_get_processor(), 0 );
+#endif
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Pre_SchedulerCount_Prepare(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx,
+ ScoreTqReqSurrenderPriorityInherit_Pre_SchedulerCount state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderPriorityInherit_Pre_SchedulerCount_One: {
+ /*
+ * Where the system has exactly one schedulers.
+ */
+ if ( rtems_scheduler_get_processor_maximum() != 1 ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Pre_SchedulerCount_Two: {
+ /*
+ * Where the system has exactly two schedulers.
+ */
+ if ( rtems_scheduler_get_processor_maximum() != 2 ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Pre_SchedulerCount_More: {
+ /*
+ * Where the system has at least three schedulers.
+ */
+ if ( rtems_scheduler_get_processor_maximum() < 3 ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Pre_SchedulerCount_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Pre_InheritedPriority_Prepare(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx,
+ ScoreTqReqSurrenderPriorityInherit_Pre_InheritedPriority state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderPriorityInherit_Pre_InheritedPriority_Vital: {
+ /*
+ * While at least one priority inherited through the thread queue for the
+ * previous owner is the highest priority of the previous owner.
+ */
+ ctx->inherited_priorities_are_dispensible = false;
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Pre_InheritedPriority_Dispensable: {
+ /*
+ * While all priorities inherited through the thread queue for the
+ * previous owner are not the highest priority of the previous owner.
+ */
+ ctx->inherited_priorities_are_dispensible = true;
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Pre_InheritedPriority_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Pre_PreviousHelping_Prepare(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx,
+ ScoreTqReqSurrenderPriorityInherit_Pre_PreviousHelping state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderPriorityInherit_Pre_PreviousHelping_Vital: {
+ /*
+ * While at least one helping scheduler of the previous owner is only
+ * available due to a priority inherited through the thread queue.
+ */
+ ctx->helping_schedules_are_dispensible = false;
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Pre_PreviousHelping_Dispensable: {
+ /*
+ * While all helping scheduler of the previous owner are not only
+ * available due to a priority inherited through the thread queue.
+ */
+ ctx->helping_schedules_are_dispensible = true;
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Pre_PreviousHelping_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Pre_UsedScheduler_Prepare(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx,
+ ScoreTqReqSurrenderPriorityInherit_Pre_UsedScheduler state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderPriorityInherit_Pre_UsedScheduler_Home: {
+ /*
+ * While the previous owner executes in its home scheduler.
+ */
+ ctx->use_helping_scheduler = false;
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Pre_UsedScheduler_Helping: {
+ /*
+ * While the previous owner executes in a helping scheduler which is
+ * available due to a priority inherited through the thread queue.
+ */
+ ctx->use_helping_scheduler = true;
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Pre_UsedScheduler_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Pre_NewPriority_Prepare(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx,
+ ScoreTqReqSurrenderPriorityInherit_Pre_NewPriority state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderPriorityInherit_Pre_NewPriority_Vital: {
+ /*
+ * While at least one highest priority of the new owner is only available
+ * due to a priority inherited through the thread queue.
+ */
+ ctx->gains_new_priority = true;
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Pre_NewPriority_Dispensable: {
+ /*
+ * While all highest priorities of the new owner are not only available
+ * due to a priority inherited through the thread queue.
+ */
+ ctx->gains_new_priority = false;
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Pre_NewPriority_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Pre_NewHelping_Prepare(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx,
+ ScoreTqReqSurrenderPriorityInherit_Pre_NewHelping state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderPriorityInherit_Pre_NewHelping_Vital: {
+ /*
+ * While at least one helping scheduler of the new owner is only
+ * available due to a priority inherited through the thread queue.
+ */
+ ctx->gains_new_helping_scheduler = true;
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Pre_NewHelping_Dispensable: {
+ /*
+ * While all helping scheduler of the new owner are not only available
+ * due to a priority inherited through the thread queue.
+ */
+ ctx->gains_new_helping_scheduler = false;
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Pre_NewHelping_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Pre_Suspended_Prepare(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx,
+ ScoreTqReqSurrenderPriorityInherit_Pre_Suspended state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderPriorityInherit_Pre_Suspended_Yes: {
+ /*
+ * While the new owner is suspended.
+ */
+ ctx->suspended = true;
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Pre_Suspended_No: {
+ /*
+ * While the new owner is not suspended.
+ */
+ ctx->suspended = false;
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Pre_Suspended_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Pre_WaitState_Prepare(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx,
+ ScoreTqReqSurrenderPriorityInherit_Pre_WaitState state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderPriorityInherit_Pre_WaitState_Blocked: {
+ /*
+ * While the new owner is in the blocked wait state.
+ */
+ ctx->intend_to_block = false;
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Pre_WaitState_IntendToBlock: {
+ /*
+ * While the new owner is in the intend to block wait state.
+ */
+ ctx->intend_to_block = true;
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Pre_WaitState_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Check(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority: {
+ /*
+ * The first thread in priority order shall be dequeued from the thread
+ * queue.
+ */
+ /* Validation is done by spec:/score/tq/req/enqueue-priority */
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Check(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock state
+)
+{
+ size_t i;
+
+ i = 0;
+
+ switch ( state ) {
+ case ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes: {
+ /*
+ * The dequeued thread shall be unblocked by the thread queue surrender
+ * operation.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, NEW_OWNER ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No: {
+ /*
+ * The dequeued thread shall not be unblocked by the thread queue
+ * surrender operation.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA:
+ break;
+ }
+}
+
+static void
+ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Check(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop: {
+ /*
+ * Each eligible priority of the previous owner which had the highest
+ * priority inherited through the thread queue shall be updated.
+ */
+ T_eq_u32( ctx->priority_after, PRIO_NORMAL );
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop: {
+ /*
+ * No eligible priority of the previous owner shall be updated.
+ */
+ T_eq_u32( ctx->priority_after, ctx->priority_before );
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Check(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority state
+)
+{
+ rtems_id scheduler_id;
+ rtems_task_priority priority;
+ rtems_status_code sc;
+
+ switch ( state ) {
+ case ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise: {
+ /*
+ * Each eligible priority of the new owner which inherited the highest
+ * priority through the thread queue shall be updated.
+ */
+ sc = rtems_task_get_priority(
+ ctx->tq_ctx->worker_id[ NEW_OWNER ],
+ SCHEDULER_A_ID,
+ &priority
+ );
+ T_rsc_success( sc );
+ T_eq_u32( priority, PRIO_LOW );
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop: {
+ /*
+ * No highest priority of the new owner shall be changed.
+ */
+ if ( ctx->gains_new_helping_scheduler ) {
+ scheduler_id = SCHEDULER_C_ID;
+ } else {
+ scheduler_id = SCHEDULER_A_ID;
+ }
+
+ sc = rtems_task_get_priority(
+ ctx->tq_ctx->worker_id[ NEW_OWNER ],
+ scheduler_id,
+ &priority
+ );
+ #if defined(RTEMS_SMP)
+ T_rsc( sc, RTEMS_NOT_DEFINED );
+ #else
+ T_rsc_success( sc );
+ T_eq_u32( priority, PRIO_HIGH );
+ #endif
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Check(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper state
+)
+{
+ rtems_task_priority priority;
+ rtems_status_code sc;
+
+ switch ( state ) {
+ case ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes: {
+ /*
+ * Each helping scheduler of the previous owner which was only available
+ * due to a priority inherited through the thread queue shall be removed
+ * from the previous owner.
+ */
+ sc = rtems_task_get_priority(
+ ctx->previous_owner,
+ SCHEDULER_B_ID,
+ &priority
+ );
+ T_rsc( sc, RTEMS_NOT_DEFINED );
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No: {
+ /*
+ * No helping scheduler shall be removed from the previous owner.
+ */
+ sc = rtems_task_get_priority(
+ ctx->previous_owner,
+ SCHEDULER_B_ID,
+ &priority
+ );
+ #if defined(RTEMS_SMP)
+ T_rsc_success( sc );
+
+ if ( ctx->tq_ctx->enqueue_variant == TQ_ENQUEUE_STICKY ) {
+ T_eq_u32( priority, PRIO_LOW );
+ } else {
+ T_eq_u32( priority, PRIO_HIGH );
+ }
+ #else
+ T_rsc( sc, RTEMS_INVALID_ID );
+ #endif
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Check(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper state
+)
+{
+ rtems_id scheduler_id;
+ rtems_task_priority priority;
+ rtems_status_code sc;
+
+ switch ( state ) {
+ case ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes: {
+ /*
+ * Each helping scheduler of the new owner which is only available due to
+ * a priority inherited through the thread queue shall be added to the
+ * new owner.
+ */
+ if ( ctx->gains_new_priority ) {
+ scheduler_id = SCHEDULER_C_ID;
+ } else {
+ scheduler_id = SCHEDULER_A_ID;
+ }
+
+ sc = rtems_task_get_priority(
+ ctx->tq_ctx->worker_id[ NEW_OWNER ],
+ scheduler_id,
+ &priority
+ );
+ T_rsc_success( sc );
+
+ if ( ctx->tq_ctx->enqueue_variant == TQ_ENQUEUE_STICKY ) {
+ T_eq_u32( priority, PRIO_VERY_HIGH );
+ } else {
+ T_eq_u32( priority, PRIO_LOW );
+ }
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No: {
+ /*
+ * No helping scheduler shall added to the new owner.
+ */
+ if ( ctx->gains_new_priority ) {
+ scheduler_id = SCHEDULER_C_ID;
+ } else {
+ scheduler_id = SCHEDULER_A_ID;
+ }
+
+ sc = rtems_task_get_priority(
+ ctx->tq_ctx->worker_id[ NEW_OWNER ],
+ scheduler_id,
+ &priority
+ );
+ #if defined(RTEMS_SMP)
+ T_rsc( sc, RTEMS_NOT_DEFINED );
+ #else
+ T_rsc_success( sc );
+ T_eq_u32( priority, PRIO_HIGH );
+ #endif
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Check(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes: {
+ /*
+ * The new owner shall be suspended.
+ */
+ T_true( IsTaskSuspended( ctx->tq_ctx->worker_id[ NEW_OWNER ] ) );
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No: {
+ /*
+ * The new owner shall be not suspended.
+ */
+ T_false( IsTaskSuspended( ctx->tq_ctx->worker_id[ NEW_OWNER ] ) );
+ break;
+ }
+
+ case ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Setup(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx
+)
+{
+ ctx->request.arg = ctx;
+ TQReset( ctx->tq_ctx );
+
+ if ( ctx->tq_ctx->enqueue_variant == TQ_ENQUEUE_STICKY ) {
+ SetupSticky( ctx );
+ } else {
+ Setup( ctx );
+ }
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Setup_Wrap( void *arg )
+{
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqSurrenderPriorityInherit_Setup( ctx );
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Teardown(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx
+)
+{
+ SetSelfScheduler( SCHEDULER_A_ID, PRIO_NORMAL );
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Teardown_Wrap( void *arg )
+{
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqSurrenderPriorityInherit_Teardown( ctx );
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Prepare(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx
+)
+{
+ ctx->action_performed = false;
+ ctx->inherited_priorities_are_dispensible = true;
+ ctx->helping_schedules_are_dispensible = true;
+ ctx->use_helping_scheduler = false;
+ ctx->gains_new_priority = false;
+ ctx->gains_new_helping_scheduler = false;
+ ctx->intend_to_block = false;
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Action(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx
+)
+{
+ if ( ctx->tq_ctx->enqueue_variant == TQ_ENQUEUE_STICKY ) {
+ ActionSticky( ctx );
+ } else {
+ Action( ctx );
+ }
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_Cleanup(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx
+)
+{
+ if ( ctx->action_performed ) {
+ if ( ctx->tq_ctx->enqueue_variant == TQ_ENQUEUE_STICKY ) {
+ CleanupSticky( ctx );
+ } else {
+ Cleanup( ctx );
+ }
+ }
+}
+
+static const ScoreTqReqSurrenderPriorityInherit_Entry
+ScoreTqReqSurrenderPriorityInherit_Entries[] = {
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#endif
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA }
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No }
+#endif
+};
+
+static const uint8_t
+ScoreTqReqSurrenderPriorityInherit_Map[] = {
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 4, 5, 6, 7, 0, 1, 0, 1,
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+ 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
+ 0, 1, 0, 1, 8, 9, 10, 11, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 2,
+ 3, 2, 3, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 2, 3, 2, 3, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 2, 3, 2, 3, 24, 25, 26, 27, 28, 29,
+ 30, 31, 4, 5, 6, 7, 2, 3, 2, 3, 24, 25, 26, 27, 28, 29, 30, 31, 4, 5, 6, 7,
+ 2, 3, 2, 3, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 2, 3, 2, 3, 32,
+ 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 2, 3, 2, 3, 44, 45, 46, 47, 48,
+ 49, 50, 51, 8, 9, 10, 11, 2, 3, 2, 3, 44, 45, 46, 47, 48, 49, 50, 51, 8, 9,
+ 10, 11, 52, 53, 54, 55, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 52,
+ 53, 54, 55, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 56, 57, 58, 59,
+ 24, 25, 26, 27, 28, 29, 30, 31, 4, 5, 6, 7, 56, 57, 58, 59, 24, 25, 26, 27,
+ 28, 29, 30, 31, 4, 5, 6, 7, 60, 61, 62, 63, 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 60, 61, 62, 63, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
+ 43, 64, 65, 66, 67, 44, 45, 46, 47, 48, 49, 50, 51, 8, 9, 10, 11, 64, 65, 66,
+ 67, 44, 45, 46, 47, 48, 49, 50, 51, 8, 9, 10, 11
+};
+
+static size_t ScoreTqReqSurrenderPriorityInherit_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ ScoreTqReqSurrenderPriorityInherit_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreTqReqSurrenderPriorityInherit_Fixture = {
+ .setup = ScoreTqReqSurrenderPriorityInherit_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreTqReqSurrenderPriorityInherit_Teardown_Wrap,
+ .scope = ScoreTqReqSurrenderPriorityInherit_Scope,
+ .initial_context = &ScoreTqReqSurrenderPriorityInherit_Instance
+};
+
+static const uint8_t ScoreTqReqSurrenderPriorityInherit_Weights[] = {
+ 128, 64, 32, 16, 8, 4, 2, 1
+};
+
+static void ScoreTqReqSurrenderPriorityInherit_Skip(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx,
+ size_t index
+)
+{
+ switch ( index + 1 ) {
+ case 1:
+ ctx->Map.pcs[ 1 ] = ScoreTqReqSurrenderPriorityInherit_Pre_InheritedPriority_NA - 1;
+ /* Fall through */
+ case 2:
+ ctx->Map.pcs[ 2 ] = ScoreTqReqSurrenderPriorityInherit_Pre_PreviousHelping_NA - 1;
+ /* Fall through */
+ case 3:
+ ctx->Map.pcs[ 3 ] = ScoreTqReqSurrenderPriorityInherit_Pre_UsedScheduler_NA - 1;
+ /* Fall through */
+ case 4:
+ ctx->Map.pcs[ 4 ] = ScoreTqReqSurrenderPriorityInherit_Pre_NewPriority_NA - 1;
+ /* Fall through */
+ case 5:
+ ctx->Map.pcs[ 5 ] = ScoreTqReqSurrenderPriorityInherit_Pre_NewHelping_NA - 1;
+ /* Fall through */
+ case 6:
+ ctx->Map.pcs[ 6 ] = ScoreTqReqSurrenderPriorityInherit_Pre_Suspended_NA - 1;
+ /* Fall through */
+ case 7:
+ ctx->Map.pcs[ 7 ] = ScoreTqReqSurrenderPriorityInherit_Pre_WaitState_NA - 1;
+ break;
+ }
+}
+
+static inline ScoreTqReqSurrenderPriorityInherit_Entry
+ScoreTqReqSurrenderPriorityInherit_PopEntry(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx
+)
+{
+ size_t index;
+
+ if ( ctx->Map.skip ) {
+ size_t i;
+
+ ctx->Map.skip = false;
+ index = 0;
+
+ for ( i = 0; i < 8; ++i ) {
+ index += ScoreTqReqSurrenderPriorityInherit_Weights[ i ] * ctx->Map.pcs[ i ];
+ }
+ } else {
+ index = ctx->Map.index;
+ }
+
+ ctx->Map.index = index + 1;
+
+ return ScoreTqReqSurrenderPriorityInherit_Entries[
+ ScoreTqReqSurrenderPriorityInherit_Map[ index ]
+ ];
+}
+
+static void ScoreTqReqSurrenderPriorityInherit_TestVariant(
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx
+)
+{
+ ScoreTqReqSurrenderPriorityInherit_Pre_SchedulerCount_Prepare(
+ ctx,
+ ctx->Map.pcs[ 0 ]
+ );
+
+ if ( ctx->Map.skip ) {
+ ScoreTqReqSurrenderPriorityInherit_Skip( ctx, 0 );
+ return;
+ }
+
+ ScoreTqReqSurrenderPriorityInherit_Pre_InheritedPriority_Prepare(
+ ctx,
+ ctx->Map.pcs[ 1 ]
+ );
+ ScoreTqReqSurrenderPriorityInherit_Pre_PreviousHelping_Prepare(
+ ctx,
+ ctx->Map.pcs[ 2 ]
+ );
+ ScoreTqReqSurrenderPriorityInherit_Pre_UsedScheduler_Prepare(
+ ctx,
+ ctx->Map.pcs[ 3 ]
+ );
+ ScoreTqReqSurrenderPriorityInherit_Pre_NewPriority_Prepare(
+ ctx,
+ ctx->Map.pcs[ 4 ]
+ );
+ ScoreTqReqSurrenderPriorityInherit_Pre_NewHelping_Prepare(
+ ctx,
+ ctx->Map.pcs[ 5 ]
+ );
+ ScoreTqReqSurrenderPriorityInherit_Pre_Suspended_Prepare(
+ ctx,
+ ctx->Map.pcs[ 6 ]
+ );
+ ScoreTqReqSurrenderPriorityInherit_Pre_WaitState_Prepare(
+ ctx,
+ ctx->Map.pcs[ 7 ]
+ );
+ ScoreTqReqSurrenderPriorityInherit_Action( ctx );
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Check(
+ ctx,
+ ctx->Map.entry.Post_Dequeue
+ );
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Check(
+ ctx,
+ ctx->Map.entry.Post_Unblock
+ );
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Check(
+ ctx,
+ ctx->Map.entry.Post_PreviousOwnerPriority
+ );
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Check(
+ ctx,
+ ctx->Map.entry.Post_NewPriority
+ );
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Check(
+ ctx,
+ ctx->Map.entry.Post_RemoveHelper
+ );
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Check(
+ ctx,
+ ctx->Map.entry.Post_AddHelper
+ );
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Check(
+ ctx,
+ ctx->Map.entry.Post_Suspended
+ );
+}
+
+static T_fixture_node ScoreTqReqSurrenderPriorityInherit_Node;
+
+static T_remark ScoreTqReqSurrenderPriorityInherit_Remark = {
+ .next = NULL,
+ .remark = "ScoreTqReqSurrenderPriorityInherit"
+};
+
+void ScoreTqReqSurrenderPriorityInherit_Run( TQContext *tq_ctx )
+{
+ ScoreTqReqSurrenderPriorityInherit_Context *ctx;
+
+ ctx = &ScoreTqReqSurrenderPriorityInherit_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreTqReqSurrenderPriorityInherit_Node,
+ &ScoreTqReqSurrenderPriorityInherit_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+ ctx->Map.skip = false;
+
+ for (
+ ctx->Map.pcs[ 0 ] = ScoreTqReqSurrenderPriorityInherit_Pre_SchedulerCount_One;
+ ctx->Map.pcs[ 0 ] < ScoreTqReqSurrenderPriorityInherit_Pre_SchedulerCount_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = ScoreTqReqSurrenderPriorityInherit_Pre_InheritedPriority_Vital;
+ ctx->Map.pcs[ 1 ] < ScoreTqReqSurrenderPriorityInherit_Pre_InheritedPriority_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = ScoreTqReqSurrenderPriorityInherit_Pre_PreviousHelping_Vital;
+ ctx->Map.pcs[ 2 ] < ScoreTqReqSurrenderPriorityInherit_Pre_PreviousHelping_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 3 ] = ScoreTqReqSurrenderPriorityInherit_Pre_UsedScheduler_Home;
+ ctx->Map.pcs[ 3 ] < ScoreTqReqSurrenderPriorityInherit_Pre_UsedScheduler_NA;
+ ++ctx->Map.pcs[ 3 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 4 ] = ScoreTqReqSurrenderPriorityInherit_Pre_NewPriority_Vital;
+ ctx->Map.pcs[ 4 ] < ScoreTqReqSurrenderPriorityInherit_Pre_NewPriority_NA;
+ ++ctx->Map.pcs[ 4 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 5 ] = ScoreTqReqSurrenderPriorityInherit_Pre_NewHelping_Vital;
+ ctx->Map.pcs[ 5 ] < ScoreTqReqSurrenderPriorityInherit_Pre_NewHelping_NA;
+ ++ctx->Map.pcs[ 5 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 6 ] = ScoreTqReqSurrenderPriorityInherit_Pre_Suspended_Yes;
+ ctx->Map.pcs[ 6 ] < ScoreTqReqSurrenderPriorityInherit_Pre_Suspended_NA;
+ ++ctx->Map.pcs[ 6 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 7 ] = ScoreTqReqSurrenderPriorityInherit_Pre_WaitState_Blocked;
+ ctx->Map.pcs[ 7 ] < ScoreTqReqSurrenderPriorityInherit_Pre_WaitState_NA;
+ ++ctx->Map.pcs[ 7 ]
+ ) {
+ ctx->Map.entry = ScoreTqReqSurrenderPriorityInherit_PopEntry(
+ ctx
+ );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ ScoreTqReqSurrenderPriorityInherit_Prepare( ctx );
+ ScoreTqReqSurrenderPriorityInherit_TestVariant( ctx );
+ ScoreTqReqSurrenderPriorityInherit_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ T_add_remark( &ScoreTqReqSurrenderPriorityInherit_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-tq-surrender-priority-inherit.h b/testsuites/validation/tr-tq-surrender-priority-inherit.h
new file mode 100644
index 0000000000..941e9eb545
--- /dev/null
+++ b/testsuites/validation/tr-tq-surrender-priority-inherit.h
@@ -0,0 +1,169 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqSurrenderPriorityInherit
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_TQ_SURRENDER_PRIORITY_INHERIT_H
+#define _TR_TQ_SURRENDER_PRIORITY_INHERIT_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreTqReqSurrenderPriorityInherit
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreTqReqSurrenderPriorityInherit_Pre_SchedulerCount_One,
+ ScoreTqReqSurrenderPriorityInherit_Pre_SchedulerCount_Two,
+ ScoreTqReqSurrenderPriorityInherit_Pre_SchedulerCount_More,
+ ScoreTqReqSurrenderPriorityInherit_Pre_SchedulerCount_NA
+} ScoreTqReqSurrenderPriorityInherit_Pre_SchedulerCount;
+
+typedef enum {
+ ScoreTqReqSurrenderPriorityInherit_Pre_InheritedPriority_Vital,
+ ScoreTqReqSurrenderPriorityInherit_Pre_InheritedPriority_Dispensable,
+ ScoreTqReqSurrenderPriorityInherit_Pre_InheritedPriority_NA
+} ScoreTqReqSurrenderPriorityInherit_Pre_InheritedPriority;
+
+typedef enum {
+ ScoreTqReqSurrenderPriorityInherit_Pre_PreviousHelping_Vital,
+ ScoreTqReqSurrenderPriorityInherit_Pre_PreviousHelping_Dispensable,
+ ScoreTqReqSurrenderPriorityInherit_Pre_PreviousHelping_NA
+} ScoreTqReqSurrenderPriorityInherit_Pre_PreviousHelping;
+
+typedef enum {
+ ScoreTqReqSurrenderPriorityInherit_Pre_UsedScheduler_Home,
+ ScoreTqReqSurrenderPriorityInherit_Pre_UsedScheduler_Helping,
+ ScoreTqReqSurrenderPriorityInherit_Pre_UsedScheduler_NA
+} ScoreTqReqSurrenderPriorityInherit_Pre_UsedScheduler;
+
+typedef enum {
+ ScoreTqReqSurrenderPriorityInherit_Pre_NewPriority_Vital,
+ ScoreTqReqSurrenderPriorityInherit_Pre_NewPriority_Dispensable,
+ ScoreTqReqSurrenderPriorityInherit_Pre_NewPriority_NA
+} ScoreTqReqSurrenderPriorityInherit_Pre_NewPriority;
+
+typedef enum {
+ ScoreTqReqSurrenderPriorityInherit_Pre_NewHelping_Vital,
+ ScoreTqReqSurrenderPriorityInherit_Pre_NewHelping_Dispensable,
+ ScoreTqReqSurrenderPriorityInherit_Pre_NewHelping_NA
+} ScoreTqReqSurrenderPriorityInherit_Pre_NewHelping;
+
+typedef enum {
+ ScoreTqReqSurrenderPriorityInherit_Pre_Suspended_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Pre_Suspended_No,
+ ScoreTqReqSurrenderPriorityInherit_Pre_Suspended_NA
+} ScoreTqReqSurrenderPriorityInherit_Pre_Suspended;
+
+typedef enum {
+ ScoreTqReqSurrenderPriorityInherit_Pre_WaitState_Blocked,
+ ScoreTqReqSurrenderPriorityInherit_Pre_WaitState_IntendToBlock,
+ ScoreTqReqSurrenderPriorityInherit_Pre_WaitState_NA
+} ScoreTqReqSurrenderPriorityInherit_Pre_WaitState;
+
+typedef enum {
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_Priority,
+ ScoreTqReqSurrenderPriorityInherit_Post_Dequeue_NA
+} ScoreTqReqSurrenderPriorityInherit_Post_Dequeue;
+
+typedef enum {
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Unblock_NA
+} ScoreTqReqSurrenderPriorityInherit_Post_Unblock;
+
+typedef enum {
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Drop,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority_NA
+} ScoreTqReqSurrenderPriorityInherit_Post_PreviousOwnerPriority;
+
+typedef enum {
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Raise,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_Nop,
+ ScoreTqReqSurrenderPriorityInherit_Post_NewPriority_NA
+} ScoreTqReqSurrenderPriorityInherit_Post_NewPriority;
+
+typedef enum {
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper_NA
+} ScoreTqReqSurrenderPriorityInherit_Post_RemoveHelper;
+
+typedef enum {
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_AddHelper_NA
+} ScoreTqReqSurrenderPriorityInherit_Post_AddHelper;
+
+typedef enum {
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_Yes,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_No,
+ ScoreTqReqSurrenderPriorityInherit_Post_Suspended_NA
+} ScoreTqReqSurrenderPriorityInherit_Post_Suspended;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue test context.
+ */
+void ScoreTqReqSurrenderPriorityInherit_Run( TQContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_TQ_SURRENDER_PRIORITY_INHERIT_H */
diff --git a/testsuites/validation/tr-tq-surrender.c b/testsuites/validation/tr-tq-surrender.c
new file mode 100644
index 0000000000..ce680d71d2
--- /dev/null
+++ b/testsuites/validation/tr-tq-surrender.c
@@ -0,0 +1,690 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqSurrender
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/smpbarrier.h>
+#include <rtems/score/threadimpl.h>
+
+#include "tr-tq-surrender.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTqReqSurrender spec:/score/tq/req/surrender
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_HasOwner_NA : 1;
+ uint8_t Pre_Discipline_NA : 1;
+ uint8_t Pre_WaitState_NA : 1;
+ uint8_t Post_Dequeue : 2;
+ uint8_t Post_Unblock : 2;
+} ScoreTqReqSurrender_Entry;
+
+/**
+ * @brief Test context for spec:/score/tq/req/surrender test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the call within ISR request.
+ */
+ CallWithinISRRequest request;
+
+ /**
+ * @brief This member contains the barrier to synchronize the runner and the
+ * worker.
+ */
+ SMP_barrier_Control barrier;
+
+ /**
+ * @brief If this member is true, then the dequeued thread shall be in the
+ * intend to block wait state.
+ */
+ bool intend_to_block;
+
+ /**
+ * @brief If this member contains the expected counter of worker B.
+ */
+ uint32_t expected_blocker_b_counter;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreTqReqSurrender_Run() parameter.
+ */
+ TQContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 3 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreTqReqSurrender_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreTqReqSurrender_Context;
+
+static ScoreTqReqSurrender_Context
+ ScoreTqReqSurrender_Instance;
+
+static const char * const ScoreTqReqSurrender_PreDesc_HasOwner[] = {
+ "Yes",
+ "No",
+ "NA"
+};
+
+static const char * const ScoreTqReqSurrender_PreDesc_Discipline[] = {
+ "FIFO",
+ "Priority",
+ "NA"
+};
+
+static const char * const ScoreTqReqSurrender_PreDesc_WaitState[] = {
+ "Blocked",
+ "IntendToBlock",
+ "NA"
+};
+
+static const char * const * const ScoreTqReqSurrender_PreDesc[] = {
+ ScoreTqReqSurrender_PreDesc_HasOwner,
+ ScoreTqReqSurrender_PreDesc_Discipline,
+ ScoreTqReqSurrender_PreDesc_WaitState,
+ NULL
+};
+
+typedef ScoreTqReqSurrender_Context Context;
+
+static const rtems_tcb *GetUnblock( Context *ctx, size_t *index )
+{
+ return TQGetNextUnblock( ctx->tq_ctx, index )->thread;
+}
+
+static const rtems_tcb *GetTCB( Context *ctx, TQWorkerKind worker )
+{
+ return ctx->tq_ctx->worker_tcb[ worker ];
+}
+
+static void Surrender( void *arg )
+{
+ Context *ctx;
+ Status_Control status;
+
+ ctx = arg;
+ TQSchedulerRecordStart( ctx->tq_ctx );
+
+ status = TQSurrender( ctx->tq_ctx );
+ T_eq_int( status, TQConvertStatus( ctx->tq_ctx, STATUS_SUCCESSFUL ) );
+
+ TQSchedulerRecordStop( ctx->tq_ctx );
+}
+
+#if defined(RTEMS_SMP)
+static void Delay( void *arg )
+{
+ Context *ctx;
+ SMP_barrier_State state;
+
+ ctx = arg;
+ _SMP_barrier_State_initialize( &state );
+
+ /* B0 */
+ _SMP_barrier_Wait( &ctx->barrier, &state, 2 );
+
+ /* B1 */
+ _SMP_barrier_Wait( &ctx->barrier, &state, 2 );
+}
+#endif
+
+static void SchedulerBlock(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ if (
+ when == T_SCHEDULER_BEFORE &&
+ event->operation == T_SCHEDULER_BLOCK
+ ) {
+ T_scheduler_set_event_handler( NULL, NULL );
+#if defined(RTEMS_SMP)
+ ctx->request.handler = Delay;
+#else
+ ctx->request.handler = Surrender;
+#endif
+ CallWithinISRSubmit( &ctx->request );
+ }
+}
+
+static void ScoreTqReqSurrender_Pre_HasOwner_Prepare(
+ ScoreTqReqSurrender_Context *ctx,
+ ScoreTqReqSurrender_Pre_HasOwner state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrender_Pre_HasOwner_Yes: {
+ /*
+ * Where the thread queue has a previous owner thread.
+ */
+ if ( ctx->tq_ctx->get_owner == NULL ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreTqReqSurrender_Pre_HasOwner_No: {
+ /*
+ * Where the thread queue has no owner threads.
+ */
+ if ( ctx->tq_ctx->get_owner != NULL ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreTqReqSurrender_Pre_HasOwner_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrender_Pre_Discipline_Prepare(
+ ScoreTqReqSurrender_Context *ctx,
+ ScoreTqReqSurrender_Pre_Discipline state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrender_Pre_Discipline_FIFO: {
+ /*
+ * Where the thread queue uses the FIFO discipline.
+ */
+ if ( ctx->tq_ctx->discipline != TQ_FIFO ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreTqReqSurrender_Pre_Discipline_Priority: {
+ /*
+ * Where the thread queue uses the priority discipline.
+ */
+ if ( ctx->tq_ctx->discipline != TQ_PRIORITY ) {
+ ctx->Map.skip = true;
+ }
+ break;
+ }
+
+ case ScoreTqReqSurrender_Pre_Discipline_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrender_Pre_WaitState_Prepare(
+ ScoreTqReqSurrender_Context *ctx,
+ ScoreTqReqSurrender_Pre_WaitState state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrender_Pre_WaitState_Blocked: {
+ /*
+ * While the dequeued thread is in the blocked wait state.
+ */
+ ctx->intend_to_block = false;
+ break;
+ }
+
+ case ScoreTqReqSurrender_Pre_WaitState_IntendToBlock: {
+ /*
+ * While the dequeued thread is in the intend to block wait state.
+ */
+ ctx->intend_to_block = true;
+ break;
+ }
+
+ case ScoreTqReqSurrender_Pre_WaitState_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrender_Post_Dequeue_Check(
+ ScoreTqReqSurrender_Context *ctx,
+ ScoreTqReqSurrender_Post_Dequeue state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqSurrender_Post_Dequeue_FIFO: {
+ /*
+ * The first thread in FIFO order shall be dequeued from the thread
+ * queue.
+ */
+ T_eq_u32( TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ), 1 );
+ T_eq_u32(
+ TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_B ),
+ ctx->expected_blocker_b_counter
+ );
+ break;
+ }
+
+ case ScoreTqReqSurrender_Post_Dequeue_Priority: {
+ /*
+ * The first thread in priority order shall be dequeued from the thread
+ * queue.
+ */
+ T_eq_u32( TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_A ), 1 );
+ T_eq_u32( TQGetWorkerCounter( ctx->tq_ctx, TQ_BLOCKER_B ), 2 );
+ break;
+ }
+
+ case ScoreTqReqSurrender_Post_Dequeue_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrender_Post_Unblock_Check(
+ ScoreTqReqSurrender_Context *ctx,
+ ScoreTqReqSurrender_Post_Unblock state
+)
+{
+ size_t i;
+
+ i = 0;
+
+ switch ( state ) {
+ case ScoreTqReqSurrender_Post_Unblock_Yes: {
+ /*
+ * The dequeued thread shall be unblocked by surrender operation.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqSurrender_Post_Unblock_No: {
+ /*
+ * The dequeued thread shall not be unblocked by surrender operation.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqSurrender_Post_Unblock_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqSurrender_Setup( ScoreTqReqSurrender_Context *ctx )
+{
+ ctx->request.arg = ctx;
+ TQReset( ctx->tq_ctx );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_A, PRIO_VERY_HIGH );
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_B, PRIO_HIGH );
+
+ #if defined(RTEMS_SMP)
+ /*
+ * For the mutexes with priority ceiling protocol, we need a scheduler with
+ * two processors to set up the intend to block wait state.
+ */
+ RemoveProcessor( SCHEDULER_B_ID, 1 );
+ AddProcessor( SCHEDULER_A_ID, 1 );
+ #endif
+}
+
+static void ScoreTqReqSurrender_Setup_Wrap( void *arg )
+{
+ ScoreTqReqSurrender_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqSurrender_Setup( ctx );
+}
+
+static void ScoreTqReqSurrender_Teardown( ScoreTqReqSurrender_Context *ctx )
+{
+ TQReset( ctx->tq_ctx );
+
+ #if defined(RTEMS_SMP)
+ RemoveProcessor( SCHEDULER_A_ID, 1 );
+ AddProcessor( SCHEDULER_B_ID, 1 );
+ #endif
+}
+
+static void ScoreTqReqSurrender_Teardown_Wrap( void *arg )
+{
+ ScoreTqReqSurrender_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqSurrender_Teardown( ctx );
+}
+
+static void ScoreTqReqSurrender_Action( ScoreTqReqSurrender_Context *ctx )
+{
+ Status_Control status;
+
+ TQResetCounter( ctx->tq_ctx );
+ ctx->expected_blocker_b_counter = 0;
+
+ status = TQEnqueue( ctx->tq_ctx, TQ_NO_WAIT );
+ T_eq_int( status, TQConvertStatus( ctx->tq_ctx, STATUS_SUCCESSFUL ) );
+
+ if ( ctx->intend_to_block ) {
+ #if defined(RTEMS_SMP)
+ SMP_barrier_State state;
+ #endif
+
+ /*
+ * In uniprocessor configurations, it is impossible to dequeue a thread
+ * in FIFO order which is in the intend to block wait state. Run this
+ * test with just one worker.
+ */
+ if ( ctx->tq_ctx->discipline != TQ_FIFO ) {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_BLOCKER_B,
+ TQ_EVENT_ENQUEUE
+ );
+ ctx->expected_blocker_b_counter = 2;
+ }
+
+
+ #if defined(RTEMS_SMP)
+ _SMP_barrier_Control_initialize( &ctx->barrier );
+ _SMP_barrier_State_initialize( &state );
+ #endif
+
+ T_scheduler_set_event_handler( SchedulerBlock, ctx );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
+
+ #if defined(RTEMS_SMP)
+ /* B0 */
+ _SMP_barrier_Wait( &ctx->barrier, &state, 2 );
+
+ Surrender( ctx );
+
+ /* B1 */
+ _SMP_barrier_Wait( &ctx->barrier, &state, 2 );
+ #endif
+ } else {
+ TQSend(
+ ctx->tq_ctx,
+ TQ_BLOCKER_A,
+ TQ_EVENT_HELPER_A_SYNC | TQ_EVENT_ENQUEUE
+ );
+ TQSynchronizeRunner();
+ TQWaitForExecutionStop( ctx->tq_ctx, TQ_BLOCKER_A );
+
+ TQSend(
+ ctx->tq_ctx,
+ TQ_BLOCKER_B,
+ TQ_EVENT_HELPER_A_SYNC | TQ_EVENT_ENQUEUE
+ );
+ TQSynchronizeRunner();
+ TQWaitForExecutionStop( ctx->tq_ctx, TQ_BLOCKER_B );
+ ctx->expected_blocker_b_counter = 2;
+
+ Surrender( ctx );
+ }
+
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_BLOCKER_A,
+ TQ_EVENT_SURRENDER
+ );
+
+ if ( ctx->expected_blocker_b_counter != 0 ) {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ TQ_BLOCKER_B,
+ TQ_EVENT_SURRENDER
+ );
+ }
+}
+
+static const ScoreTqReqSurrender_Entry
+ScoreTqReqSurrender_Entries[] = {
+ { 0, 0, 0, 0, ScoreTqReqSurrender_Post_Dequeue_FIFO,
+ ScoreTqReqSurrender_Post_Unblock_Yes },
+ { 0, 0, 0, 0, ScoreTqReqSurrender_Post_Dequeue_Priority,
+ ScoreTqReqSurrender_Post_Unblock_Yes },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, ScoreTqReqSurrender_Post_Dequeue_NA,
+ ScoreTqReqSurrender_Post_Unblock_NA },
+#else
+ { 0, 0, 0, 0, ScoreTqReqSurrender_Post_Dequeue_FIFO,
+ ScoreTqReqSurrender_Post_Unblock_No },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, ScoreTqReqSurrender_Post_Dequeue_NA,
+ ScoreTqReqSurrender_Post_Unblock_NA },
+#else
+ { 0, 0, 0, 0, ScoreTqReqSurrender_Post_Dequeue_Priority,
+ ScoreTqReqSurrender_Post_Unblock_No },
+#endif
+ { 0, 0, 0, 0, ScoreTqReqSurrender_Post_Dequeue_FIFO,
+ ScoreTqReqSurrender_Post_Unblock_No },
+ { 0, 0, 0, 0, ScoreTqReqSurrender_Post_Dequeue_Priority,
+ ScoreTqReqSurrender_Post_Unblock_No }
+};
+
+static const uint8_t
+ScoreTqReqSurrender_Map[] = {
+ 0, 2, 1, 3, 0, 4, 1, 5
+};
+
+static size_t ScoreTqReqSurrender_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreTqReqSurrender_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( ScoreTqReqSurrender_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreTqReqSurrender_Fixture = {
+ .setup = ScoreTqReqSurrender_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreTqReqSurrender_Teardown_Wrap,
+ .scope = ScoreTqReqSurrender_Scope,
+ .initial_context = &ScoreTqReqSurrender_Instance
+};
+
+static const uint8_t ScoreTqReqSurrender_Weights[] = {
+ 4, 2, 1
+};
+
+static void ScoreTqReqSurrender_Skip(
+ ScoreTqReqSurrender_Context *ctx,
+ size_t index
+)
+{
+ switch ( index + 1 ) {
+ case 1:
+ ctx->Map.pcs[ 1 ] = ScoreTqReqSurrender_Pre_Discipline_NA - 1;
+ /* Fall through */
+ case 2:
+ ctx->Map.pcs[ 2 ] = ScoreTqReqSurrender_Pre_WaitState_NA - 1;
+ break;
+ }
+}
+
+static inline ScoreTqReqSurrender_Entry ScoreTqReqSurrender_PopEntry(
+ ScoreTqReqSurrender_Context *ctx
+)
+{
+ size_t index;
+
+ if ( ctx->Map.skip ) {
+ size_t i;
+
+ ctx->Map.skip = false;
+ index = 0;
+
+ for ( i = 0; i < 3; ++i ) {
+ index += ScoreTqReqSurrender_Weights[ i ] * ctx->Map.pcs[ i ];
+ }
+ } else {
+ index = ctx->Map.index;
+ }
+
+ ctx->Map.index = index + 1;
+
+ return ScoreTqReqSurrender_Entries[
+ ScoreTqReqSurrender_Map[ index ]
+ ];
+}
+
+static void ScoreTqReqSurrender_TestVariant( ScoreTqReqSurrender_Context *ctx )
+{
+ ScoreTqReqSurrender_Pre_HasOwner_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+
+ if ( ctx->Map.skip ) {
+ ScoreTqReqSurrender_Skip( ctx, 0 );
+ return;
+ }
+
+ ScoreTqReqSurrender_Pre_Discipline_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+
+ if ( ctx->Map.skip ) {
+ ScoreTqReqSurrender_Skip( ctx, 1 );
+ return;
+ }
+
+ ScoreTqReqSurrender_Pre_WaitState_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ ScoreTqReqSurrender_Action( ctx );
+ ScoreTqReqSurrender_Post_Dequeue_Check( ctx, ctx->Map.entry.Post_Dequeue );
+ ScoreTqReqSurrender_Post_Unblock_Check( ctx, ctx->Map.entry.Post_Unblock );
+}
+
+static T_fixture_node ScoreTqReqSurrender_Node;
+
+static T_remark ScoreTqReqSurrender_Remark = {
+ .next = NULL,
+ .remark = "ScoreTqReqSurrender"
+};
+
+void ScoreTqReqSurrender_Run( TQContext *tq_ctx )
+{
+ ScoreTqReqSurrender_Context *ctx;
+
+ ctx = &ScoreTqReqSurrender_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreTqReqSurrender_Node,
+ &ScoreTqReqSurrender_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+ ctx->Map.skip = false;
+
+ for (
+ ctx->Map.pcs[ 0 ] = ScoreTqReqSurrender_Pre_HasOwner_Yes;
+ ctx->Map.pcs[ 0 ] < ScoreTqReqSurrender_Pre_HasOwner_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = ScoreTqReqSurrender_Pre_Discipline_FIFO;
+ ctx->Map.pcs[ 1 ] < ScoreTqReqSurrender_Pre_Discipline_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 2 ] = ScoreTqReqSurrender_Pre_WaitState_Blocked;
+ ctx->Map.pcs[ 2 ] < ScoreTqReqSurrender_Pre_WaitState_NA;
+ ++ctx->Map.pcs[ 2 ]
+ ) {
+ ctx->Map.entry = ScoreTqReqSurrender_PopEntry( ctx );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ ScoreTqReqSurrender_TestVariant( ctx );
+ }
+ }
+ }
+
+ T_add_remark( &ScoreTqReqSurrender_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-tq-surrender.h b/testsuites/validation/tr-tq-surrender.h
new file mode 100644
index 0000000000..8155387069
--- /dev/null
+++ b/testsuites/validation/tr-tq-surrender.h
@@ -0,0 +1,109 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqSurrender
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_TQ_SURRENDER_H
+#define _TR_TQ_SURRENDER_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreTqReqSurrender
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreTqReqSurrender_Pre_HasOwner_Yes,
+ ScoreTqReqSurrender_Pre_HasOwner_No,
+ ScoreTqReqSurrender_Pre_HasOwner_NA
+} ScoreTqReqSurrender_Pre_HasOwner;
+
+typedef enum {
+ ScoreTqReqSurrender_Pre_Discipline_FIFO,
+ ScoreTqReqSurrender_Pre_Discipline_Priority,
+ ScoreTqReqSurrender_Pre_Discipline_NA
+} ScoreTqReqSurrender_Pre_Discipline;
+
+typedef enum {
+ ScoreTqReqSurrender_Pre_WaitState_Blocked,
+ ScoreTqReqSurrender_Pre_WaitState_IntendToBlock,
+ ScoreTqReqSurrender_Pre_WaitState_NA
+} ScoreTqReqSurrender_Pre_WaitState;
+
+typedef enum {
+ ScoreTqReqSurrender_Post_Dequeue_FIFO,
+ ScoreTqReqSurrender_Post_Dequeue_Priority,
+ ScoreTqReqSurrender_Post_Dequeue_NA
+} ScoreTqReqSurrender_Post_Dequeue;
+
+typedef enum {
+ ScoreTqReqSurrender_Post_Unblock_Yes,
+ ScoreTqReqSurrender_Post_Unblock_No,
+ ScoreTqReqSurrender_Post_Unblock_NA
+} ScoreTqReqSurrender_Post_Unblock;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue test context.
+ */
+void ScoreTqReqSurrender_Run( TQContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_TQ_SURRENDER_H */
diff --git a/testsuites/validation/tr-tq-timeout-mrsp.c b/testsuites/validation/tr-tq-timeout-mrsp.c
new file mode 100644
index 0000000000..7362e1943b
--- /dev/null
+++ b/testsuites/validation/tr-tq-timeout-mrsp.c
@@ -0,0 +1,482 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqTimeoutMrsp
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/smpimpl.h>
+#include <rtems/score/threadimpl.h>
+
+#include "tr-tq-timeout-mrsp.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTqReqTimeoutMrsp spec:/score/tq/req/timeout-mrsp
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_Scheduler_NA : 1;
+ uint8_t Pre_WaitState_NA : 1;
+ uint8_t Post_Status : 2;
+ uint8_t Post_Unblock : 1;
+} ScoreTqReqTimeoutMrsp_Entry;
+
+/**
+ * @brief Test context for spec:/score/tq/req/timeout-mrsp test case.
+ */
+typedef struct {
+ /**
+ * @brief If this member is true, then the enqueued thread shall use a home
+ * scheduler other than the home scheduler of the owner.
+ */
+ bool other_scheduler;
+
+ /**
+ * @brief If this member is true, then the processor set of the schedulers
+ * shall be restored.
+ */
+ bool restore_scheduler;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreTqReqTimeoutMrsp_Run() parameter.
+ */
+ TQContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 2 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreTqReqTimeoutMrsp_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreTqReqTimeoutMrsp_Context;
+
+static ScoreTqReqTimeoutMrsp_Context
+ ScoreTqReqTimeoutMrsp_Instance;
+
+static const char * const ScoreTqReqTimeoutMrsp_PreDesc_Scheduler[] = {
+ "Same",
+ "Other",
+ "NA"
+};
+
+static const char * const ScoreTqReqTimeoutMrsp_PreDesc_WaitState[] = {
+ "IntendToBlock",
+ "ReadyAgain",
+ "NA"
+};
+
+static const char * const * const ScoreTqReqTimeoutMrsp_PreDesc[] = {
+ ScoreTqReqTimeoutMrsp_PreDesc_Scheduler,
+ ScoreTqReqTimeoutMrsp_PreDesc_WaitState,
+ NULL
+};
+
+typedef ScoreTqReqTimeoutMrsp_Context Context;
+
+static const rtems_tcb *GetUnblock( Context *ctx, size_t *index )
+{
+ return TQGetNextUnblock( ctx->tq_ctx, index )->thread;
+}
+
+static void Tick( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ FinalClockTick();
+ TQSchedulerRecordStop( ctx->tq_ctx );
+}
+
+static void ScoreTqReqTimeoutMrsp_Pre_Scheduler_Prepare(
+ ScoreTqReqTimeoutMrsp_Context *ctx,
+ ScoreTqReqTimeoutMrsp_Pre_Scheduler state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqTimeoutMrsp_Pre_Scheduler_Same: {
+ /*
+ * While the home scheduler of the thread is equal to the home scheduler
+ * of the thread queue owner.
+ */
+ ctx->other_scheduler = false;
+
+ TQSetScheduler(
+ ctx->tq_ctx,
+ TQ_BLOCKER_A,
+ SCHEDULER_A_ID,
+ PRIO_LOW
+ );
+ RemoveProcessor( SCHEDULER_B_ID, 1 );
+ AddProcessor( SCHEDULER_A_ID, 1 );
+ ctx->restore_scheduler = true;
+ break;
+ }
+
+ case ScoreTqReqTimeoutMrsp_Pre_Scheduler_Other: {
+ /*
+ * While the home scheduler of the thread is not equal to the home
+ * scheduler of the thread queue owner.
+ */
+ ctx->other_scheduler = true;
+
+ TQSetScheduler(
+ ctx->tq_ctx,
+ TQ_BLOCKER_A,
+ SCHEDULER_B_ID,
+ PRIO_NORMAL
+ );
+ break;
+ }
+
+ case ScoreTqReqTimeoutMrsp_Pre_Scheduler_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeoutMrsp_Pre_WaitState_Prepare(
+ ScoreTqReqTimeoutMrsp_Context *ctx,
+ ScoreTqReqTimeoutMrsp_Pre_WaitState state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqTimeoutMrsp_Pre_WaitState_IntendToBlock: {
+ /*
+ * While the thread of the timeout operation is in the intend to block
+ * wait state.
+ */
+ Per_CPU_Control *cpu;
+
+ TQEnqueuePrepare( ctx->tq_ctx );
+ TQSendAndWaitForIntendToBlock(
+ ctx->tq_ctx,
+ TQ_BLOCKER_A,
+ TQ_EVENT_ENQUEUE
+ );
+ cpu = _Thread_Get_CPU( ctx->tq_ctx->worker_tcb[ TQ_BLOCKER_A ] );
+
+ /*
+ * We have to make sure that the worker thread inserted its thread
+ * timer. Checking the intend to block wait state is not enough to
+ * ensure this.
+ */
+ while ( cpu->thread_dispatch_disable_level != 0 ) {
+ /* Wait */
+ }
+
+ Tick( ctx );
+ WaitForExecutionStop( ctx->tq_ctx->worker_id[ TQ_BLOCKER_A ] );
+ TQEnqueueDone( ctx->tq_ctx );
+ break;
+ }
+
+ case ScoreTqReqTimeoutMrsp_Pre_WaitState_ReadyAgain: {
+ /*
+ * While the thread of the timeout operation is in the ready again wait
+ * state.
+ */
+ TQEnqueuePrepare( ctx->tq_ctx );
+ TQSendAndWaitForIntendToBlock(
+ ctx->tq_ctx,
+ TQ_BLOCKER_A,
+ TQ_EVENT_ENQUEUE | TQ_EVENT_TIMEOUT | TQ_EVENT_SURRENDER |
+ TQ_EVENT_SCHEDULER_RECORD_STOP
+ );
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ TQEnqueueDone( ctx->tq_ctx );
+ WaitForExecutionStop( ctx->tq_ctx->worker_id[ TQ_BLOCKER_A ] );
+ break;
+ }
+
+ case ScoreTqReqTimeoutMrsp_Pre_WaitState_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeoutMrsp_Post_Status_Check(
+ ScoreTqReqTimeoutMrsp_Context *ctx,
+ ScoreTqReqTimeoutMrsp_Post_Status state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqTimeoutMrsp_Post_Status_Ok: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_SUCCESSFUL.
+ */
+ T_eq_int(
+ ctx->tq_ctx->status[ TQ_BLOCKER_A ],
+ TQConvertStatus( ctx->tq_ctx, STATUS_SUCCESSFUL )
+ );
+ break;
+ }
+
+ case ScoreTqReqTimeoutMrsp_Post_Status_Timeout: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_TIMEOUT.
+ */
+ T_eq_int(
+ ctx->tq_ctx->status[ TQ_BLOCKER_A ],
+ TQConvertStatus( ctx->tq_ctx, STATUS_TIMEOUT )
+ );
+ break;
+ }
+
+ case ScoreTqReqTimeoutMrsp_Post_Status_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeoutMrsp_Post_Unblock_Check(
+ ScoreTqReqTimeoutMrsp_Context *ctx,
+ ScoreTqReqTimeoutMrsp_Post_Unblock state
+)
+{
+ size_t i;
+
+ i = 0;
+
+ switch ( state ) {
+ case ScoreTqReqTimeoutMrsp_Post_Unblock_No: {
+ /*
+ * The thread of the timeout operation shall not be unblocked by the
+ * timeout operation.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqTimeoutMrsp_Post_Unblock_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeoutMrsp_Setup( ScoreTqReqTimeoutMrsp_Context *ctx )
+{
+ TQReset( ctx->tq_ctx );
+}
+
+static void ScoreTqReqTimeoutMrsp_Setup_Wrap( void *arg )
+{
+ ScoreTqReqTimeoutMrsp_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqTimeoutMrsp_Setup( ctx );
+}
+
+static void ScoreTqReqTimeoutMrsp_Teardown(
+ ScoreTqReqTimeoutMrsp_Context *ctx
+)
+{
+ TQReset( ctx->tq_ctx );
+}
+
+static void ScoreTqReqTimeoutMrsp_Teardown_Wrap( void *arg )
+{
+ ScoreTqReqTimeoutMrsp_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqTimeoutMrsp_Teardown( ctx );
+}
+
+static void ScoreTqReqTimeoutMrsp_Prepare( ScoreTqReqTimeoutMrsp_Context *ctx )
+{
+ ctx->restore_scheduler = false;
+}
+
+static void ScoreTqReqTimeoutMrsp_Action( ScoreTqReqTimeoutMrsp_Context *ctx )
+{
+ /*
+ * The action is performed by the ``WaitState`` pre-condition preparation.
+ */
+}
+
+static void ScoreTqReqTimeoutMrsp_Cleanup( ScoreTqReqTimeoutMrsp_Context *ctx )
+{
+ if ( ctx->restore_scheduler ) {
+ RemoveProcessor( SCHEDULER_A_ID, 1 );
+ AddProcessor( SCHEDULER_B_ID, 1 );
+ }
+}
+
+static const ScoreTqReqTimeoutMrsp_Entry
+ScoreTqReqTimeoutMrsp_Entries[] = {
+ { 0, 0, 0, ScoreTqReqTimeoutMrsp_Post_Status_Timeout,
+ ScoreTqReqTimeoutMrsp_Post_Unblock_No },
+ { 0, 0, 0, ScoreTqReqTimeoutMrsp_Post_Status_Ok,
+ ScoreTqReqTimeoutMrsp_Post_Unblock_No }
+};
+
+static const uint8_t
+ScoreTqReqTimeoutMrsp_Map[] = {
+ 0, 1, 0, 1
+};
+
+static size_t ScoreTqReqTimeoutMrsp_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreTqReqTimeoutMrsp_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( ScoreTqReqTimeoutMrsp_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreTqReqTimeoutMrsp_Fixture = {
+ .setup = ScoreTqReqTimeoutMrsp_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreTqReqTimeoutMrsp_Teardown_Wrap,
+ .scope = ScoreTqReqTimeoutMrsp_Scope,
+ .initial_context = &ScoreTqReqTimeoutMrsp_Instance
+};
+
+static inline ScoreTqReqTimeoutMrsp_Entry ScoreTqReqTimeoutMrsp_PopEntry(
+ ScoreTqReqTimeoutMrsp_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return ScoreTqReqTimeoutMrsp_Entries[
+ ScoreTqReqTimeoutMrsp_Map[ index ]
+ ];
+}
+
+static void ScoreTqReqTimeoutMrsp_TestVariant(
+ ScoreTqReqTimeoutMrsp_Context *ctx
+)
+{
+ ScoreTqReqTimeoutMrsp_Pre_Scheduler_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ ScoreTqReqTimeoutMrsp_Pre_WaitState_Prepare( ctx, ctx->Map.pcs[ 1 ] );
+ ScoreTqReqTimeoutMrsp_Action( ctx );
+ ScoreTqReqTimeoutMrsp_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ ScoreTqReqTimeoutMrsp_Post_Unblock_Check( ctx, ctx->Map.entry.Post_Unblock );
+}
+
+static T_fixture_node ScoreTqReqTimeoutMrsp_Node;
+
+static T_remark ScoreTqReqTimeoutMrsp_Remark = {
+ .next = NULL,
+ .remark = "ScoreTqReqTimeoutMrsp"
+};
+
+void ScoreTqReqTimeoutMrsp_Run( TQContext *tq_ctx )
+{
+ ScoreTqReqTimeoutMrsp_Context *ctx;
+
+ ctx = &ScoreTqReqTimeoutMrsp_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreTqReqTimeoutMrsp_Node,
+ &ScoreTqReqTimeoutMrsp_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = ScoreTqReqTimeoutMrsp_Pre_Scheduler_Same;
+ ctx->Map.pcs[ 0 ] < ScoreTqReqTimeoutMrsp_Pre_Scheduler_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ for (
+ ctx->Map.pcs[ 1 ] = ScoreTqReqTimeoutMrsp_Pre_WaitState_IntendToBlock;
+ ctx->Map.pcs[ 1 ] < ScoreTqReqTimeoutMrsp_Pre_WaitState_NA;
+ ++ctx->Map.pcs[ 1 ]
+ ) {
+ ctx->Map.entry = ScoreTqReqTimeoutMrsp_PopEntry( ctx );
+ ScoreTqReqTimeoutMrsp_Prepare( ctx );
+ ScoreTqReqTimeoutMrsp_TestVariant( ctx );
+ ScoreTqReqTimeoutMrsp_Cleanup( ctx );
+ }
+ }
+
+ T_add_remark( &ScoreTqReqTimeoutMrsp_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-tq-timeout-mrsp.h b/testsuites/validation/tr-tq-timeout-mrsp.h
new file mode 100644
index 0000000000..56df23d88b
--- /dev/null
+++ b/testsuites/validation/tr-tq-timeout-mrsp.h
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqTimeoutMrsp
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_TQ_TIMEOUT_MRSP_H
+#define _TR_TQ_TIMEOUT_MRSP_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreTqReqTimeoutMrsp
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreTqReqTimeoutMrsp_Pre_Scheduler_Same,
+ ScoreTqReqTimeoutMrsp_Pre_Scheduler_Other,
+ ScoreTqReqTimeoutMrsp_Pre_Scheduler_NA
+} ScoreTqReqTimeoutMrsp_Pre_Scheduler;
+
+typedef enum {
+ ScoreTqReqTimeoutMrsp_Pre_WaitState_IntendToBlock,
+ ScoreTqReqTimeoutMrsp_Pre_WaitState_ReadyAgain,
+ ScoreTqReqTimeoutMrsp_Pre_WaitState_NA
+} ScoreTqReqTimeoutMrsp_Pre_WaitState;
+
+typedef enum {
+ ScoreTqReqTimeoutMrsp_Post_Status_Ok,
+ ScoreTqReqTimeoutMrsp_Post_Status_Timeout,
+ ScoreTqReqTimeoutMrsp_Post_Status_NA
+} ScoreTqReqTimeoutMrsp_Post_Status;
+
+typedef enum {
+ ScoreTqReqTimeoutMrsp_Post_Unblock_No,
+ ScoreTqReqTimeoutMrsp_Post_Unblock_NA
+} ScoreTqReqTimeoutMrsp_Post_Unblock;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue test context.
+ */
+void ScoreTqReqTimeoutMrsp_Run( TQContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_TQ_TIMEOUT_MRSP_H */
diff --git a/testsuites/validation/tr-tq-timeout-priority-inherit.c b/testsuites/validation/tr-tq-timeout-priority-inherit.c
new file mode 100644
index 0000000000..12ac70df90
--- /dev/null
+++ b/testsuites/validation/tr-tq-timeout-priority-inherit.c
@@ -0,0 +1,2160 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqTimeoutPriorityInherit
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/smpimpl.h>
+#include <rtems/score/threadimpl.h>
+
+#include "tr-tq-timeout-priority-inherit.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTqReqTimeoutPriorityInherit \
+ * spec:/score/tq/req/timeout-priority-inherit
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint32_t Skip : 1;
+ uint32_t Pre_HomeScheduler_NA : 1;
+ uint32_t Pre_EligibleScheduler_NA : 1;
+ uint32_t Pre_Queue_NA : 1;
+ uint32_t Pre_OwnerPriority_NA : 1;
+ uint32_t Pre_OwnerState_NA : 1;
+ uint32_t Pre_OwnerQueue_NA : 1;
+ uint32_t Pre_OwnerOwnerPriority_NA : 1;
+ uint32_t Pre_WaitState_NA : 1;
+ uint32_t Post_Status : 2;
+ uint32_t Post_Unblock : 2;
+ uint32_t Post_OwnerPriority : 2;
+ uint32_t Post_OwnerOwnerPriority : 2;
+} ScoreTqReqTimeoutPriorityInherit_Entry;
+
+/**
+ * @brief Test context for spec:/score/tq/req/timeout-priority-inherit test
+ * case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the call within ISR request.
+ */
+ CallWithinISRRequest request;
+
+ /**
+ * @brief This member specifies the scheduler of the thread.
+ */
+ rtems_id scheduler_id;
+
+ /**
+ * @brief If this member is true, then the thread shall have at least two
+ * eligible scheduler.
+ */
+ bool other_scheduler;
+
+ /**
+ * @brief This member specifies the queue node kind.
+ */
+ TQNodeKind queue_node;
+
+ /**
+ * @brief This member specifies the owner priority node kind.
+ */
+ TQNodeKind owner_node;
+
+ /**
+ * @brief This member specifies which mutex obtain event shall be used to
+ * block the thread queue owner.
+ */
+ rtems_event_set owner_obtain;
+
+ /**
+ * @brief This member specifies which mutex release event shall be used to
+ * unblock the thread queue owner.
+ */
+ rtems_event_set owner_release;
+
+ /**
+ * @brief This member specifies the owner queue node kind.
+ */
+ TQNodeKind owner_queue_node;
+
+ /**
+ * @brief This member specifies the kind of the priority node of the owner of
+ * the thread queue on which the owner of the thread queue is blocked.
+ */
+ TQNodeKind owner_owner_node;
+
+ /**
+ * @brief This member specifies the wait state.
+ */
+ TQWaitState wait_state;
+
+ /**
+ * @brief This member contains the thread queue priority.
+ */
+ rtems_task_priority queue_priority;
+
+ /**
+ * @brief This member contains the owner priority.
+ */
+ rtems_task_priority owner_priority;
+
+ /**
+ * @brief This member contains the owner priority after the timeout or
+ * surrender.
+ */
+ rtems_task_priority owner_priority_after;
+
+ /**
+ * @brief This member contains the priority of the thread queue on which the
+ * owner is enqueued.
+ */
+ rtems_task_priority owner_queue_priority;
+
+ /**
+ * @brief This member contains the priority of the owner of the thread queue
+ * on which the owner is enqueued.
+ */
+ rtems_task_priority owner_owner_priority;
+
+ /**
+ * @brief This member contains the priority after the timeout or surrender of
+ * the owner of the thread queue on which the owner is enqueued.
+ */
+ rtems_task_priority owner_owner_priority_after;
+
+ /**
+ * @brief If this member is true, then the queue helper shall surrender the
+ * thread queue.
+ */
+ bool queue_helper_surrender;
+
+ /**
+ * @brief If this member is true, then the owner helper shall release mutex
+ * A.
+ */
+ bool owner_helper_release;
+
+ /**
+ * @brief If this member is true, then the owner queue helper shall release
+ * the mutex on which the owner is blocked.
+ */
+ bool owner_queue_helper_release;
+
+ /**
+ * @brief If this member is true, then helper of the owner of the mutex which
+ * the owner blocked shall release mutex B.
+ */
+ bool owner_owner_helper_release;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreTqReqTimeoutPriorityInherit_Run() parameter.
+ */
+ TQContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition indices for the next
+ * action.
+ */
+ size_t pci[ 8 ];
+
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 8 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreTqReqTimeoutPriorityInherit_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreTqReqTimeoutPriorityInherit_Context;
+
+static ScoreTqReqTimeoutPriorityInherit_Context
+ ScoreTqReqTimeoutPriorityInherit_Instance;
+
+static const char * const ScoreTqReqTimeoutPriorityInherit_PreDesc_HomeScheduler[] = {
+ "Home",
+ "Helping",
+ "NA"
+};
+
+static const char * const ScoreTqReqTimeoutPriorityInherit_PreDesc_EligibleScheduler[] = {
+ "One",
+ "More",
+ "NA"
+};
+
+static const char * const ScoreTqReqTimeoutPriorityInherit_PreDesc_Queue[] = {
+ "Only",
+ "Vital",
+ "Dispensable",
+ "NA"
+};
+
+static const char * const ScoreTqReqTimeoutPriorityInherit_PreDesc_OwnerPriority[] = {
+ "Only",
+ "Vital",
+ "Dispensable",
+ "NA"
+};
+
+static const char * const ScoreTqReqTimeoutPriorityInherit_PreDesc_OwnerState[] = {
+ "NotEnqueued",
+ "FIFO",
+ "Priority",
+ "PriorityInherit",
+ "NA"
+};
+
+static const char * const ScoreTqReqTimeoutPriorityInherit_PreDesc_OwnerQueue[] = {
+ "Only",
+ "Vital",
+ "Dispensable",
+ "NA"
+};
+
+static const char * const ScoreTqReqTimeoutPriorityInherit_PreDesc_OwnerOwnerPriority[] = {
+ "Only",
+ "Vital",
+ "Dispensable",
+ "NA"
+};
+
+static const char * const ScoreTqReqTimeoutPriorityInherit_PreDesc_WaitState[] = {
+ "Blocked",
+ "IntendToBlock",
+ "ReadyAgain",
+ "NA"
+};
+
+static const char * const * const ScoreTqReqTimeoutPriorityInherit_PreDesc[] = {
+ ScoreTqReqTimeoutPriorityInherit_PreDesc_HomeScheduler,
+ ScoreTqReqTimeoutPriorityInherit_PreDesc_EligibleScheduler,
+ ScoreTqReqTimeoutPriorityInherit_PreDesc_Queue,
+ ScoreTqReqTimeoutPriorityInherit_PreDesc_OwnerPriority,
+ ScoreTqReqTimeoutPriorityInherit_PreDesc_OwnerState,
+ ScoreTqReqTimeoutPriorityInherit_PreDesc_OwnerQueue,
+ ScoreTqReqTimeoutPriorityInherit_PreDesc_OwnerOwnerPriority,
+ ScoreTqReqTimeoutPriorityInherit_PreDesc_WaitState,
+ NULL
+};
+
+typedef ScoreTqReqTimeoutPriorityInherit_Context Context;
+
+#define THREAD TQ_BLOCKER_A
+
+#define THREAD_HELPER_A TQ_HELPER_B
+
+#define THREAD_HELPER_B TQ_HELPER_C
+
+#define QUEUE_HELPER TQ_BLOCKER_B
+
+#define OWNER TQ_BLOCKER_C
+
+#define OWNER_HELPER TQ_BLOCKER_D
+
+#define OWNER_QUEUE_HELPER TQ_BLOCKER_E
+
+#define OWNER_OWNER TQ_WORKER_F
+
+#define OWNER_OWNER_HELPER TQ_HELPER_A
+
+static bool GetUnblock( const Context *ctx, size_t *index )
+{
+ while ( true ) {
+ const T_scheduler_event *event;
+
+ event = TQGetNextUnblock( ctx->tq_ctx, index );
+
+ if ( event == &T_scheduler_event_null ) {
+ return false;
+ }
+
+ if ( event->thread == ctx->tq_ctx->worker_tcb[ THREAD ] ) {
+ return true;
+ }
+ }
+}
+
+static void Tick( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ FinalClockTick();
+ TQSchedulerRecordStop( ctx->tq_ctx );
+}
+
+static void SchedulerBlock(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ if (
+ when == T_SCHEDULER_BEFORE &&
+ event->operation == T_SCHEDULER_BLOCK &&
+ event->thread == ctx->tq_ctx->worker_tcb[ THREAD ]
+ ) {
+ T_scheduler_set_event_handler( NULL, NULL );
+ ctx->request.handler = Tick;
+ CallWithinISRSubmit( &ctx->request );
+ }
+}
+
+static void ThreadTimeout( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ _Thread_Timeout(
+ &ctx->tq_ctx->worker_tcb[ THREAD ]->Timer.Watchdog
+ );
+ TQSchedulerRecordStop( ctx->tq_ctx );
+}
+
+static void SchedulerUnblock(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ if (
+ when == T_SCHEDULER_BEFORE &&
+ event->operation == T_SCHEDULER_UNBLOCK &&
+ event->thread == ctx->tq_ctx->worker_tcb[ THREAD ]
+ ) {
+ T_scheduler_set_event_handler( NULL, NULL );
+
+ if ( ctx->scheduler_id == SCHEDULER_B_ID ) {
+#if defined(RTEMS_SMP)
+ _SMP_Unicast_action( 1, ThreadTimeout, ctx );
+#else
+ T_unreachable();
+#endif
+ } else {
+ ctx->request.handler = ThreadTimeout;
+ CallWithinISRSubmit( &ctx->request );
+ }
+ }
+}
+
+static void GetPriorities( Context *ctx )
+{
+ ctx->owner_priority_after = GetPriorityByScheduler(
+ ctx->tq_ctx->worker_id[ OWNER ],
+ ctx->scheduler_id
+ );
+ ctx->owner_owner_priority_after = GetPriorityByScheduler(
+ ctx->tq_ctx->worker_id[ OWNER_OWNER ],
+ ctx->scheduler_id
+ );
+}
+
+static void PrepareThread( const Context *ctx )
+{
+ if ( ctx->other_scheduler ) {
+ rtems_id other_scheduler_id;
+
+ if ( ctx->scheduler_id == SCHEDULER_A_ID ) {
+ other_scheduler_id = SCHEDULER_B_ID;
+ } else {
+ other_scheduler_id = SCHEDULER_B_ID;
+ }
+
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ THREAD,
+ TQ_EVENT_MUTEX_D_OBTAIN
+ );
+
+ TQSetScheduler(
+ ctx->tq_ctx,
+ THREAD_HELPER_A,
+ other_scheduler_id,
+ PRIO_NEARLY_IDLE - 1
+ );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ THREAD_HELPER_A,
+ TQ_EVENT_MUTEX_D_OBTAIN
+ );
+
+ if ( rtems_scheduler_get_processor_maximum() >= 3 ) {
+ TQSetScheduler(
+ ctx->tq_ctx,
+ THREAD_HELPER_B,
+ SCHEDULER_C_ID,
+ PRIO_NORMAL
+ );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ THREAD_HELPER_B,
+ TQ_EVENT_MUTEX_D_OBTAIN
+ );
+ }
+ }
+}
+
+static rtems_task_priority PrepareQueue(
+ Context *ctx,
+ rtems_task_priority priority
+)
+{
+ switch ( ctx->queue_node ) {
+ case TQ_NODE_ONLY:
+ ctx->queue_helper_surrender = false;
+ break;
+ case TQ_NODE_VITAL:
+ ctx->queue_helper_surrender = true;
+ TQSetScheduler(
+ ctx->tq_ctx,
+ QUEUE_HELPER,
+ ctx->scheduler_id,
+ priority + 1
+ );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ QUEUE_HELPER,
+ TQ_EVENT_ENQUEUE
+ );
+ break;
+ case TQ_NODE_DISPENSABLE:
+ ctx->queue_helper_surrender = true;
+ --priority;
+ TQSetScheduler(
+ ctx->tq_ctx,
+ QUEUE_HELPER,
+ ctx->scheduler_id,
+ priority
+ );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ QUEUE_HELPER,
+ TQ_EVENT_ENQUEUE
+ );
+ break;
+ }
+
+ ctx->queue_priority = priority;
+
+ return priority;
+}
+
+static rtems_task_priority PrepareOwner(
+ Context *ctx,
+ rtems_task_priority priority
+)
+{
+ switch ( ctx->owner_node ) {
+ case TQ_NODE_ONLY:
+ ctx->owner_helper_release = false;
+ TQSetPriority( ctx->tq_ctx, OWNER, PRIO_FLEXIBLE );
+ break;
+ case TQ_NODE_VITAL:
+ if ( ctx->scheduler_id == SCHEDULER_A_ID ) {
+ ctx->owner_helper_release = false;
+ TQSetPriority( ctx->tq_ctx, OWNER, priority + 1 );
+ } else {
+ ctx->owner_helper_release = true;
+ TQSetPriority( ctx->tq_ctx, OWNER, PRIO_FLEXIBLE );
+ TQSetScheduler(
+ ctx->tq_ctx,
+ OWNER_HELPER,
+ ctx->scheduler_id,
+ priority + 1
+ );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ OWNER_HELPER,
+ TQ_EVENT_MUTEX_A_OBTAIN
+ );
+ }
+ break;
+ case TQ_NODE_DISPENSABLE:
+ --priority;
+
+ if ( ctx->scheduler_id == SCHEDULER_A_ID ) {
+ ctx->owner_helper_release = false;
+ TQSetPriority( ctx->tq_ctx, OWNER, priority );
+ } else {
+ ctx->owner_helper_release = true;
+ TQSetPriority( ctx->tq_ctx, OWNER, PRIO_FLEXIBLE );
+ TQSetScheduler(
+ ctx->tq_ctx,
+ OWNER_HELPER,
+ ctx->scheduler_id,
+ priority
+ );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ OWNER_HELPER,
+ TQ_EVENT_MUTEX_A_OBTAIN
+ );
+ }
+ break;
+ }
+
+ ctx->owner_priority = priority;
+
+ return priority;
+}
+
+static rtems_task_priority PrepareOwnerQueue(
+ Context *ctx,
+ rtems_task_priority priority
+)
+{
+ if ( ctx->owner_obtain != 0 ) {
+ switch ( ctx->owner_queue_node ) {
+ case TQ_NODE_ONLY:
+ ctx->owner_queue_helper_release = false;
+ break;
+ case TQ_NODE_VITAL:
+ ctx->owner_queue_helper_release = true;
+ TQSetScheduler(
+ ctx->tq_ctx,
+ OWNER_QUEUE_HELPER,
+ ctx->scheduler_id,
+ priority + 1
+ );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ OWNER_QUEUE_HELPER,
+ ctx->owner_obtain
+ );
+ break;
+ case TQ_NODE_DISPENSABLE:
+ ctx->owner_queue_helper_release = true;
+ --priority;
+ TQSetScheduler(
+ ctx->tq_ctx,
+ OWNER_QUEUE_HELPER,
+ ctx->scheduler_id,
+ priority
+ );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ OWNER_QUEUE_HELPER,
+ ctx->owner_obtain
+ );
+ break;
+ }
+
+ ctx->owner_queue_priority = priority;
+ } else {
+ ctx->owner_queue_helper_release = false;
+ ctx->owner_queue_priority = PRIO_INVALID;
+ }
+
+ return priority;
+}
+
+static void PrepareOwnerOwner( Context *ctx, rtems_task_priority priority )
+{
+ if ( ctx->owner_obtain != 0 ) {
+ switch ( ctx->owner_owner_node ) {
+ case TQ_NODE_ONLY:
+ ctx->owner_owner_helper_release = false;
+ TQSetPriority( ctx->tq_ctx, OWNER_OWNER, PRIO_FLEXIBLE );
+ break;
+ case TQ_NODE_VITAL:
+ if ( ctx->scheduler_id == SCHEDULER_A_ID ) {
+ ctx->owner_owner_helper_release = false;
+ TQSetPriority( ctx->tq_ctx, OWNER_OWNER, priority + 1 );
+ } else {
+ ctx->owner_owner_helper_release = true;
+ TQSetPriority( ctx->tq_ctx, OWNER_OWNER, PRIO_FLEXIBLE );
+ TQSetScheduler(
+ ctx->tq_ctx,
+ OWNER_OWNER_HELPER,
+ ctx->scheduler_id,
+ priority + 1
+ );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ OWNER_OWNER_HELPER,
+ TQ_EVENT_MUTEX_B_OBTAIN
+ );
+ }
+ break;
+ case TQ_NODE_DISPENSABLE:
+ --priority;
+
+ if ( ctx->scheduler_id == SCHEDULER_A_ID ) {
+ ctx->owner_owner_helper_release = false;
+ TQSetPriority( ctx->tq_ctx, OWNER_OWNER, priority );
+ } else {
+ ctx->owner_owner_helper_release = true;
+ TQSetPriority( ctx->tq_ctx, OWNER_OWNER, PRIO_FLEXIBLE );
+ TQSetScheduler(
+ ctx->tq_ctx,
+ OWNER_OWNER_HELPER,
+ ctx->scheduler_id,
+ priority
+ );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ OWNER_OWNER_HELPER,
+ TQ_EVENT_MUTEX_B_OBTAIN
+ );
+ }
+ break;
+ }
+
+ ctx->owner_owner_priority = priority;
+ } else {
+ ctx->owner_owner_helper_release = false;
+ ctx->owner_owner_priority = PRIO_INVALID;
+ }
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Pre_HomeScheduler_Prepare(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx,
+ ScoreTqReqTimeoutPriorityInherit_Pre_HomeScheduler state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqTimeoutPriorityInherit_Pre_HomeScheduler_Home: {
+ /*
+ * While the home scheduler of the thread is the home scheduler of the
+ * thread queue owner.
+ */
+ ctx->scheduler_id = SCHEDULER_A_ID;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_HomeScheduler_Helping: {
+ /*
+ * While the home scheduler of the thread is a helping scheduler of the
+ * thread queue owner.
+ */
+ ctx->scheduler_id = SCHEDULER_B_ID;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_HomeScheduler_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Pre_EligibleScheduler_Prepare(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx,
+ ScoreTqReqTimeoutPriorityInherit_Pre_EligibleScheduler state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqTimeoutPriorityInherit_Pre_EligibleScheduler_One: {
+ /*
+ * While the thread has exactly one eligible scheduler.
+ */
+ ctx->other_scheduler = false;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_EligibleScheduler_More: {
+ /*
+ * While the thread has at least two eligible scheduler.
+ */
+ ctx->other_scheduler = true;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_EligibleScheduler_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Pre_Queue_Prepare(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx,
+ ScoreTqReqTimeoutPriorityInherit_Pre_Queue state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqTimeoutPriorityInherit_Pre_Queue_Only: {
+ /*
+ * While the priority node of the thread is the only priority node in the
+ * priority queue associated with the scheduler of the thread queue.
+ */
+ ctx->queue_node = TQ_NODE_ONLY;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_Queue_Vital: {
+ /*
+ * While the priority node of the thread is not the only priority node in
+ * the priority queue associated with the scheduler of the thread queue,
+ * while the priority node of the thread is the highest priority node in
+ * the priority queue.
+ */
+ ctx->queue_node = TQ_NODE_VITAL;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_Queue_Dispensable: {
+ /*
+ * While the priority node of the thread is not the only priority node in
+ * the priority queue associated with the scheduler of the thread queue,
+ * while the priority node of the thread is not the highest priority node
+ * in the priority queue.
+ */
+ ctx->queue_node = TQ_NODE_DISPENSABLE;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_Queue_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Pre_OwnerPriority_Prepare(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx,
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerPriority state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqTimeoutPriorityInherit_Pre_OwnerPriority_Only: {
+ /*
+ * While the priority node of the thread queue is the only priority node
+ * associated with the scheduler available to the owner.
+ */
+ ctx->owner_node = TQ_NODE_ONLY;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_OwnerPriority_Vital: {
+ /*
+ * While the priority node of the thread queue is not the only priority
+ * node associated with the scheduler available to the owner, while the
+ * priority node of the thread queue is the highest priority node
+ * available to the owner.
+ */
+ ctx->owner_node = TQ_NODE_VITAL;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_OwnerPriority_Dispensable: {
+ /*
+ * While the priority node of the thread queue is not the only priority
+ * node associated with the scheduler available to the owner, while the
+ * priority node of the thread queue is not the highest priority node
+ * available to the owner.
+ */
+ ctx->owner_node = TQ_NODE_DISPENSABLE;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_OwnerPriority_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Pre_OwnerState_Prepare(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx,
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerState state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqTimeoutPriorityInherit_Pre_OwnerState_NotEnqueued: {
+ /*
+ * While the owner of the thread queue is not enqueued on a thread queue.
+ */
+ ctx->owner_obtain = 0;
+ ctx->owner_release = 0;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_OwnerState_FIFO: {
+ /*
+ * While the owner of the thread queue is enqueued on a thread queue in
+ * FIFO order.
+ */
+ ctx->owner_obtain = TQ_EVENT_MUTEX_FIFO_OBTAIN;
+ ctx->owner_release = TQ_EVENT_MUTEX_FIFO_RELEASE;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_OwnerState_Priority: {
+ /*
+ * While the owner of the thread queue is enqueued on a thread queue in
+ * priority order.
+ */
+ ctx->owner_obtain = TQ_EVENT_MUTEX_NO_PROTOCOL_OBTAIN;
+ ctx->owner_release = TQ_EVENT_MUTEX_NO_PROTOCOL_RELEASE;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_OwnerState_PriorityInherit: {
+ /*
+ * While the owner of the thread queue is enqueued on a thread queue in
+ * priority order with priority inheritance.
+ */
+ ctx->owner_obtain = TQ_EVENT_MUTEX_C_OBTAIN;
+ ctx->owner_release = TQ_EVENT_MUTEX_C_RELEASE;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_OwnerState_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Pre_OwnerQueue_Prepare(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx,
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerQueue state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqTimeoutPriorityInherit_Pre_OwnerQueue_Only: {
+ /*
+ * While the priority node of the owner is the only priority node in the
+ * priority queue associated with the scheduler of the thread queue on
+ * which the owner is enqueued.
+ */
+ ctx->owner_queue_node = TQ_NODE_ONLY;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_OwnerQueue_Vital: {
+ /*
+ * While the priority node of the owner is not the only priority node in
+ * the priority queue associated with the scheduler of the thread queue
+ * on which the owner is enqueued, while the priority node of the owner
+ * is the highest priority node in the priority queue.
+ */
+ ctx->owner_queue_node = TQ_NODE_VITAL;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_OwnerQueue_Dispensable: {
+ /*
+ * While the priority node of the owner is not the only priority node in
+ * the priority queue associated with the scheduler of the thread queue
+ * on which the owner is enqueued, while the priority node of the owner
+ * is not the highest priority node in the priority queue.
+ */
+ ctx->owner_queue_node = TQ_NODE_DISPENSABLE;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_OwnerQueue_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Pre_OwnerOwnerPriority_Prepare(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx,
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerOwnerPriority state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqTimeoutPriorityInherit_Pre_OwnerOwnerPriority_Only: {
+ /*
+ * While the priority node of the thread queue on which the owner is
+ * enqueued is the only priority node associated with the scheduler
+ * available to the owner of the thread queue on which the owner is
+ * enqueued.
+ */
+ ctx->owner_owner_node = TQ_NODE_ONLY;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_OwnerOwnerPriority_Vital: {
+ /*
+ * While the priority node of the thread queue on which the owner is
+ * enqueued is not the only priority node associated with the scheduler
+ * available to the owner of the thread queue on which the owner is
+ * enqueued, while the priority node of the thread queue on which the
+ * owner is enqueued is the highest priority node available to the owner
+ * of the thread queue on which the owner is enqueued.
+ */
+ ctx->owner_owner_node = TQ_NODE_VITAL;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_OwnerOwnerPriority_Dispensable: {
+ /*
+ * While the priority node of the thread queue on which the owner is
+ * enqueued is not the only priority node associated with the scheduler
+ * available to the owner of the thread queue on which the owner is
+ * enqueued, while the priority node of the thread queue is on which the
+ * owner is enqueued not the highest priority node available to the owner
+ * of the thread queue on which the owner is enqueued.
+ */
+ ctx->owner_owner_node = TQ_NODE_DISPENSABLE;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_OwnerOwnerPriority_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Pre_WaitState_Prepare(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx,
+ ScoreTqReqTimeoutPriorityInherit_Pre_WaitState state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqTimeoutPriorityInherit_Pre_WaitState_Blocked: {
+ /*
+ * While the thread is in the blocked wait state.
+ */
+ ctx->wait_state = TQ_WAIT_STATE_BLOCKED;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_WaitState_IntendToBlock: {
+ /*
+ * While the thread is in the intend to block wait state.
+ */
+ ctx->wait_state = TQ_WAIT_STATE_INTEND_TO_BLOCK;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_WaitState_ReadyAgain: {
+ /*
+ * While the thread is in the ready again wait state.
+ */
+ ctx->wait_state = TQ_WAIT_STATE_READY_AGAIN;
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Pre_WaitState_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Post_Status_Check(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqTimeoutPriorityInherit_Post_Status_Ok: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_SUCCESSFUL.
+ */
+ T_eq_int(
+ ctx->tq_ctx->status[ THREAD ],
+ TQConvertStatus( ctx->tq_ctx, STATUS_SUCCESSFUL )
+ );
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_TIMEOUT.
+ */
+ T_eq_int(
+ ctx->tq_ctx->status[ THREAD ],
+ TQConvertStatus( ctx->tq_ctx, STATUS_TIMEOUT )
+ );
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Post_Status_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Check(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock state
+)
+{
+ size_t i;
+
+ i = 0;
+
+ switch ( state ) {
+ case ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes: {
+ /*
+ * The thread shall be unblocked by the timeout operation.
+ */
+ T_true( GetUnblock( ctx, &i ) );
+ T_false( GetUnblock( ctx, &i ) );
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No: {
+ /*
+ * The thread shall not be unblocked by the timeout operation.
+ */
+ T_false( GetUnblock( ctx, &i ) );
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Check(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Nop: {
+ /*
+ * The priority of the owner with respect to the scheduler shall not
+ * change by the timeout operation.
+ */
+ T_eq_u32( ctx->owner_priority_after, ctx->owner_priority );
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower: {
+ /*
+ * The priority of the owner with respect to the scheduler shall be
+ * lowered to the next highest priority.
+ */
+ T_eq_u32( ctx->owner_priority_after, ctx->owner_priority + 1 );
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Drop: {
+ /*
+ * The owner shall not have a priority with respect to the scheduler.
+ */
+ T_eq_u32( ctx->owner_priority_after, PRIO_INVALID );
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Check(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Nop: {
+ /*
+ * The priority of the owner of the thread queue on which the owner is
+ * enqueued with respect to the scheduler shall not change by the timeout
+ * operation.
+ */
+ T_eq_u32( ctx->owner_owner_priority_after, ctx->owner_owner_priority );
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Lower: {
+ /*
+ * The priority of the owner of the thread queue on which the owner is
+ * enqueued with respect to the scheduler shall be lowered to the next
+ * highest priority.
+ */
+ T_eq_u32( ctx->owner_owner_priority_after, ctx->owner_owner_priority + 1 );
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Drop: {
+ /*
+ * The owner of the thread queue on which the owner is enqueued shall not
+ * have a priority with respect to the scheduler.
+ */
+ T_eq_u32( ctx->owner_owner_priority_after, PRIO_INVALID );
+ break;
+ }
+
+ case ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Setup(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx
+)
+{
+ ctx->request.arg = ctx;
+ TQReset( ctx->tq_ctx );
+ SetSelfPriority( PRIO_NEARLY_IDLE );
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Setup_Wrap( void *arg )
+{
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqTimeoutPriorityInherit_Setup( ctx );
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Teardown(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx
+)
+{
+ TQReset( ctx->tq_ctx );
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Teardown_Wrap( void *arg )
+{
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqTimeoutPriorityInherit_Teardown( ctx );
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Prepare(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx
+)
+{
+ ctx->queue_helper_surrender = false;
+ ctx->owner_helper_release = false;
+ ctx->owner_queue_helper_release = false;
+ ctx->owner_owner_helper_release = false;
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Action(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx
+)
+{
+ rtems_task_priority priority;
+
+ priority = PRIO_FLEXIBLE;
+ TQSetScheduler( ctx->tq_ctx, THREAD, ctx->scheduler_id, priority );
+
+ TQSend(
+ ctx->tq_ctx,
+ OWNER,
+ TQ_EVENT_MUTEX_A_OBTAIN | TQ_EVENT_ENQUEUE
+ );
+
+ if ( ctx->owner_obtain != 0 ) {
+ TQSend(
+ ctx->tq_ctx,
+ OWNER_OWNER,
+ TQ_EVENT_MUTEX_B_OBTAIN | ctx->owner_obtain
+ );
+ TQSend( ctx->tq_ctx, OWNER, ctx->owner_obtain | ctx->owner_release );
+ }
+
+ PrepareThread( ctx );
+ priority = PrepareQueue( ctx, priority );
+ priority = PrepareOwner( ctx, priority );
+ priority = PrepareOwnerQueue( ctx, priority );
+ PrepareOwnerOwner( ctx, priority );
+
+ TQClearDone( ctx->tq_ctx, THREAD );
+
+ switch ( ctx->wait_state ) {
+ case TQ_WAIT_STATE_BLOCKED:
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ THREAD,
+ TQ_EVENT_ENQUEUE_TIMED
+ );
+ Tick( ctx );
+ GetPriorities( ctx );
+ TQSend( ctx->tq_ctx, OWNER, TQ_EVENT_SURRENDER );
+ break;
+ case TQ_WAIT_STATE_INTEND_TO_BLOCK:
+ T_scheduler_set_event_handler( SchedulerBlock, ctx );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ THREAD,
+ TQ_EVENT_ENQUEUE_TIMED
+ );
+ GetPriorities( ctx );
+ TQSend( ctx->tq_ctx, OWNER, TQ_EVENT_SURRENDER );
+ break;
+ case TQ_WAIT_STATE_READY_AGAIN:
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ THREAD,
+ TQ_EVENT_ENQUEUE_TIMED
+ );
+ T_scheduler_set_event_handler( SchedulerUnblock, ctx );
+ TQSend( ctx->tq_ctx, OWNER, TQ_EVENT_SURRENDER );
+ GetPriorities( ctx );
+ TQSend( ctx->tq_ctx, THREAD, TQ_EVENT_SURRENDER );
+ break;
+ }
+
+ TQWaitForDone( ctx->tq_ctx, THREAD );
+ TQWaitForExecutionStop( ctx->tq_ctx, THREAD );
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_Cleanup(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx
+)
+{
+ if ( ctx->owner_obtain != 0 ) {
+ TQSend(
+ ctx->tq_ctx,
+ OWNER_OWNER,
+ TQ_EVENT_MUTEX_B_RELEASE | ctx->owner_release
+ );
+
+ if ( ctx->owner_queue_helper_release ) {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ OWNER_QUEUE_HELPER,
+ ctx->owner_release
+ );
+ }
+
+ if ( ctx->owner_owner_helper_release ) {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ OWNER_OWNER_HELPER,
+ TQ_EVENT_MUTEX_B_RELEASE
+ );
+ }
+ }
+
+ TQSend( ctx->tq_ctx, OWNER, TQ_EVENT_MUTEX_A_RELEASE );
+
+ if ( ctx->queue_helper_surrender ) {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ QUEUE_HELPER,
+ TQ_EVENT_SURRENDER
+ );
+ }
+
+ if ( ctx->owner_helper_release ) {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ OWNER_HELPER,
+ TQ_EVENT_MUTEX_A_RELEASE
+ );
+ }
+
+ if ( ctx->other_scheduler ) {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ THREAD,
+ TQ_EVENT_MUTEX_D_RELEASE
+ );
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ THREAD_HELPER_A,
+ TQ_EVENT_MUTEX_D_RELEASE
+ );
+
+ if ( rtems_scheduler_get_processor_maximum() >= 3 ) {
+ TQSendAndWaitForExecutionStop(
+ ctx->tq_ctx,
+ THREAD_HELPER_B,
+ TQ_EVENT_MUTEX_D_RELEASE
+ );
+ }
+ }
+}
+
+static const ScoreTqReqTimeoutPriorityInherit_Entry
+ScoreTqReqTimeoutPriorityInherit_Entries[] = {
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 1, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 1, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 1, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 1, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 1, 1, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_Ok,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Nop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Nop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 1, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Drop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 1, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Drop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 1, 1, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_Ok,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Drop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Nop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Nop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Lower },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Lower },
+#endif
+ { 0, 0, 0, 0, 0, 0, 1, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+ { 0, 0, 0, 0, 0, 0, 1, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 1, 1, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_Ok,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Drop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Drop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#endif
+ { 0, 0, 0, 0, 0, 0, 1, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+ { 0, 0, 0, 0, 0, 0, 1, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+ { 0, 0, 0, 0, 0, 0, 1, 1, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_Ok,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Drop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Nop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Drop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Nop },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 1, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Nop },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Nop },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Drop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Lower },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Drop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Lower },
+#endif
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Lower },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Lower },
+ { 0, 0, 0, 0, 0, 0, 1, 1, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_Ok,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA },
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Drop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Drop },
+#endif
+#if !defined(RTEMS_SMP)
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, ScoreTqReqTimeoutPriorityInherit_Post_Status_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA }
+#else
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Drop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Drop }
+#endif
+};
+
+static const uint8_t
+ScoreTqReqTimeoutPriorityInherit_Map[] = {
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1,
+ 1, 2, 2, 2, 2, 2, 2, 24, 25, 31, 24, 25, 31, 2, 2, 2, 24, 25, 31, 24, 25, 31,
+ 2, 2, 2, 1, 1, 1, 24, 25, 31, 2, 2, 2, 24, 25, 11, 24, 25, 11, 2, 2, 2, 24,
+ 25, 11, 24, 25, 11, 2, 2, 2, 1, 1, 1, 24, 25, 11, 2, 2, 2, 32, 33, 11, 32,
+ 33, 11, 2, 2, 2, 32, 33, 11, 32, 33, 11, 2, 2, 2, 1, 1, 1, 32, 33, 11, 2, 2,
+ 2, 44, 45, 11, 36, 37, 11, 2, 2, 2, 44, 45, 11, 36, 37, 11, 2, 2, 2, 1, 1, 1,
+ 36, 37, 11, 2, 2, 2, 1, 1, 1, 29, 30, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
+ 1, 1, 1, 29, 30, 46, 2, 2, 2, 1, 1, 1, 29, 30, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 1, 1, 1, 29, 30, 11, 2, 2, 2, 1, 1, 1, 38, 39, 11, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 2, 2, 2, 1, 1, 1, 38, 39, 11, 2, 2, 2, 1, 1, 1, 40, 41, 11, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 40, 41, 11, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 24, 25,
+ 31, 24, 25, 31, 2, 2, 2, 24, 25, 31, 24, 25, 31, 2, 2, 2, 1, 1, 1, 24, 25,
+ 31, 2, 2, 2, 24, 25, 11, 24, 25, 11, 2, 2, 2, 24, 25, 11, 24, 25, 11, 2, 2,
+ 2, 1, 1, 1, 24, 25, 11, 2, 2, 2, 32, 33, 11, 32, 33, 11, 2, 2, 2, 32, 33, 11,
+ 32, 33, 11, 2, 2, 2, 1, 1, 1, 32, 33, 11, 2, 2, 2, 44, 45, 11, 36, 37, 11, 2,
+ 2, 2, 44, 45, 11, 36, 37, 11, 2, 2, 2, 1, 1, 1, 36, 37, 11, 2, 2, 2, 1, 1, 1,
+ 29, 30, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 29, 30, 46, 2, 2, 2,
+ 1, 1, 1, 29, 30, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 29, 30, 11,
+ 2, 2, 2, 1, 1, 1, 38, 39, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1,
+ 38, 39, 11, 2, 2, 2, 1, 1, 1, 40, 41, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
+ 1, 1, 1, 40, 41, 11, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
+ 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 29, 30, 11, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 29, 30, 11, 2, 2, 2, 1, 1, 1, 29,
+ 30, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 29, 30, 11, 2, 2, 2, 1,
+ 1, 1, 38, 39, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 38, 39, 11, 2,
+ 2, 2, 1, 1, 1, 40, 41, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 40,
+ 41, 11, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0,
+ 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0,
+ 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 0, 0, 0, 3, 3, 3, 3, 3, 3, 5, 6, 12, 5, 6, 12, 3, 3, 3, 5, 6, 12, 5, 6,
+ 12, 3, 3, 3, 0, 0, 0, 5, 6, 12, 3, 3, 3, 5, 6, 4, 5, 6, 4, 3, 3, 3, 5, 6, 4,
+ 5, 6, 4, 3, 3, 3, 0, 0, 0, 5, 6, 4, 3, 3, 3, 9, 10, 4, 9, 10, 4, 3, 3, 3, 9,
+ 10, 4, 9, 10, 4, 3, 3, 3, 0, 0, 0, 9, 10, 4, 3, 3, 3, 22, 23, 4, 20, 21, 4,
+ 3, 3, 3, 22, 23, 4, 20, 21, 4, 3, 3, 3, 0, 0, 0, 20, 21, 4, 3, 3, 3, 0, 0, 0,
+ 7, 8, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 7, 8, 26, 3, 3, 3, 0,
+ 0, 0, 7, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 7, 8, 4, 3, 3, 3,
+ 0, 0, 0, 13, 14, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 13, 14, 4,
+ 3, 3, 3, 0, 0, 0, 15, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 15,
+ 16, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0,
+ 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0,
+ 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 0, 0, 0, 3, 3, 3, 3, 3, 3, 5, 6, 12, 5, 6, 12, 3, 3, 3, 5, 6, 12, 5, 6,
+ 12, 3, 3, 3, 0, 0, 0, 5, 6, 12, 3, 3, 3, 5, 6, 4, 5, 6, 4, 3, 3, 3, 5, 6, 4,
+ 5, 6, 4, 3, 3, 3, 0, 0, 0, 5, 6, 4, 3, 3, 3, 9, 10, 4, 9, 10, 4, 3, 3, 3, 9,
+ 10, 4, 9, 10, 4, 3, 3, 3, 0, 0, 0, 9, 10, 4, 3, 3, 3, 22, 23, 4, 20, 21, 4,
+ 3, 3, 3, 22, 23, 4, 20, 21, 4, 3, 3, 3, 0, 0, 0, 20, 21, 4, 3, 3, 3, 0, 0, 0,
+ 7, 8, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 7, 8, 26, 3, 3, 3, 0,
+ 0, 0, 7, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 7, 8, 4, 3, 3, 3,
+ 0, 0, 0, 13, 14, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 13, 14, 4,
+ 3, 3, 3, 0, 0, 0, 15, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 15,
+ 16, 4, 3, 3, 3, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0,
+ 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0,
+ 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3,
+ 0, 0, 0, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3,
+ 3, 0, 0, 0, 3, 3, 3, 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, 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, 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, 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, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 7, 8, 4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 3, 3, 3, 0, 0, 0, 7, 8, 4, 3, 3, 3, 0, 0, 0, 7, 8, 4, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 7, 8, 4, 3, 3, 3, 0, 0, 0, 13, 14, 4, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 13, 14, 4, 3, 3, 3, 0, 0, 0, 15, 16, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 15, 16, 4, 17, 18, 19, 17, 18,
+ 19, 17, 18, 19, 17, 18, 19, 17, 18, 19, 17, 18, 19, 17, 18, 19, 0, 0, 0, 17,
+ 18, 19, 17, 18, 4, 17, 18, 4, 17, 18, 4, 17, 18, 4, 17, 18, 4, 17, 18, 4, 17,
+ 18, 4, 0, 0, 0, 17, 18, 4, 27, 28, 4, 27, 28, 4, 27, 28, 4, 27, 28, 4, 27,
+ 28, 4, 27, 28, 4, 27, 28, 4, 0, 0, 0, 27, 28, 4, 47, 48, 4, 42, 43, 4, 34,
+ 35, 4, 42, 43, 4, 42, 43, 4, 34, 35, 4, 34, 35, 4, 0, 0, 0, 34, 35, 4, 5, 6,
+ 12, 5, 6, 12, 5, 6, 12, 5, 6, 12, 5, 6, 12, 5, 6, 12, 5, 6, 12, 0, 0, 0, 5,
+ 6, 12, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 0, 0,
+ 0, 5, 6, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9,
+ 10, 4, 0, 0, 0, 9, 10, 4, 22, 23, 4, 22, 23, 4, 20, 21, 4, 22, 23, 4, 22, 23,
+ 4, 20, 21, 4, 20, 21, 4, 0, 0, 0, 20, 21, 4, 7, 8, 26, 0, 0, 0, 7, 8, 26, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 26, 0, 0, 0, 7, 8, 26, 7, 8, 4, 0, 0, 0, 7, 8,
+ 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 4, 0, 0, 0, 7, 8, 4, 13, 14, 4, 0, 0, 0,
+ 13, 14, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 4, 0, 0, 0, 13, 14, 4, 15, 16,
+ 4, 0, 0, 0, 15, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 4, 0, 0, 0, 15, 16,
+ 4, 5, 6, 19, 5, 6, 19, 5, 6, 19, 5, 6, 19, 5, 6, 19, 5, 6, 19, 5, 6, 19, 0,
+ 0, 0, 5, 6, 19, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6,
+ 4, 0, 0, 0, 5, 6, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10,
+ 4, 9, 10, 4, 0, 0, 0, 9, 10, 4, 22, 23, 4, 22, 23, 4, 20, 21, 4, 22, 23, 4,
+ 22, 23, 4, 20, 21, 4, 20, 21, 4, 0, 0, 0, 20, 21, 4, 5, 6, 12, 5, 6, 12, 5,
+ 6, 12, 5, 6, 12, 5, 6, 12, 5, 6, 12, 5, 6, 12, 0, 0, 0, 5, 6, 12, 5, 6, 4, 5,
+ 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 0, 0, 0, 5, 6, 4, 9, 10,
+ 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 0, 0, 0, 9,
+ 10, 4, 22, 23, 4, 22, 23, 4, 20, 21, 4, 22, 23, 4, 22, 23, 4, 20, 21, 4, 20,
+ 21, 4, 0, 0, 0, 20, 21, 4, 7, 8, 26, 0, 0, 0, 7, 8, 26, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 7, 8, 26, 0, 0, 0, 7, 8, 26, 7, 8, 4, 0, 0, 0, 7, 8, 4, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7, 8, 4, 0, 0, 0, 7, 8, 4, 13, 14, 4, 0, 0, 0, 13, 14, 4, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 13, 14, 4, 0, 0, 0, 13, 14, 4, 15, 16, 4, 0, 0, 0, 15,
+ 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 4, 0, 0, 0, 15, 16, 4, 7, 8, 4, 0,
+ 0, 0, 7, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 4, 0, 0, 0, 7, 8, 4, 7, 8, 4,
+ 0, 0, 0, 7, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 4, 0, 0, 0, 7, 8, 4, 13,
+ 14, 4, 0, 0, 0, 13, 14, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 4, 0, 0, 0, 13,
+ 14, 4, 15, 16, 4, 0, 0, 0, 15, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 4,
+ 0, 0, 0, 15, 16, 4, 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, 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, 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, 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, 0, 0, 0, 0, 7, 8, 4, 0, 0, 0, 7, 8, 4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 7, 8, 4, 0, 0, 0, 7, 8, 4, 7, 8, 4, 0, 0, 0, 7, 8, 4, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7, 8, 4, 0, 0, 0, 7, 8, 4, 13, 14, 4, 0, 0, 0, 13, 14, 4, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 13, 14, 4, 0, 0, 0, 13, 14, 4, 15, 16, 4, 0, 0, 0, 15,
+ 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 4, 0, 0, 0, 15, 16, 4, 17, 18, 19,
+ 17, 18, 19, 17, 18, 19, 17, 18, 19, 17, 18, 19, 17, 18, 19, 17, 18, 19, 0, 0,
+ 0, 17, 18, 19, 17, 18, 4, 17, 18, 4, 17, 18, 4, 17, 18, 4, 17, 18, 4, 17, 18,
+ 4, 17, 18, 4, 0, 0, 0, 17, 18, 4, 27, 28, 4, 27, 28, 4, 27, 28, 4, 27, 28, 4,
+ 27, 28, 4, 27, 28, 4, 27, 28, 4, 0, 0, 0, 27, 28, 4, 47, 48, 4, 42, 43, 4,
+ 34, 35, 4, 42, 43, 4, 42, 43, 4, 34, 35, 4, 34, 35, 4, 0, 0, 0, 34, 35, 4, 5,
+ 6, 12, 5, 6, 12, 5, 6, 12, 5, 6, 12, 5, 6, 12, 5, 6, 12, 5, 6, 12, 0, 0, 0,
+ 5, 6, 12, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 0,
+ 0, 0, 5, 6, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9,
+ 10, 4, 0, 0, 0, 9, 10, 4, 22, 23, 4, 22, 23, 4, 20, 21, 4, 22, 23, 4, 22, 23,
+ 4, 20, 21, 4, 20, 21, 4, 0, 0, 0, 20, 21, 4, 7, 8, 26, 0, 0, 0, 7, 8, 26, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 26, 0, 0, 0, 7, 8, 26, 7, 8, 4, 0, 0, 0, 7, 8,
+ 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 4, 0, 0, 0, 7, 8, 4, 13, 14, 4, 0, 0, 0,
+ 13, 14, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 4, 0, 0, 0, 13, 14, 4, 15, 16,
+ 4, 0, 0, 0, 15, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 4, 0, 0, 0, 15, 16,
+ 4, 5, 6, 19, 5, 6, 19, 5, 6, 19, 5, 6, 19, 5, 6, 19, 5, 6, 19, 5, 6, 19, 0,
+ 0, 0, 5, 6, 19, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6,
+ 4, 0, 0, 0, 5, 6, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10,
+ 4, 9, 10, 4, 0, 0, 0, 9, 10, 4, 22, 23, 4, 22, 23, 4, 20, 21, 4, 22, 23, 4,
+ 22, 23, 4, 20, 21, 4, 20, 21, 4, 0, 0, 0, 20, 21, 4, 5, 6, 12, 5, 6, 12, 5,
+ 6, 12, 5, 6, 12, 5, 6, 12, 5, 6, 12, 5, 6, 12, 0, 0, 0, 5, 6, 12, 5, 6, 4, 5,
+ 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 5, 6, 4, 0, 0, 0, 5, 6, 4, 9, 10,
+ 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 9, 10, 4, 0, 0, 0, 9,
+ 10, 4, 22, 23, 4, 22, 23, 4, 20, 21, 4, 22, 23, 4, 22, 23, 4, 20, 21, 4, 20,
+ 21, 4, 0, 0, 0, 20, 21, 4, 7, 8, 26, 0, 0, 0, 7, 8, 26, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 7, 8, 26, 0, 0, 0, 7, 8, 26, 7, 8, 4, 0, 0, 0, 7, 8, 4, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7, 8, 4, 0, 0, 0, 7, 8, 4, 13, 14, 4, 0, 0, 0, 13, 14, 4, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 13, 14, 4, 0, 0, 0, 13, 14, 4, 15, 16, 4, 0, 0, 0, 15,
+ 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 4, 0, 0, 0, 15, 16, 4, 7, 8, 4, 0,
+ 0, 0, 7, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 4, 0, 0, 0, 7, 8, 4, 7, 8, 4,
+ 0, 0, 0, 7, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 8, 4, 0, 0, 0, 7, 8, 4, 13,
+ 14, 4, 0, 0, 0, 13, 14, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 14, 4, 0, 0, 0, 13,
+ 14, 4, 15, 16, 4, 0, 0, 0, 15, 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 4,
+ 0, 0, 0, 15, 16, 4, 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, 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, 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, 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, 0, 0, 0, 0, 7, 8, 4, 0, 0, 0, 7, 8, 4, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 7, 8, 4, 0, 0, 0, 7, 8, 4, 7, 8, 4, 0, 0, 0, 7, 8, 4, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 7, 8, 4, 0, 0, 0, 7, 8, 4, 13, 14, 4, 0, 0, 0, 13, 14, 4, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 13, 14, 4, 0, 0, 0, 13, 14, 4, 15, 16, 4, 0, 0, 0, 15,
+ 16, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 16, 4, 0, 0, 0, 15, 16, 4
+};
+
+static size_t ScoreTqReqTimeoutPriorityInherit_Scope(
+ void *arg,
+ char *buf,
+ size_t n
+)
+{
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope(
+ ScoreTqReqTimeoutPriorityInherit_PreDesc,
+ buf,
+ n,
+ ctx->Map.pcs
+ );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreTqReqTimeoutPriorityInherit_Fixture = {
+ .setup = ScoreTqReqTimeoutPriorityInherit_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreTqReqTimeoutPriorityInherit_Teardown_Wrap,
+ .scope = ScoreTqReqTimeoutPriorityInherit_Scope,
+ .initial_context = &ScoreTqReqTimeoutPriorityInherit_Instance
+};
+
+static inline ScoreTqReqTimeoutPriorityInherit_Entry
+ScoreTqReqTimeoutPriorityInherit_PopEntry(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return ScoreTqReqTimeoutPriorityInherit_Entries[
+ ScoreTqReqTimeoutPriorityInherit_Map[ index ]
+ ];
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_SetPreConditionStates(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx
+)
+{
+ ctx->Map.pcs[ 0 ] = ctx->Map.pci[ 0 ];
+ ctx->Map.pcs[ 1 ] = ctx->Map.pci[ 1 ];
+ ctx->Map.pcs[ 2 ] = ctx->Map.pci[ 2 ];
+ ctx->Map.pcs[ 3 ] = ctx->Map.pci[ 3 ];
+ ctx->Map.pcs[ 4 ] = ctx->Map.pci[ 4 ];
+
+ if ( ctx->Map.entry.Pre_OwnerQueue_NA ) {
+ ctx->Map.pcs[ 5 ] = ScoreTqReqTimeoutPriorityInherit_Pre_OwnerQueue_NA;
+ } else {
+ ctx->Map.pcs[ 5 ] = ctx->Map.pci[ 5 ];
+ }
+
+ if ( ctx->Map.entry.Pre_OwnerOwnerPriority_NA ) {
+ ctx->Map.pcs[ 6 ] = ScoreTqReqTimeoutPriorityInherit_Pre_OwnerOwnerPriority_NA;
+ } else {
+ ctx->Map.pcs[ 6 ] = ctx->Map.pci[ 6 ];
+ }
+
+ ctx->Map.pcs[ 7 ] = ctx->Map.pci[ 7 ];
+}
+
+static void ScoreTqReqTimeoutPriorityInherit_TestVariant(
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx
+)
+{
+ ScoreTqReqTimeoutPriorityInherit_Pre_HomeScheduler_Prepare(
+ ctx,
+ ctx->Map.pcs[ 0 ]
+ );
+ ScoreTqReqTimeoutPriorityInherit_Pre_EligibleScheduler_Prepare(
+ ctx,
+ ctx->Map.pcs[ 1 ]
+ );
+ ScoreTqReqTimeoutPriorityInherit_Pre_Queue_Prepare( ctx, ctx->Map.pcs[ 2 ] );
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerPriority_Prepare(
+ ctx,
+ ctx->Map.pcs[ 3 ]
+ );
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerState_Prepare(
+ ctx,
+ ctx->Map.pcs[ 4 ]
+ );
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerQueue_Prepare(
+ ctx,
+ ctx->Map.pcs[ 5 ]
+ );
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerOwnerPriority_Prepare(
+ ctx,
+ ctx->Map.pcs[ 6 ]
+ );
+ ScoreTqReqTimeoutPriorityInherit_Pre_WaitState_Prepare(
+ ctx,
+ ctx->Map.pcs[ 7 ]
+ );
+ ScoreTqReqTimeoutPriorityInherit_Action( ctx );
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Check(
+ ctx,
+ ctx->Map.entry.Post_Status
+ );
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Check(
+ ctx,
+ ctx->Map.entry.Post_Unblock
+ );
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Check(
+ ctx,
+ ctx->Map.entry.Post_OwnerPriority
+ );
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Check(
+ ctx,
+ ctx->Map.entry.Post_OwnerOwnerPriority
+ );
+}
+
+static T_fixture_node ScoreTqReqTimeoutPriorityInherit_Node;
+
+static T_remark ScoreTqReqTimeoutPriorityInherit_Remark = {
+ .next = NULL,
+ .remark = "ScoreTqReqTimeoutPriorityInherit"
+};
+
+void ScoreTqReqTimeoutPriorityInherit_Run( TQContext *tq_ctx )
+{
+ ScoreTqReqTimeoutPriorityInherit_Context *ctx;
+
+ ctx = &ScoreTqReqTimeoutPriorityInherit_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture(
+ &ScoreTqReqTimeoutPriorityInherit_Node,
+ &ScoreTqReqTimeoutPriorityInherit_Fixture
+ );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pci[ 0 ] = ScoreTqReqTimeoutPriorityInherit_Pre_HomeScheduler_Home;
+ ctx->Map.pci[ 0 ] < ScoreTqReqTimeoutPriorityInherit_Pre_HomeScheduler_NA;
+ ++ctx->Map.pci[ 0 ]
+ ) {
+ for (
+ ctx->Map.pci[ 1 ] = ScoreTqReqTimeoutPriorityInherit_Pre_EligibleScheduler_One;
+ ctx->Map.pci[ 1 ] < ScoreTqReqTimeoutPriorityInherit_Pre_EligibleScheduler_NA;
+ ++ctx->Map.pci[ 1 ]
+ ) {
+ for (
+ ctx->Map.pci[ 2 ] = ScoreTqReqTimeoutPriorityInherit_Pre_Queue_Only;
+ ctx->Map.pci[ 2 ] < ScoreTqReqTimeoutPriorityInherit_Pre_Queue_NA;
+ ++ctx->Map.pci[ 2 ]
+ ) {
+ for (
+ ctx->Map.pci[ 3 ] = ScoreTqReqTimeoutPriorityInherit_Pre_OwnerPriority_Only;
+ ctx->Map.pci[ 3 ] < ScoreTqReqTimeoutPriorityInherit_Pre_OwnerPriority_NA;
+ ++ctx->Map.pci[ 3 ]
+ ) {
+ for (
+ ctx->Map.pci[ 4 ] = ScoreTqReqTimeoutPriorityInherit_Pre_OwnerState_NotEnqueued;
+ ctx->Map.pci[ 4 ] < ScoreTqReqTimeoutPriorityInherit_Pre_OwnerState_NA;
+ ++ctx->Map.pci[ 4 ]
+ ) {
+ for (
+ ctx->Map.pci[ 5 ] = ScoreTqReqTimeoutPriorityInherit_Pre_OwnerQueue_Only;
+ ctx->Map.pci[ 5 ] < ScoreTqReqTimeoutPriorityInherit_Pre_OwnerQueue_NA;
+ ++ctx->Map.pci[ 5 ]
+ ) {
+ for (
+ ctx->Map.pci[ 6 ] = ScoreTqReqTimeoutPriorityInherit_Pre_OwnerOwnerPriority_Only;
+ ctx->Map.pci[ 6 ] < ScoreTqReqTimeoutPriorityInherit_Pre_OwnerOwnerPriority_NA;
+ ++ctx->Map.pci[ 6 ]
+ ) {
+ for (
+ ctx->Map.pci[ 7 ] = ScoreTqReqTimeoutPriorityInherit_Pre_WaitState_Blocked;
+ ctx->Map.pci[ 7 ] < ScoreTqReqTimeoutPriorityInherit_Pre_WaitState_NA;
+ ++ctx->Map.pci[ 7 ]
+ ) {
+ ctx->Map.entry = ScoreTqReqTimeoutPriorityInherit_PopEntry(
+ ctx
+ );
+
+ if ( ctx->Map.entry.Skip ) {
+ continue;
+ }
+
+ ScoreTqReqTimeoutPriorityInherit_SetPreConditionStates(
+ ctx
+ );
+ ScoreTqReqTimeoutPriorityInherit_Prepare( ctx );
+ ScoreTqReqTimeoutPriorityInherit_TestVariant( ctx );
+ ScoreTqReqTimeoutPriorityInherit_Cleanup( ctx );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ T_add_remark( &ScoreTqReqTimeoutPriorityInherit_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-tq-timeout-priority-inherit.h b/testsuites/validation/tr-tq-timeout-priority-inherit.h
new file mode 100644
index 0000000000..149ca69755
--- /dev/null
+++ b/testsuites/validation/tr-tq-timeout-priority-inherit.h
@@ -0,0 +1,160 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqTimeoutPriorityInherit
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_TQ_TIMEOUT_PRIORITY_INHERIT_H
+#define _TR_TQ_TIMEOUT_PRIORITY_INHERIT_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreTqReqTimeoutPriorityInherit
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreTqReqTimeoutPriorityInherit_Pre_HomeScheduler_Home,
+ ScoreTqReqTimeoutPriorityInherit_Pre_HomeScheduler_Helping,
+ ScoreTqReqTimeoutPriorityInherit_Pre_HomeScheduler_NA
+} ScoreTqReqTimeoutPriorityInherit_Pre_HomeScheduler;
+
+typedef enum {
+ ScoreTqReqTimeoutPriorityInherit_Pre_EligibleScheduler_One,
+ ScoreTqReqTimeoutPriorityInherit_Pre_EligibleScheduler_More,
+ ScoreTqReqTimeoutPriorityInherit_Pre_EligibleScheduler_NA
+} ScoreTqReqTimeoutPriorityInherit_Pre_EligibleScheduler;
+
+typedef enum {
+ ScoreTqReqTimeoutPriorityInherit_Pre_Queue_Only,
+ ScoreTqReqTimeoutPriorityInherit_Pre_Queue_Vital,
+ ScoreTqReqTimeoutPriorityInherit_Pre_Queue_Dispensable,
+ ScoreTqReqTimeoutPriorityInherit_Pre_Queue_NA
+} ScoreTqReqTimeoutPriorityInherit_Pre_Queue;
+
+typedef enum {
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerPriority_Only,
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerPriority_Vital,
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerPriority_Dispensable,
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerPriority_NA
+} ScoreTqReqTimeoutPriorityInherit_Pre_OwnerPriority;
+
+typedef enum {
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerState_NotEnqueued,
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerState_FIFO,
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerState_Priority,
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerState_PriorityInherit,
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerState_NA
+} ScoreTqReqTimeoutPriorityInherit_Pre_OwnerState;
+
+typedef enum {
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerQueue_Only,
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerQueue_Vital,
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerQueue_Dispensable,
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerQueue_NA
+} ScoreTqReqTimeoutPriorityInherit_Pre_OwnerQueue;
+
+typedef enum {
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerOwnerPriority_Only,
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerOwnerPriority_Vital,
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerOwnerPriority_Dispensable,
+ ScoreTqReqTimeoutPriorityInherit_Pre_OwnerOwnerPriority_NA
+} ScoreTqReqTimeoutPriorityInherit_Pre_OwnerOwnerPriority;
+
+typedef enum {
+ ScoreTqReqTimeoutPriorityInherit_Pre_WaitState_Blocked,
+ ScoreTqReqTimeoutPriorityInherit_Pre_WaitState_IntendToBlock,
+ ScoreTqReqTimeoutPriorityInherit_Pre_WaitState_ReadyAgain,
+ ScoreTqReqTimeoutPriorityInherit_Pre_WaitState_NA
+} ScoreTqReqTimeoutPriorityInherit_Pre_WaitState;
+
+typedef enum {
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Ok,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_Timeout,
+ ScoreTqReqTimeoutPriorityInherit_Post_Status_NA
+} ScoreTqReqTimeoutPriorityInherit_Post_Status;
+
+typedef enum {
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_Yes,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_No,
+ ScoreTqReqTimeoutPriorityInherit_Post_Unblock_NA
+} ScoreTqReqTimeoutPriorityInherit_Post_Unblock;
+
+typedef enum {
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Nop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_Drop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority_NA
+} ScoreTqReqTimeoutPriorityInherit_Post_OwnerPriority;
+
+typedef enum {
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Nop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Lower,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_Drop,
+ ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority_NA
+} ScoreTqReqTimeoutPriorityInherit_Post_OwnerOwnerPriority;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue test context.
+ */
+void ScoreTqReqTimeoutPriorityInherit_Run( TQContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_TQ_TIMEOUT_PRIORITY_INHERIT_H */
diff --git a/testsuites/validation/tr-tq-timeout.c b/testsuites/validation/tr-tq-timeout.c
new file mode 100644
index 0000000000..c9bc13a937
--- /dev/null
+++ b/testsuites/validation/tr-tq-timeout.c
@@ -0,0 +1,459 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqTimeout
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/score/threadimpl.h>
+
+#include "tr-tq-timeout.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup ScoreTqReqTimeout spec:/score/tq/req/timeout
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ *
+ * @{
+ */
+
+typedef struct {
+ uint8_t Skip : 1;
+ uint8_t Pre_WaitState_NA : 1;
+ uint8_t Post_Status : 2;
+ uint8_t Post_Unblock : 2;
+} ScoreTqReqTimeout_Entry;
+
+/**
+ * @brief Test context for spec:/score/tq/req/timeout test case.
+ */
+typedef struct {
+ /**
+ * @brief This member contains the call within ISR request.
+ */
+ CallWithinISRRequest request;
+
+ /**
+ * @brief This member contains a copy of the corresponding
+ * ScoreTqReqTimeout_Run() parameter.
+ */
+ TQContext *tq_ctx;
+
+ struct {
+ /**
+ * @brief This member defines the pre-condition states for the next action.
+ */
+ size_t pcs[ 1 ];
+
+ /**
+ * @brief If this member is true, then the test action loop is executed.
+ */
+ bool in_action_loop;
+
+ /**
+ * @brief This member contains the next transition map index.
+ */
+ size_t index;
+
+ /**
+ * @brief This member contains the current transition map entry.
+ */
+ ScoreTqReqTimeout_Entry entry;
+
+ /**
+ * @brief If this member is true, then the current transition variant
+ * should be skipped.
+ */
+ bool skip;
+ } Map;
+} ScoreTqReqTimeout_Context;
+
+static ScoreTqReqTimeout_Context
+ ScoreTqReqTimeout_Instance;
+
+static const char * const ScoreTqReqTimeout_PreDesc_WaitState[] = {
+ "Blocked",
+ "IntendToBlock",
+ "ReadyAgain",
+ "NA"
+};
+
+static const char * const * const ScoreTqReqTimeout_PreDesc[] = {
+ ScoreTqReqTimeout_PreDesc_WaitState,
+ NULL
+};
+
+typedef ScoreTqReqTimeout_Context Context;
+
+static const rtems_tcb *GetUnblock( Context *ctx, size_t *index )
+{
+ return TQGetNextUnblock( ctx->tq_ctx, index )->thread;
+}
+
+static const rtems_tcb *GetTCB( Context *ctx, TQWorkerKind worker )
+{
+ return ctx->tq_ctx->worker_tcb[ worker ];
+}
+
+static void Tick( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ FinalClockTick();
+ TQSchedulerRecordStop( ctx->tq_ctx );
+}
+
+static void SchedulerBlock(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ if (
+ when == T_SCHEDULER_BEFORE &&
+ event->operation == T_SCHEDULER_BLOCK
+ ) {
+ T_scheduler_set_event_handler( NULL, NULL );
+ ctx->request.handler = Tick;
+ CallWithinISRSubmit( &ctx->request );
+ }
+}
+
+static void ThreadTimeout( void *arg )
+{
+ Context *ctx;
+
+ ctx = arg;
+ TQSchedulerRecordStart( ctx->tq_ctx );
+ _Thread_Timeout(
+ &ctx->tq_ctx->worker_tcb[ TQ_BLOCKER_A ]->Timer.Watchdog
+ );
+ TQSchedulerRecordStop( ctx->tq_ctx );
+}
+
+static void SchedulerUnblock(
+ void *arg,
+ const T_scheduler_event *event,
+ T_scheduler_when when
+)
+{
+ Context *ctx;
+
+ ctx = arg;
+
+ if (
+ when == T_SCHEDULER_BEFORE &&
+ event->operation == T_SCHEDULER_UNBLOCK
+ ) {
+ T_scheduler_set_event_handler( NULL, NULL );
+ ctx->request.handler = ThreadTimeout;
+ CallWithinISRSubmit( &ctx->request );
+ }
+}
+
+static void ScoreTqReqTimeout_Pre_WaitState_Prepare(
+ ScoreTqReqTimeout_Context *ctx,
+ ScoreTqReqTimeout_Pre_WaitState state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqTimeout_Pre_WaitState_Blocked: {
+ /*
+ * While the thread of the timeout operation is in the blocked wait
+ * state.
+ */
+ TQEnqueuePrepare( ctx->tq_ctx );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
+ Yield();
+ Tick( ctx );
+ TQEnqueueDone( ctx->tq_ctx );
+ break;
+ }
+
+ case ScoreTqReqTimeout_Pre_WaitState_IntendToBlock: {
+ /*
+ * While the thread of the timeout operation is in the intend to block
+ * wait state.
+ */
+ TQEnqueuePrepare( ctx->tq_ctx );
+ T_scheduler_set_event_handler( SchedulerBlock, ctx );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
+ Yield();
+ TQEnqueueDone( ctx->tq_ctx );
+ break;
+ }
+
+ case ScoreTqReqTimeout_Pre_WaitState_ReadyAgain: {
+ /*
+ * While the thread of the timeout operation is in the ready again wait
+ * state.
+ */
+ TQEnqueuePrepare( ctx->tq_ctx );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_ENQUEUE );
+ Yield();
+ T_scheduler_set_event_handler( SchedulerUnblock, ctx );
+ TQEnqueueDone( ctx->tq_ctx );
+ TQSend( ctx->tq_ctx, TQ_BLOCKER_A, TQ_EVENT_SURRENDER );
+ break;
+ }
+
+ case ScoreTqReqTimeout_Pre_WaitState_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeout_Post_Status_Check(
+ ScoreTqReqTimeout_Context *ctx,
+ ScoreTqReqTimeout_Post_Status state
+)
+{
+ switch ( state ) {
+ case ScoreTqReqTimeout_Post_Status_Ok: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_SUCCESSFUL.
+ */
+ T_eq_int(
+ ctx->tq_ctx->status[ TQ_BLOCKER_A ],
+ TQConvertStatus( ctx->tq_ctx, STATUS_SUCCESSFUL )
+ );
+ break;
+ }
+
+ case ScoreTqReqTimeout_Post_Status_Timeout: {
+ /*
+ * The return status of the directive call shall be derived from
+ * STATUS_TIMEOUT.
+ */
+ T_eq_int(
+ ctx->tq_ctx->status[ TQ_BLOCKER_A ],
+ TQConvertStatus( ctx->tq_ctx, STATUS_TIMEOUT )
+ );
+ break;
+ }
+
+ case ScoreTqReqTimeout_Post_Status_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeout_Post_Unblock_Check(
+ ScoreTqReqTimeout_Context *ctx,
+ ScoreTqReqTimeout_Post_Unblock state
+)
+{
+ size_t i;
+
+ i = 0;
+
+ switch ( state ) {
+ case ScoreTqReqTimeout_Post_Unblock_Yes: {
+ /*
+ * The thread of the timeout operation shall be unblocked by the timeout
+ * operation.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), GetTCB( ctx, TQ_BLOCKER_A ) );
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqTimeout_Post_Unblock_No: {
+ /*
+ * The thread of the timeout operation shall not be unblocked by the
+ * timeout operation.
+ */
+ T_eq_ptr( GetUnblock( ctx, &i ), NULL );
+ break;
+ }
+
+ case ScoreTqReqTimeout_Post_Unblock_NA:
+ break;
+ }
+}
+
+static void ScoreTqReqTimeout_Setup( ScoreTqReqTimeout_Context *ctx )
+{
+ ctx->request.arg = ctx;
+ TQReset( ctx->tq_ctx );
+
+ if ( ctx->tq_ctx->enqueue_variant == TQ_ENQUEUE_STICKY ) {
+ TQSetScheduler( ctx->tq_ctx, TQ_BLOCKER_A, SCHEDULER_B_ID, PRIO_NORMAL );
+ } else {
+ TQSetPriority( ctx->tq_ctx, TQ_BLOCKER_A, PRIO_HIGH );
+ }
+}
+
+static void ScoreTqReqTimeout_Setup_Wrap( void *arg )
+{
+ ScoreTqReqTimeout_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqTimeout_Setup( ctx );
+}
+
+static void ScoreTqReqTimeout_Teardown( ScoreTqReqTimeout_Context *ctx )
+{
+ TQReset( ctx->tq_ctx );
+}
+
+static void ScoreTqReqTimeout_Teardown_Wrap( void *arg )
+{
+ ScoreTqReqTimeout_Context *ctx;
+
+ ctx = arg;
+ ctx->Map.in_action_loop = false;
+ ScoreTqReqTimeout_Teardown( ctx );
+}
+
+static void ScoreTqReqTimeout_Action( ScoreTqReqTimeout_Context *ctx )
+{
+ /*
+ * The action is performed by the ``WaitState`` pre-condition preparation.
+ */
+}
+
+static const ScoreTqReqTimeout_Entry
+ScoreTqReqTimeout_Entries[] = {
+ { 0, 0, ScoreTqReqTimeout_Post_Status_Timeout,
+ ScoreTqReqTimeout_Post_Unblock_Yes },
+ { 0, 0, ScoreTqReqTimeout_Post_Status_Timeout,
+ ScoreTqReqTimeout_Post_Unblock_No },
+ { 0, 0, ScoreTqReqTimeout_Post_Status_Ok, ScoreTqReqTimeout_Post_Unblock_No }
+};
+
+static const uint8_t
+ScoreTqReqTimeout_Map[] = {
+ 0, 1, 2
+};
+
+static size_t ScoreTqReqTimeout_Scope( void *arg, char *buf, size_t n )
+{
+ ScoreTqReqTimeout_Context *ctx;
+
+ ctx = arg;
+
+ if ( ctx->Map.in_action_loop ) {
+ return T_get_scope( ScoreTqReqTimeout_PreDesc, buf, n, ctx->Map.pcs );
+ }
+
+ return 0;
+}
+
+static T_fixture ScoreTqReqTimeout_Fixture = {
+ .setup = ScoreTqReqTimeout_Setup_Wrap,
+ .stop = NULL,
+ .teardown = ScoreTqReqTimeout_Teardown_Wrap,
+ .scope = ScoreTqReqTimeout_Scope,
+ .initial_context = &ScoreTqReqTimeout_Instance
+};
+
+static inline ScoreTqReqTimeout_Entry ScoreTqReqTimeout_PopEntry(
+ ScoreTqReqTimeout_Context *ctx
+)
+{
+ size_t index;
+
+ index = ctx->Map.index;
+ ctx->Map.index = index + 1;
+ return ScoreTqReqTimeout_Entries[
+ ScoreTqReqTimeout_Map[ index ]
+ ];
+}
+
+static void ScoreTqReqTimeout_TestVariant( ScoreTqReqTimeout_Context *ctx )
+{
+ ScoreTqReqTimeout_Pre_WaitState_Prepare( ctx, ctx->Map.pcs[ 0 ] );
+ ScoreTqReqTimeout_Action( ctx );
+ ScoreTqReqTimeout_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
+ ScoreTqReqTimeout_Post_Unblock_Check( ctx, ctx->Map.entry.Post_Unblock );
+}
+
+static T_fixture_node ScoreTqReqTimeout_Node;
+
+static T_remark ScoreTqReqTimeout_Remark = {
+ .next = NULL,
+ .remark = "ScoreTqReqTimeout"
+};
+
+void ScoreTqReqTimeout_Run( TQContext *tq_ctx )
+{
+ ScoreTqReqTimeout_Context *ctx;
+
+ ctx = &ScoreTqReqTimeout_Instance;
+ ctx->tq_ctx = tq_ctx;
+
+ ctx = T_push_fixture( &ScoreTqReqTimeout_Node, &ScoreTqReqTimeout_Fixture );
+ ctx->Map.in_action_loop = true;
+ ctx->Map.index = 0;
+
+ for (
+ ctx->Map.pcs[ 0 ] = ScoreTqReqTimeout_Pre_WaitState_Blocked;
+ ctx->Map.pcs[ 0 ] < ScoreTqReqTimeout_Pre_WaitState_NA;
+ ++ctx->Map.pcs[ 0 ]
+ ) {
+ ctx->Map.entry = ScoreTqReqTimeout_PopEntry( ctx );
+ ScoreTqReqTimeout_TestVariant( ctx );
+ }
+
+ T_add_remark( &ScoreTqReqTimeout_Remark );
+ T_pop_fixture();
+}
+
+/** @} */
diff --git a/testsuites/validation/tr-tq-timeout.h b/testsuites/validation/tr-tq-timeout.h
new file mode 100644
index 0000000000..825ba798ea
--- /dev/null
+++ b/testsuites/validation/tr-tq-timeout.h
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup ScoreTqReqTimeout
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifndef _TR_TQ_TIMEOUT_H
+#define _TR_TQ_TIMEOUT_H
+
+#include "tx-thread-queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ScoreTqReqTimeout
+ *
+ * @{
+ */
+
+typedef enum {
+ ScoreTqReqTimeout_Pre_WaitState_Blocked,
+ ScoreTqReqTimeout_Pre_WaitState_IntendToBlock,
+ ScoreTqReqTimeout_Pre_WaitState_ReadyAgain,
+ ScoreTqReqTimeout_Pre_WaitState_NA
+} ScoreTqReqTimeout_Pre_WaitState;
+
+typedef enum {
+ ScoreTqReqTimeout_Post_Status_Ok,
+ ScoreTqReqTimeout_Post_Status_Timeout,
+ ScoreTqReqTimeout_Post_Status_NA
+} ScoreTqReqTimeout_Post_Status;
+
+typedef enum {
+ ScoreTqReqTimeout_Post_Unblock_Yes,
+ ScoreTqReqTimeout_Post_Unblock_No,
+ ScoreTqReqTimeout_Post_Unblock_NA
+} ScoreTqReqTimeout_Post_Unblock;
+
+/**
+ * @brief Runs the parameterized test case.
+ *
+ * @param[in,out] tq_ctx is the thread queue test context.
+ */
+void ScoreTqReqTimeout_Run( TQContext *tq_ctx );
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TR_TQ_TIMEOUT_H */
diff --git a/testsuites/validation/ts-acfg.h b/testsuites/validation/ts-acfg.h
new file mode 100644
index 0000000000..60d1833857
--- /dev/null
+++ b/testsuites/validation/ts-acfg.h
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This header file provides a validation test suite runner for
+ * validation test cases specific to the application configuration.
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <rtems/test.h>
+#include <rtems/test-info.h>
+#include <rtems/testopts.h>
+
+static char buffer[ 512 ];
+
+static const T_action actions[] = {
+ T_report_hash_sha256
+};
+
+static const T_config test_config = {
+ .name = rtems_test_name,
+ .buf = buffer,
+ .buf_size = sizeof( buffer ),
+ .putchar = rtems_put_char,
+ .verbosity = RTEMS_TEST_VERBOSITY,
+ .now = T_now_tick,
+ .allocate = T_memory_allocate,
+ .deallocate = T_memory_deallocate,
+ .action_count = T_ARRAY_SIZE( actions ),
+ .actions = actions
+};
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+RTEMS_NO_RETURN static void RunTestSuite( void )
+{
+ int exit_code;
+
+ rtems_test_begin( rtems_test_name, TEST_STATE );
+ T_register();
+ exit_code = T_main( &test_config );
+
+ if ( exit_code == 0 ) {
+ rtems_test_end( rtems_test_name );
+ }
+
+ rtems_fatal( RTEMS_FATAL_SOURCE_EXIT, (uint32_t) exit_code );
+}
diff --git a/testsuites/validation/ts-config.h b/testsuites/validation/ts-config.h
new file mode 100644
index 0000000000..f5f46738f0
--- /dev/null
+++ b/testsuites/validation/ts-config.h
@@ -0,0 +1,126 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This header file provides the constants used by the test suite
+ * configuration.
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _TS_CONFIG_H
+#define _TS_CONFIG_H
+
+#include <rtems.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup RTEMSTestSuitesValidation
+ *
+ * @{
+ */
+
+#define TEST_MICROSECONDS_PER_TICK 1000
+
+#define TEST_RUNNER_NAME rtems_build_name( 'R', 'U', 'N', ' ' )
+
+#define TEST_RUNNER_ARGUMENT 123456789
+
+#define TEST_RUNNER_INITIAL_MODES RTEMS_NO_ASR
+
+#define TEST_SCHEDULER_A_NAME rtems_build_name( 'A', ' ', ' ', ' ' )
+
+#define TEST_SCHEDULER_B_NAME rtems_build_name( 'B', ' ', ' ', ' ' )
+
+#define TEST_SCHEDULER_C_NAME rtems_build_name( 'C', ' ', ' ', ' ' )
+
+#define TEST_SCHEDULER_D_NAME rtems_build_name( 'D', ' ', ' ', ' ' )
+
+#if defined( __OPTIMIZE__ ) && !defined( RTEMS_GCOV_COVERAGE )
+#define TEST_BASE_STACK_SIZE RTEMS_MINIMUM_STACK_SIZE
+#else
+#define TEST_BASE_STACK_SIZE ( 4 * RTEMS_MINIMUM_STACK_SIZE )
+#endif
+
+#define TEST_MAXIMUM_TLS_SIZE \
+ RTEMS_ALIGN_UP( 64, RTEMS_TASK_STORAGE_ALIGNMENT )
+
+#define TEST_MINIMUM_STACK_SIZE \
+ ( TEST_BASE_STACK_SIZE + CPU_STACK_ALIGNMENT )
+
+#define TEST_IDLE_STACK_SIZE \
+ ( TEST_BASE_STACK_SIZE + 2 * CPU_STACK_ALIGNMENT )
+
+#define TEST_INTERRUPT_STACK_SIZE \
+ ( TEST_BASE_STACK_SIZE + 4 * CPU_INTERRUPT_STACK_ALIGNMENT )
+
+#define TEST_MAXIMUM_BARRIERS 7
+
+#define TEST_MAXIMUM_MESSAGE_QUEUES 3
+
+#define TEST_MAXIMUM_PARTITIONS 4
+
+#define TEST_MAXIMUM_PERIODS 2
+
+#define TEST_MAXIMUM_SEMAPHORES 7
+
+#define TEST_MAXIMUM_TASKS 32
+
+#define TEST_MAXIMUM_TIMERS 10
+
+#define TEST_MAXIMUM_USER_EXTENSIONS 5
+
+/*
+ * Use at least two so that the CPU time budget decrement in
+ * _Scheduler_default_Tick() does not always result in a zero.
+ */
+#define TEST_TICKS_PER_TIMESLICE 2
+
+void *test_task_stack_allocate( size_t size );
+
+void test_task_stack_deallocate( void *stack );
+
+void *test_idle_task_stack_allocate( uint32_t cpu_index, size_t *size );
+
+extern rtems_task_argument test_runner_argument;
+
+extern rtems_task_priority test_runner_initial_priority;
+
+extern rtems_mode test_runner_initial_modes;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TS_CONFIG_H */
diff --git a/testsuites/validation/ts-default.h b/testsuites/validation/ts-default.h
index addf1866f5..86c0b4e345 100644
--- a/testsuites/validation/ts-default.h
+++ b/testsuites/validation/ts-default.h
@@ -3,12 +3,14 @@
/**
* @file
*
+ * @ingroup RTEMSTestSuitesValidation
+ *
* @brief This header file provides the default validation test suite runner
* and application configuration.
*/
/*
- * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -32,23 +34,29 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <rtems.h>
+#include <bsp.h>
#include <rtems/bspIo.h>
#include <rtems/chain.h>
#include <rtems/test-info.h>
#include <rtems/testopts.h>
#include <rtems/test.h>
+#include <rtems/test-scheduler.h>
+
+#include "ts-config.h"
+#include "tx-support.h"
-#define MAX_TLS_SIZE RTEMS_ALIGN_UP( 64, RTEMS_TASK_STORAGE_ALIGNMENT )
+#if !defined( MAX_TLS_SIZE )
+#define MAX_TLS_SIZE TEST_MAXIMUM_TLS_SIZE
+#endif
-#define MAX_TASKS 32
+#define MAX_TASKS ( TEST_MAXIMUM_TASKS - 1 )
#define TASK_ATTRIBUTES RTEMS_FLOATING_POINT
#define TASK_STORAGE_SIZE \
RTEMS_TASK_STORAGE_SIZE( \
- MAX_TLS_SIZE + RTEMS_MINIMUM_STACK_SIZE + \
+ MAX_TLS_SIZE + TEST_MINIMUM_STACK_SIZE + \
CPU_STACK_ALIGNMENT - CPU_HEAP_ALIGNMENT, \
TASK_ATTRIBUTES \
)
@@ -75,7 +83,11 @@ static const T_config test_config = {
.buf_size = sizeof( buffer ),
.putchar = rtems_put_char,
.verbosity = RTEMS_TEST_VERBOSITY,
+#if defined(CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER)
.now = T_now_clock,
+#else
+ .now = T_now_tick,
+#endif
.allocate = T_memory_allocate,
.deallocate = T_memory_deallocate,
.action_count = T_ARRAY_SIZE( actions ),
@@ -91,11 +103,29 @@ static union {
rtems_chain_node node;
} task_storage[ MAX_TASKS ];
-static void Init( rtems_task_argument arg )
+rtems_task_argument test_runner_argument;
+
+rtems_task_priority test_runner_initial_priority;
+
+rtems_mode test_runner_initial_modes;
+
+static void Runner( rtems_task_argument arg )
{
int exit_code;
- (void) arg;
+ test_runner_argument = arg;
+
+ (void) rtems_task_mode(
+ RTEMS_ASR,
+ RTEMS_ASR_MASK,
+ &test_runner_initial_modes
+ );
+
+ (void) rtems_task_set_priority(
+ RTEMS_SELF,
+ PRIO_DEFAULT,
+ &test_runner_initial_priority
+ );
rtems_chain_initialize(
&free_task_storage,
@@ -115,16 +145,18 @@ static void Init( rtems_task_argument arg )
rtems_fatal( RTEMS_FATAL_SOURCE_EXIT, (uint32_t) exit_code );
}
-static void *task_stack_allocate( size_t size )
+void *test_task_stack_allocate( size_t size )
{
if ( size > sizeof( task_storage[ 0 ] ) ) {
return NULL;
}
+ T_quiet_ge_sz( size, TEST_MINIMUM_STACK_SIZE );
+
return rtems_chain_get_unprotected( &free_task_storage );
}
-static void task_stack_deallocate( void *stack )
+void test_task_stack_deallocate( void *stack )
{
rtems_chain_append_unprotected(
&free_task_storage,
@@ -132,28 +164,36 @@ static void task_stack_deallocate( void *stack )
);
}
+#if !defined( CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER )
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#endif
-#define CONFIGURE_MAXIMUM_BARRIERS 3
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE TEST_MINIMUM_STACK_SIZE
-#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES 3
+#define CONFIGURE_INTERRUPT_STACK_SIZE TEST_INTERRUPT_STACK_SIZE
-#define CONFIGURE_MAXIMUM_PARTITIONS 3
+#define CONFIGURE_MAXIMUM_BARRIERS TEST_MAXIMUM_BARRIERS
-#define CONFIGURE_MAXIMUM_PERIODS 3
+#define CONFIGURE_MAXIMUM_MESSAGE_QUEUES TEST_MAXIMUM_MESSAGE_QUEUES
-#define CONFIGURE_MAXIMUM_SEMAPHORES 3
+#define CONFIGURE_MAXIMUM_PARTITIONS TEST_MAXIMUM_PARTITIONS
-#define CONFIGURE_MAXIMUM_TASKS ( 1 + MAX_TASKS )
+#define CONFIGURE_MAXIMUM_PERIODS TEST_MAXIMUM_PERIODS
+
+#define CONFIGURE_MAXIMUM_SEMAPHORES TEST_MAXIMUM_SEMAPHORES
+
+#define CONFIGURE_MAXIMUM_TASKS TEST_MAXIMUM_TASKS
#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE \
CONFIGURE_MAXIMUM_TASKS
-#define CONFIGURE_MAXIMUM_TIMERS 3
+#define CONFIGURE_MAXIMUM_TIMERS TEST_MAXIMUM_TIMERS
-#define CONFIGURE_MAXIMUM_USER_EXTENSIONS 3
+#define CONFIGURE_MAXIMUM_USER_EXTENSIONS TEST_MAXIMUM_USER_EXTENSIONS
-#define CONFIGURE_MICROSECONDS_PER_TICK 1000
+#define CONFIGURE_MICROSECONDS_PER_TICK TEST_MICROSECONDS_PER_TICK
+
+#define CONFIGURE_TICKS_PER_TIMESLICE TEST_TICKS_PER_TIMESLICE
#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
@@ -165,35 +205,67 @@ static void task_stack_deallocate( void *stack )
#define CONFIGURE_TASK_STACK_ALLOCATOR_AVOIDS_WORK_SPACE
-#define CONFIGURE_TASK_STACK_ALLOCATOR task_stack_allocate
+#define CONFIGURE_TASK_STACK_ALLOCATOR test_task_stack_allocate
-#define CONFIGURE_TASK_STACK_DEALLOCATOR task_stack_deallocate
+#define CONFIGURE_TASK_STACK_DEALLOCATOR test_task_stack_deallocate
#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
-#define CONFIGURE_INIT_TASK_ATTRIBUTES TASK_ATTRIBUTES
+#define CONFIGURE_INIT_TASK_ARGUMENTS TEST_RUNNER_ARGUMENT
-#define CONFIGURE_INIT_TASK_INITIAL_MODES RTEMS_DEFAULT_MODES
+#define CONFIGURE_INIT_TASK_ATTRIBUTES ( RTEMS_SYSTEM_TASK | TASK_ATTRIBUTES )
#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE TASK_STORAGE_SIZE
+#define CONFIGURE_INIT_TASK_ENTRY_POINT Runner
+
+#define CONFIGURE_INIT_TASK_INITIAL_MODES TEST_RUNNER_INITIAL_MODES
+
+#define CONFIGURE_INIT_TASK_NAME TEST_RUNNER_NAME
+
+#define CONFIGURE_INIT_TASK_PRIORITY 0
+
+#if !defined( CONFIGURE_INITIAL_EXTENSIONS )
+#define CONFIGURE_INITIAL_EXTENSIONS { .fatal = FatalInitialExtension }
+#endif
+
#if defined( RTEMS_SMP ) && \
( CONFIGURE_MAXIMUM_PROCESSORS == 4 || CONFIGURE_MAXIMUM_PROCESSORS == 5 )
+#include <rtems/score/scheduleredfsmp.h>
+
+const Scheduler_Operations
+T_scheduler_operations[ CONFIGURE_MAXIMUM_PROCESSORS ] = {
+ SCHEDULER_EDF_SMP_ENTRY_POINTS,
+ SCHEDULER_EDF_SMP_ENTRY_POINTS,
+ SCHEDULER_EDF_SMP_ENTRY_POINTS,
+#if CONFIGURE_MAXIMUM_PROCESSORS >= 5
+ SCHEDULER_EDF_SMP_ENTRY_POINTS,
+#endif
+ SCHEDULER_EDF_SMP_ENTRY_POINTS
+};
+
+#undef SCHEDULER_EDF_SMP_ENTRY_POINTS
+
+#define SCHEDULER_EDF_SMP_ENTRY_POINTS T_SCHEDULER_ENTRY_POINTS
+
#define CONFIGURE_SCHEDULER_EDF_SMP
#include <rtems/scheduler.h>
-RTEMS_SCHEDULER_EDF_SMP(a);
+RTEMS_SCHEDULER_EDF_SMP( a );
+
+RTEMS_SCHEDULER_EDF_SMP( b );
-RTEMS_SCHEDULER_EDF_SMP(b);
+RTEMS_SCHEDULER_EDF_SMP( c );
-RTEMS_SCHEDULER_EDF_SMP(c);
+RTEMS_SCHEDULER_EDF_SMP( d );
#define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
- RTEMS_SCHEDULER_TABLE_EDF_SMP(a, rtems_build_name('A', ' ', ' ', ' ')), \
- RTEMS_SCHEDULER_TABLE_EDF_SMP(b, rtems_build_name('B', ' ', ' ', ' ')), \
- RTEMS_SCHEDULER_TABLE_EDF_SMP(c, rtems_build_name('C', ' ', ' ', ' '))
+ RTEMS_SCHEDULER_TABLE_EDF_SMP( a, TEST_SCHEDULER_A_NAME ), \
+ RTEMS_SCHEDULER_TABLE_EDF_SMP( b, TEST_SCHEDULER_B_NAME ), \
+ RTEMS_SCHEDULER_TABLE_EDF_SMP( c, TEST_SCHEDULER_C_NAME ), \
+ RTEMS_SCHEDULER_TABLE_EDF_SMP( d, TEST_SCHEDULER_D_NAME )
#if CONFIGURE_MAXIMUM_PROCESSORS == 5
#define CONFIGURE_SCHEDULER_ASSIGNMENTS \
@@ -210,7 +282,61 @@ RTEMS_SCHEDULER_EDF_SMP(c);
RTEMS_SCHEDULER_ASSIGN(2, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL)
#endif
-#endif /* RTEMS_SMP */
+#elif !defined( CONFIGURE_SCHEDULER_ASSIGNMENTS )
+
+#include <rtems/score/schedulerpriority.h>
+
+#undef CONFIGURE_MAXIMUM_PROCESSORS
+#define CONFIGURE_MAXIMUM_PROCESSORS 1
+
+const Scheduler_Operations
+T_scheduler_operations[ CONFIGURE_MAXIMUM_PROCESSORS ] = {
+ SCHEDULER_PRIORITY_ENTRY_POINTS
+};
+
+#undef SCHEDULER_PRIORITY_ENTRY_POINTS
+
+#define SCHEDULER_PRIORITY_ENTRY_POINTS T_SCHEDULER_ENTRY_POINTS
+
+#define CONFIGURE_SCHEDULER_PRIORITY
+
+#if defined(CONFIGURE_SCHEDULER_TABLE_ENTRIES)
+
+#include <rtems/scheduler.h>
+
+RTEMS_SCHEDULER_PRIORITY( a, 64 );
+
+#else /* CONFIGURE_SCHEDULER_TABLE_ENTRIES */
+
+#define CONFIGURE_SCHEDULER_NAME TEST_SCHEDULER_A_NAME
+
+#define CONFIGURE_MAXIMUM_PRIORITY 127
+
+#endif /* CONFIGURE_SCHEDULER_TABLE_ENTRIES */
+
+#endif
+
+#define CONFIGURE_IDLE_TASK_STACK_SIZE TEST_IDLE_STACK_SIZE
+
+static char test_idle_stacks[ CONFIGURE_MAXIMUM_PROCESSORS ][
+ RTEMS_ALIGN_UP(
+ MAX_TLS_SIZE + TEST_IDLE_STACK_SIZE + CPU_IDLE_TASK_IS_FP * CONTEXT_FP_SIZE,
+ CPU_INTERRUPT_STACK_ALIGNMENT
+ )
+]
+RTEMS_ALIGNED( CPU_INTERRUPT_STACK_ALIGNMENT )
+RTEMS_SECTION( ".rtemsstack.idle" );
+
+void *test_idle_task_stack_allocate( uint32_t cpu_index, size_t *size )
+{
+ if ( *size > sizeof( test_idle_stacks[ 0 ] ) ) {
+ rtems_fatal( RTEMS_FATAL_SOURCE_APPLICATION, 0xABAD1DEA );
+ }
+
+ return &test_idle_stacks[ cpu_index ][0];
+}
+
+#define CONFIGURE_TASK_STACK_ALLOCATOR_FOR_IDLE test_idle_task_stack_allocate
#define CONFIGURE_INIT
diff --git a/testsuites/validation/ts-fatal-boot-processor-not-assigned-to-scheduler.c b/testsuites/validation/ts-fatal-boot-processor-not-assigned-to-scheduler.c
new file mode 100644
index 0000000000..c983cfd406
--- /dev/null
+++ b/testsuites/validation/ts-fatal-boot-processor-not-assigned-to-scheduler.c
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesFatalBootProcessorNotAssignedToScheduler
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-fatal-boot-processor-not-assigned-to-scheduler.h"
+#include "ts-config.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesFatalBootProcessorNotAssignedToScheduler \
+ * spec:/testsuites/fatal-boot-processor-not-assigned-to-scheduler
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite uses an application configuration which
+ * triggers a fatal error during system initialization.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesFatalBootProcessorNotAssignedToScheduler";
+
+#define FATAL_SYSINIT_RUN \
+ ScoreSmpValFatalBootProcessorNotAssignedToScheduler_Run
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 2
+
+#include <rtems/score/scheduleredfsmp.h>
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#include <rtems/scheduler.h>
+
+RTEMS_SCHEDULER_EDF_SMP( a );
+
+#define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
+ RTEMS_SCHEDULER_TABLE_EDF_SMP( a, TEST_SCHEDULER_A_NAME )
+
+#define CONFIGURE_SCHEDULER_ASSIGNMENTS \
+ RTEMS_SCHEDULER_ASSIGN_NO_SCHEDULER, \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL )
+
+#include "ts-fatal-sysinit.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-fatal-idle-thread-create-failed.c b/testsuites/validation/ts-fatal-idle-thread-create-failed.c
new file mode 100644
index 0000000000..fb7a36c11a
--- /dev/null
+++ b/testsuites/validation/ts-fatal-idle-thread-create-failed.c
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesFatalIdleThreadCreateFailed
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-fatal-idle-thread-create-failed.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesFatalIdleThreadCreateFailed \
+ * spec:/testsuites/fatal-idle-thread-create-failed
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains a test case which is triggered by
+ * a fatal error during system initialization.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesFatalIdleThreadCreateFailed";
+
+static bool CreateTask( rtems_tcb *executing, rtems_tcb *created )
+{
+ (void) executing;
+ (void) created;
+ return false;
+}
+
+#define FATAL_SYSINIT_RUN ScoreThreadValFatalIdleThreadCreateFailed_Run
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
+
+#define FATAL_SYSINIT_INITIAL_EXTENSION { .thread_create = CreateTask }
+
+#include "ts-fatal-sysinit.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-fatal-idle-thread-stack-too-small.c b/testsuites/validation/ts-fatal-idle-thread-stack-too-small.c
new file mode 100644
index 0000000000..ddfe59df13
--- /dev/null
+++ b/testsuites/validation/ts-fatal-idle-thread-stack-too-small.c
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesFatalIdleThreadStackTooSmall
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-fatal-idle-thread-stack-too-small.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesFatalIdleThreadStackTooSmall \
+ * spec:/testsuites/fatal-idle-thread-stack-too-small
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains a test case which triggers a
+ * fatal error during system initialization.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesFatalIdleThreadStackTooSmall";
+
+#define FATAL_SYSINIT_RUN ScoreThreadValFatalIdleThreadStackTooSmall_Run
+
+static _Thread_local volatile uint8_t zero[ RTEMS_MINIMUM_STACK_SIZE ];
+
+static void Init( rtems_task_argument arg )
+{
+ (void) arg;
+ rtems_fatal( RTEMS_FATAL_SOURCE_EXIT, zero[ 0 ] + 1 );
+}
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_TASKS 1
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE 1
+
+#define CONFIGURE_INIT_TASK_PRIORITY 0
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#include "ts-fatal-sysinit.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-fatal-init-task-construct-failed.c b/testsuites/validation/ts-fatal-init-task-construct-failed.c
new file mode 100644
index 0000000000..d8c87428e8
--- /dev/null
+++ b/testsuites/validation/ts-fatal-init-task-construct-failed.c
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesFatalInitTaskConstructFailed
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-fatal-init-task-construct-failed.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesFatalInitTaskConstructFailed \
+ * spec:/testsuites/fatal-init-task-construct-failed
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains a test case which triggers a
+ * fatal error during system initialization.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesFatalInitTaskConstructFailed";
+
+#define FATAL_SYSINIT_RUN AcfgValFatalInitTaskConstructFailed_Run
+
+static void Init( rtems_task_argument arg )
+{
+ (void) arg;
+ rtems_fatal( RTEMS_FATAL_SOURCE_EXIT, 1 );
+}
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_TASKS 1
+
+#define CONFIGURE_MINIMUM_TASKS_WITH_USER_PROVIDED_STORAGE 1
+
+#define CONFIGURE_INIT_TASK_PRIORITY 0
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#include "ts-fatal-sysinit.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-fatal-mandatory-processor-not-present.c b/testsuites/validation/ts-fatal-mandatory-processor-not-present.c
new file mode 100644
index 0000000000..f9629d9699
--- /dev/null
+++ b/testsuites/validation/ts-fatal-mandatory-processor-not-present.c
@@ -0,0 +1,127 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesFatalMandatoryProcessorNotPresent
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-fatal-mandatory-processor-not-present.h"
+#include "ts-config.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesFatalMandatoryProcessorNotPresent \
+ * spec:/testsuites/fatal-mandatory-processor-not-present
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains a test case which triggers a
+ * fatal error during system initialization.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesFatalMandatoryProcessorNotPresent";
+
+#define FATAL_SYSINIT_RUN ScoreSmpValFatalMandatoryProcessorNotPresent_Run
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 32
+
+#include <rtems/score/scheduleredfsmp.h>
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#include <rtems/scheduler.h>
+
+RTEMS_SCHEDULER_EDF_SMP( a );
+
+#define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
+ RTEMS_SCHEDULER_TABLE_EDF_SMP( a, TEST_SCHEDULER_A_NAME )
+
+#define CONFIGURE_SCHEDULER_ASSIGNMENTS \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY )
+
+#include "ts-fatal-sysinit.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-fatal-scheduler-requires-exactly-one-processor.c b/testsuites/validation/ts-fatal-scheduler-requires-exactly-one-processor.c
new file mode 100644
index 0000000000..d1de45d836
--- /dev/null
+++ b/testsuites/validation/ts-fatal-scheduler-requires-exactly-one-processor.c
@@ -0,0 +1,98 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesFatalSchedulerRequiresExactlyOneProcessor
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-fatal-scheduler-requires-exactly-one-processor.h"
+#include "ts-config.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesFatalSchedulerRequiresExactlyOneProcessor \
+ * spec:/testsuites/fatal-scheduler-requires-exactly-one-processor
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite uses an application configuration which
+ * triggers a fatal error during system initialization.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesFatalSchedulerRequiresExactlyOneProcessor";
+
+#define FATAL_SYSINIT_RUN \
+ ScoreSmpValFatalSchedulerRequiresExactlyOneProcessor_Run
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 2
+
+#include <rtems/score/schedulerpriority.h>
+
+#define CONFIGURE_SCHEDULER_PRIORITY
+
+#include <rtems/scheduler.h>
+
+RTEMS_SCHEDULER_PRIORITY( a, 256 );
+
+#define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
+ RTEMS_SCHEDULER_TABLE_PRIORITY( a, TEST_SCHEDULER_A_NAME )
+
+#define CONFIGURE_SCHEDULER_ASSIGNMENTS \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY )
+
+#include "ts-fatal-sysinit.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-fatal-smp.c b/testsuites/validation/ts-fatal-smp.c
new file mode 100644
index 0000000000..ff6fd19d42
--- /dev/null
+++ b/testsuites/validation/ts-fatal-smp.c
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesFatalSmp
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-fatal-smp.h"
+#include "ts-config.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesFatalSmp spec:/testsuites/fatal-smp
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains a test case which triggers
+ * SMP-specific fatal errors.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesFatalSmp";
+
+#define FATAL_SYSINIT_RUN ScoreSmpValFatal_Run
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 3
+
+#include <rtems/score/scheduleredfsmp.h>
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#include <rtems/scheduler.h>
+
+RTEMS_SCHEDULER_EDF_SMP( a );
+
+#define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
+ RTEMS_SCHEDULER_TABLE_EDF_SMP( a, TEST_SCHEDULER_A_NAME )
+
+#define CONFIGURE_SCHEDULER_ASSIGNMENTS \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN_NO_SCHEDULER
+
+#include "ts-fatal-sysinit.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-fatal-start-of-mandatory-processor-failed.c b/testsuites/validation/ts-fatal-start-of-mandatory-processor-failed.c
new file mode 100644
index 0000000000..8ab860eea2
--- /dev/null
+++ b/testsuites/validation/ts-fatal-start-of-mandatory-processor-failed.c
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesFatalStartOfMandatoryProcessorFailed
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-fatal-start-of-mandatory-processor-failed.h"
+#include "ts-config.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesFatalStartOfMandatoryProcessorFailed \
+ * spec:/testsuites/fatal-start-of-mandatory-processor-failed
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains a test case which triggers a
+ * fatal error during system initialization.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesFatalStartOfMandatoryProcessorFailed";
+
+#define FATAL_SYSINIT_RUN ScoreSmpValFatalStartOfMandatoryProcessorFailed_Run
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 2
+
+#include <rtems/score/scheduleredfsmp.h>
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#include <rtems/scheduler.h>
+
+RTEMS_SCHEDULER_EDF_SMP( a );
+
+#define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
+ RTEMS_SCHEDULER_TABLE_EDF_SMP( a, TEST_SCHEDULER_A_NAME )
+
+#define CONFIGURE_SCHEDULER_ASSIGNMENTS \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY )
+
+#include "ts-fatal-sysinit.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-fatal-start-on-not-online-processor.c b/testsuites/validation/ts-fatal-start-on-not-online-processor.c
new file mode 100644
index 0000000000..794983823c
--- /dev/null
+++ b/testsuites/validation/ts-fatal-start-on-not-online-processor.c
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesFatalStartOnNotOnlineProcessor
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-fatal-start-on-not-online-processor.h"
+#include "ts-config.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesFatalStartOnNotOnlineProcessor \
+ * spec:/testsuites/fatal-start-on-not-online-processor
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains a test case which triggers a
+ * fatal error during system initialization.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesFatalStartOnNotOnlineProcessor";
+
+#define FATAL_SYSINIT_RUN ScoreSmpValFatalStartOnNotOnlineProcessor_Run
+
+#define CONFIGURE_IDLE_TASK_BODY _CPU_Thread_Idle_body
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 2
+
+#include "ts-fatal-sysinit.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-fatal-sysinit.h b/testsuites/validation/ts-fatal-sysinit.h
new file mode 100644
index 0000000000..0b8f735f54
--- /dev/null
+++ b/testsuites/validation/ts-fatal-sysinit.h
@@ -0,0 +1,161 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This header file provides a configurable validation test suite runner
+ * and application configuration for fatal error tests which occur during
+ * system initialization.
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <rtems/sysinit.h>
+#include <rtems/test-info.h>
+#include <rtems/testopts.h>
+#include <rtems/score/atomic.h>
+
+#include <rtems/test.h>
+
+#include "tx-support.h"
+
+static char buffer[ 512 ];
+
+static const T_action actions[] = {
+ T_report_hash_sha256
+};
+
+static const T_config test_config = {
+ .name = rtems_test_name,
+ .buf = buffer,
+ .buf_size = sizeof( buffer ),
+ .putchar = rtems_put_char,
+ .verbosity = RTEMS_TEST_VERBOSITY,
+#if defined(CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER)
+ .now = T_now_clock,
+#else
+ .now = T_now_tick,
+#endif
+ .allocate = T_memory_allocate,
+ .deallocate = T_memory_deallocate,
+ .action_count = T_ARRAY_SIZE( actions ),
+ .actions = actions
+};
+
+static Atomic_Uint counter;
+
+static void TestSuiteFatalExtension(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code
+)
+{
+ rtems_fatal_code exit_code;
+
+ (void) always_set_to_false;
+
+ if ( source == RTEMS_FATAL_SOURCE_EXIT ) {
+ return;
+ }
+
+ if ( _Atomic_Fetch_add_uint( &counter, 1, ATOMIC_ORDER_RELAXED ) != 0 ) {
+ return;
+ }
+
+ T_make_runner();
+ FATAL_SYSINIT_RUN( source, code );
+
+ if ( T_run_finalize() ) {
+ rtems_test_end( rtems_test_name );
+ exit_code = 0;
+ } else {
+ exit_code = 1;
+ }
+
+#if defined(FATAL_SYSINIT_EXIT)
+ FATAL_SYSINIT_EXIT( exit_code );
+#else
+ rtems_fatal( RTEMS_FATAL_SOURCE_EXIT, exit_code );
+#endif
+}
+
+static void TestRunInitialize( void )
+{
+ rtems_test_begin( rtems_test_name, TEST_STATE );
+ T_run_initialize( &test_config );
+}
+
+RTEMS_SYSINIT_ITEM(
+ TestRunInitialize,
+ RTEMS_SYSINIT_BSP_EARLY,
+ RTEMS_SYSINIT_ORDER_FIRST
+);
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#ifdef FATAL_SYSINIT_INITIAL_EXTENSION
+#define OPTIONAL_FATAL_SYSINIT_INITIAL_EXTENSION FATAL_SYSINIT_INITIAL_EXTENSION,
+#else
+#define OPTIONAL_FATAL_SYSINIT_INITIAL_EXTENSION
+#endif
+
+#define CONFIGURE_INITIAL_EXTENSIONS \
+ OPTIONAL_FATAL_SYSINIT_INITIAL_EXTENSION \
+ { .fatal = FatalInitialExtension }, \
+ { .fatal = TestSuiteFatalExtension }
+
+#define CONFIGURE_IDLE_TASK_STORAGE_SIZE RTEMS_MINIMUM_STACK_SIZE
+
+#if !defined(CONFIGURE_RTEMS_INIT_TASKS_TABLE)
+
+#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
+
+#if !defined(CONFIGURE_IDLE_TASK_BODY)
+
+#define CONFIGURE_IDLE_TASK_BODY IdleBody
+
+void *IdleBody( uintptr_t ignored )
+{
+ (void) ignored;
+
+ rtems_fatal( RTEMS_FATAL_SOURCE_EXIT, 1 );
+}
+
+#endif /* CONFIGURE_IDLE_TASK_BODY */
+
+#endif /* CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION */
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/validation/ts-fatal-too-large-tls-size.c b/testsuites/validation/ts-fatal-too-large-tls-size.c
new file mode 100644
index 0000000000..ba2cc512df
--- /dev/null
+++ b/testsuites/validation/ts-fatal-too-large-tls-size.c
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesFatalTooLargeTlsSize
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tr-fatal-too-large-tls-size.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesFatalTooLargeTlsSize \
+ * spec:/testsuites/fatal-too-large-tls-size
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains a test case which triggers a
+ * fatal error during system initialization.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesFatalTooLargeTlsSize";
+
+#define FATAL_SYSINIT_RUN AcfgValFatalTooLargeTlsSize_Run
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_THREAD_LOCAL_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_ALIGNMENT
+
+#include "ts-fatal-sysinit.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-idle.h b/testsuites/validation/ts-idle.h
new file mode 100644
index 0000000000..6c4c8955f1
--- /dev/null
+++ b/testsuites/validation/ts-idle.h
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This header file provides a configurable validation test suite runner
+ * and application configuration for tests which should run within an idle
+ * task without a user initialization task.
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <rtems.h>
+#include <rtems/bspIo.h>
+#include <rtems/test-info.h>
+#include <rtems/testopts.h>
+
+#include <rtems/test.h>
+
+#include "tx-support.h"
+
+static char buffer[ 512 ];
+
+static const T_action actions[] = {
+ T_report_hash_sha256
+};
+
+static const T_config test_config = {
+ .name = rtems_test_name,
+ .buf = buffer,
+ .buf_size = sizeof( buffer ),
+ .putchar = rtems_put_char,
+ .verbosity = RTEMS_TEST_VERBOSITY,
+ .now = T_now_tick,
+ .allocate = T_memory_allocate,
+ .deallocate = T_memory_deallocate,
+ .action_count = T_ARRAY_SIZE( actions ),
+ .actions = actions
+};
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_INITIAL_EXTENSIONS \
+ { .fatal = FatalInitialExtension }
+
+#ifndef CONFIGURE_IDLE_TASK_STORAGE_SIZE
+#define CONFIGURE_IDLE_TASK_STORAGE_SIZE RTEMS_MINIMUM_STACK_SIZE
+#endif
+
+#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
+
+void *IdleBody( uintptr_t ignored )
+{
+ int exit_code;
+
+ (void) ignored;
+
+ rtems_test_begin( rtems_test_name, TEST_STATE );
+ T_register();
+ exit_code = T_main( &test_config );
+
+ if ( exit_code == 0 ) {
+ rtems_test_end( rtems_test_name );
+ }
+
+ rtems_fatal( RTEMS_FATAL_SOURCE_EXIT, (uint32_t) exit_code );
+}
+
+#define CONFIGURE_IDLE_TASK_BODY IdleBody
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/validation/ts-performance-0.c b/testsuites/validation/ts-performance-no-clock-0.c
index 1fb15ecfce..b50276a46e 100644
--- a/testsuites/validation/ts-performance-0.c
+++ b/testsuites/validation/ts-performance-no-clock-0.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestSuiteTestsuitesPerformance0
+ * @ingroup TestsuitesPerformanceNoClock0
*/
/*
- * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -57,10 +57,10 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestSuiteTestsuitesPerformance0 \
- * spec:/testsuites/performance-0
+ * @defgroup TestsuitesPerformanceNoClock0 \
+ * spec:/testsuites/performance-no-clock-0
*
- * @ingroup RTEMSTestSuites
+ * @ingroup RTEMSTestSuitesValidation
*
* @brief This general purpose performance test suite provides enough resources
* to run basic performance tests for all specified managers and functions.
@@ -71,7 +71,11 @@
* @{
*/
-const char rtems_test_name[] = "Performance0";
+const char rtems_test_name[] = "TestsuitesPerformanceNoClock0";
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 4
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
#include "ts-default.h"
diff --git a/testsuites/validation/ts-terminate.c b/testsuites/validation/ts-terminate.c
new file mode 100644
index 0000000000..670c7ec6a2
--- /dev/null
+++ b/testsuites/validation/ts-terminate.c
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesTerminate
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tc-userext.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesTerminate spec:/testsuites/terminate
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains a test case for the system
+ * termination procedure.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesTerminate";
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 2
+
+#define CONFIGURE_INITIAL_EXTENSIONS \
+ { .fatal = FatalExtension0 }, \
+ { .fatal = FatalExtension1 }
+
+#define CONFIGURE_DISABLE_BSP_SETTINGS
+
+#include "ts-default.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-userext.c b/testsuites/validation/ts-userext.c
new file mode 100644
index 0000000000..461a1ddc0e
--- /dev/null
+++ b/testsuites/validation/ts-userext.c
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesUserext
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tc-userext.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesUserext spec:/testsuites/userext
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains a test cases related to the
+ * invocation of user extensions.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesUserext";
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 2
+
+#define CONFIGURE_INITIAL_EXTENSIONS \
+ { \
+ .thread_begin = ThreadBeginExtension0, \
+ .thread_create = ThreadCreateExtension0, \
+ .thread_delete = ThreadDeleteExtension0, \
+ .thread_exitted = ThreadExittedExtension0, \
+ .thread_restart = ThreadRestartExtension0, \
+ .thread_start = ThreadStartExtension0, \
+ .thread_switch = ThreadSwitchExtension0, \
+ .thread_terminate = ThreadTerminateExtension0 \
+ }, { \
+ .thread_begin = ThreadBeginExtension1, \
+ .thread_create = ThreadCreateExtension1, \
+ .thread_delete = ThreadDeleteExtension1, \
+ .thread_exitted = ThreadExittedExtension1, \
+ .thread_restart = ThreadRestartExtension1, \
+ .thread_start = ThreadStartExtension1, \
+ .thread_switch = ThreadSwitchExtension1, \
+ .thread_terminate = ThreadTerminateExtension1 \
+ }
+
+#define CONFIGURE_IDLE_TASK_BODY IdleBody
+
+#include "ts-default.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-validation-0.c b/testsuites/validation/ts-validation-0.c
index b80c09d47f..7f7dfb9215 100644
--- a/testsuites/validation/ts-validation-0.c
+++ b/testsuites/validation/ts-validation-0.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation0
+ * @ingroup TestsuitesValidation0
*/
/*
- * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -55,9 +55,9 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestSuiteTestsuitesValidation0 spec:/testsuites/validation-0
+ * @defgroup TestsuitesValidation0 spec:/testsuites/validation-0
*
- * @ingroup RTEMSTestSuites
+ * @ingroup RTEMSTestSuitesValidation
*
* @brief This general purpose validation test suite provides enough resources
* to run basic tests for all specified managers and functions.
@@ -68,7 +68,7 @@
* @{
*/
-const char rtems_test_name[] = "Validation0";
+const char rtems_test_name[] = "TestsuitesValidation0";
#define CONFIGURE_MAXIMUM_PROCESSORS 5
diff --git a/testsuites/validation/ts-validation-1.c b/testsuites/validation/ts-validation-1.c
index 11bef51fb7..a33593afb1 100644
--- a/testsuites/validation/ts-validation-1.c
+++ b/testsuites/validation/ts-validation-1.c
@@ -3,11 +3,11 @@
/**
* @file
*
- * @ingroup RTEMSTestSuiteTestsuitesValidation1
+ * @ingroup TestsuitesValidation1
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2020 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -55,20 +55,22 @@
#include <rtems/test.h>
/**
- * @defgroup RTEMSTestSuiteTestsuitesValidation1 spec:/testsuites/validation-1
+ * @defgroup TestsuitesValidation1 spec:/testsuites/validation-1
*
- * @ingroup RTEMSTestSuites
+ * @ingroup RTEMSTestSuitesValidation
*
* @brief This general purpose validation test suite provides enough resources
- * to run basic tests for all specified managers and functions in a
- * configuration with exactly one processor.
+ * to run basic tests for all specified managers and functions.
+ *
+ * In SMP configurations, up to three scheduler instances using the SMP EDF
+ * scheduler are provided using up to four processors.
*
* @{
*/
-const char rtems_test_name[] = "Validation1";
+const char rtems_test_name[] = "TestsuitesValidation1";
-#define CONFIGURE_MAXIMUM_PROCESSORS 1
+#define CONFIGURE_MAXIMUM_PROCESSORS 5
#include "ts-default.h"
diff --git a/testsuites/validation/ts-validation-acfg-0.c b/testsuites/validation/ts-validation-acfg-0.c
new file mode 100644
index 0000000000..2afd0dae86
--- /dev/null
+++ b/testsuites/validation/ts-validation-acfg-0.c
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesValidationAcfg0
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ts-acfg.h"
+#include "tx-support.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesValidationAcfg0 spec:/testsuites/validation-acfg-0
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite is used to validate the default value of
+ * application configuration options taking the optional BSP provided
+ * settings into account.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesValidationAcfg0";
+
+#define CONFIGURE_IDLE_TASK_STORAGE_SIZE RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
+
+void *IdleBody( uintptr_t ignored )
+{
+ (void) ignored;
+ RunTestSuite();
+}
+
+#define CONFIGURE_IDLE_TASK_BODY IdleBody
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
+
+/** @} */
diff --git a/testsuites/validation/ts-validation-acfg-1.c b/testsuites/validation/ts-validation-acfg-1.c
new file mode 100644
index 0000000000..d1b44cf1ec
--- /dev/null
+++ b/testsuites/validation/ts-validation-acfg-1.c
@@ -0,0 +1,112 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesValidationAcfg1
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <bsp.h>
+
+#include "ts-acfg.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesValidationAcfg1 spec:/testsuites/validation-acfg-1
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite is used to validate the default value of
+ * application configuration options where all optional BSP provided settings
+ * are disabled.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesValidationAcfg1";
+
+static void FatalExtension(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code
+)
+{
+ rtems_extensions_table bsp = BSP_INITIAL_EXTENSION;
+
+ ( *bsp.fatal )( source, always_set_to_false, code );
+}
+
+static void Init( rtems_task_argument arg )
+{
+ (void) arg;
+ RunTestSuite();
+}
+
+#define CONFIGURE_INITIAL_EXTENSIONS { .fatal = FatalExtension }
+
+#define CONFIGURE_DISABLE_BSP_SETTINGS
+
+#define CONFIGURE_IDLE_TASK_STORAGE_SIZE RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_MAXIMUM_TASKS 1
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT_TASK_CONSTRUCT_STORAGE_SIZE \
+ RTEMS_TASK_STORAGE_SIZE( \
+ RTEMS_MINIMUM_STACK_SIZE, \
+ RTEMS_DEFAULT_ATTRIBUTES \
+ )
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
+
+/** @} */
diff --git a/testsuites/validation/ts-validation-cache.c b/testsuites/validation/ts-validation-cache.c
new file mode 100644
index 0000000000..3522c02db7
--- /dev/null
+++ b/testsuites/validation/ts-validation-cache.c
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesValidationCache
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesValidationCache spec:/testsuites/validation-cache
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite provides enough resources to run tests for
+ * the directives of the @ref RTEMSAPIClassicCache.
+ *
+ * In SMP configurations, up to three scheduler instances using the SMP EDF
+ * scheduler are provided using up to four processors.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesValidationCache";
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 4
+
+#include "ts-default.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-validation-intr.c b/testsuites/validation/ts-validation-intr.c
new file mode 100644
index 0000000000..74f849441a
--- /dev/null
+++ b/testsuites/validation/ts-validation-intr.c
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesValidationIntr
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesValidationIntr spec:/testsuites/validation-intr
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite provides enough resources to run tests for
+ * the interrupt controller related directives of the @ref
+ * RTEMSAPIClassicIntr.
+ *
+ * In SMP configurations, up to three scheduler instances using the SMP EDF
+ * scheduler are provided using up to four processors.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesValidationIntr";
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 5
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#include "ts-default.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-validation-io-kernel.c b/testsuites/validation/ts-validation-io-kernel.c
new file mode 100644
index 0000000000..35779f6060
--- /dev/null
+++ b/testsuites/validation/ts-validation-io-kernel.c
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesValidationIoKernel
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <bsp/bootcard.h>
+#include <rtems/test-info.h>
+#include <rtems/test.h>
+#include <rtems/testopts.h>
+
+#include "tr-io-kernel.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesValidationIoKernel spec:/testsuites/validation-io-kernel
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains test cases which test the kernel
+ * character input/output device provided by the BSP before the system
+ * initialization is performed.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesValidationIoKernel";
+
+static char buffer[ 512 ];
+
+static const T_action actions[] = {
+ T_report_hash_sha256
+};
+
+static const T_config test_config = {
+ .name = rtems_test_name,
+ .buf = buffer,
+ .buf_size = sizeof( buffer ),
+ .putchar = rtems_put_char,
+ .verbosity = RTEMS_TEST_VERBOSITY,
+ .now = T_now_tick,
+ .action_count = T_ARRAY_SIZE( actions ),
+ .actions = actions
+};
+
+void boot_card( const char *cmdline )
+{
+ uint32_t exit_code;
+
+ (void) cmdline;
+
+ rtems_test_begin( rtems_test_name, TEST_STATE );
+ T_run_initialize( &test_config );
+ RtemsIoValKernel_Run();
+
+ if ( T_run_finalize() ) {
+ rtems_test_end( rtems_test_name );
+ exit_code = 0;
+ } else {
+ exit_code = 1;
+ }
+
+ rtems_fatal( RTEMS_FATAL_SOURCE_EXIT, exit_code );
+}
+
+static void *IdleBody( uintptr_t ignored )
+{
+ (void) ignored;
+
+ while ( true ) {
+ /* Do nothing */
+ }
+
+ return NULL;
+}
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 0
+
+#define CONFIGURE_DISABLE_NEWLIB_REENTRANCY
+
+#define CONFIGURE_APPLICATION_DISABLE_FILESYSTEM
+
+#define CONFIGURE_SCHEDULER_USER
+
+#define CONFIGURE_SCHEDULER
+
+#define CONFIGURE_SCHEDULER_TABLE_ENTRIES { }
+
+#define CONFIGURE_IDLE_TASK_STORAGE_SIZE RTEMS_MINIMUM_STACK_SIZE
+
+#define CONFIGURE_IDLE_TASK_INITIALIZES_APPLICATION
+
+#define CONFIGURE_IDLE_TASK_BODY IdleBody
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
+
+/** @} */
diff --git a/testsuites/validation/ts-validation-no-clock-0.c b/testsuites/validation/ts-validation-no-clock-0.c
new file mode 100644
index 0000000000..1fa610a3b4
--- /dev/null
+++ b/testsuites/validation/ts-validation-no-clock-0.c
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesValidationNoClock0
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesValidationNoClock0 \
+ * spec:/testsuites/validation-no-clock-0
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This general purpose validation test suite provides enough resources
+ * to run basic tests without a Clock Driver for all specified managers and
+ * functions.
+ *
+ * In SMP configurations, up to three scheduler instances using the SMP EDF
+ * scheduler are provided using up to four processors.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesValidationNoClock0";
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 5
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#include "ts-default.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-validation-non-smp.c b/testsuites/validation/ts-validation-non-smp.c
new file mode 100644
index 0000000000..b7460222b5
--- /dev/null
+++ b/testsuites/validation/ts-validation-non-smp.c
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesValidationNonSmp
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesValidationNonSmp spec:/testsuites/validation-non-smp
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This test suite for non-SMP test cases provides enough resources to
+ * run basic tests for all specified managers and functions.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesValidationNonSmp";
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 1
+
+#include "ts-default.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-validation-one-cpu-0.c b/testsuites/validation/ts-validation-one-cpu-0.c
new file mode 100644
index 0000000000..6eefe21b15
--- /dev/null
+++ b/testsuites/validation/ts-validation-one-cpu-0.c
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesValidationOneCpu0
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesValidationOneCpu0 spec:/testsuites/validation-one-cpu-0
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This general purpose validation test suite provides enough resources
+ * to run basic tests with exactly one processor and without a Clock Driver.
+ *
+ * Two test suites of this configuration are provided to limit test run
+ * duration.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesValidationOneCpu0";
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 1
+
+#include "ts-default.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-validation-one-cpu-1.c b/testsuites/validation/ts-validation-one-cpu-1.c
new file mode 100644
index 0000000000..29288686b1
--- /dev/null
+++ b/testsuites/validation/ts-validation-one-cpu-1.c
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesValidationOneCpu1
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ts-config.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesValidationOneCpu1 spec:/testsuites/validation-one-cpu-1
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This general purpose validation test suite provides enough resources
+ * to run basic tests with exactly one processor and without a Clock Driver.
+ *
+ * Two test suites of this configuration are provided to limit test run
+ * duration.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesValidationOneCpu1";
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 1
+
+#define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
+ RTEMS_SCHEDULER_TABLE_PRIORITY( a, TEST_SCHEDULER_A_NAME )
+
+#include "ts-default.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-validation-smp-one-cpu-0.c b/testsuites/validation/ts-validation-smp-one-cpu-0.c
new file mode 100644
index 0000000000..c5be91fb9e
--- /dev/null
+++ b/testsuites/validation/ts-validation-smp-one-cpu-0.c
@@ -0,0 +1,76 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesValidationSmpOneCpu0
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesValidationSmpOneCpu0 \
+ * spec:/testsuites/validation-smp-one-cpu-0
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This general purpose validation test suite provides enough resources
+ * to run basic tests for all specified managers and functions in a
+ * configuration with exactly one processor and an uniprocessor scheduler.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesValidationSmpOneCpu0";
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 1
+
+#include "ts-default.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-validation-smp-only-0.c b/testsuites/validation/ts-validation-smp-only-0.c
new file mode 100644
index 0000000000..30b1f705ed
--- /dev/null
+++ b/testsuites/validation/ts-validation-smp-only-0.c
@@ -0,0 +1,78 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesValidationSmpOnly0
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesValidationSmpOnly0 \
+ * spec:/testsuites/validation-smp-only-0
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This test suite for SMP-only test cases provides enough resources to
+ * run basic tests for all specified managers and functions.
+ *
+ * Up to three scheduler instances using the SMP EDF scheduler are provided
+ * using up to four processors.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesValidationSmpOnly0";
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 5
+
+#include "ts-default.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-validation-smp-only-2.c b/testsuites/validation/ts-validation-smp-only-2.c
new file mode 100644
index 0000000000..62f0cd95d6
--- /dev/null
+++ b/testsuites/validation/ts-validation-smp-only-2.c
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesValidationSmpOnly2
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "ts-config.h"
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesValidationSmpOnly2 \
+ * spec:/testsuites/validation-smp-only-2
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This SMP-only test suite validates the clustered scheduler
+ * configuration through an application configuration with a processor
+ * maximum of two. The second processor has a optional scheduler assigned
+ * and fails to start.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesValidationSmpOnly2";
+
+bool __wrap__CPU_SMP_Start_processor( uint32_t cpu_index );
+
+bool __wrap__CPU_SMP_Start_processor( uint32_t cpu_index )
+{
+ (void) cpu_index;
+ return false;
+}
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 2
+
+#include <rtems/score/scheduleredfsmp.h>
+
+#define CONFIGURE_SCHEDULER_EDF_SMP
+
+#include <rtems/scheduler.h>
+
+RTEMS_SCHEDULER_EDF_SMP( a );
+
+#define CONFIGURE_SCHEDULER_TABLE_ENTRIES \
+ RTEMS_SCHEDULER_TABLE_EDF_SMP( a, TEST_SCHEDULER_A_NAME )
+
+#define CONFIGURE_SCHEDULER_ASSIGNMENTS \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_MANDATORY ), \
+ RTEMS_SCHEDULER_ASSIGN( 0, RTEMS_SCHEDULER_ASSIGN_PROCESSOR_OPTIONAL )
+
+#include "ts-default.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-validation-timecounter-0.c b/testsuites/validation/ts-validation-timecounter-0.c
new file mode 100644
index 0000000000..7a042c75ae
--- /dev/null
+++ b/testsuites/validation/ts-validation-timecounter-0.c
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesValidationTimecounter0
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesValidationTimecounter0 \
+ * spec:/testsuites/validation-timecounter-0
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite is intended test cases related to the
+ * installation of timecouters. The Clock Driver is disabled.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesValidationTimecounter0";
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 1
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#include "ts-default.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-validation-timecounter-1.c b/testsuites/validation/ts-validation-timecounter-1.c
new file mode 100644
index 0000000000..918d6d093c
--- /dev/null
+++ b/testsuites/validation/ts-validation-timecounter-1.c
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesValidationTimecounter1
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesValidationTimecounter1 \
+ * spec:/testsuites/validation-timecounter-1
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite is intended test cases related to the use
+ * of timecouters. The Clock Driver is enabled.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesValidationTimecounter1";
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 4
+
+#include "ts-default.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-validation-timecounter-smp-0.c b/testsuites/validation/ts-validation-timecounter-smp-0.c
new file mode 100644
index 0000000000..849a64d94b
--- /dev/null
+++ b/testsuites/validation/ts-validation-timecounter-smp-0.c
@@ -0,0 +1,77 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesValidationTimecounterSmp0
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesValidationTimecounterSmp0 \
+ * spec:/testsuites/validation-timecounter-smp-0
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite is intended test cases related to the use
+ * of timecouters. The Clock Driver is disabled.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesValidationTimecounterSmp0";
+
+#define CONFIGURE_MAXIMUM_PROCESSORS 4
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+
+#include "ts-default.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-validation-tls-0.c b/testsuites/validation/ts-validation-tls-0.c
new file mode 100644
index 0000000000..fe32bf35bd
--- /dev/null
+++ b/testsuites/validation/ts-validation-tls-0.c
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesValidationTls0
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesValidationTls0 spec:/testsuites/validation-tls-0
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains test cases related to the
+ * thread-local storage support.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesValidationTls0";
+
+#define MAX_TLS_SIZE 1024
+
+#include "ts-default.h"
+
+/** @} */
diff --git a/testsuites/validation/ts-validation-tls-1.c b/testsuites/validation/ts-validation-tls-1.c
new file mode 100644
index 0000000000..00b74008b2
--- /dev/null
+++ b/testsuites/validation/ts-validation-tls-1.c
@@ -0,0 +1,75 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup TestsuitesValidationTls1
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file is part of the RTEMS quality process and was automatically
+ * generated. If you find something that needs to be fixed or
+ * worded better please post a report or patch to an RTEMS mailing list
+ * or raise a bug report:
+ *
+ * https://www.rtems.org/bugs.html
+ *
+ * For information on updating and regenerating please refer to the How-To
+ * section in the Software Requirements Engineering chapter of the
+ * RTEMS Software Engineering manual. The manual is provided as a part of
+ * a release. For development sources please refer to the online
+ * documentation at:
+ *
+ * https://docs.rtems.org
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/test.h>
+
+/**
+ * @defgroup TestsuitesValidationTls1 spec:/testsuites/validation-tls-1
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This validation test suite contains test cases related to the
+ * thread-local storage support.
+ *
+ * @{
+ */
+
+const char rtems_test_name[] = "TestsuitesValidationTls1";
+
+#define CONFIGURE_IDLE_TASK_STORAGE_SIZE \
+ ( RTEMS_MINIMUM_STACK_SIZE + 4096 )
+
+#include "ts-idle.h"
+
+/** @} */
diff --git a/testsuites/validation/tx-call-within-isr.c b/testsuites/validation/tx-call-within-isr.c
index 226647c0bc..8bbe0e7c29 100644
--- a/testsuites/validation/tx-call-within-isr.c
+++ b/testsuites/validation/tx-call-within-isr.c
@@ -3,14 +3,15 @@
/**
* @file
*
- * @ingroup RTEMSTestSuites
+ * @ingroup RTEMSTestSuitesValidation
*
- * @brief This source file contains the implementation of CallWithinISR(),
+ * @brief This source file contains the implementation of CallWithinISRClear(),
+ * CallWithinISRGetVector(), CallWithinISR(), CallWithinISRRaise(),
* CallWithinISRSubmit(), and CallWithinISRWait().
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021, 2022 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -44,6 +45,7 @@
#include <rtems/score/chainimpl.h>
#include <bsp.h>
+#include <bsp/irq-generic.h>
/* Some target architectures need this variable for <tm27.h> */
uint32_t Interrupt_nest;
@@ -64,13 +66,29 @@ static CallWithinISRContext CallWithinISRInstance = {
.pending = CHAIN_INITIALIZER_EMPTY( CallWithinISRInstance.pending )
};
-static void CallWithinISRHandler( rtems_vector_number vector )
+void CallWithinISRRaise( void )
+{
+ Cause_tm27_intr();
+}
+
+void CallWithinISRClear( void )
+{
+ Clear_tm27_intr();
+}
+
+#ifdef TM27_USE_VECTOR_HANDLER
+static rtems_isr CallWithinISRHandler( rtems_vector_number arg )
+#else
+static void CallWithinISRHandler( void *arg )
+#endif
{
CallWithinISRContext *ctx;
- (void) vector;
+ (void) arg;
ctx = &CallWithinISRInstance;
+ CallWithinISRClear();
+
while ( true ) {
rtems_interrupt_lock_context lock_context;
CallWithinISRRequest *request;
@@ -112,7 +130,7 @@ void CallWithinISRSubmit( CallWithinISRRequest *request )
_Chain_Append_unprotected( &ctx->pending, &request->node );
rtems_interrupt_lock_release( &ctx->lock, &lock_context );
- Cause_tm27_intr();
+ CallWithinISRRaise();
}
void CallWithinISRWait( const CallWithinISRRequest *request )
@@ -122,6 +140,82 @@ void CallWithinISRWait( const CallWithinISRRequest *request )
}
}
+#if !defined( TM27_INTERRUPT_VECTOR_DEFAULT )
+static void CallWithinISRIsHandlerInstalled(
+ void *arg,
+ const char *info,
+ rtems_option option,
+ rtems_interrupt_handler handler,
+ void *handler_arg
+)
+{
+ (void) info;
+ (void) option;
+ (void) handler_arg;
+
+ if ( handler == CallWithinISRHandler && handler_arg == NULL ) {
+ *(bool *) arg = true;
+ }
+}
+#endif
+
+rtems_vector_number CallWithinISRGetVector( void )
+{
+#if defined( TM27_INTERRUPT_VECTOR_DEFAULT )
+ return TM27_INTERRUPT_VECTOR_DEFAULT;
+#else
+ rtems_vector_number vector;
+
+ for ( vector = 0; vector < BSP_INTERRUPT_VECTOR_COUNT; ++vector ) {
+ bool installed;
+
+ installed = false;
+ (void) rtems_interrupt_handler_iterate(
+ vector,
+ CallWithinISRIsHandlerInstalled,
+ &installed
+ );
+
+ if ( installed ) {
+ return vector;
+ }
+ }
+
+ return UINT32_MAX;
+#endif
+}
+
+rtems_vector_number GetSoftwareInterruptVector( void )
+{
+#if defined( TM27_INTERRUPT_VECTOR_ALTERNATIVE )
+ return TM27_INTERRUPT_VECTOR_ALTERNATIVE;
+#else
+ return UINT32_MAX;
+#endif
+}
+
+rtems_status_code RaiseSoftwareInterrupt( rtems_vector_number vector )
+{
+#if defined( TM27_INTERRUPT_VECTOR_ALTERNATIVE )
+ if ( vector == TM27_INTERRUPT_VECTOR_ALTERNATIVE ) {
+ return _TM27_Raise_alternative();
+ }
+#endif
+
+ return rtems_interrupt_raise( vector );
+}
+
+rtems_status_code ClearSoftwareInterrupt( rtems_vector_number vector )
+{
+#if defined( TM27_INTERRUPT_VECTOR_ALTERNATIVE )
+ if ( vector == TM27_INTERRUPT_VECTOR_ALTERNATIVE ) {
+ return _TM27_Clear_alternative();
+ }
+#endif
+
+ return rtems_interrupt_clear( vector );
+}
+
static void CallWithinISRInitialize( void )
{
Install_tm27_vector( CallWithinISRHandler );
diff --git a/testsuites/validation/tx-default-task-config.c b/testsuites/validation/tx-default-task-config.c
new file mode 100644
index 0000000000..0facc78298
--- /dev/null
+++ b/testsuites/validation/tx-default-task-config.c
@@ -0,0 +1,61 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This source file contains the definition of ::DefaultTaskConfig.
+ */
+
+/*
+ * Copyright (C) 2022 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tx-support.h"
+#include "ts-config.h"
+
+#define TASK_ATTRIBUTES RTEMS_DEFAULT_ATTRIBUTES
+
+RTEMS_ALIGNED( RTEMS_TASK_STORAGE_ALIGNMENT )
+static char DefaultTaskStorage[
+ RTEMS_TASK_STORAGE_SIZE(
+ TEST_MAXIMUM_TLS_SIZE + TEST_MINIMUM_STACK_SIZE,
+ TASK_ATTRIBUTES
+ )
+];
+
+const rtems_task_config DefaultTaskConfig = {
+ .name = rtems_build_name( 'D', 'T', 'S', 'K' ),
+ .initial_priority = 1,
+ .storage_area = DefaultTaskStorage,
+ .storage_size = sizeof( DefaultTaskStorage ),
+ .maximum_thread_local_storage_size = TEST_MAXIMUM_TLS_SIZE,
+ .initial_modes = RTEMS_DEFAULT_MODES,
+ .attributes = TASK_ATTRIBUTES
+};
diff --git a/testsuites/validation/tx-interrupt.c b/testsuites/validation/tx-interrupt.c
index e75c7a2aa0..c5ea4142c2 100644
--- a/testsuites/validation/tx-interrupt.c
+++ b/testsuites/validation/tx-interrupt.c
@@ -3,14 +3,14 @@
/**
* @file
*
- * @ingroup RTEMSTestSuites
+ * @ingroup RTEMSTestSuitesValidation
*
* @brief This source file contains the implementation of
* HasInterruptVectorEntriesInstalled().
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -45,6 +45,30 @@
#include <bsp/irq-generic.h>
+static bool HasRequiredAttributes(
+ const rtems_interrupt_attributes *required,
+ const rtems_interrupt_attributes *actual
+)
+{
+ if ( required == NULL ) {
+ return true;
+ }
+
+ if ( required->can_get_affinity && !actual->can_get_affinity ) {
+ return false;
+ }
+
+ if ( required->can_raise && !actual->can_raise ) {
+ return false;
+ }
+
+ if ( required->can_raise_on && !actual->can_raise_on ) {
+ return false;
+ }
+
+ return true;
+}
+
rtems_vector_number GetValidInterruptVectorNumber(
const rtems_interrupt_attributes *required
)
@@ -57,11 +81,7 @@ rtems_vector_number GetValidInterruptVectorNumber(
sc = rtems_interrupt_get_attributes( vector, &attr );
- if (
- sc == RTEMS_SUCCESSFUL &&
- ( required == NULL ||
- !required->can_get_affinity || attr.can_get_affinity )
- ) {
+ if ( sc == RTEMS_SUCCESSFUL && HasRequiredAttributes( required, &attr ) ) {
break;
}
}
@@ -69,7 +89,9 @@ rtems_vector_number GetValidInterruptVectorNumber(
return vector;
}
-rtems_vector_number GetTestableInterruptVector( void )
+rtems_vector_number GetTestableInterruptVector(
+ const rtems_interrupt_attributes *required
+)
{
rtems_vector_number vector;
@@ -87,6 +109,10 @@ rtems_vector_number GetTestableInterruptVector( void )
continue;
}
+ if ( !HasRequiredAttributes( required, &attr ) ) {
+ continue;
+ }
+
if ( HasInterruptVectorEntriesInstalled( vector ) ) {
continue;
}
@@ -113,6 +139,10 @@ rtems_vector_number GetTestableInterruptVector( void )
}
}
+ if ( vector == BSP_INTERRUPT_VECTOR_COUNT ) {
+ vector = GetSoftwareInterruptVector();
+ }
+
return vector;
}
diff --git a/testsuites/validation/tx-io-relax.c b/testsuites/validation/tx-io-relax.c
new file mode 100644
index 0000000000..30cc097b3a
--- /dev/null
+++ b/testsuites/validation/tx-io-relax.c
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This source file contains the implementation of SetIORelaxHandler().
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tx-support.h"
+
+void __real__IO_Relax( void );
+
+void __wrap__IO_Relax( void );
+
+static void ( *io_relax_handler )( void * );
+
+static void *io_relax_arg;
+
+void __wrap__IO_Relax( void )
+{
+ void ( *handler )( void * );
+
+ handler = io_relax_handler;
+
+ if ( handler != NULL ) {
+ ( *handler )( io_relax_arg );
+ }
+
+ __real__IO_Relax();
+}
+
+void SetIORelaxHandler( void ( *handler )( void * ), void *arg )
+{
+ io_relax_handler = handler;
+ io_relax_arg = arg;
+}
diff --git a/testsuites/validation/tx-memory-alloc.c b/testsuites/validation/tx-memory-alloc.c
new file mode 100644
index 0000000000..8959dbbdc5
--- /dev/null
+++ b/testsuites/validation/tx-memory-alloc.c
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This source file contains the implementation of
+ * MemoryAllocationFailWhen() and __wrap_rtems_malloc().
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tx-support.h"
+
+void *__real_rtems_malloc( size_t );
+
+void *__wrap_rtems_malloc( size_t );
+
+static uint32_t fail_when_counter;
+
+void MemoryAllocationFailWhen( uint32_t counter )
+{
+ fail_when_counter = counter;
+}
+
+static bool IsFail( void )
+{
+ uint32_t counter;
+
+ counter = fail_when_counter;
+
+ if ( counter == 1 ) {
+ fail_when_counter = 0;
+ return true;
+ }
+
+ if ( counter > 1 ) {
+ fail_when_counter = counter - 1;
+ }
+
+ return false;
+}
+
+void *__wrap_rtems_malloc( size_t size )
+{
+ if ( IsFail() ) {
+ return NULL;
+ }
+
+ return __real_rtems_malloc( size );
+}
diff --git a/testsuites/validation/tx-preemption-intervention.c b/testsuites/validation/tx-preemption-intervention.c
new file mode 100644
index 0000000000..f66ab839e5
--- /dev/null
+++ b/testsuites/validation/tx-preemption-intervention.c
@@ -0,0 +1,155 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This source file contains the implementation of
+ * SetPreemptionIntervention().
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tx-support.h"
+
+#include <rtems/sysinit.h>
+#include <rtems/score/chainimpl.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/threadimpl.h>
+
+#include <rtems/test.h>
+
+#if defined(RTEMS_SMP)
+typedef struct {
+ void ( *handler )( void * );
+ void *arg;
+ Scheduler_Context scheduler_context;
+ Scheduler_Node scheduler_node;
+ Thread_Control thread;
+} PreemptionInterventionContext;
+
+static PreemptionInterventionContext preemption_intervention_instance;
+
+static bool PreemptionInterventionAskForHelp(
+ const Scheduler_Control *scheduler,
+ Thread_Control *thread,
+ Scheduler_Node *node
+)
+{
+ PreemptionInterventionContext *ctx;
+ void ( *handler )( void * );
+ void *arg;
+
+ (void) scheduler;
+ (void) thread;
+ (void) node;
+
+ ctx = &preemption_intervention_instance;
+ handler = ctx->handler;
+ arg = ctx->arg;
+ ctx->handler = NULL;
+ ctx->arg = NULL;
+ ( *handler )( arg );
+
+ return true;
+}
+
+static const Scheduler_Control preemption_intervention_scheduler = {
+ .context = &preemption_intervention_instance.scheduler_context,
+ .Operations = {
+ .ask_for_help = PreemptionInterventionAskForHelp
+ }
+};
+
+static void PreemptionInterventionInitialize( void )
+{
+ PreemptionInterventionContext *ctx;
+
+ ctx = &preemption_intervention_instance;
+
+ _Chain_Initialize_node( &ctx->thread.Scheduler.Help_node );
+ _Thread_queue_Initialize(
+ &ctx->thread.Join_queue,
+ "Preemption Intervention"
+ );
+ _ISR_lock_Initialize(
+ &ctx->scheduler_context.Lock,
+ "Preemption Intervention"
+ );
+ _Scheduler_Node_do_initialize(
+ &preemption_intervention_scheduler,
+ &ctx->scheduler_node,
+ &ctx->thread,
+ 0
+ );
+ _Chain_Initialize_one(
+ &ctx->thread.Scheduler.Scheduler_nodes,
+ &ctx->scheduler_node.Thread.Scheduler_node.Chain
+ );
+}
+
+RTEMS_SYSINIT_ITEM(
+ PreemptionInterventionInitialize,
+ RTEMS_SYSINIT_DEVICE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_MIDDLE
+);
+#endif
+
+void SetPreemptionIntervention(
+ struct Per_CPU_Control *cpu,
+ void ( *handler )( void * ),
+ void *arg
+)
+{
+#if defined(RTEMS_SMP)
+ PreemptionInterventionContext *ctx;
+ rtems_interrupt_level level;
+ ISR_lock_Context lock_context;
+
+ ctx = &preemption_intervention_instance;
+ T_quiet_assert_null( ctx->handler );
+ ctx->handler = handler;
+ ctx->arg = arg;
+
+ rtems_interrupt_local_disable( level );
+ _Per_CPU_Acquire( cpu, &lock_context );
+ _Chain_Append_unprotected(
+ &cpu->Threads_in_need_for_help,
+ &ctx->thread.Scheduler.Help_node
+ );
+ _Per_CPU_Release( cpu, &lock_context );
+ rtems_interrupt_local_enable( level );
+#else
+ (void) cpu;
+ (void) handler;
+ (void) arg;
+#endif
+}
diff --git a/testsuites/validation/tx-support.c b/testsuites/validation/tx-support.c
index dcb7603832..64ebe260f6 100644
--- a/testsuites/validation/tx-support.c
+++ b/testsuites/validation/tx-support.c
@@ -3,17 +3,14 @@
/**
* @file
*
- * @ingroup RTEMSTestSuites
+ * @ingroup RTEMSTestSuitesValidation
*
- * @brief This source file contains the definition of DeleteTask(),
- * DoCreateTask(), GetMode(), GetPriority(), GetSelfPriority(),
- * ReceiveAnyEvents(), RestoreRunnerASR(), RestoreRunnerMode(),
- * RestoreRunnerPriority(), SendEvents(), SetMode(), SetSelfPriority(),
- * SetPriority(), and StartTask().
+ * @brief This source file contains the implementation of support functions for
+ * the validation test cases.
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -42,8 +39,16 @@
#endif
#include "tx-support.h"
+#include "ts-config.h"
#include <rtems/test.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/smpimpl.h>
+#include <rtems/score/threaddispatch.h>
+#include <rtems/score/threadimpl.h>
+#include <rtems/rtems/semimpl.h>
+
+#include <string.h>
rtems_id DoCreateTask( rtems_name name, rtems_task_priority priority )
{
@@ -53,7 +58,7 @@ rtems_id DoCreateTask( rtems_name name, rtems_task_priority priority )
sc = rtems_task_create(
name,
priority,
- RTEMS_MINIMUM_STACK_SIZE,
+ TEST_MINIMUM_STACK_SIZE,
RTEMS_DEFAULT_MODES,
RTEMS_DEFAULT_ATTRIBUTES,
&id
@@ -77,33 +82,115 @@ void DeleteTask( rtems_id id )
rtems_status_code sc;
sc = rtems_task_delete( id );
- T_rsc_success( sc );
+ T_quiet_rsc_success( sc );
}
}
-rtems_event_set ReceiveAnyEvents( void )
+void SuspendTask( rtems_id id )
+{
+ rtems_status_code sc;
+
+ sc = rtems_task_suspend( id );
+ T_quiet_rsc_success( sc );
+}
+
+void SuspendSelf( void )
+{
+ SuspendTask( RTEMS_SELF );
+}
+
+void ResumeTask( rtems_id id )
+{
+ rtems_status_code sc;
+
+ sc = rtems_task_resume( id );
+ T_quiet_rsc_success( sc );
+}
+
+bool IsTaskSuspended( rtems_id id )
+{
+ rtems_status_code sc;
+
+ sc = rtems_task_is_suspended( id );
+ T_quiet_true( sc == RTEMS_SUCCESSFUL || sc == RTEMS_ALREADY_SUSPENDED );
+
+ return sc == RTEMS_ALREADY_SUSPENDED;
+}
+
+rtems_event_set QueryPendingEvents( void )
{
rtems_status_code sc;
rtems_event_set events;
events = 0;
sc = rtems_event_receive(
+ RTEMS_PENDING_EVENTS,
+ RTEMS_EVENT_ALL | RTEMS_NO_WAIT,
+ 0,
+ &events
+ );
+ T_quiet_rsc_success( sc );
+
+ return events;
+}
+
+rtems_event_set PollAnyEvents( void )
+{
+ rtems_event_set events;
+
+ events = 0;
+ (void) rtems_event_receive(
+ RTEMS_ALL_EVENTS,
+ RTEMS_EVENT_ANY | RTEMS_NO_WAIT,
+ 0,
+ &events
+ );
+
+ return events;
+}
+
+rtems_event_set ReceiveAnyEvents( void )
+{
+ return ReceiveAnyEventsTimed( RTEMS_NO_TIMEOUT );
+}
+
+rtems_event_set ReceiveAnyEventsTimed( rtems_interval ticks )
+{
+ rtems_event_set events;
+
+ events = 0;
+ (void) rtems_event_receive(
RTEMS_ALL_EVENTS,
RTEMS_EVENT_ANY | RTEMS_WAIT,
- RTEMS_NO_TIMEOUT,
+ ticks,
&events
);
- T_rsc_success( sc );
return events;
}
+void ReceiveAllEvents( rtems_event_set events )
+{
+ rtems_status_code sc;
+ rtems_event_set received;
+
+ received = 0;
+ sc = rtems_event_receive(
+ events,
+ RTEMS_EVENT_ALL | RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT,
+ &received
+ );
+ T_quiet_rsc_success( sc );
+ T_quiet_eq_u32( received, events );
+}
+
void SendEvents( rtems_id id, rtems_event_set events )
{
rtems_status_code sc;
sc = rtems_event_send( id, events );
- T_rsc_success( sc );
+ T_quiet_rsc_success( sc );
}
rtems_mode GetMode( void )
@@ -117,7 +204,7 @@ rtems_mode SetMode( rtems_mode set, rtems_mode mask )
rtems_mode previous;
sc = rtems_task_mode( set, mask, &previous );
- T_rsc_success( sc );
+ T_quiet_rsc_success( sc );
return previous;
}
@@ -127,13 +214,32 @@ rtems_task_priority GetPriority( rtems_id id )
return SetPriority( id, RTEMS_CURRENT_PRIORITY );
}
+rtems_task_priority GetPriorityByScheduler(
+ rtems_id task_id,
+ rtems_id scheduler_id
+)
+{
+ rtems_status_code sc;
+ rtems_task_priority priority;
+
+ priority = PRIO_INVALID;
+ sc = rtems_task_get_priority( task_id, scheduler_id, &priority );
+
+ if ( sc != RTEMS_SUCCESSFUL ) {
+ return PRIO_INVALID;
+ }
+
+ return priority;
+}
+
rtems_task_priority SetPriority( rtems_id id, rtems_task_priority priority )
{
rtems_status_code sc;
rtems_task_priority previous;
+ previous = PRIO_INVALID;
sc = rtems_task_set_priority( id, priority, &previous );
- T_rsc_success( sc );
+ T_quiet_rsc_success( sc );
return previous;
}
@@ -148,12 +254,293 @@ rtems_task_priority SetSelfPriority( rtems_task_priority priority )
return SetPriority( RTEMS_SELF, priority );
}
+rtems_task_priority SetSelfPriorityNoYield( rtems_task_priority priority )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ /*
+ * If the priority is lowered, then this sequence ensures that we do not
+ * carry out an implicit yield.
+ */
+
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'T', 'E', 'M', 'P' ),
+ 0,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_PRIORITY_CEILING,
+ 1,
+ &id
+ );
+ T_quiet_rsc_success( sc );
+
+ priority = SetSelfPriority( priority );
+ ReleaseMutex( id );
+ DeleteMutex( id );
+
+ return priority;
+}
+
+rtems_id GetScheduler( rtems_id id )
+{
+ rtems_status_code sc;
+ rtems_id scheduler_id;
+
+ scheduler_id = 0xffffffff;
+ sc = rtems_task_get_scheduler( id, &scheduler_id );
+ T_quiet_rsc_success( sc );
+
+ return scheduler_id;
+}
+
+rtems_id GetSelfScheduler( void )
+{
+ return GetScheduler( RTEMS_SELF );
+}
+
+void SetScheduler(
+ rtems_id task_id,
+ rtems_id scheduler_id,
+ rtems_task_priority priority
+)
+{
+ rtems_status_code sc;
+
+ sc = rtems_task_set_scheduler( task_id, scheduler_id, priority );
+ T_quiet_rsc_success( sc );
+}
+
+void SetSelfScheduler( rtems_id scheduler_id, rtems_task_priority priority )
+{
+ SetScheduler( RTEMS_SELF, scheduler_id, priority );
+}
+
+void GetAffinity( rtems_id id, cpu_set_t *set )
+{
+ rtems_status_code sc;
+
+ CPU_ZERO( set );
+ sc = rtems_task_get_affinity( id, sizeof( *set ), set );
+ T_quiet_rsc_success( sc );
+}
+
+void GetSelfAffinity( cpu_set_t *set )
+{
+ GetAffinity( RTEMS_SELF, set );
+}
+
+void SetAffinity( rtems_id id, const cpu_set_t *set )
+{
+ rtems_status_code sc;
+
+ sc = rtems_task_set_affinity( id, sizeof( *set ), set );
+ T_quiet_rsc_success( sc );
+}
+
+void SetSelfAffinity( const cpu_set_t *set )
+{
+ SetAffinity( RTEMS_SELF, set );
+}
+
+void SetAffinityOne( rtems_id id, uint32_t cpu_index )
+{
+ cpu_set_t set;
+
+ CPU_ZERO( &set );
+ CPU_SET( (int) cpu_index, &set );
+ SetAffinity( id, &set );
+}
+
+void SetSelfAffinityOne( uint32_t cpu_index )
+{
+ SetAffinityOne( RTEMS_SELF, cpu_index );
+}
+
+void SetAffinityAll( rtems_id id )
+{
+ cpu_set_t set;
+
+ CPU_FILL( &set );
+ SetAffinity( id, &set );
+}
+
+void SetSelfAffinityAll( void )
+{
+ SetAffinityAll( RTEMS_SELF );
+}
+
+void Yield( void )
+{
+ rtems_status_code sc;
+
+ sc = rtems_task_wake_after( RTEMS_YIELD_PROCESSOR );
+ T_quiet_rsc_success( sc );
+}
+
+void YieldTask( rtems_id id )
+{
+ Thread_Control *the_thread;
+ ISR_lock_Context lock_context;
+ Per_CPU_Control *cpu_self;
+
+ the_thread = _Thread_Get( id, &lock_context );
+
+ if ( the_thread == NULL ) {
+ return;
+ }
+
+ cpu_self = _Thread_Dispatch_disable_critical( &lock_context );
+ _ISR_lock_ISR_enable( &lock_context);
+ _Thread_Yield( the_thread );
+ _Thread_Dispatch_direct( cpu_self );
+}
+
+void AddProcessor( rtems_id scheduler_id, uint32_t cpu_index )
+{
+ rtems_status_code sc;
+
+ sc = rtems_scheduler_add_processor( scheduler_id, cpu_index );
+ T_quiet_rsc_success( sc );
+}
+
+void RemoveProcessor( rtems_id scheduler_id, uint32_t cpu_index )
+{
+ rtems_status_code sc;
+
+ sc = rtems_scheduler_remove_processor( scheduler_id, cpu_index );
+ T_quiet_rsc_success( sc );
+}
+
+rtems_id CreateMutex( void )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ id = INVALID_ID;
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'M', 'U', 'T', 'X' ),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
+ 0,
+ &id
+ );
+ T_rsc_success( sc );
+
+ return id;
+}
+
+rtems_id CreateMutexNoProtocol( void )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ id = INVALID_ID;
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'M', 'U', 'T', 'X' ),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY,
+ 0,
+ &id
+ );
+ T_rsc_success( sc );
+
+ return id;
+}
+
+rtems_id CreateMutexFIFO( void )
+{
+ rtems_status_code sc;
+ rtems_id id;
+
+ id = INVALID_ID;
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'M', 'U', 'T', 'X' ),
+ 1,
+ RTEMS_BINARY_SEMAPHORE | RTEMS_FIFO,
+ 0,
+ &id
+ );
+ T_rsc_success( sc );
+
+ return id;
+}
+
+void DeleteMutex( rtems_id id )
+{
+ if ( id != INVALID_ID ) {
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_delete( id );
+ T_rsc_success( sc );
+ }
+}
+
+bool IsMutexOwner( rtems_id id )
+{
+ Semaphore_Control *the_semaphore;
+ Thread_queue_Context queue_context;
+
+ the_semaphore = _Semaphore_Get( id, &queue_context );
+ if ( the_semaphore == NULL ) {
+ return false;
+ }
+
+ _ISR_lock_ISR_enable( &queue_context.Lock_context.Lock_context );
+ return the_semaphore->Core_control.Wait_queue.Queue.owner ==
+ _Thread_Get_executing();
+}
+
+void ObtainMutex( rtems_id id )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_obtain( id, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
+ T_rsc_success( sc );
+}
+
+void ObtainMutexTimed( rtems_id id, rtems_interval ticks )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_obtain( id, RTEMS_WAIT, ticks );
+ T_rsc_success( sc );
+}
+
+void ObtainMutexDeadlock( rtems_id id )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_obtain( id, RTEMS_WAIT, RTEMS_NO_TIMEOUT );
+ T_rsc( sc, RTEMS_INCORRECT_STATE );
+}
+
+void ReleaseMutex( rtems_id id )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_release( id );
+ T_rsc_success( sc );
+}
+
+Thread_queue_Queue *GetMutexThreadQueue( rtems_id id )
+{
+ Semaphore_Control *the_semaphore;
+ Thread_queue_Context queue_context;
+
+ the_semaphore = _Semaphore_Get( id, &queue_context );
+ if ( the_semaphore == NULL ) {
+ return NULL;
+ }
+
+ _ISR_lock_ISR_enable( &queue_context.Lock_context.Lock_context );
+ return &the_semaphore->Core_control.Wait_queue.Queue;
+}
+
void RestoreRunnerASR( void )
{
rtems_status_code sc;
sc = rtems_signal_catch( NULL, RTEMS_DEFAULT_MODES );
- T_rsc_success( sc );
+ T_quiet_rsc_success( sc );
}
void RestoreRunnerMode( void )
@@ -162,10 +549,485 @@ void RestoreRunnerMode( void )
rtems_mode mode;
sc = rtems_task_mode( RTEMS_DEFAULT_MODES, RTEMS_ALL_MODE_MASKS, &mode );
- T_rsc_success( sc );
+ T_quiet_rsc_success( sc );
}
void RestoreRunnerPriority( void )
{
- SetSelfPriority( PRIO_ULTRA_HIGH );
+ SetSelfPriority( 1 );
+}
+
+void RestoreRunnerScheduler( void )
+{
+ SetSelfScheduler( SCHEDULER_A_ID, 1 );
+}
+
+Thread_Control *GetThread( rtems_id id )
+{
+ Thread_Control *the_thread;
+ ISR_lock_Context lock_context;
+
+ the_thread = _Thread_Get( id, &lock_context );
+
+ if ( the_thread == NULL ) {
+ return NULL;
+ }
+
+ _ISR_lock_ISR_enable( &lock_context);
+ return the_thread;
+}
+
+Thread_Control *GetExecuting( void )
+{
+ return _Thread_Get_executing();
+}
+
+void KillZombies( void )
+{
+ _RTEMS_Lock_allocator();
+ _Thread_Kill_zombies();
+ _RTEMS_Unlock_allocator();
+}
+
+void WaitForExecutionStop( rtems_id task_id )
+{
+#if defined( RTEMS_SMP )
+ Thread_Control *the_thread;
+
+ the_thread = GetThread( task_id );
+ T_assert_not_null( the_thread );
+
+ while ( _Thread_Is_executing_on_a_processor( the_thread ) ) {
+ /* Wait */
+ }
+#else
+ (void) task_id;
+#endif
+}
+
+void WaitForIntendToBlock( rtems_id task_id )
+{
+#if defined( RTEMS_SMP )
+ Thread_Control *the_thread;
+ Thread_Wait_flags intend_to_block;
+
+ the_thread = GetThread( task_id );
+ T_assert_not_null( the_thread );
+
+ intend_to_block = THREAD_WAIT_CLASS_OBJECT |
+ THREAD_WAIT_STATE_INTEND_TO_BLOCK;
+
+ while ( _Thread_Wait_flags_get_acquire( the_thread ) != intend_to_block ) {
+ /* Wait */
+ }
+#else
+ (void) task_id;
+#endif
+}
+
+void WaitForHeir( uint32_t cpu_index, rtems_id task_id )
+{
+ Per_CPU_Control *cpu;
+
+ cpu = _Per_CPU_Get_by_index( cpu_index );
+
+ while ( cpu->heir->Object.id != task_id ) {
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ }
+}
+
+void WaitForNextTask( uint32_t cpu_index, rtems_id task_id )
+{
+ Per_CPU_Control *cpu;
+
+ cpu = _Per_CPU_Get_by_index( cpu_index );
+
+ while ( cpu->heir->Object.id == task_id ) {
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ }
+
+ while ( cpu->thread_dispatch_disable_level != 0 ) {
+ RTEMS_COMPILER_MEMORY_BARRIER();
+ }
+}
+
+void GetTaskTimerInfo( rtems_id id, TaskTimerInfo *info )
+{
+ GetTaskTimerInfoByThread( GetThread( id ), info );
+}
+
+void GetTaskTimerInfoByThread(
+ struct _Thread_Control *thread,
+ TaskTimerInfo *info
+)
+{
+ info->expire_ticks = 0;
+ info->expire_timespec.tv_sec = -1;
+ info->expire_timespec.tv_nsec = -1;
+
+ if ( thread != NULL ) {
+ ISR_lock_Context lock_context;
+ ISR_lock_Context lock_context_2;
+ Per_CPU_Control *cpu;
+
+ _ISR_lock_ISR_disable_and_acquire( &thread->Timer.Lock, &lock_context );
+ info->expire_ticks = thread->Timer.Watchdog.expire;
+#if defined( RTEMS_SMP )
+ cpu = thread->Timer.Watchdog.cpu;
+#else
+ cpu = _Per_CPU_Get();
+#endif
+ _Watchdog_Per_CPU_acquire_critical( cpu, &lock_context_2 );
+
+ if ( _Watchdog_Is_scheduled( &thread->Timer.Watchdog ) ) {
+ const Watchdog_Header *hdr;
+
+ hdr = thread->Timer.header;
+
+ if ( hdr == &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ] ) {
+ info->state = TASK_TIMER_TICKS;
+ } else {
+ _Watchdog_Ticks_to_timespec(
+ info->expire_ticks,
+ &info->expire_timespec
+ );
+
+ if ( hdr == &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ] ) {
+ info->state = TASK_TIMER_REALTIME;
+ } else {
+ T_quiet_eq_ptr(
+ hdr,
+ &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ]
+ );
+ info->state = TASK_TIMER_MONOTONIC;
+ }
+ }
+ } else {
+ info->state = TASK_TIMER_INACTIVE;
+ }
+
+ _Watchdog_Per_CPU_release_critical( cpu, &lock_context_2 );
+ _ISR_lock_Release_and_ISR_enable( &thread->Timer.Lock, &lock_context );
+ } else {
+ info->state = TASK_TIMER_INVALID;
+ }
+}
+
+#if defined( RTEMS_SMP )
+static void DoWatchdogTick( void *arg )
+{
+ (void) arg;
+ _Watchdog_Tick( _Per_CPU_Get() );
+}
+#endif
+
+void ClockTick( void )
+{
+ Per_CPU_Control *cpu_self;
+
+ cpu_self = _Thread_Dispatch_disable();
+#if defined( RTEMS_SMP )
+ DoWatchdogTick( NULL );
+ _SMP_Othercast_action( DoWatchdogTick, NULL );
+#else
+ _Watchdog_Tick( cpu_self );
+#endif
+ _Thread_Dispatch_enable( cpu_self );
+}
+
+static void FinalWatchdogTick( Per_CPU_Control *cpu )
+{
+ ISR_lock_Context lock_context;
+ Watchdog_Header *header;
+ Watchdog_Control *first;
+
+ _ISR_lock_ISR_disable_and_acquire( &cpu->Watchdog.Lock, &lock_context );
+
+ header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_TICKS ];
+ first = _Watchdog_Header_first( header );
+
+ if ( first != NULL ) {
+ _Watchdog_Tickle(
+ header,
+ first,
+ UINT64_MAX,
+ &cpu->Watchdog.Lock,
+ &lock_context
+ );
+ }
+
+ header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_MONOTONIC ];
+ first = _Watchdog_Header_first( header );
+
+ if ( first != NULL ) {
+ _Watchdog_Tickle(
+ header,
+ first,
+ UINT64_MAX,
+ &cpu->Watchdog.Lock,
+ &lock_context
+ );
+ }
+
+ header = &cpu->Watchdog.Header[ PER_CPU_WATCHDOG_REALTIME ];
+ first = _Watchdog_Header_first( header );
+
+ if ( first != NULL ) {
+ _Watchdog_Tickle(
+ header,
+ first,
+ UINT64_MAX,
+ &cpu->Watchdog.Lock,
+ &lock_context
+ );
+ }
+
+ _ISR_lock_Release_and_ISR_enable( &cpu->Watchdog.Lock, &lock_context );
+}
+
+#if defined( RTEMS_SMP )
+static void DoFinalWatchdogTick( void *arg )
+{
+ (void) arg;
+ FinalWatchdogTick( _Per_CPU_Get() );
+}
+#endif
+
+void FinalClockTick( void )
+{
+ Per_CPU_Control *cpu_self;
+
+ cpu_self = _Thread_Dispatch_disable();
+#if defined( RTEMS_SMP )
+ DoFinalWatchdogTick( NULL );
+ _SMP_Othercast_action( DoFinalWatchdogTick, NULL );
+#else
+ FinalWatchdogTick( cpu_self );
+#endif
+ _Thread_Dispatch_enable( cpu_self );
+}
+
+static FatalHandler fatal_handler;
+
+static void *fatal_arg;
+
+void FatalInitialExtension(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code
+)
+{
+ FatalHandler fatal;
+
+ T_quiet_false( always_set_to_false );
+ fatal = fatal_handler;
+
+ if ( fatal != NULL ) {
+ ( *fatal )( source, code, fatal_arg );
+ }
+}
+
+void SetFatalHandler( FatalHandler fatal, void *arg )
+{
+ fatal_handler = fatal;
+ fatal_arg = arg;
+}
+
+static rtems_id task_switch_id;
+
+static rtems_task_switch_extension task_switch_extension;
+
+static void TaskSwitchExtension( rtems_tcb *executing, rtems_tcb *heir )
+{
+ ( *task_switch_extension )( executing, heir );
+}
+
+void SetTaskSwitchExtension( rtems_task_switch_extension task_switch )
+{
+ rtems_task_switch_extension last;
+ rtems_status_code sc;
+
+ last = task_switch_extension;
+
+ if ( task_switch == NULL ) {
+ if ( last != NULL ) {
+ sc = rtems_extension_delete( task_switch_id );
+ T_quiet_rsc_success( sc );
+
+ task_switch_extension = NULL;
+ }
+ } else {
+ task_switch_extension = task_switch;
+
+ if ( last == NULL ) {
+ rtems_extensions_table table = {
+ .thread_switch = TaskSwitchExtension
+ };
+
+ sc = rtems_extension_create(
+ rtems_build_name( 'T', 'S', 'W', 'I' ),
+ &table,
+ &task_switch_id
+ );
+ T_quiet_rsc_success( sc );
+ }
+ }
+}
+
+void ClearExtensionCalls( ExtensionCalls *calls )
+{
+ memset( calls, 0, sizeof( *calls ) );
+}
+
+void CopyExtensionCalls( const ExtensionCalls *from, ExtensionCalls *to )
+{
+ memcpy( to, from, sizeof( *to ) );
+}
+
+#if defined(RTEMS_SMP)
+static volatile bool delay_thread_dispatch;
+
+static void DelayThreadDispatchHandler( void *arg )
+{
+ (void) arg;
+
+ while ( delay_thread_dispatch ) {
+ /* Wait */
+ }
+}
+
+static const Per_CPU_Job_context delay_thread_dispatch_context = {
+ .handler = DelayThreadDispatchHandler
+};
+
+static Per_CPU_Job delay_thread_dispatch_job = {
+ .context = &delay_thread_dispatch_context
+};
+#endif
+
+void StartDelayThreadDispatch( uint32_t cpu_index )
+{
+#if defined(RTEMS_SMP)
+ if ( rtems_configuration_get_maximum_processors() > cpu_index ) {
+ delay_thread_dispatch = true;
+ _Per_CPU_Submit_job(
+ _Per_CPU_Get_by_index( cpu_index ),
+ &delay_thread_dispatch_job
+ );
+ }
+#endif
+}
+
+void StopDelayThreadDispatch( uint32_t cpu_index )
+{
+#if defined(RTEMS_SMP)
+ if ( rtems_configuration_get_maximum_processors() > cpu_index ) {
+ Per_CPU_Control *cpu_self;
+
+ cpu_self = _Thread_Dispatch_disable();
+ delay_thread_dispatch = false;
+ _Per_CPU_Wait_for_job(
+ _Per_CPU_Get_by_index( cpu_index ),
+ &delay_thread_dispatch_job
+ );
+ _Thread_Dispatch_enable( cpu_self );
+ }
+#endif
+}
+
+bool AreInterruptsEnabled( void )
+{
+ return _ISR_Get_level() == 0;
+}
+
+static bool IsWhiteSpace( char c )
+{
+ return c == ' ' || c == '\t';
}
+
+bool IsWhiteSpaceOnly( const char *s )
+{
+ char c;
+
+ while ( ( c = *s ) != '\0' ) {
+ if ( !IsWhiteSpace( c ) ) {
+ return false;
+ }
+
+ ++s;
+ }
+
+ return true;
+}
+
+static const char *EatWhiteSpace( const char *s )
+{
+ char c;
+
+ while ( ( c = *s ) != '\0' ) {
+ if ( !IsWhiteSpace( c ) ) {
+ break;
+ }
+
+ ++s;
+ }
+
+ return s;
+}
+
+bool IsEqualIgnoreWhiteSpace( const char *a, const char *b )
+{
+ while ( true ) {
+ a = EatWhiteSpace( a );
+ b = EatWhiteSpace( b );
+
+ if ( *a != *b ) {
+ return false;
+ }
+
+ if ( *a == '\0' ) {
+ return true;
+ }
+
+ ++a;
+ ++b;
+ }
+
+ return true;
+}
+
+#if defined(RTEMS_SMP)
+bool TicketLockIsAvailable( const SMP_ticket_lock_Control *lock )
+{
+ unsigned int now_serving;
+ unsigned int next_ticket;
+
+ now_serving = _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_RELAXED );
+ next_ticket = _Atomic_Load_uint( &lock->next_ticket, ATOMIC_ORDER_RELAXED );
+
+ return now_serving == next_ticket;
+}
+
+void TicketLockWaitForOwned( const SMP_ticket_lock_Control *lock )
+{
+ while ( TicketLockIsAvailable( lock ) ) {
+ /* Wait */
+ }
+}
+
+void TicketLockWaitForOthers(
+ const SMP_ticket_lock_Control *lock,
+ unsigned int others
+)
+{
+ unsigned int expected;
+ unsigned int actual;
+
+ expected = _Atomic_Load_uint( &lock->now_serving, ATOMIC_ORDER_RELAXED );
+ expected += others + 1;
+
+ do {
+ actual = _Atomic_Load_uint( &lock->next_ticket, ATOMIC_ORDER_RELAXED );
+ } while ( expected != actual );
+}
+#endif
diff --git a/testsuites/validation/tx-support.h b/testsuites/validation/tx-support.h
index b0e466fda1..378bc4c466 100644
--- a/testsuites/validation/tx-support.h
+++ b/testsuites/validation/tx-support.h
@@ -3,14 +3,14 @@
/**
* @file
*
- * @ingroup RTEMSTestSuites
+ * @ingroup RTEMSTestSuitesValidation
*
* @brief This header file provides the support functions for the validation
* test cases.
*/
/*
- * Copyright (C) 2021 embedded brains GmbH (http://www.embedded-brains.de)
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -40,19 +40,21 @@
#include <rtems.h>
#include <rtems/irq-extension.h>
#include <rtems/score/atomic.h>
+#include <rtems/score/threadq.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
- * @addtogroup RTEMSTestSuites
+ * @addtogroup RTEMSTestSuitesValidation
*
* @{
*/
typedef enum {
PRIO_PSEUDO_ISR,
+ PRIO_VERY_ULTRA_HIGH,
PRIO_ULTRA_HIGH,
PRIO_VERY_HIGH,
PRIO_HIGH,
@@ -63,24 +65,84 @@ typedef enum {
} Priority;
/**
+ * @brief This constants represents the default priority of the runner task.
+ */
+#define PRIO_DEFAULT 1
+
+/**
+ * @brief This constants represents an invalid RTEMS task priority value.
+ *
+ * It should be an invalid priority value which is not equal to
+ * RTEMS_CURRENT_PRIORITY and RTEMS_TIMER_SERVER_DEFAULT_PRIORITY.
+ */
+#define PRIO_INVALID 0xfffffffe
+
+/**
+ * @brief This constants represents a priority which is close to the priority
+ * of the idle thread.
+ *
+ * It may be used for the runner thread together with PRIO_FLEXIBLE for worker
+ * threads.
+ */
+#define PRIO_NEARLY_IDLE 126
+
+/**
+ * @brief This constants represents a priority with a wider range of higher and
+ * lower priorities around it.
+ *
+ * It may be used for the worker threads together with PRIO_NEARLY_IDLE for the
+ * runner thread.
+ */
+#define PRIO_FLEXIBLE 64
+
+/**
* @brief This constants represents an invalid RTEMS object identifier.
*/
#define INVALID_ID 0xfffffffd
+/**
+ * @brief This constants represents an object name for tests.
+ */
+#define OBJECT_NAME rtems_build_name( 'T', 'E', 'S', 'T' )
+
#define CreateTask( name, priority ) \
DoCreateTask( \
rtems_build_name( name[ 0 ], name[ 1 ], name[ 2 ], name[ 3 ] ), \
priority \
)
+#define SCHEDULER_A_ID 0xf010001
+
+#define SCHEDULER_B_ID 0xf010002
+
+#define SCHEDULER_C_ID 0xf010003
+
+#define SCHEDULER_D_ID 0xf010004
+
rtems_id DoCreateTask( rtems_name name, rtems_task_priority priority );
void StartTask( rtems_id id, rtems_task_entry entry, void *arg );
void DeleteTask( rtems_id id );
+void SuspendTask( rtems_id id );
+
+void SuspendSelf( void );
+
+void ResumeTask( rtems_id id );
+
+bool IsTaskSuspended( rtems_id id );
+
+rtems_event_set QueryPendingEvents( void );
+
+rtems_event_set PollAnyEvents( void );
+
rtems_event_set ReceiveAnyEvents( void );
+rtems_event_set ReceiveAnyEventsTimed( rtems_interval ticks );
+
+void ReceiveAllEvents( rtems_event_set events );
+
void SendEvents( rtems_id id, rtems_event_set events );
rtems_mode GetMode( void );
@@ -89,18 +151,232 @@ rtems_mode SetMode( rtems_mode set, rtems_mode mask );
rtems_task_priority GetPriority( rtems_id id );
+rtems_task_priority GetPriorityByScheduler(
+ rtems_id task_id,
+ rtems_id scheduler_id
+);
+
rtems_task_priority SetPriority( rtems_id id, rtems_task_priority priority );
rtems_task_priority GetSelfPriority( void );
rtems_task_priority SetSelfPriority( rtems_task_priority priority );
+rtems_task_priority SetSelfPriorityNoYield( rtems_task_priority priority );
+
+rtems_id GetScheduler( rtems_id id );
+
+rtems_id GetSelfScheduler( void );
+
+void SetScheduler(
+ rtems_id task_id,
+ rtems_id scheduler_id,
+ rtems_task_priority priority
+);
+
+void SetSelfScheduler( rtems_id scheduler_id, rtems_task_priority priority );
+
+void GetAffinity( rtems_id id, cpu_set_t *set );
+
+void GetSelfAffinity( cpu_set_t *set );
+
+void SetAffinity( rtems_id id, const cpu_set_t *set );
+
+void SetSelfAffinity( const cpu_set_t *set );
+
+void SetAffinityOne( rtems_id id, uint32_t cpu_index );
+
+void SetSelfAffinityOne( uint32_t cpu_index );
+
+void SetAffinityAll( rtems_id id );
+
+void SetSelfAffinityAll( void );
+
+void Yield( void );
+
+void YieldTask( rtems_id id );
+
+void AddProcessor( rtems_id scheduler_id, uint32_t cpu_index );
+
+void RemoveProcessor( rtems_id scheduler_id, uint32_t cpu_index );
+
+rtems_id CreateMutex( void );
+
+rtems_id CreateMutexNoProtocol( void );
+
+rtems_id CreateMutexFIFO( void );
+
+bool IsMutexOwner( rtems_id id );
+
+void DeleteMutex( rtems_id id );
+
+void ObtainMutex( rtems_id id );
+
+void ObtainMutexTimed( rtems_id id, rtems_interval ticks );
+
+void ObtainMutexDeadlock( rtems_id id );
+
+void ReleaseMutex( rtems_id id );
+
+struct Thread_queue_Queue;
+
+struct Thread_queue_Queue *GetMutexThreadQueue( rtems_id id );
+
void RestoreRunnerASR( void );
void RestoreRunnerMode( void );
void RestoreRunnerPriority( void );
+void RestoreRunnerScheduler( void );
+
+struct _Thread_Control;
+
+struct _Thread_Control *GetThread( rtems_id id );
+
+struct _Thread_Control *GetExecuting( void );
+
+void KillZombies( void );
+
+void WaitForExecutionStop( rtems_id task_id );
+
+void WaitForIntendToBlock( rtems_id task_id );
+
+void WaitForHeir( uint32_t cpu_index, rtems_id task_id );
+
+void WaitForNextTask( uint32_t cpu_index, rtems_id task_id );
+
+typedef enum {
+ TASK_TIMER_INVALID,
+ TASK_TIMER_INACTIVE,
+ TASK_TIMER_TICKS,
+ TASK_TIMER_REALTIME,
+ TASK_TIMER_MONOTONIC
+} TaskTimerState;
+
+typedef struct {
+ TaskTimerState state;
+ uint64_t expire_ticks;
+ struct timespec expire_timespec;
+} TaskTimerInfo;
+
+void GetTaskTimerInfo( rtems_id id, TaskTimerInfo *info );
+
+void GetTaskTimerInfoByThread(
+ struct _Thread_Control *thread,
+ TaskTimerInfo *info
+);
+
+void ClockTick( void );
+
+/**
+ * @brief Simulates a clock tick with the final expire time point of
+ * UINT64_MAX for all clocks.
+ *
+ * This function does not update the clock ticks counter.
+ */
+void FinalClockTick( void );
+
+/**
+ * @brief Simulates a single clock tick using the software timecounter.
+ *
+ * In contrast to ClockTick(), this function updates also CLOCK_MONOTONIC and
+ * CLOCK_REALTIME to the next software timecounter clock tick time point.
+ *
+ * This function is designed for test suites not having a clock driver.
+ */
+void TimecounterTick( void );
+
+typedef uint32_t ( *GetTimecountHandler )( void );
+
+/**
+ * @brief Sets the get timecount handler.
+ *
+ * Using this function will replace the timecounter of the clock driver.
+ *
+ * @return Returns the previous get timecount handler.
+ */
+GetTimecountHandler SetGetTimecountHandler( GetTimecountHandler handler );
+
+/**
+ * @brief This constant represents the fake frequency of the software
+ * timecounter.
+ */
+#define SOFTWARE_TIMECOUNTER_FREQUENCY 1000000
+
+/**
+ * @brief Gets the software timecount counter value.
+ *
+ * @return Returns the current software timecounter counter value.
+ */
+uint32_t GetTimecountCounter( void );
+
+/**
+ * @brief Sets and gets the software timecount counter value.
+ *
+ * @param counter is the new software timecounter counter value.
+ *
+ * @return Returns the previous software timecounter counter value.
+ */
+uint32_t SetTimecountCounter( uint32_t counter );
+
+/**
+ * @brief Return the task id of the timer server task
+ *
+ * This function is an attempt to avoid using RTEMS internal global
+ * _Timer_server throughout the validation test code.
+ *
+ * @return Returns the task id of the timer server task, if
+ * rtems_timer_initiate_server() has been invoked before,
+ * otherwise - if the timer server task does not exist -
+ * RTEMS_INVALID_ID is returned.
+ */
+rtems_id GetTimerServerTaskId( void );
+
+/**
+ * @brief Undo the effects of rtems_timer_initiate_server()
+ *
+ * If rtems_timer_initiate_server() was never called before,
+ * nothing is done.
+ *
+ * If rtems_timer_initiate_server() was called before, the
+ * created thread and other resources are freed so that
+ * rtems_timer_initiate_server() can be called again.
+ * There should be no pending timers which are not yet executed
+ * by the server task. Naturally, there should be no
+ * timer server timers scheduled for execution.
+ *
+ * @return Returns true, if rtems_timer_initiate_server() has been
+ * invoked before and the timer server task has indeed been deleted,
+ * otherwise false.
+ */
+bool DeleteTimerServer( void );
+
+typedef struct {
+ struct {
+ const void *begin;
+ void *free_begin;
+ const void *end;
+ } areas[ 2 ];
+ size_t count;
+} MemoryContext;
+
+void MemorySave( MemoryContext *ctx );
+
+void MemoryRestore( const MemoryContext *ctx );
+
+/**
+ * @brief Fails a dynamic memory allocation when the counter reaches zero.
+ *
+ * This function initializes an internal counter which is decremented before
+ * each dynamic memory allocation though the rtems_malloc() directive. When
+ * the counter decrements from one to zero, the allocation fails and NULL will
+ * be returned.
+ *
+ * @param counter is the initial counter value.
+ */
+void MemoryAllocationFailWhen( uint32_t counter );
+
typedef struct {
Chain_Node node;
void ( *handler )( void * );
@@ -114,14 +390,229 @@ void CallWithinISRSubmit( CallWithinISRRequest *request );
void CallWithinISRWait( const CallWithinISRRequest *request );
+void CallWithinISRRaise( void );
+
+void CallWithinISRClear( void );
+
+rtems_vector_number CallWithinISRGetVector( void );
+
+rtems_vector_number GetSoftwareInterruptVector( void );
+
+typedef struct {
+ Thread_queue_Operations tq_ops;
+ const Thread_queue_Operations *wrapped_ops;
+ Thread_queue_Control thread_queue;
+ CallWithinISRRequest isr_request;
+} WrapThreadQueueContext;
+
+void WrapThreadQueueInitialize(
+ WrapThreadQueueContext *ctx,
+ void ( *handler )( void * ),
+ void *arg
+);
+
+void WrapThreadQueueExtract(
+ WrapThreadQueueContext *ctx,
+ struct _Thread_Control *thread
+);
+
+void WrapThreadQueueExtractDirect(
+ WrapThreadQueueContext *ctx,
+ Thread_Control *thread
+);
+
+void WrapThreadQueueDestroy( WrapThreadQueueContext *ctx );
+
+struct Per_CPU_Control;
+
+void SetPreemptionIntervention(
+ struct Per_CPU_Control *cpu,
+ void ( *handler )( void * ),
+ void *arg
+);
+
rtems_vector_number GetValidInterruptVectorNumber(
const rtems_interrupt_attributes *required
);
-rtems_vector_number GetTestableInterruptVector( void );
+rtems_vector_number GetTestableInterruptVector(
+ const rtems_interrupt_attributes *required
+);
+
+rtems_status_code RaiseSoftwareInterrupt( rtems_vector_number vector );
+
+rtems_status_code ClearSoftwareInterrupt( rtems_vector_number vector );
bool HasInterruptVectorEntriesInstalled( rtems_vector_number vector );
+/**
+ * @brief Get the clock and context of a timer from RTEMS internal data.
+ *
+ * With exception of TIMER_DORMANT, the return values are bits or-ed together.
+ *
+ * @param id The timer ID.
+ *
+ * @retval TIMER_DORMANT Either the id argument is invalid or the timer has
+ * never been used before.
+ * @return The TIMER_CLASS_BIT_ON_TASK is set, if the timer server routine
+ * was or will be executed in task context, otherwise it was or will be
+ * executed in interrupt context.
+ *
+ * The TIMER_CLASS_BIT_TIME_OF_DAY is set, if the clock used is or was the
+ * ${/glossary/clock-realtime:/term}, otherwise the
+ * ${/glossary/clock-tick:/term} based clock is or was used.
+ */
+Timer_Classes GetTimerClass( rtems_id id );
+
+/**
+ * @brief This structure provides data used by RTEMS to schedule a timer
+ * service routine.
+ */
+typedef struct {
+ /**
+ * @brief This member contains a reference to the timer service routine.
+ */
+ rtems_timer_service_routine_entry routine;
+ /**
+ * @brief This member contains a reference to the user data to be provided
+ * to the timer service routine.
+ */
+ void *user_data;
+ /**
+ * @brief This member contains the timer interval in ticks or seconds.
+ */
+ Watchdog_Interval interval;
+} Timer_Scheduling_Data;
+
+/**
+ * @brief Get data related to scheduling a timer service routine
+ * from RTEMS internal structures.
+ *
+ * @param id The timer ID.
+ * @param[out] data If the reference is not NULL, the data retrieved from
+ * internal RTEMS structures is stored here.
+ */
+void GetTimerSchedulingData(
+ rtems_id id,
+ Timer_Scheduling_Data *data
+);
+
+/**
+ * @brief The various states of a timer.
+ */
+typedef enum {
+ TIMER_INVALID,
+ TIMER_INACTIVE,
+ TIMER_SCHEDULED,
+ TIMER_PENDING
+} Timer_States;
+
+/**
+ * @brief Get the state of a timer from RTEMS internal data.
+ *
+ * @param id The timer ID.
+ *
+ * @retval TIMER_INVALID The id argument is invalid.
+ * @retval TIMER_INACTIVE The timer is not scheduled (i.e. it is
+ * new, run off, or canceled).
+ * @retval TIMER_SCHEDULED The timer is scheduled.
+ * @retval TIMER_PENDING The timer is pending.
+ */
+Timer_States GetTimerState( rtems_id id );
+
+/**
+ * @brief Mark the realtime clock as never set.
+ *
+ * This function manipulates RTEMS internal data structures to undo the
+ * effect of rtems_clock_set(). If the clock is not set, the function has no
+ * effect.
+ */
+void UnsetClock( void );
+
+void FatalInitialExtension(
+ rtems_fatal_source source,
+ bool always_set_to_false,
+ rtems_fatal_code code
+);
+
+typedef void ( *FatalHandler )(
+ rtems_fatal_source source,
+ rtems_fatal_code code,
+ void *arg
+);
+
+void SetFatalHandler( FatalHandler fatal, void *arg );
+
+void SetTaskSwitchExtension( rtems_task_switch_extension task_switch );
+
+typedef struct {
+ uint32_t fatal;
+ uint32_t thread_begin;
+ uint32_t thread_create;
+ uint32_t thread_delete;
+ uint32_t thread_exitted;
+ uint32_t thread_restart;
+ uint32_t thread_start;
+ uint32_t thread_switch;
+ uint32_t thread_terminate;
+} ExtensionCalls;
+
+void ClearExtensionCalls( ExtensionCalls *calls );
+
+void CopyExtensionCalls( const ExtensionCalls *from, ExtensionCalls *to );
+
+void SetIORelaxHandler( void ( *handler )( void * ), void *arg );
+
+void StartDelayThreadDispatch( uint32_t cpu_index );
+
+void StopDelayThreadDispatch( uint32_t cpu_index );
+
+bool AreInterruptsEnabled( void );
+
+bool IsWhiteSpaceOnly( const char *s );
+
+bool IsEqualIgnoreWhiteSpace( const char *a, const char *b );
+
+#if defined(RTEMS_SMP)
+bool TicketLockIsAvailable( const SMP_ticket_lock_Control *lock );
+
+void TicketLockWaitForOwned( const SMP_ticket_lock_Control *lock );
+
+void TicketLockWaitForOthers(
+ const SMP_ticket_lock_Control *lock,
+ unsigned int others
+);
+
+static inline bool ISRLockIsAvailable( const ISR_lock_Control *lock )
+{
+ return TicketLockIsAvailable( &lock->Lock.Ticket_lock );
+}
+
+static inline void ISRLockWaitForOwned( const ISR_lock_Control *lock )
+{
+ TicketLockWaitForOwned( &lock->Lock.Ticket_lock );
+}
+
+static inline void ISRLockWaitForOthers(
+ const ISR_lock_Control *lock,
+ unsigned int others
+)
+{
+ TicketLockWaitForOthers( &lock->Lock.Ticket_lock, others );
+}
+#endif
+
+void *IdleBody( uintptr_t ignored );
+
+/**
+ * @brief This task configurations may be used to construct a task during
+ * tests.
+ *
+ * Only one task shall use this configuration at a time, otherwise two tasks
+ * would share a stack.
+ */
+extern const rtems_task_config DefaultTaskConfig;
+
/** @} */
#ifdef __cplusplus
diff --git a/testsuites/validation/tx-thread-queue.c b/testsuites/validation/tx-thread-queue.c
new file mode 100644
index 0000000000..ee9d2cf96d
--- /dev/null
+++ b/testsuites/validation/tx-thread-queue.c
@@ -0,0 +1,858 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This source file contains the implementation of the thread queue test
+ * support.
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tx-thread-queue.h"
+#include "tx-support.h"
+#include "ts-config.h"
+
+#include <rtems/score/threadimpl.h>
+#include <rtems/rtems/semimpl.h>
+
+void TQSend(
+ TQContext *ctx,
+ TQWorkerKind worker,
+ rtems_event_set events
+)
+{
+#if defined( RTEMS_SMP )
+ ctx->event_received[ worker ] = false;
+#endif
+
+ SendEvents( ctx->worker_id[ worker ], events );
+}
+
+void TQWaitForEventsReceived( const TQContext *ctx, TQWorkerKind worker )
+{
+#if defined( RTEMS_SMP )
+ while ( !ctx->event_received[ worker ] ) {
+ /* Wait */
+ }
+#endif
+}
+
+void TQWaitForExecutionStop( const TQContext *ctx, TQWorkerKind worker )
+{
+#if defined( RTEMS_SMP )
+ WaitForExecutionStop( ctx->worker_id[ worker ] );
+#endif
+}
+
+void TQSendAndWaitForExecutionStop(
+ TQContext *ctx,
+ TQWorkerKind worker,
+ rtems_event_set events
+)
+{
+ TQSend( ctx, worker, events );
+
+#if defined( RTEMS_SMP )
+ TQWaitForEventsReceived( ctx, worker );
+ WaitForExecutionStop( ctx->worker_id[ worker ] );
+#endif
+}
+
+void TQWaitForIntendToBlock( const TQContext *ctx, TQWorkerKind worker )
+{
+ const rtems_tcb *thread;
+ Thread_Wait_flags intend_to_block;
+
+ thread = ctx->worker_tcb[ worker ];
+ intend_to_block = THREAD_WAIT_CLASS_OBJECT |
+ THREAD_WAIT_STATE_INTEND_TO_BLOCK;
+
+ while ( _Thread_Wait_flags_get_acquire( thread ) != intend_to_block ) {
+ /* Wait */
+ }
+}
+
+void TQSendAndWaitForIntendToBlock(
+ TQContext *ctx,
+ TQWorkerKind worker,
+ rtems_event_set events
+)
+{
+ TQSend( ctx, worker, events );
+
+#if defined( RTEMS_SMP )
+ TQWaitForEventsReceived( ctx, worker );
+ TQWaitForIntendToBlock( ctx, worker );
+#endif
+}
+
+void TQSendAndWaitForExecutionStopOrIntendToBlock(
+ TQContext *ctx,
+ TQWorkerKind worker,
+ rtems_event_set events
+)
+{
+#if defined( RTEMS_SMP )
+ const rtems_tcb *thread;
+ Thread_Wait_flags intend_to_block;
+#endif
+
+ TQSend( ctx, worker, events );
+
+#if defined( RTEMS_SMP )
+ TQWaitForEventsReceived( ctx, worker );
+ thread = ctx->worker_tcb[ worker ];
+ intend_to_block = THREAD_WAIT_CLASS_OBJECT |
+ THREAD_WAIT_STATE_INTEND_TO_BLOCK;
+
+ while (
+ _Thread_Is_executing_on_a_processor( thread ) &&
+ _Thread_Wait_flags_get_acquire( thread ) != intend_to_block
+ ) {
+ /* Wait */
+ }
+#endif
+}
+
+void TQSendAndSynchronizeRunner(
+ TQContext *ctx,
+ TQWorkerKind worker,
+ rtems_event_set events
+)
+{
+ T_quiet_eq_u32( QueryPendingEvents() & TQ_EVENT_RUNNER_SYNC, 0 );
+ TQSend( ctx, worker, events | TQ_EVENT_RUNNER_SYNC );
+ TQSynchronizeRunner();
+}
+
+void TQClearDone( TQContext *ctx, TQWorkerKind worker )
+{
+ ctx->done[ worker ] = false;
+}
+
+void TQWaitForDone( const TQContext *ctx, TQWorkerKind worker )
+{
+ while ( !ctx->done[ worker ] ) {
+ /* Wait */
+ }
+}
+
+void TQSynchronizeRunner( void )
+{
+ ReceiveAllEvents( TQ_EVENT_RUNNER_SYNC );
+}
+
+void TQSynchronizeRunner2( void )
+{
+ ReceiveAllEvents( TQ_EVENT_RUNNER_SYNC | TQ_EVENT_RUNNER_SYNC_2 );
+}
+
+void TQResetCounter( TQContext *ctx )
+{
+ ctx->counter = 0;
+ memset( &ctx->worker_counter, 0, sizeof( ctx->worker_counter ) );
+}
+
+uint32_t TQGetCounter( const TQContext *ctx )
+{
+ return ctx->counter;
+}
+
+uint32_t TQGetWorkerCounter( const TQContext *ctx, TQWorkerKind worker )
+{
+ return ctx->worker_counter[ worker ];
+}
+
+void TQMutexObtain( const TQContext *ctx, TQMutex mutex )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_obtain(
+ ctx->mutex_id[ mutex ],
+ RTEMS_WAIT,
+ RTEMS_NO_TIMEOUT
+ );
+ T_rsc_success( sc );
+}
+
+void TQMutexRelease( const TQContext *ctx, TQMutex mutex )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_release( ctx->mutex_id[ mutex ] );
+ T_rsc_success( sc );
+}
+
+void TQSetPriority(
+ const TQContext *ctx,
+ TQWorkerKind worker,
+ Priority priority
+)
+{
+ SetPriority( ctx->worker_id[ worker ], priority );
+}
+
+Priority TQGetPriority( const TQContext *ctx, TQWorkerKind worker )
+{
+ return GetPriority( ctx->worker_id[ worker ] );
+}
+
+void TQSetScheduler(
+ const TQContext *ctx,
+ TQWorkerKind worker,
+ rtems_id scheduler_id,
+ Priority priority
+)
+{
+#if defined( RTEMS_SMP )
+ rtems_status_code sc;
+
+ sc = rtems_task_set_scheduler(
+ ctx->worker_id[ worker ],
+ scheduler_id,
+ priority
+ );
+ T_rsc_success( sc );
+#else
+ (void) scheduler_id;
+ SetPriority( ctx->worker_id[ worker ], priority );
+#endif
+}
+
+static void Count( TQContext *ctx, TQWorkerKind worker )
+{
+ unsigned int counter;
+
+ counter = _Atomic_Fetch_add_uint( &ctx->counter, 1, ATOMIC_ORDER_RELAXED );
+ ctx->worker_counter[ worker ] = counter + 1;
+}
+
+static void Enqueue( TQContext *ctx, TQWorkerKind worker, TQWait wait )
+{
+ ctx->status[ worker ] = TQEnqueue( ctx, wait );
+ Count( ctx, worker );
+}
+
+static void ThreadQueueDeadlock(
+ rtems_fatal_source source,
+ rtems_fatal_code code,
+ void *arg
+)
+{
+ TQContext *ctx;
+
+ ctx = arg;
+ T_eq_int( source, INTERNAL_ERROR_CORE );
+ T_eq_int( code, INTERNAL_ERROR_THREAD_QUEUE_DEADLOCK );
+ SetFatalHandler( NULL, NULL );
+ longjmp( ctx->before_enqueue, 1 );
+}
+
+static void Worker( rtems_task_argument arg, TQWorkerKind worker )
+{
+ TQContext *ctx;
+
+ ctx = (TQContext *) arg;
+
+ while ( true ) {
+ rtems_event_set events;
+
+ events = ReceiveAnyEvents();
+ ctx->event_received[ worker ] = true;
+
+ if ( ( events & TQ_EVENT_HELPER_A_SYNC ) != 0 ) {
+ SendEvents( ctx->worker_id[ TQ_HELPER_A ], TQ_EVENT_RUNNER_SYNC );
+ }
+
+ if ( ( events & TQ_EVENT_HELPER_B_SYNC ) != 0 ) {
+ SendEvents( ctx->worker_id[ TQ_HELPER_B ], TQ_EVENT_RUNNER_SYNC );
+ }
+
+ if ( ( events & TQ_EVENT_SCHEDULER_RECORD_START ) != 0 ) {
+ TQSchedulerRecordStart( ctx );
+ }
+
+ if ( ( events & TQ_EVENT_ENQUEUE_PREPARE ) != 0 ) {
+ TQEnqueuePrepare( ctx );
+ }
+
+ if ( ( events & TQ_EVENT_ENQUEUE ) != 0 ) {
+ Enqueue( ctx, worker, ctx->wait );
+ }
+
+ if ( ( events & TQ_EVENT_ENQUEUE_TIMED ) != 0 ) {
+ Enqueue( ctx, worker, TQ_WAIT_TIMED );
+ }
+
+ if ( ( events & TQ_EVENT_ENQUEUE_FATAL ) != 0 ) {
+ SetFatalHandler( ThreadQueueDeadlock, ctx );
+
+ if ( setjmp( ctx->before_enqueue ) == 0 ) {
+ ctx->status[ worker ] = STATUS_MINUS_ONE;
+ Enqueue( ctx, worker, ctx->wait );
+ } else {
+ ctx->status[ worker ] = STATUS_DEADLOCK;
+ }
+ }
+
+ if ( ( events & TQ_EVENT_TIMEOUT ) != 0 ) {
+ Per_CPU_Control *cpu_self;
+
+ cpu_self = _Thread_Dispatch_disable();
+ _Thread_Timeout( &ctx->worker_tcb[ worker ]->Timer.Watchdog );
+ _Thread_Dispatch_direct( cpu_self );
+ }
+
+ if ( ( events & TQ_EVENT_FLUSH_ALL ) != 0 ) {
+ TQFlush( ctx, true );
+ }
+
+ if ( ( events & TQ_EVENT_FLUSH_PARTIAL ) != 0 ) {
+ TQFlush( ctx, false );
+ }
+
+ if ( ( events & TQ_EVENT_ENQUEUE_DONE ) != 0 ) {
+ TQEnqueueDone( ctx );
+ }
+
+ if ( ( events & TQ_EVENT_SURRENDER ) != 0 ) {
+ Status_Control status;
+
+ status = TQSurrender( ctx );
+ T_eq_int( status, TQConvertStatus( ctx, STATUS_SUCCESSFUL ) );
+ }
+
+ if ( ( events & TQ_EVENT_MUTEX_A_OBTAIN ) != 0 ) {
+ TQMutexObtain( ctx, TQ_MUTEX_A );
+ }
+
+ if ( ( events & TQ_EVENT_MUTEX_A_RELEASE ) != 0 ) {
+ TQMutexRelease( ctx, TQ_MUTEX_A );
+ }
+
+ if ( ( events & TQ_EVENT_MUTEX_B_OBTAIN ) != 0 ) {
+ TQMutexObtain( ctx, TQ_MUTEX_B );
+ }
+
+ if ( ( events & TQ_EVENT_MUTEX_B_RELEASE ) != 0 ) {
+ TQMutexRelease( ctx, TQ_MUTEX_B );
+ }
+
+ if ( ( events & TQ_EVENT_MUTEX_C_OBTAIN ) != 0 ) {
+ TQMutexObtain( ctx, TQ_MUTEX_C );
+ }
+
+ if ( ( events & TQ_EVENT_MUTEX_C_RELEASE ) != 0 ) {
+ TQMutexRelease( ctx, TQ_MUTEX_C );
+ }
+
+ if ( ( events & TQ_EVENT_MUTEX_D_OBTAIN ) != 0 ) {
+ TQMutexObtain( ctx, TQ_MUTEX_D );
+ }
+
+ if ( ( events & TQ_EVENT_MUTEX_D_RELEASE ) != 0 ) {
+ TQMutexRelease( ctx, TQ_MUTEX_D );
+ }
+
+ if ( ( events & TQ_EVENT_MUTEX_NO_PROTOCOL_OBTAIN ) != 0 ) {
+ TQMutexObtain( ctx, TQ_MUTEX_NO_PROTOCOL );
+ }
+
+ if ( ( events & TQ_EVENT_MUTEX_NO_PROTOCOL_RELEASE ) != 0 ) {
+ TQMutexRelease( ctx, TQ_MUTEX_NO_PROTOCOL );
+ }
+
+ if ( ( events & TQ_EVENT_MUTEX_FIFO_OBTAIN ) != 0 ) {
+ TQMutexObtain( ctx, TQ_MUTEX_FIFO );
+ }
+
+ if ( ( events & TQ_EVENT_MUTEX_FIFO_RELEASE ) != 0 ) {
+ TQMutexRelease( ctx, TQ_MUTEX_FIFO );
+ }
+
+ if ( ( events & TQ_EVENT_PIN ) != 0 ) {
+ _Thread_Pin( _Thread_Get_executing() );
+ }
+
+ if ( ( events & TQ_EVENT_UNPIN ) != 0 ) {
+ Per_CPU_Control *cpu_self;
+
+ cpu_self = _Thread_Dispatch_disable();
+ _Thread_Unpin( _Thread_Get_executing(), cpu_self );
+ _Thread_Dispatch_direct( cpu_self );
+ }
+
+ if ( ( events & TQ_EVENT_SCHEDULER_RECORD_STOP ) != 0 ) {
+ TQSchedulerRecordStop( ctx );
+ }
+
+ if ( ( events & TQ_EVENT_RUNNER_SYNC ) != 0 ) {
+ SendEvents( ctx->runner_id, TQ_EVENT_RUNNER_SYNC );
+ }
+
+ if ( ( events & TQ_EVENT_COUNT ) != 0 ) {
+ Count( ctx, worker );
+ }
+
+ if ( ( events & TQ_EVENT_BUSY_WAIT ) != 0 ) {
+ while ( ctx->busy_wait[ worker ] ) {
+ /* Wait */
+ }
+ }
+
+ if ( ( events & TQ_EVENT_RUNNER_SYNC_2 ) != 0 ) {
+ SendEvents( ctx->runner_id, TQ_EVENT_RUNNER_SYNC_2 );
+ }
+
+ ctx->done[ worker ] = true;
+ }
+}
+
+static void BlockerA( rtems_task_argument arg )
+{
+ Worker( arg, TQ_BLOCKER_A );
+}
+
+static void BlockerB( rtems_task_argument arg )
+{
+ Worker( arg, TQ_BLOCKER_B );
+}
+
+static void BlockerC( rtems_task_argument arg )
+{
+ Worker( arg, TQ_BLOCKER_C );
+}
+
+static void BlockerD( rtems_task_argument arg )
+{
+ Worker( arg, TQ_BLOCKER_D );
+}
+
+static void BlockerE( rtems_task_argument arg )
+{
+ Worker( arg, TQ_BLOCKER_E );
+}
+
+static void WorkerF( rtems_task_argument arg )
+{
+ Worker( arg, TQ_WORKER_F );
+}
+
+static void HelperA( rtems_task_argument arg )
+{
+ Worker( arg, TQ_HELPER_A );
+}
+
+static void HelperB( rtems_task_argument arg )
+{
+ Worker( arg, TQ_HELPER_B );
+}
+
+static void HelperC( rtems_task_argument arg )
+{
+ Worker( arg, TQ_HELPER_C );
+}
+
+void TQInitialize( TQContext *ctx )
+{
+ rtems_status_code sc;
+ size_t i;
+
+ ctx->runner_id = rtems_task_self();
+ ctx->runner_tcb = GetThread( RTEMS_SELF );
+
+ /*
+ * Use a lower priority than all started worker tasks to make sure they wait
+ * for events.
+ */
+ SetSelfPriority( PRIO_VERY_LOW );
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->mutex_id ); ++i ) {
+ rtems_attribute attributes;
+
+ attributes = RTEMS_BINARY_SEMAPHORE;
+
+ if ( i == TQ_MUTEX_NO_PROTOCOL ) {
+ attributes |= RTEMS_PRIORITY;
+ } else if ( i == TQ_MUTEX_FIFO ) {
+ attributes |= RTEMS_FIFO;
+ } else {
+ attributes |= RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY;
+ }
+
+ sc = rtems_semaphore_create(
+ rtems_build_name( 'M', 'T', 'X', 'A' + i ),
+ 1,
+ attributes,
+ 0,
+ &ctx->mutex_id[ i ]
+ );
+ T_rsc_success( sc );
+ }
+
+ ctx->worker_id[ TQ_BLOCKER_A ] = CreateTask( "BLKA", PRIO_HIGH );
+ StartTask( ctx->worker_id[ TQ_BLOCKER_A ], BlockerA, ctx );
+ ctx->worker_id[ TQ_BLOCKER_B ] = CreateTask( "BLKB", PRIO_VERY_HIGH );
+ StartTask( ctx->worker_id[ TQ_BLOCKER_B ], BlockerB, ctx );
+ ctx->worker_id[ TQ_BLOCKER_C ] = CreateTask( "BLKC", PRIO_ULTRA_HIGH );
+ StartTask( ctx->worker_id[ TQ_BLOCKER_C ], BlockerC, ctx );
+ ctx->worker_id[ TQ_BLOCKER_D ] = CreateTask( "BLKD", PRIO_LOW );
+ StartTask( ctx->worker_id[ TQ_BLOCKER_D ], BlockerD, ctx );
+ ctx->worker_id[ TQ_BLOCKER_E ] = CreateTask( "BLKE", PRIO_LOW );
+ StartTask( ctx->worker_id[ TQ_BLOCKER_E ], BlockerE, ctx );
+ ctx->worker_id[ TQ_WORKER_F ] = CreateTask( "WRKF", PRIO_LOW );
+ StartTask( ctx->worker_id[ TQ_WORKER_F ], WorkerF, ctx );
+ ctx->worker_id[ TQ_HELPER_A ] = CreateTask( "HLPA", PRIO_LOW );
+ StartTask( ctx->worker_id[ TQ_HELPER_A ], HelperA, ctx );
+ ctx->worker_id[ TQ_HELPER_B ] = CreateTask( "HLPB", PRIO_LOW );
+ StartTask( ctx->worker_id[ TQ_HELPER_B ], HelperB, ctx );
+ ctx->worker_id[ TQ_HELPER_C ] = CreateTask( "HLPC", PRIO_LOW );
+ StartTask( ctx->worker_id[ TQ_HELPER_C ], HelperC, ctx );
+
+ for (i = 0; i < RTEMS_ARRAY_SIZE( ctx->worker_tcb ); ++i) {
+ ctx->worker_tcb[ i ] = GetThread( ctx->worker_id[ i ] );
+ }
+
+ SetSelfPriority( PRIO_NORMAL );
+}
+
+void TQDestroy( TQContext *ctx )
+{
+ size_t i;
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->worker_id ); ++i ) {
+ DeleteTask( ctx->worker_id[ i ] );
+ }
+
+ for ( i = 0; i < RTEMS_ARRAY_SIZE( ctx->mutex_id ); ++i ) {
+ if ( ctx->mutex_id[ i ] != 0 ) {
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_delete( ctx->mutex_id[ i ] );
+ T_rsc_success( sc );
+ }
+ }
+
+ RestoreRunnerPriority();
+}
+
+void TQReset( TQContext *ctx )
+{
+ rtems_id scheduler_id;
+
+ scheduler_id = SCHEDULER_A_ID;
+ SetScheduler( ctx->runner_id, scheduler_id, PRIO_NORMAL );
+ TQSetScheduler( ctx, TQ_BLOCKER_A, scheduler_id, PRIO_HIGH );
+ TQSetScheduler( ctx, TQ_BLOCKER_B, scheduler_id, PRIO_VERY_HIGH );
+ TQSetScheduler( ctx, TQ_BLOCKER_C, scheduler_id, PRIO_ULTRA_HIGH );
+ TQSetScheduler( ctx, TQ_BLOCKER_D, scheduler_id, PRIO_LOW );
+ TQSetScheduler( ctx, TQ_BLOCKER_E, scheduler_id, PRIO_LOW );
+ TQSetScheduler( ctx, TQ_HELPER_A, scheduler_id, PRIO_LOW );
+ TQSetScheduler( ctx, TQ_HELPER_B, scheduler_id, PRIO_LOW );
+ TQSetScheduler( ctx, TQ_HELPER_C, scheduler_id, PRIO_LOW );
+}
+
+void TQSortMutexesByID( TQContext *ctx )
+{
+ size_t i;
+ size_t n;
+
+ n = 3;
+
+ /* Bubble sort */
+ for ( i = 1; i < n ; ++i ) {
+ size_t j;
+
+ for ( j = 0; j < n - i; ++j ) {
+ if ( ctx->mutex_id[ j ] > ctx->mutex_id[ j + 1 ] ) {
+ rtems_id tmp;
+
+ tmp = ctx->mutex_id[ j ];
+ ctx->mutex_id[ j ] = ctx->mutex_id[ j + 1 ];
+ ctx->mutex_id[ j + 1 ] = tmp;
+ }
+ }
+ }
+}
+
+void TQGetProperties( TQContext *ctx, TQWorkerKind enqueued_worker )
+{
+ ( *ctx->get_properties )( ctx, enqueued_worker );
+}
+
+Status_Control TQConvertStatus( TQContext *ctx, Status_Control status )
+{
+ return ( *ctx->convert_status )( status );
+}
+
+void TQEnqueuePrepare( TQContext *ctx )
+{
+ ( *ctx->enqueue_prepare )( ctx );
+}
+
+Status_Control TQEnqueue( TQContext *ctx, TQWait wait )
+{
+ return ( *ctx->enqueue )( ctx, wait );
+}
+
+Status_Control TQEnqueueFatal( TQContext *ctx )
+{
+ Status_Control status;
+
+ SetFatalHandler( ThreadQueueDeadlock, ctx );
+ status = STATUS_MINUS_ONE;
+
+ if ( setjmp( ctx->before_enqueue ) == 0 ) {
+ status = TQEnqueue( ctx, ctx->wait );
+ } else {
+ status = STATUS_DEADLOCK;
+ }
+
+ return status;
+}
+
+void TQEnqueueDone( TQContext *ctx )
+{
+ ( *ctx->enqueue_done )( ctx );
+}
+
+Status_Control TQSurrender( TQContext *ctx )
+{
+ return ( *ctx->surrender )( ctx );
+}
+
+void TQFlush( TQContext *ctx, bool flush_all )
+{
+ ctx->flush_count = ( *ctx->flush )( ctx, ctx->how_many, flush_all );
+}
+
+rtems_tcb *TQGetOwner( TQContext *ctx )
+{
+ rtems_tcb *( *get_owner )( TQContext * );
+
+ get_owner = ctx->get_owner;
+
+ if ( get_owner == NULL ) {
+ return NULL;
+ }
+
+ return ( *get_owner )( ctx );
+}
+
+void TQSchedulerRecordStart( TQContext *ctx )
+{
+ T_scheduler_log *log;
+
+ log = T_scheduler_record_40( &ctx->scheduler_log );
+ T_null( log );
+}
+
+void TQSchedulerRecordStop( TQContext *ctx )
+{
+ T_scheduler_log *log;
+
+ log = T_scheduler_record( NULL );
+ T_eq_ptr( &log->header, &ctx->scheduler_log.header );
+}
+
+const T_scheduler_event *TQGetNextAny( TQContext *ctx, size_t *index )
+{
+ return T_scheduler_next_any(
+ &ctx->scheduler_log.header,
+ index
+ );
+}
+
+const T_scheduler_event *TQGetNextBlock( TQContext *ctx, size_t *index )
+{
+ return T_scheduler_next(
+ &ctx->scheduler_log.header,
+ T_SCHEDULER_BLOCK,
+ index
+ );
+}
+
+const T_scheduler_event *TQGetNextUnblock( TQContext *ctx, size_t *index )
+{
+ return T_scheduler_next(
+ &ctx->scheduler_log.header,
+ T_SCHEDULER_UNBLOCK,
+ index
+ );
+}
+
+const T_scheduler_event *TQGetNextUpdatePriority(
+ TQContext *ctx,
+ size_t *index
+)
+{
+ return T_scheduler_next(
+ &ctx->scheduler_log.header,
+ T_SCHEDULER_UPDATE_PRIORITY,
+ index
+ );
+}
+
+const T_scheduler_event *TQGetNextAskForHelp(
+ TQContext *ctx,
+ size_t *index
+)
+{
+ return T_scheduler_next(
+ &ctx->scheduler_log.header,
+ T_SCHEDULER_ASK_FOR_HELP,
+ index
+ );
+}
+
+void TQDoNothing( TQContext *ctx )
+{
+ (void) ctx;
+}
+
+Status_Control TQDoNothingSuccessfully( TQContext *ctx )
+{
+ (void) ctx;
+
+ return STATUS_SUCCESSFUL;
+}
+
+Status_Control TQConvertStatusClassic( Status_Control status )
+{
+ return STATUS_BUILD( STATUS_GET_CLASSIC( status ), 0 );
+}
+
+Status_Control TQConvertStatusPOSIX( Status_Control status )
+{
+ return STATUS_BUILD( 0, STATUS_GET_POSIX( status ) );
+}
+
+void TQEnqueuePrepareDefault( TQContext *ctx )
+{
+ Status_Control status;
+
+ status = TQEnqueue( ctx, TQ_NO_WAIT );
+ T_eq_int( status, TQConvertStatus( ctx, STATUS_SUCCESSFUL ) );
+}
+
+void TQEnqueueDoneDefault( TQContext *ctx )
+{
+ Status_Control status;
+
+ status = TQSurrender( ctx );
+ T_eq_int( status, TQConvertStatus( ctx, STATUS_SUCCESSFUL ) );
+}
+
+Status_Control TQEnqueueClassicSem( TQContext *ctx, TQWait wait )
+{
+ rtems_status_code sc;
+ rtems_option option;
+ rtems_option timeout;
+
+ switch ( wait ) {
+ case TQ_WAIT_FOREVER:
+ option = RTEMS_WAIT;
+ timeout = RTEMS_NO_TIMEOUT;
+ break;
+ case TQ_WAIT_TIMED:
+ option = RTEMS_WAIT;
+ timeout = UINT32_MAX;
+ break;
+ default:
+ option = RTEMS_NO_WAIT;
+ timeout = 0;
+ break;
+ }
+
+ sc = rtems_semaphore_obtain( ctx->thread_queue_id, option, timeout );
+
+ return STATUS_BUILD( sc, 0 );
+}
+
+Status_Control TQSurrenderClassicSem( TQContext *ctx )
+{
+ rtems_status_code sc;
+
+ sc = rtems_semaphore_release( ctx->thread_queue_id );
+
+ return STATUS_BUILD( sc, 0 );
+}
+
+rtems_tcb *TQGetOwnerClassicSem( TQContext *ctx )
+{
+ Semaphore_Control *semaphore;
+ Thread_queue_Context queue_context;
+ rtems_tcb *thread;
+
+ semaphore = _Semaphore_Get( ctx->thread_queue_id, &queue_context );
+ T_assert_not_null( semaphore );
+ thread = semaphore->Core_control.Wait_queue.Queue.owner;
+ _ISR_lock_ISR_enable( &queue_context.Lock_context.Lock_context );
+
+ return thread;
+}
+
+uint32_t TQSemGetCount( TQSemContext *ctx )
+{
+ return ( *ctx->get_count )( ctx );
+}
+
+void TQSemSetCount( TQSemContext *ctx, uint32_t count )
+{
+ ( *ctx->set_count )( ctx, count );
+}
+
+uint32_t TQSemGetCountClassic( TQSemContext *ctx )
+{
+ Semaphore_Control *semaphore;
+ Thread_queue_Context queue_context;
+ uint32_t count;
+
+ semaphore = _Semaphore_Get( ctx->base.thread_queue_id, &queue_context );
+ T_assert_not_null( semaphore );
+ count = semaphore->Core_control.Semaphore.count;
+ _ISR_lock_ISR_enable( &queue_context.Lock_context.Lock_context );
+
+ return count;
+}
+
+void TQSemSetCountClassic( TQSemContext *ctx, uint32_t count )
+{
+ Semaphore_Control *semaphore;
+ Thread_queue_Context queue_context;
+
+ semaphore = _Semaphore_Get( ctx->base.thread_queue_id, &queue_context );
+ T_assert_not_null( semaphore );
+ semaphore->Core_control.Semaphore.count = count;
+ _ISR_lock_ISR_enable( &queue_context.Lock_context.Lock_context );
+}
diff --git a/testsuites/validation/tx-thread-queue.h b/testsuites/validation/tx-thread-queue.h
new file mode 100644
index 0000000000..f95fcb790b
--- /dev/null
+++ b/testsuites/validation/tx-thread-queue.h
@@ -0,0 +1,537 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This header file provides the functions to test the
+ * @ref RTEMSScoreThreadQueue.
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _TX_THREAD_QUEUE_H
+#define _TX_THREAD_QUEUE_H
+
+#include "tx-support.h"
+
+#include <rtems/test-scheduler.h>
+#include <rtems/score/atomic.h>
+#include <rtems/score/status.h>
+
+#include <setjmp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup RTEMSTestSuitesValidation
+ *
+ * @{
+ */
+
+typedef enum {
+ TQ_NODE_ONLY,
+ TQ_NODE_VITAL,
+ TQ_NODE_DISPENSABLE
+} TQNodeKind;
+
+typedef enum {
+ TQ_WAIT_STATE_BLOCKED,
+ TQ_WAIT_STATE_INTEND_TO_BLOCK,
+ TQ_WAIT_STATE_READY_AGAIN
+} TQWaitState;
+
+typedef enum {
+ TQ_BLOCKER_A,
+ TQ_BLOCKER_B,
+ TQ_BLOCKER_C,
+ TQ_BLOCKER_D,
+ TQ_BLOCKER_E,
+ TQ_WORKER_F,
+ TQ_HELPER_A,
+ TQ_HELPER_B,
+ TQ_HELPER_C,
+ TQ_WORKER_COUNT
+} TQWorkerKind;
+
+typedef enum {
+ TQ_MUTEX_A,
+ TQ_MUTEX_B,
+ TQ_MUTEX_C,
+ TQ_MUTEX_D,
+ TQ_MUTEX_NO_PROTOCOL,
+ TQ_MUTEX_FIFO,
+ TQ_MUTEX_COUNT
+} TQMutex;
+
+typedef enum {
+ TQ_FIFO,
+ TQ_PRIORITY
+} TQDiscipline;
+
+typedef enum {
+ TQ_NO_WAIT,
+ TQ_WAIT_FOREVER,
+ TQ_WAIT_TIMED
+} TQWait;
+
+typedef enum {
+ TQ_DEADLOCK_STATUS,
+ TQ_DEADLOCK_FATAL
+} TQDeadlock;
+
+typedef enum {
+ TQ_EVENT_ENQUEUE_PREPARE = RTEMS_EVENT_0,
+ TQ_EVENT_ENQUEUE = RTEMS_EVENT_1,
+ TQ_EVENT_ENQUEUE_DONE = RTEMS_EVENT_2,
+ TQ_EVENT_SURRENDER = RTEMS_EVENT_3,
+ TQ_EVENT_RUNNER_SYNC = RTEMS_EVENT_4,
+ TQ_EVENT_RUNNER_SYNC_2 = RTEMS_EVENT_5,
+ TQ_EVENT_HELPER_A_SYNC = RTEMS_EVENT_6,
+ TQ_EVENT_HELPER_B_SYNC = RTEMS_EVENT_7,
+ TQ_EVENT_MUTEX_A_OBTAIN = RTEMS_EVENT_8,
+ TQ_EVENT_MUTEX_A_RELEASE = RTEMS_EVENT_9,
+ TQ_EVENT_MUTEX_B_OBTAIN = RTEMS_EVENT_10,
+ TQ_EVENT_MUTEX_B_RELEASE = RTEMS_EVENT_11,
+ TQ_EVENT_BUSY_WAIT = RTEMS_EVENT_12,
+ TQ_EVENT_FLUSH_ALL = RTEMS_EVENT_13,
+ TQ_EVENT_FLUSH_PARTIAL = RTEMS_EVENT_14,
+ TQ_EVENT_SCHEDULER_RECORD_START = RTEMS_EVENT_15,
+ TQ_EVENT_SCHEDULER_RECORD_STOP = RTEMS_EVENT_16,
+ TQ_EVENT_TIMEOUT = RTEMS_EVENT_17,
+ TQ_EVENT_MUTEX_NO_PROTOCOL_OBTAIN = RTEMS_EVENT_18,
+ TQ_EVENT_MUTEX_NO_PROTOCOL_RELEASE = RTEMS_EVENT_19,
+ TQ_EVENT_ENQUEUE_FATAL = RTEMS_EVENT_20,
+ TQ_EVENT_MUTEX_C_OBTAIN = RTEMS_EVENT_21,
+ TQ_EVENT_MUTEX_C_RELEASE = RTEMS_EVENT_22,
+ TQ_EVENT_MUTEX_FIFO_OBTAIN = RTEMS_EVENT_23,
+ TQ_EVENT_MUTEX_FIFO_RELEASE = RTEMS_EVENT_24,
+ TQ_EVENT_ENQUEUE_TIMED = RTEMS_EVENT_25,
+ TQ_EVENT_MUTEX_D_OBTAIN = RTEMS_EVENT_26,
+ TQ_EVENT_MUTEX_D_RELEASE = RTEMS_EVENT_27,
+ TQ_EVENT_PIN = RTEMS_EVENT_28,
+ TQ_EVENT_UNPIN = RTEMS_EVENT_29,
+ TQ_EVENT_COUNT = RTEMS_EVENT_30
+} TQEvent;
+
+typedef enum {
+ TQ_ENQUEUE_BLOCKS,
+ TQ_ENQUEUE_STICKY
+} TQEnqueueVariant;
+
+typedef struct TQContext {
+ /**
+ * @brief This member defines the thread queue discipline.
+ */
+ TQDiscipline discipline;
+
+ /**
+ * @brief This member defines the enqueue wait behaviour.
+ *
+ * If TQ_NO_WAIT is used, then no thread queue enqueue shall be performed.
+ */
+ TQWait wait;
+
+ /**
+ * @brief This member defines the enqueue variant.
+ */
+ TQEnqueueVariant enqueue_variant;
+
+ /**
+ * @brief This member defines the deadlock enqueue behaviour.
+ */
+ TQDeadlock deadlock;
+
+ /**
+ * @brief This member contains the runner task identifier.
+ */
+ rtems_id runner_id;
+
+ /**
+ * @brief This member contains a reference to the runner task control block.
+ */
+ rtems_tcb *runner_tcb;
+
+ /**
+ * @brief This member contains the worker task identifiers.
+ */
+ rtems_id worker_id[ TQ_WORKER_COUNT ];
+
+ /**
+ * @brief This member contains references to the worker task control
+ * blocks.
+ */
+ rtems_tcb *worker_tcb[ TQ_WORKER_COUNT ];
+
+ /**
+ * @brief When a worker received an event, the corresponding element shall be
+ * set to true.
+ */
+ volatile bool event_received[ TQ_WORKER_COUNT ];
+
+ /**
+ * @brief If this member is true, then the worker shall busy wait on request.
+ */
+ volatile bool busy_wait[ TQ_WORKER_COUNT ];
+
+ /**
+ * @brief When a worker is done processing its current event set, the
+ * corresponding element shall be set to true.
+ */
+ volatile bool done[ TQ_WORKER_COUNT ];
+
+ /**
+ * @brief This member provides the counter used for the worker counters.
+ */
+ Atomic_Uint counter;
+
+ /**
+ * @brief When a worker returned from TQEnqueue() the counter is incremented
+ * and stored in this member.
+ */
+ uint32_t worker_counter[ TQ_WORKER_COUNT ];
+
+ /**
+ * @brief This member contains the last return status of a TQEnqueue() of the
+ * corresponding worker.
+ */
+ Status_Control status[ TQ_WORKER_COUNT ];
+
+ union {
+ /**
+ * @brief This member contains the identifier of an object providing the
+ * thread queue under test.
+ */
+ rtems_id thread_queue_id;
+
+ /**
+ * @brief This member contains the reference to object containing the
+ * thread queue under test.
+ */
+ void *thread_queue_object;
+ };
+
+ /**
+ * @brief This member contains the identifier of priority inheritance
+ * mutexes.
+ */
+ rtems_id mutex_id[ TQ_MUTEX_COUNT ];
+
+ /**
+ * @brief This member provides the scheduler log.
+ */
+ T_scheduler_log_40 scheduler_log;
+
+ /**
+ * @brief This member provides the get properties handler.
+ */
+ void ( *get_properties )( struct TQContext *, TQWorkerKind );
+
+ /**
+ * @brief This member provides the status convert handler.
+ */
+ Status_Control ( *convert_status )( Status_Control );
+
+ /**
+ * @brief This this member specifies how many threads shall be enqueued.
+ */
+ uint32_t how_many;
+
+ /**
+ * @brief This this member contains the count of the least recently flushed
+ * threads.
+ */
+ uint32_t flush_count;
+
+ /**
+ * @brief This this member provides a context to jump back to before the
+ * enqueue.
+ */
+ jmp_buf before_enqueue;
+
+ /**
+ * @brief This member provides the thread queue enqueue prepare handler.
+ */
+ void ( *enqueue_prepare )( struct TQContext * );
+
+ /**
+ * @brief This member provides the thread queue enqueue handler.
+ */
+ Status_Control ( *enqueue )( struct TQContext *, TQWait );
+
+ /**
+ * @brief This member provides the thread queue enqueue done handler.
+ */
+ void ( *enqueue_done )( struct TQContext * );
+
+ /**
+ * @brief This member provides the thread queue surrender handler.
+ */
+ Status_Control ( *surrender )( struct TQContext * );
+
+ /**
+ * @brief This member provides the thread queue flush handler.
+ *
+ * The second parameter specifies the count of enqueued threads. While the
+ * third parameter is true, all enqueued threads shall be extracted,
+ * otherwise the thread queue shall be partially flushed. The handler shall
+ * return the count of flushed threads.
+ */
+ uint32_t ( *flush )( struct TQContext *, uint32_t, bool );
+
+ /**
+ * @brief This member provides the get owner handler.
+ */
+ rtems_tcb *( *get_owner )( struct TQContext * );
+} TQContext;
+
+void TQSend(
+ TQContext *ctx,
+ TQWorkerKind worker,
+ rtems_event_set events
+);
+
+void TQSendAndWaitForExecutionStop(
+ TQContext *ctx,
+ TQWorkerKind worker,
+ rtems_event_set events
+);
+
+void TQSendAndWaitForIntendToBlock(
+ TQContext *ctx,
+ TQWorkerKind worker,
+ rtems_event_set events
+);
+
+void TQSendAndWaitForExecutionStopOrIntendToBlock(
+ TQContext *ctx,
+ TQWorkerKind worker,
+ rtems_event_set events
+);
+
+void TQSendAndSynchronizeRunner(
+ TQContext *ctx,
+ TQWorkerKind worker,
+ rtems_event_set events
+);
+
+void TQWaitForEventsReceived( const TQContext *ctx, TQWorkerKind worker );
+
+void TQWaitForIntendToBlock( const TQContext *ctx, TQWorkerKind worker );
+
+void TQWaitForExecutionStop( const TQContext *ctx, TQWorkerKind worker );
+
+void TQClearDone( TQContext *ctx, TQWorkerKind worker );
+
+void TQWaitForDone( const TQContext *ctx, TQWorkerKind worker );
+
+void TQSynchronizeRunner( void );
+
+void TQSynchronizeRunner2( void );
+
+void TQResetCounter( TQContext *ctx );
+
+uint32_t TQGetCounter( const TQContext *ctx );
+
+uint32_t TQGetWorkerCounter( const TQContext *ctx, TQWorkerKind worker );
+
+void TQMutexObtain( const TQContext *ctx, TQMutex mutex );
+
+void TQMutexRelease( const TQContext *ctx, TQMutex mutex );
+
+void TQSetPriority(
+ const TQContext *ctx,
+ TQWorkerKind worker,
+ Priority priority
+);
+
+Priority TQGetPriority( const TQContext *ctx, TQWorkerKind worker );
+
+void TQSetScheduler(
+ const TQContext *ctx,
+ TQWorkerKind worker,
+ rtems_id scheduler_id,
+ Priority priority
+);
+
+void TQInitialize( TQContext *ctx );
+
+void TQDestroy( TQContext *ctx );
+
+void TQReset( TQContext *ctx );
+
+void TQSortMutexesByID( TQContext *ctx );
+
+void TQGetProperties( TQContext *ctx, TQWorkerKind enqueued_worker );
+
+Status_Control TQConvertStatus( TQContext *ctx, Status_Control status );
+
+void TQEnqueuePrepare( TQContext *ctx );
+
+Status_Control TQEnqueue( TQContext *ctx, TQWait wait );
+
+Status_Control TQEnqueueFatal( TQContext *ctx );
+
+void TQEnqueueDone( TQContext *ctx );
+
+Status_Control TQSurrender( TQContext *ctx );
+
+void TQFlush( TQContext *ctx, bool flush_all );
+
+rtems_tcb *TQGetOwner( TQContext *ctx );
+
+void TQSchedulerRecordStart( TQContext *ctx );
+
+void TQSchedulerRecordStop( TQContext *ctx );
+
+const T_scheduler_event *TQGetNextAny( TQContext *ctx, size_t *index );
+
+const T_scheduler_event *TQGetNextBlock( TQContext *ctx, size_t *index );
+
+const T_scheduler_event *TQGetNextUnblock( TQContext *ctx, size_t *index );
+
+const T_scheduler_event *TQGetNextUpdatePriority(
+ TQContext *ctx,
+ size_t *index
+);
+
+const T_scheduler_event *TQGetNextAskForHelp( TQContext *ctx, size_t *index );
+
+void TQDoNothing( TQContext *ctx );
+
+Status_Control TQDoNothingSuccessfully( TQContext *ctx );
+
+Status_Control TQConvertStatusClassic( Status_Control status );
+
+Status_Control TQConvertStatusPOSIX( Status_Control status );
+
+void TQEnqueuePrepareDefault( TQContext *ctx );
+
+void TQEnqueueDoneDefault( TQContext *ctx );
+
+Status_Control TQEnqueueClassicSem( TQContext *ctx, TQWait wait );
+
+Status_Control TQSurrenderClassicSem( TQContext *ctx );
+
+rtems_tcb *TQGetOwnerClassicSem( TQContext *ctx );
+
+typedef enum {
+ TQ_SEM_BINARY,
+ TQ_SEM_COUNTING
+} TQSemVariant;
+
+typedef struct TQSemContext {
+ /**
+ * @brief This member contains the base thread queue test context.
+ */
+ TQContext base;
+
+ /**
+ * @brief This member defines the semaphore variant.
+ */
+ TQSemVariant variant;
+
+ /**
+ * @brief This member provides the semaphore get count handler.
+ */
+ uint32_t ( *get_count )( struct TQSemContext * );
+
+ /**
+ * @brief This member provides the semaphore set count handler.
+ */
+ void ( *set_count )( struct TQSemContext *, uint32_t );
+} TQSemContext;
+
+Status_Control TQSemSurrender( TQSemContext *ctx );
+
+uint32_t TQSemGetCount( TQSemContext *ctx );
+
+void TQSemSetCount( TQSemContext *ctx, uint32_t count );
+
+Status_Control TQSemSurrenderClassic( TQSemContext *ctx );
+
+uint32_t TQSemGetCountClassic( TQSemContext *ctx );
+
+void TQSemSetCountClassic( TQSemContext *ctx, uint32_t count );
+
+typedef enum {
+ TQ_MTX_NO_PROTOCOL,
+ TQ_MTX_PRIORITY_INHERIT,
+ TQ_MTX_PRIORITY_CEILING,
+ TQ_MTX_MRSP
+} TQMtxProtocol;
+
+typedef enum {
+ TQ_MTX_RECURSIVE_ALLOWED,
+ TQ_MTX_RECURSIVE_DEADLOCK,
+ TQ_MTX_RECURSIVE_UNAVAILABLE
+} TQMtxRecursive;
+
+typedef enum {
+ TQ_MTX_NO_OWNER_CHECK,
+ TQ_MTX_CHECKS_OWNER
+} TQMtxOwnerCheck;
+
+typedef struct TQMtxContext {
+ /**
+ * @brief This member contains the base thread queue test context.
+ */
+ TQContext base;
+
+ /**
+ * @brief This member defines the locking protocol.
+ */
+ TQMtxProtocol protocol;
+
+ /**
+ * @brief This member defines the recursive seize behaviour.
+ */
+ TQMtxRecursive recursive;
+
+ /**
+ * @brief This member defines the owner check behaviour.
+ */
+ TQMtxOwnerCheck owner_check;
+
+ /**
+ * @brief This member defines the priority ceiling of the mutex.
+ *
+ * Use PRIO_INVALID to indicate that the mutex does not provide a priority
+ * ceiling.
+ */
+ rtems_task_priority priority_ceiling;
+} TQMtxContext;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TX_THREAD_QUEUE_H */
diff --git a/testsuites/validation/tx-timecounter.c b/testsuites/validation/tx-timecounter.c
new file mode 100644
index 0000000000..01b55f2578
--- /dev/null
+++ b/testsuites/validation/tx-timecounter.c
@@ -0,0 +1,160 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This source file contains the definition of SetGetTimecountHandler(),
+ * GetTimecountCounter(), and SetTimecountCounter().
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tx-support.h"
+
+#include <rtems/sysinit.h>
+#include <rtems/timecounter.h>
+#include <rtems/score/atomic.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/smpimpl.h>
+#include <rtems/score/threaddispatch.h>
+
+typedef struct {
+ struct timecounter base;
+ GetTimecountHandler handler;
+ Atomic_Ulong counter;
+} TimecounterControl;
+
+static TimecounterControl TimecounterInstance;
+
+GetTimecountHandler SetGetTimecountHandler( GetTimecountHandler handler )
+{
+ GetTimecountHandler previous;
+
+ previous = TimecounterInstance.handler;
+ TimecounterInstance.handler = handler;
+ return previous;
+}
+
+uint32_t GetTimecountCounter( void )
+{
+ return (uint32_t) _Atomic_Load_ulong(
+ &TimecounterInstance.counter,
+ ATOMIC_ORDER_RELAXED
+ );
+}
+
+uint32_t SetTimecountCounter( uint32_t counter )
+{
+ return (uint32_t) _Atomic_Exchange_ulong(
+ &TimecounterInstance.counter,
+ counter,
+ ATOMIC_ORDER_RELAXED
+ );
+}
+
+static uint32_t GetTimecountSoftware( void )
+{
+ return (uint32_t) _Atomic_Fetch_add_ulong(
+ &TimecounterInstance.counter,
+ 1,
+ ATOMIC_ORDER_RELAXED
+ );
+}
+
+static uint32_t GetTimecountWrapper( struct timecounter *tc )
+{
+ TimecounterControl *self;
+
+ self = (TimecounterControl *) tc;
+ return ( *self->handler )();
+}
+
+static void InstallTimecounter( void )
+{
+ TimecounterControl *self;
+
+ self = &TimecounterInstance;
+ self->handler = GetTimecountSoftware;
+ self->base.tc_get_timecount = GetTimecountWrapper;
+ self->base.tc_counter_mask = 0xffffffff;
+ self->base.tc_frequency = SOFTWARE_TIMECOUNTER_FREQUENCY;
+ self->base.tc_quality = RTEMS_TIMECOUNTER_QUALITY_CLOCK_DRIVER + 1;
+ rtems_timecounter_install( &self->base );
+}
+
+RTEMS_SYSINIT_ITEM(
+ InstallTimecounter,
+ RTEMS_SYSINIT_DEVICE_DRIVERS,
+ RTEMS_SYSINIT_ORDER_LAST
+);
+
+static void DoTimecounterTick( void *arg )
+{
+ (void) arg;
+ _Timecounter_Tick();
+}
+
+void TimecounterTick( void )
+{
+ unsigned long counter_ticks_per_clock_tick;
+ Per_CPU_Control *cpu_self;
+ bool success;
+
+ counter_ticks_per_clock_tick =
+ SOFTWARE_TIMECOUNTER_FREQUENCY / rtems_clock_get_ticks_per_second();
+ cpu_self = _Thread_Dispatch_disable();
+
+ do {
+ unsigned long old_counter;
+ unsigned long new_counter;
+
+ old_counter = _Atomic_Load_ulong(
+ &TimecounterInstance.counter,
+ ATOMIC_ORDER_RELAXED
+ );
+ new_counter = old_counter + counter_ticks_per_clock_tick -
+ ( old_counter % counter_ticks_per_clock_tick );
+ success = _Atomic_Compare_exchange_ulong(
+ &TimecounterInstance.counter,
+ &old_counter,
+ new_counter,
+ ATOMIC_ORDER_RELAXED,
+ ATOMIC_ORDER_RELAXED
+ );
+ } while ( !success );
+
+ DoTimecounterTick( NULL );
+#if defined( RTEMS_SMP )
+ _SMP_Othercast_action( DoTimecounterTick, NULL );
+#endif
+ _Thread_Dispatch_enable( cpu_self );
+}
diff --git a/testsuites/validation/tx-timer-server.c b/testsuites/validation/tx-timer-server.c
new file mode 100644
index 0000000000..29575eb490
--- /dev/null
+++ b/testsuites/validation/tx-timer-server.c
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This source file contains the definition of DeleteTimerServer().
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tx-support.h"
+
+#include <rtems/test.h>
+#include <rtems/rtems/timerimpl.h>
+#include <rtems/score/todimpl.h>
+
+rtems_id GetTimerServerTaskId( void )
+{
+ if ( _Timer_server == NULL ) {
+ return RTEMS_INVALID_ID;
+ }
+ return _Timer_server->server_id;
+}
+
+bool DeleteTimerServer( void )
+{
+ Timer_server_Control *server;
+
+ server = _Timer_server;
+
+ if ( server == NULL ) {
+ return false;
+ }
+
+ DeleteTask( server->server_id );
+ _ISR_lock_Destroy( &server->Lock );
+ T_true( _Chain_Is_empty( &server->Pending ) );
+ _Timer_server = NULL;
+
+ return true;
+}
+
+Timer_Classes GetTimerClass( rtems_id id )
+{
+ /* This code is derived from rtems_timer_get_information() */
+ Timer_Classes result = TIMER_DORMANT;
+ Timer_Control *the_timer;
+ ISR_lock_Context lock_context;
+ Per_CPU_Control *cpu;
+
+ the_timer = _Timer_Get( id, &lock_context );
+ if ( the_timer != NULL ) {
+ cpu = _Timer_Acquire_critical( the_timer, &lock_context );
+ result = the_timer->the_class;
+ _Timer_Release( cpu, &lock_context );
+ }
+
+ return result;
+}
+
+void GetTimerSchedulingData(
+ rtems_id id,
+ Timer_Scheduling_Data *data
+)
+{
+ /* This code is derived from rtems_timer_get_information() */
+ Timer_Control *the_timer;
+ ISR_lock_Context lock_context;
+ Per_CPU_Control *cpu;
+
+ if ( data == NULL ) {
+ return;
+ }
+
+ the_timer = _Timer_Get( id, &lock_context );
+ if ( the_timer != NULL ) {
+ cpu = _Timer_Acquire_critical( the_timer, &lock_context );
+ data->routine = the_timer->routine;
+ data->user_data = the_timer->user_data;
+ data->interval = the_timer->initial;
+ _Timer_Release( cpu, &lock_context );
+ }
+}
+
+Timer_States GetTimerState( rtems_id id )
+{
+ /* This code is derived from rtems_timer_cancel() and _timer_cancel() */
+ Timer_States result = TIMER_INVALID;
+ Timer_Control *the_timer;
+ ISR_lock_Context lock_context;
+ Per_CPU_Control *cpu;
+ Timer_Classes the_class;
+ Timer_server_Control *timer_server = _Timer_server;
+ ISR_lock_Context lock_context_server;
+
+ the_timer = _Timer_Get( id, &lock_context );
+ if ( the_timer != NULL ) {
+ result = TIMER_INACTIVE;
+ cpu = _Timer_Acquire_critical( the_timer, &lock_context );
+ the_class = the_timer->the_class;
+
+ if ( _Watchdog_Is_scheduled( &the_timer->Ticker ) ) {
+ result = TIMER_SCHEDULED;
+ } else if ( _Timer_Is_on_task_class( the_class ) ) {
+ _Assert( timer_server != NULL );
+ _Timer_server_Acquire_critical( timer_server, &lock_context_server );
+ if ( _Watchdog_Get_state( &the_timer->Ticker ) == WATCHDOG_PENDING ) {
+ result = TIMER_PENDING;
+ }
+ _Timer_server_Release_critical( timer_server, &lock_context_server );
+ }
+ _Timer_Release( cpu, &lock_context );
+ }
+
+ return result;
+}
+
+void UnsetClock( void )
+{
+ _TOD.is_set = false;
+}
diff --git a/testsuites/validation/tx-wrap-thread-queue.c b/testsuites/validation/tx-wrap-thread-queue.c
new file mode 100644
index 0000000000..39d7b38129
--- /dev/null
+++ b/testsuites/validation/tx-wrap-thread-queue.c
@@ -0,0 +1,144 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup RTEMSTestSuitesValidation
+ *
+ * @brief This source file contains the implementation of the thread queue
+ * wrapper.
+ */
+
+/*
+ * Copyright (C) 2021 embedded brains GmbH & Co. KG
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "tx-support.h"
+
+#include <rtems/score/threadimpl.h>
+#include <rtems/score/threadqimpl.h>
+
+#include <string.h>
+
+void WrapThreadQueueInitialize(
+ WrapThreadQueueContext *ctx,
+ void ( *handler )( void * ),
+ void *arg
+)
+{
+ memset( ctx, 0, sizeof( *ctx ) );
+ ctx->isr_request.handler = handler;
+ ctx->isr_request.arg = arg;
+ _Thread_queue_Initialize( &ctx->thread_queue, "Wrap" );
+}
+
+static void Prepare(
+ WrapThreadQueueContext *ctx,
+ Thread_Control *thread
+)
+{
+ if ( thread->Wait.queue != NULL ) {
+ ctx->wrapped_ops = thread->Wait.operations;
+ thread->Wait.operations = &ctx->tq_ops;
+ } else {
+ Thread_queue_Context queue_context;
+
+ ctx->wrapped_ops = NULL;
+ _Thread_queue_Context_initialize( &queue_context );
+ _Thread_queue_Acquire( &ctx->thread_queue, &queue_context );
+ _Thread_Wait_flags_set(
+ thread,
+ THREAD_WAIT_CLASS_OBJECT | THREAD_WAIT_STATE_INTEND_TO_BLOCK
+ );
+ _Thread_Wait_claim( thread, &ctx->thread_queue.Queue );
+ _Thread_Wait_claim_finalize( thread, &ctx->tq_ops );
+ _Thread_queue_Release( &ctx->thread_queue, &queue_context );
+ }
+}
+
+static void WrappedExtract(
+ WrapThreadQueueContext *ctx,
+ Thread_queue_Queue *queue,
+ Thread_Control *thread,
+ Thread_queue_Context *queue_context
+)
+{
+ if ( ctx->wrapped_ops ) {
+ thread->Wait.operations = ctx->wrapped_ops;
+ ( *thread->Wait.operations->extract )( queue, thread, queue_context );
+ }
+}
+
+static void Extract(
+ Thread_queue_Queue *queue,
+ Thread_Control *thread,
+ Thread_queue_Context *queue_context
+)
+{
+ WrapThreadQueueContext *ctx;
+
+ ctx = (WrapThreadQueueContext *) thread->Wait.operations;
+ CallWithinISRSubmit( &ctx->isr_request );
+ WrappedExtract( ctx, queue, thread, queue_context );
+}
+
+void WrapThreadQueueExtract(
+ WrapThreadQueueContext *ctx,
+ Thread_Control *thread
+)
+{
+ ctx->tq_ops.extract = Extract;
+ Prepare( ctx, thread );
+}
+
+static void ExtractDirect(
+ Thread_queue_Queue *queue,
+ Thread_Control *thread,
+ Thread_queue_Context *queue_context
+)
+{
+ WrapThreadQueueContext *ctx;
+
+ ctx = (WrapThreadQueueContext *) thread->Wait.operations;
+ ( *ctx->isr_request.handler )( ctx->isr_request.arg );
+ WrappedExtract( ctx, queue, thread, queue_context );
+}
+
+void WrapThreadQueueExtractDirect(
+ WrapThreadQueueContext *ctx,
+ Thread_Control *thread
+)
+{
+ ctx->tq_ops.extract = ExtractDirect;
+ Prepare( ctx, thread );
+}
+
+void WrapThreadQueueDestroy( WrapThreadQueueContext *ctx )
+{
+ _Thread_queue_Destroy( &ctx->thread_queue );
+}