File indexing completed on 2025-05-11 08:24:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifdef HAVE_CONFIG_H
0012 #include "config.h"
0013 #endif
0014
0015 #include <rtems/score/atomic.h>
0016 #include <stdio.h>
0017 #include <rtems.h>
0018
0019 #include "tmacros.h"
0020
0021 const char rtems_test_name[] = "SPATOMIC 1";
0022
0023 typedef struct {
0024 Atomic_Uint uint_atomic;
0025 Atomic_Uintptr uintptr_atomic;
0026 Atomic_Ulong ulong_atomic;
0027 } test_context;
0028
0029 static test_context test_instance;
0030
0031 static void test_static_and_dynamic_initialization(void)
0032 {
0033 #if (__SIZEOF_INT__ == 2)
0034 #define UINT_CONSTANT 0xc0feU
0035 #else
0036 #define UINT_CONSTANT 0xc01dc0feU
0037 #endif
0038
0039 static Atomic_Uint static_uint = ATOMIC_INITIALIZER_UINT(UINT_CONSTANT);
0040 static Atomic_Ulong static_ulong = ATOMIC_INITIALIZER_ULONG(0xdeadbeefUL);
0041 static Atomic_Uintptr static_uintptr =
0042 ATOMIC_INITIALIZER_UINTPTR((uintptr_t) &static_uintptr);
0043 static Atomic_Flag static_flag = ATOMIC_INITIALIZER_FLAG;
0044
0045 Atomic_Uint stack_uint;
0046 Atomic_Ulong stack_ulong;
0047 Atomic_Uintptr stack_uintptr;
0048 Atomic_Flag stack_flag;
0049
0050 puts("=== static and dynamic initialization test case ===");
0051
0052 _Atomic_Init_uint(&stack_uint, UINT_CONSTANT);
0053 _Atomic_Init_ulong(&stack_ulong, 0xdeadbeefUL);
0054 _Atomic_Init_uintptr(&stack_uintptr, (uintptr_t) &static_uintptr);
0055 _Atomic_Flag_clear(&stack_flag, ATOMIC_ORDER_RELAXED);
0056
0057 rtems_test_assert(
0058 memcmp(&stack_uint, &static_uint, sizeof(stack_uint)) == 0
0059 );
0060 rtems_test_assert(
0061 memcmp(&stack_ulong, &static_ulong, sizeof(stack_ulong)) == 0
0062 );
0063 rtems_test_assert(
0064 memcmp(&stack_uintptr, &static_uintptr, sizeof(stack_uintptr)) == 0
0065 );
0066 rtems_test_assert(
0067 memcmp(&stack_flag, &static_flag, sizeof(stack_flag)) == 0
0068 );
0069
0070 rtems_test_assert(
0071 _Atomic_Load_uint(&stack_uint, ATOMIC_ORDER_RELAXED) == 0xc01dc0feU
0072 );
0073 rtems_test_assert(
0074 _Atomic_Load_ulong(&stack_ulong, ATOMIC_ORDER_RELAXED) == 0xdeadbeefUL
0075 );
0076 rtems_test_assert(
0077 _Atomic_Load_uintptr(&stack_uintptr, ATOMIC_ORDER_RELAXED)
0078 == (uintptr_t) &static_uintptr
0079 );
0080 rtems_test_assert(
0081 !_Atomic_Flag_test_and_set(&stack_flag, ATOMIC_ORDER_RELAXED)
0082 );
0083 }
0084
0085 typedef void (*simple_test_body)(test_context *ctx);
0086
0087 static void test_simple_atomic_add_body(test_context *ctx)
0088 {
0089 unsigned int ia = 8, ib = 4;
0090 unsigned int ic;
0091 uintptr_t pa = 42, pb = 24;
0092 uintptr_t pc;
0093 unsigned long a = 2, b = 1;
0094 unsigned long c;
0095
0096 puts("=== atomic simple add test case ===");
0097
0098 _Atomic_Store_uint(&ctx->uint_atomic, ia, ATOMIC_ORDER_RELAXED);
0099 _Atomic_Fetch_add_uint(&ctx->uint_atomic, ib, ATOMIC_ORDER_RELAXED);
0100 ic = _Atomic_Load_uint(&ctx->uint_atomic, ATOMIC_ORDER_RELAXED);
0101 rtems_test_assert(ic == (ia + ib));
0102
0103 _Atomic_Store_uintptr(&ctx->uintptr_atomic, pa, ATOMIC_ORDER_RELAXED);
0104 _Atomic_Fetch_add_uintptr(&ctx->uintptr_atomic, pb, ATOMIC_ORDER_RELAXED);
0105 pc = _Atomic_Load_uintptr(&ctx->uintptr_atomic, ATOMIC_ORDER_RELAXED);
0106 rtems_test_assert(pc == (pa + pb));
0107
0108 _Atomic_Store_ulong(&ctx->ulong_atomic, a, ATOMIC_ORDER_RELAXED);
0109 _Atomic_Fetch_add_ulong(&ctx->ulong_atomic, b, ATOMIC_ORDER_RELAXED);
0110 c = _Atomic_Load_ulong(&ctx->ulong_atomic, ATOMIC_ORDER_RELAXED);
0111 rtems_test_assert(c == (a + b));
0112 }
0113
0114 static void test_simple_atomic_sub_body(test_context *ctx)
0115 {
0116 unsigned int ia = 8, ib = 4;
0117 unsigned int ic;
0118 uintptr_t pa = 42, pb = 24;
0119 uintptr_t pc;
0120 unsigned long a = 2, b = 1;
0121 unsigned long c;
0122
0123 puts("=== atomic simple sub test case ===");
0124
0125 _Atomic_Store_uint(&ctx->uint_atomic, ia, ATOMIC_ORDER_RELAXED);
0126 _Atomic_Fetch_sub_uint(&ctx->uint_atomic, ib, ATOMIC_ORDER_RELAXED);
0127 ic = _Atomic_Load_uint(&ctx->uint_atomic, ATOMIC_ORDER_RELAXED);
0128 rtems_test_assert(ic == (ia - ib));
0129
0130 _Atomic_Store_uintptr(&ctx->uintptr_atomic, pa, ATOMIC_ORDER_RELAXED);
0131 _Atomic_Fetch_sub_uintptr(&ctx->uintptr_atomic, pb, ATOMIC_ORDER_RELAXED);
0132 pc = _Atomic_Load_uintptr(&ctx->uintptr_atomic, ATOMIC_ORDER_RELAXED);
0133 rtems_test_assert(pc == (pa - pb));
0134
0135 _Atomic_Store_ulong(&ctx->ulong_atomic, a, ATOMIC_ORDER_RELAXED);
0136 _Atomic_Fetch_sub_ulong(&ctx->ulong_atomic, b, ATOMIC_ORDER_RELAXED);
0137 c = _Atomic_Load_ulong(&ctx->ulong_atomic, ATOMIC_ORDER_RELAXED);
0138 rtems_test_assert(c == (a - b));
0139 }
0140
0141 static void test_simple_atomic_or_body(test_context *ctx)
0142 {
0143 unsigned int ia = 8, ib = 4;
0144 unsigned int ic;
0145 uintptr_t pa = 42, pb = 24;
0146 uintptr_t pc;
0147 unsigned long a = 2, b = 1;
0148 unsigned long c;
0149
0150 puts("=== atomic simple or test case ===");
0151
0152 _Atomic_Store_uint(&ctx->uint_atomic, ia, ATOMIC_ORDER_RELAXED);
0153 _Atomic_Fetch_or_uint(&ctx->uint_atomic, ib, ATOMIC_ORDER_RELAXED);
0154 ic = _Atomic_Load_uint(&ctx->uint_atomic, ATOMIC_ORDER_RELAXED);
0155 rtems_test_assert(ic == (ia | ib));
0156
0157 _Atomic_Store_uintptr(&ctx->uintptr_atomic, pa, ATOMIC_ORDER_RELAXED);
0158 _Atomic_Fetch_or_uintptr(&ctx->uintptr_atomic, pb, ATOMIC_ORDER_RELAXED);
0159 pc = _Atomic_Load_uintptr(&ctx->uintptr_atomic, ATOMIC_ORDER_RELAXED);
0160 rtems_test_assert(pc == (pa | pb));
0161
0162 _Atomic_Store_ulong(&ctx->ulong_atomic, a, ATOMIC_ORDER_RELAXED);
0163 _Atomic_Fetch_or_ulong(&ctx->ulong_atomic, b, ATOMIC_ORDER_RELAXED);
0164 c = _Atomic_Load_ulong(&ctx->ulong_atomic, ATOMIC_ORDER_RELAXED);
0165 rtems_test_assert(c == (a | b));
0166 }
0167
0168 static void test_simple_atomic_and_body(test_context *ctx)
0169 {
0170 unsigned int ia = 8, ib = 4;
0171 unsigned int ic;
0172 uintptr_t pa = 42, pb = 24;
0173 uintptr_t pc;
0174 unsigned long a = 2, b = 1;
0175 unsigned long c;
0176
0177 puts("=== atomic simple and test case ===");
0178
0179 _Atomic_Store_uint(&ctx->uint_atomic, ia, ATOMIC_ORDER_RELAXED);
0180 _Atomic_Fetch_and_uint(&ctx->uint_atomic, ib, ATOMIC_ORDER_RELAXED);
0181 ic = _Atomic_Load_uint(&ctx->uint_atomic, ATOMIC_ORDER_RELAXED);
0182 rtems_test_assert(ic == (ia & ib));
0183
0184 _Atomic_Store_uintptr(&ctx->uintptr_atomic, pa, ATOMIC_ORDER_RELAXED);
0185 _Atomic_Fetch_and_uintptr(&ctx->uintptr_atomic, pb, ATOMIC_ORDER_RELAXED);
0186 pc = _Atomic_Load_uintptr(&ctx->uintptr_atomic, ATOMIC_ORDER_RELAXED);
0187 rtems_test_assert(pc == (pa & pb));
0188
0189 _Atomic_Store_ulong(&ctx->ulong_atomic, a, ATOMIC_ORDER_RELAXED);
0190 _Atomic_Fetch_and_ulong(&ctx->ulong_atomic, b, ATOMIC_ORDER_RELAXED);
0191 c = _Atomic_Load_ulong(&ctx->ulong_atomic, ATOMIC_ORDER_RELAXED);
0192 rtems_test_assert(c == (a & b));
0193 }
0194
0195 static void test_simple_atomic_exchange_body(test_context *ctx)
0196 {
0197 unsigned int ia = 8, ib = 4;
0198 unsigned int ic;
0199 uintptr_t pa = 42, pb = 24;
0200 uintptr_t pc;
0201 unsigned long a = 2, b = 1;
0202 unsigned long c;
0203
0204 puts("=== atomic simple exchange test case ===");
0205
0206 _Atomic_Store_uint(&ctx->uint_atomic, ia, ATOMIC_ORDER_RELAXED);
0207 ic = _Atomic_Exchange_uint(&ctx->uint_atomic, ib, ATOMIC_ORDER_RELAXED);
0208 rtems_test_assert(ic == ia);
0209 ic = _Atomic_Load_uint(&ctx->uint_atomic, ATOMIC_ORDER_RELAXED);
0210 rtems_test_assert(ic == ib);
0211
0212 _Atomic_Store_uintptr(&ctx->uintptr_atomic, pa, ATOMIC_ORDER_RELAXED);
0213 pc = _Atomic_Exchange_uintptr(&ctx->uintptr_atomic, pb, ATOMIC_ORDER_RELAXED);
0214 rtems_test_assert(pc == pa);
0215 pc = _Atomic_Load_uintptr(&ctx->uintptr_atomic, ATOMIC_ORDER_RELAXED);
0216 rtems_test_assert(pc == pb);
0217
0218 _Atomic_Store_ulong(&ctx->ulong_atomic, a, ATOMIC_ORDER_RELAXED);
0219 c = _Atomic_Exchange_ulong(&ctx->ulong_atomic, b, ATOMIC_ORDER_RELAXED);
0220 rtems_test_assert(c == a);
0221 c = _Atomic_Load_ulong(&ctx->ulong_atomic, ATOMIC_ORDER_RELAXED);
0222 rtems_test_assert(c == b);
0223 }
0224
0225 static void test_simple_atomic_compare_exchange_body(test_context *ctx)
0226 {
0227 unsigned int ei;
0228 unsigned int vi;
0229 uintptr_t ep;
0230 uintptr_t vp;
0231 unsigned long el;
0232 unsigned long vl;
0233 bool success;
0234
0235 puts("=== atomic simple compare exchange test case ===");
0236
0237 _Atomic_Store_uint(&ctx->uint_atomic, 1, ATOMIC_ORDER_RELAXED);
0238 ei = 2;
0239 success = _Atomic_Compare_exchange_uint(
0240 &ctx->uint_atomic,
0241 &ei,
0242 3,
0243 ATOMIC_ORDER_RELAXED,
0244 ATOMIC_ORDER_RELAXED
0245 );
0246 rtems_test_assert(!success);
0247 rtems_test_assert(ei == 1);
0248 success = _Atomic_Compare_exchange_uint(
0249 &ctx->uint_atomic,
0250 &ei,
0251 3,
0252 ATOMIC_ORDER_RELAXED,
0253 ATOMIC_ORDER_RELAXED
0254 );
0255 rtems_test_assert(success);
0256 vi = _Atomic_Load_uint(&ctx->uint_atomic, ATOMIC_ORDER_RELAXED);
0257 rtems_test_assert(vi == 3);
0258
0259 _Atomic_Store_uintptr(&ctx->uintptr_atomic, 111, ATOMIC_ORDER_RELAXED);
0260 ep = 211;
0261 success = _Atomic_Compare_exchange_uintptr(
0262 &ctx->uintptr_atomic,
0263 &ep,
0264 311,
0265 ATOMIC_ORDER_RELAXED,
0266 ATOMIC_ORDER_RELAXED
0267 );
0268 rtems_test_assert(!success);
0269 rtems_test_assert(ep == 111);
0270 success = _Atomic_Compare_exchange_uintptr(
0271 &ctx->uintptr_atomic,
0272 &ep,
0273 311,
0274 ATOMIC_ORDER_RELAXED,
0275 ATOMIC_ORDER_RELAXED
0276 );
0277 rtems_test_assert(success);
0278 vp = _Atomic_Load_uintptr(&ctx->uintptr_atomic, ATOMIC_ORDER_RELAXED);
0279 rtems_test_assert(vp == 311);
0280
0281 _Atomic_Store_ulong(&ctx->ulong_atomic, 10, ATOMIC_ORDER_RELAXED);
0282 el = 11;
0283 success = _Atomic_Compare_exchange_ulong(
0284 &ctx->ulong_atomic,
0285 &el,
0286 12,
0287 ATOMIC_ORDER_RELAXED,
0288 ATOMIC_ORDER_RELAXED
0289 );
0290 rtems_test_assert(!success);
0291 rtems_test_assert(el == 10);
0292 success = _Atomic_Compare_exchange_ulong(
0293 &ctx->ulong_atomic,
0294 &el,
0295 12,
0296 ATOMIC_ORDER_RELAXED,
0297 ATOMIC_ORDER_RELAXED
0298 );
0299 rtems_test_assert(success);
0300 vl = _Atomic_Load_ulong(&ctx->ulong_atomic, ATOMIC_ORDER_RELAXED);
0301 rtems_test_assert(vl == 12);
0302 }
0303
0304 static const simple_test_body simple_test_bodies[] = {
0305 test_simple_atomic_add_body,
0306 test_simple_atomic_sub_body,
0307 test_simple_atomic_or_body,
0308 test_simple_atomic_and_body,
0309 test_simple_atomic_exchange_body,
0310 test_simple_atomic_compare_exchange_body,
0311 };
0312
0313 #define SIMPLE_TEST_COUNT RTEMS_ARRAY_SIZE(simple_test_bodies)
0314
0315 static void simple_tests(void)
0316 {
0317 test_context *ctx = &test_instance;
0318 size_t test;
0319
0320 for (test = 0; test < SIMPLE_TEST_COUNT; ++test) {
0321 const simple_test_body *test_body = &simple_test_bodies[test];
0322
0323 (*test_body)(ctx);
0324 }
0325 }
0326
0327 static void Init(rtems_task_argument arg)
0328 {
0329 TEST_BEGIN();
0330
0331 test_static_and_dynamic_initialization();
0332 simple_tests();
0333
0334 TEST_END();
0335 rtems_test_exit(0);
0336 }
0337
0338 #define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
0339 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0340
0341 #define CONFIGURE_MAXIMUM_TASKS 1
0342
0343 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
0344
0345 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0346
0347 #define CONFIGURE_INIT
0348
0349 #include <rtems/confdefs.h>