Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:46

0001 /*
0002  * Copyright (C) 2013, 2015 embedded brains GmbH & Co. KG
0003  *
0004  * Copyright (c) 2013 Deng Hengyi.
0005  *
0006  * The license and distribution terms for this file may be
0007  * found in the file LICENSE in this distribution or at
0008  * http://www.rtems.org/license/LICENSE.
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>