File indexing completed on 2025-05-11 08:24:35
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 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031
0032 #include <rtems/test.h>
0033 #include <rtems/test-info.h>
0034
0035 #include <string.h>
0036
0037 #include <rtems.h>
0038
0039 static void
0040 prepare(void *arg)
0041 {
0042 Atomic_Uint *state;
0043
0044 state = arg;
0045 _Atomic_Store_uint(state, 0, ATOMIC_ORDER_RELAXED);
0046 }
0047
0048 static void
0049 action(void *arg)
0050 {
0051 Atomic_Uint *state;
0052 unsigned int expected;
0053 bool success_0;
0054 bool success_1;
0055
0056 state = arg;
0057
0058
0059
0060
0061
0062 expected = 0;
0063 success_0 = _Atomic_Compare_exchange_uint(state, &expected, 1,
0064 ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED);
0065 expected = 1;
0066 success_1 = _Atomic_Compare_exchange_uint(state, &expected, 2,
0067 ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED);
0068 T_quiet_true(success_0);
0069 T_quiet_true(success_1);
0070
0071 T_interrupt_test_busy_wait_for_interrupt();
0072 }
0073
0074 static T_interrupt_test_state
0075 interrupt(void *arg)
0076 {
0077 Atomic_Uint *state;
0078 unsigned int expected;
0079
0080 if (T_interrupt_test_get_state() != T_INTERRUPT_TEST_ACTION) {
0081 return T_INTERRUPT_TEST_CONTINUE;
0082 }
0083
0084 state = arg;
0085 expected = 1;
0086
0087 if (_Atomic_Compare_exchange_uint(state, &expected, expected,
0088 ATOMIC_ORDER_RELAXED, ATOMIC_ORDER_RELAXED)) {
0089 return T_INTERRUPT_TEST_DONE;
0090 } else if (expected == 0) {
0091 return T_INTERRUPT_TEST_EARLY;
0092 } else {
0093 T_quiet_eq_uint(expected, 2);
0094 return T_INTERRUPT_TEST_LATE;
0095 }
0096 }
0097
0098 static const T_interrupt_test_config done_config = {
0099 .prepare = prepare,
0100 .action = action,
0101 .interrupt = interrupt,
0102 .max_iteration_count = 10000
0103 };
0104
0105 T_TEST_CASE(TestInterruptDone)
0106 {
0107 int i;
0108
0109 for (i = 0; i < 10; ++i) {
0110 Atomic_Uint action_state;
0111 T_interrupt_test_state state;
0112
0113 state = T_interrupt_test(&done_config, &action_state);
0114 T_eq_int(state, T_INTERRUPT_TEST_DONE);
0115 }
0116 }
0117
0118 static const T_interrupt_test_config timeout_config = {
0119 .interrupt = interrupt,
0120 .action = action
0121 };
0122
0123 T_TEST_CASE(TestInterruptTimeout)
0124 {
0125 Atomic_Uint action_state;
0126 T_interrupt_test_state state;
0127
0128 T_plan(1);
0129 state = T_interrupt_test(&timeout_config, &action_state);
0130 T_step_eq_int(0, state, T_INTERRUPT_TEST_TIMEOUT);
0131 }
0132
0133 static void
0134 fatal(void *arg)
0135 {
0136 (void)arg;
0137 T_plan(1);
0138 T_step(0);
0139 T_stop();
0140 }
0141
0142 static const T_interrupt_test_config fatal_config = {
0143 .prepare = fatal,
0144 .action = action,
0145 .interrupt = interrupt,
0146 .max_iteration_count = 10000
0147 };
0148
0149 T_TEST_CASE(TestInterruptFatal)
0150 {
0151 Atomic_Uint action_state;
0152
0153 T_interrupt_test(&fatal_config, &action_state);
0154 T_unreachable();
0155 }
0156
0157 static void
0158 suspend(void *arg)
0159 {
0160 rtems_status_code sc;
0161 rtems_id *id;
0162
0163 id = arg;
0164 T_plan(2);
0165 sc = rtems_task_suspend(*id);
0166 T_step_rsc_success(1, sc);
0167 }
0168
0169 static T_interrupt_test_state
0170 do_nothing(void *arg)
0171 {
0172 (void)arg;
0173 return T_INTERRUPT_TEST_ACTION;
0174 }
0175
0176 static void
0177 resume(void *arg)
0178 {
0179 T_interrupt_test_state state;
0180
0181 state = T_interrupt_test_change_state(T_INTERRUPT_TEST_ACTION,
0182 T_INTERRUPT_TEST_DONE);
0183
0184 if (state == T_INTERRUPT_TEST_ACTION) {
0185 rtems_status_code sc;
0186 rtems_id *id;
0187
0188 id = arg;
0189 sc = rtems_task_resume(*id);
0190 T_step_rsc_success(0, sc);
0191 }
0192 }
0193
0194 static const T_interrupt_test_config blocked_config = {
0195 .action = suspend,
0196 .interrupt = do_nothing,
0197 .blocked = resume,
0198 .max_iteration_count = 10000
0199 };
0200
0201 T_TEST_CASE(TestInterruptBlocked)
0202 {
0203 T_interrupt_test_state state;
0204 rtems_id id;
0205
0206 T_plan(1);
0207 id = rtems_task_self();
0208 state = T_interrupt_test(&blocked_config, &id);
0209 T_step_eq_int(0, state, T_INTERRUPT_TEST_DONE);
0210 }
0211
0212 T_TEST_CASE(TestThreadSwitch)
0213 {
0214 T_thread_switch_log_2 log_2;
0215 T_thread_switch_log_4 log_4;
0216 T_thread_switch_log_10 log_10;
0217 T_thread_switch_log *log;
0218 uint32_t executing;
0219 uint32_t heir;
0220 size_t i;
0221
0222 memset(&log_2, 0xff, sizeof(log_2));
0223 log = T_thread_switch_record_2(&log_2);
0224 T_null(log);
0225 T_eq_sz(log_2.header.recorded, 0);
0226 T_eq_sz(log_2.header.capacity, 2);
0227 T_eq_u64(log_2.header.switches, 0);
0228
0229 memset(&log_4, 0xff, sizeof(log_4));
0230 log = T_thread_switch_record_4(&log_4);
0231 T_eq_ptr(&log->header, &log_2.header);
0232 T_eq_sz(log_4.header.recorded, 0);
0233 T_eq_sz(log_4.header.capacity, 4);
0234 T_eq_u64(log_4.header.switches, 0);
0235
0236 memset(&log_10, 0xff, sizeof(log_10));
0237 log = T_thread_switch_record_10(&log_10);
0238 T_eq_ptr(&log->header, &log_4.header);
0239 T_eq_sz(log_10.header.recorded, 0);
0240 T_eq_sz(log_10.header.capacity, 10);
0241 T_eq_u64(log_10.header.switches, 0);
0242
0243 for (i = 0; i < 6; ++i) {
0244 rtems_status_code sc;
0245
0246 sc = rtems_task_wake_after(2);
0247 T_rsc_success(sc);
0248 }
0249
0250 log = T_thread_switch_record(NULL);
0251 T_eq_ptr(&log->header, &log_10.header);
0252 T_eq_sz(log->header.recorded, 10);
0253 T_eq_sz(log->header.capacity, 10);
0254 T_eq_u64(log->header.switches, 12);
0255 executing = rtems_task_self();
0256 T_eq_u32(log->events[0].executing, executing);
0257 T_ne_u32(log->events[0].heir, 0);
0258 heir = log->events[0].heir;
0259 T_eq_u32(log->events[0].cpu, 0);
0260 T_ne_u64(log->events[0].instant, 0);
0261
0262 for (i = 1; i < 10; ++i) {
0263 uint32_t tmp;
0264
0265 tmp = executing;
0266 executing = heir;
0267 heir = tmp;
0268
0269 T_eq_u32(log->events[i].executing, executing);
0270 T_eq_u32(log->events[i].heir, heir);
0271 T_eq_u32(log->events[i].cpu, 0);
0272 T_gt_u64(log->events[i].instant, log->events[i - 1].instant);
0273 }
0274 }
0275
0276 const char rtems_test_name[] = "TTEST 2";
0277
0278 static void
0279 Init(rtems_task_argument argument)
0280 {
0281 rtems_test_run(argument, TEST_STATE);
0282 }
0283
0284 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0285 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0286
0287 #define CONFIGURE_MICROSECONDS_PER_TICK 1000
0288
0289 #define CONFIGURE_MAXIMUM_TASKS 1
0290
0291 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0292
0293 #define CONFIGURE_INIT
0294
0295 #include <rtems/confdefs.h>