File indexing completed on 2025-05-11 08:24:47
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 #ifdef HAVE_CONFIG_H
0032 #include "config.h"
0033 #endif
0034
0035 #include <tmacros.h>
0036 #include <rtems/test.h>
0037
0038 #include <rtems/score/threadimpl.h>
0039 #include <rtems/rtems/eventimpl.h>
0040
0041 const char rtems_test_name[] = "SPINTRCRITICAL 10";
0042
0043 #define MAX_ITERATION_COUNT 10000
0044
0045 #define GREEN RTEMS_EVENT_0
0046
0047 #define RED RTEMS_EVENT_1
0048
0049 #define EVENTS (GREEN | RED)
0050
0051 #define DEADBEEF 0xdeadbeef
0052
0053 typedef struct {
0054 Thread_Control *thread;
0055 } test_context;
0056
0057 static bool blocks_for_event(Thread_Wait_flags flags)
0058 {
0059 return flags == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTEND_TO_BLOCK)
0060 || flags == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_BLOCKED);
0061 }
0062
0063 static bool interrupts_blocking_op(Thread_Wait_flags flags)
0064 {
0065 return
0066 flags == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTEND_TO_BLOCK);
0067 }
0068
0069 static T_interrupt_test_state any_satisfy_before_timeout_interrupt(void *arg)
0070 {
0071 rtems_status_code sc;
0072 test_context *ctx = arg;
0073 Thread_Control *thread = ctx->thread;
0074 Thread_Wait_flags flags = _Thread_Wait_flags_get(thread);
0075 T_interrupt_test_state state;
0076
0077 if (blocks_for_event(flags)) {
0078 if (interrupts_blocking_op(flags)) {
0079 state = T_INTERRUPT_TEST_DONE;
0080 } else {
0081 state = T_INTERRUPT_TEST_LATE;
0082 }
0083
0084 rtems_test_assert(
0085 *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
0086 );
0087 rtems_test_assert(_Thread_Wait_get_status(thread) == STATUS_SUCCESSFUL);
0088
0089 sc = rtems_event_send(thread->Object.id, GREEN);
0090 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0091
0092 rtems_test_assert(
0093 *(rtems_event_set *) thread->Wait.return_argument == GREEN
0094 );
0095 rtems_test_assert(_Thread_Wait_get_status(thread) == STATUS_SUCCESSFUL);
0096
0097 sc = rtems_event_send(thread->Object.id, RED);
0098 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0099
0100 rtems_test_assert(
0101 *(rtems_event_set *) thread->Wait.return_argument == GREEN
0102 );
0103 rtems_test_assert(_Thread_Wait_get_status(thread) == STATUS_SUCCESSFUL);
0104
0105 _Thread_Timeout(&thread->Timer.Watchdog);
0106
0107 rtems_test_assert(
0108 *(rtems_event_set *) thread->Wait.return_argument == GREEN
0109 );
0110 rtems_test_assert(_Thread_Wait_get_status(thread) == STATUS_SUCCESSFUL);
0111
0112 if (state == T_INTERRUPT_TEST_DONE) {
0113 rtems_test_assert(
0114 _Thread_Wait_flags_get(thread) == THREAD_WAIT_STATE_READY
0115 );
0116 }
0117
0118 rtems_test_assert(thread->Wait.count == EVENTS);
0119 } else {
0120 state = T_INTERRUPT_TEST_EARLY;
0121 }
0122
0123 return state;
0124 }
0125
0126 static void any_satisfy_before_timeout_action(void *arg)
0127 {
0128 rtems_status_code sc;
0129 rtems_event_set out;
0130
0131 (void) arg;
0132
0133 out = DEADBEEF;
0134 sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ANY | RTEMS_WAIT, 1, &out);
0135 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0136 rtems_test_assert(out == GREEN);
0137
0138 out = DEADBEEF;
0139 sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ANY | RTEMS_NO_WAIT, 0, &out);
0140 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0141 rtems_test_assert(out == RED);
0142 }
0143
0144 static const T_interrupt_test_config any_satisfy_before_timeout_config = {
0145 .action = any_satisfy_before_timeout_action,
0146 .interrupt = any_satisfy_before_timeout_interrupt,
0147 .max_iteration_count = MAX_ITERATION_COUNT
0148 };
0149
0150 T_TEST_CASE(EventAnySatisfyBeforeTimeout)
0151 {
0152 test_context ctx;
0153 T_interrupt_test_state state;
0154
0155 ctx.thread = _Thread_Get_executing();
0156 state = T_interrupt_test(&any_satisfy_before_timeout_config, &ctx);
0157 T_eq_int(state, T_INTERRUPT_TEST_DONE);
0158 }
0159
0160 static T_interrupt_test_state all_satisfy_before_timeout_interrupt(void *arg)
0161 {
0162 rtems_status_code sc;
0163 test_context *ctx = arg;
0164 Thread_Control *thread = ctx->thread;
0165 Thread_Wait_flags flags = _Thread_Wait_flags_get(thread);
0166 T_interrupt_test_state state;
0167
0168 if (blocks_for_event(flags)) {
0169 if (interrupts_blocking_op(flags)) {
0170 state = T_INTERRUPT_TEST_DONE;
0171 } else {
0172 state = T_INTERRUPT_TEST_LATE;
0173 }
0174
0175 rtems_test_assert(
0176 *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
0177 );
0178 rtems_test_assert(_Thread_Wait_get_status(thread) == STATUS_SUCCESSFUL);
0179
0180 sc = rtems_event_send(thread->Object.id, GREEN);
0181 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0182
0183 rtems_test_assert(
0184 *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
0185 );
0186 rtems_test_assert(_Thread_Wait_get_status(thread) == STATUS_SUCCESSFUL);
0187
0188 sc = rtems_event_send(thread->Object.id, RED);
0189 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0190
0191 rtems_test_assert(
0192 *(rtems_event_set *) thread->Wait.return_argument == EVENTS
0193 );
0194 rtems_test_assert(_Thread_Wait_get_status(thread) == STATUS_SUCCESSFUL);
0195
0196 _Thread_Timeout(&thread->Timer.Watchdog);
0197
0198 rtems_test_assert(
0199 *(rtems_event_set *) thread->Wait.return_argument == EVENTS
0200 );
0201 rtems_test_assert(_Thread_Wait_get_status(thread) == STATUS_SUCCESSFUL);
0202
0203 if (state == T_INTERRUPT_TEST_DONE) {
0204 rtems_test_assert(
0205 _Thread_Wait_flags_get(thread) == THREAD_WAIT_STATE_READY
0206 );
0207 }
0208
0209 rtems_test_assert(thread->Wait.count == EVENTS);
0210 } else {
0211 state = T_INTERRUPT_TEST_EARLY;
0212 }
0213
0214 return state;
0215 }
0216
0217 static void all_satisfy_before_timeout_action(void *arg)
0218 {
0219 rtems_status_code sc;
0220 rtems_event_set out;
0221
0222 out = DEADBEEF;
0223 sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ALL | RTEMS_WAIT, 1, &out);
0224 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0225 rtems_test_assert(out == EVENTS);
0226 }
0227
0228 static const T_interrupt_test_config all_satisfy_before_timeout_config = {
0229 .action = all_satisfy_before_timeout_action,
0230 .interrupt = all_satisfy_before_timeout_interrupt,
0231 .max_iteration_count = MAX_ITERATION_COUNT
0232 };
0233
0234 T_TEST_CASE(EventAllSatisfyBeforeTimeout)
0235 {
0236 test_context ctx;
0237 T_interrupt_test_state state;
0238
0239 ctx.thread = _Thread_Get_executing();
0240 state = T_interrupt_test(&all_satisfy_before_timeout_config, &ctx);
0241 T_eq_int(state, T_INTERRUPT_TEST_DONE);
0242 }
0243
0244 static T_interrupt_test_state timeout_before_satisfied_interrupt(void *arg)
0245 {
0246 rtems_status_code sc;
0247 test_context *ctx = arg;
0248 Thread_Control *thread = ctx->thread;
0249 Thread_Wait_flags flags = _Thread_Wait_flags_get(thread);
0250 T_interrupt_test_state state;
0251
0252 if (blocks_for_event(flags)) {
0253 if (interrupts_blocking_op(flags)) {
0254 state = T_INTERRUPT_TEST_DONE;
0255 } else {
0256 state = T_INTERRUPT_TEST_LATE;
0257 }
0258
0259 rtems_test_assert(
0260 *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
0261 );
0262 rtems_test_assert(_Thread_Wait_get_status(thread) == STATUS_SUCCESSFUL);
0263
0264 _Thread_Timeout(&thread->Timer.Watchdog);
0265
0266 rtems_test_assert(
0267 *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
0268 );
0269 rtems_test_assert(_Thread_Wait_get_status(thread) == STATUS_TIMEOUT);
0270
0271 sc = rtems_event_send(thread->Object.id, EVENTS);
0272 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0273
0274 rtems_test_assert(
0275 *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF
0276 );
0277 rtems_test_assert(_Thread_Wait_get_status(thread) == STATUS_TIMEOUT);
0278
0279 if (state == T_INTERRUPT_TEST_DONE) {
0280 rtems_test_assert(
0281 _Thread_Wait_flags_get(thread) == THREAD_WAIT_STATE_READY
0282 );
0283 }
0284
0285 rtems_test_assert(thread->Wait.count == EVENTS);
0286 } else {
0287 state = T_INTERRUPT_TEST_EARLY;
0288 }
0289
0290 return state;
0291 }
0292
0293 static void timeout_before_satisfied_action(void *arg)
0294 {
0295 rtems_event_set out;
0296 rtems_status_code sc;
0297
0298 out = DEADBEEF;
0299 sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ALL | RTEMS_WAIT, 1, &out);
0300 rtems_test_assert(sc == RTEMS_TIMEOUT);
0301 rtems_test_assert(out == DEADBEEF);
0302
0303 out = DEADBEEF;
0304 sc = rtems_event_receive(EVENTS, RTEMS_EVENT_ALL | RTEMS_NO_WAIT, 0, &out);
0305 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0306 rtems_test_assert(out == EVENTS);
0307 }
0308
0309 static const T_interrupt_test_config timeout_before_satisfied_config = {
0310 .action = timeout_before_satisfied_action,
0311 .interrupt = timeout_before_satisfied_interrupt,
0312 .max_iteration_count = MAX_ITERATION_COUNT
0313 };
0314
0315 T_TEST_CASE(EventTimeoutBeforeSatisfied)
0316 {
0317 test_context ctx;
0318 T_interrupt_test_state state;
0319
0320 ctx.thread = _Thread_Get_executing();
0321 state = T_interrupt_test(&timeout_before_satisfied_config, &ctx);
0322 T_eq_int(state, T_INTERRUPT_TEST_DONE);
0323 }
0324
0325 static rtems_task Init( rtems_task_argument argument )
0326 {
0327 rtems_test_run( argument, TEST_STATE );
0328 }
0329
0330
0331
0332 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0333 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0334
0335 #define CONFIGURE_MAXIMUM_TASKS 1
0336 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0337
0338 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0339 #define CONFIGURE_MICROSECONDS_PER_TICK 1000
0340
0341 #define CONFIGURE_INIT
0342 #include <rtems/confdefs.h>