1
0

atomic_tc.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-07-27 flybreak the first version
  9. * 2023-03-21 WangShun add atomic test
  10. * 2023-09-15 xqyjlj change stack size in cpu64
  11. */
  12. #include <rtthread.h>
  13. #include "utest.h"
  14. #include "rtatomic.h"
  15. #include <rthw.h>
  16. #define THREAD_PRIORITY 25
  17. #define THREAD_TIMESLICE 1
  18. #define THREAD_STACKSIZE UTEST_THR_STACK_SIZE
  19. /* convenience macro - return either 64-bit or 32-bit value */
  20. #define ATOMIC_WORD(val_if_64, val_if_32) \
  21. ((rt_atomic_t)((sizeof(void *) == sizeof(uint64_t)) ? (val_if_64) : (val_if_32)))
  22. static rt_atomic_t count = 0;
  23. static rt_sem_t sem_t;
  24. static void test_atomic_api(void)
  25. {
  26. rt_atomic_t base;
  27. rt_atomic_t oldval;
  28. rt_atomic_t result;
  29. /* rt_atomic_t */
  30. uassert_true(sizeof(rt_atomic_t) == ATOMIC_WORD(sizeof(uint64_t), sizeof(uint32_t)));
  31. /* rt_atomic_add */
  32. base = 0;
  33. result = rt_atomic_add(&base, 10);
  34. uassert_true(base == 10);
  35. uassert_true(result == 0);
  36. /* rt_atomic_add negative */
  37. base = 2;
  38. result = rt_atomic_add(&base, -4);
  39. uassert_true(base == -2);
  40. uassert_true(result == 2);
  41. /* rt_atomic_sub */
  42. base = 11;
  43. result = rt_atomic_sub(&base, 10);
  44. uassert_true(base == 1);
  45. uassert_true(result == 11);
  46. /* rt_atomic_sub negative */
  47. base = 2;
  48. result = rt_atomic_sub(&base, -5);
  49. uassert_true(base == 7);
  50. uassert_true(result == 2);
  51. /* rt_atomic_or */
  52. base = 0xFF00;
  53. result = rt_atomic_or(&base, 0x0F0F);
  54. uassert_true(base == 0xFF0F);
  55. uassert_true(result == 0xFF00);
  56. /* rt_atomic_xor */
  57. base = 0xFF00;
  58. result = rt_atomic_xor(&base, 0x0F0F);
  59. uassert_true(base == 0xF00F);
  60. uassert_true(result == 0xFF00);
  61. /* rt_atomic_and */
  62. base = 0xFF00;
  63. result = rt_atomic_and(&base, 0x0F0F);
  64. uassert_true(base == 0x0F00);
  65. uassert_true(result == 0xFF00);
  66. /* rt_atomic_exchange */
  67. base = 0xFF00;
  68. result = rt_atomic_exchange(&base, 0x0F0F);
  69. uassert_true(base == 0x0F0F);
  70. uassert_true(result == 0xFF00);
  71. /* rt_atomic_flag_test_and_set (Flag 0) */
  72. base = 0x0;
  73. result = rt_atomic_flag_test_and_set(&base);
  74. uassert_true(base == 0x1);
  75. uassert_true(result == 0x0);
  76. /* rt_atomic_flag_test_and_set (Flag 1) */
  77. base = 0x1;
  78. result = rt_atomic_flag_test_and_set(&base);
  79. uassert_true(base == 0x1);
  80. uassert_true(result == 0x1);
  81. /* rt_atomic_flag_clear */
  82. base = 0x1;
  83. rt_atomic_flag_clear(&base);
  84. uassert_true(base == 0x0);
  85. /* rt_atomic_load */
  86. base = 0xFF00;
  87. result = rt_atomic_load(&base);
  88. uassert_true(base == 0xFF00);
  89. uassert_true(result == 0xFF00);
  90. /* rt_atomic_store */
  91. base = 0xFF00;
  92. rt_atomic_store(&base, 0x0F0F);
  93. uassert_true(base == 0x0F0F);
  94. /* rt_atomic_compare_exchange_strong (equal) */
  95. base = 10;
  96. oldval = 10;
  97. result = rt_atomic_compare_exchange_strong(&base, &oldval, 11);
  98. uassert_true(base == 11);
  99. uassert_true(result == 0x1);
  100. /* rt_atomic_compare_exchange_strong (not equal) */
  101. base = 10;
  102. oldval = 5;
  103. result = rt_atomic_compare_exchange_strong(&base, &oldval, 11);
  104. uassert_true(base == 10);
  105. uassert_true(result == 0x0);
  106. }
  107. static void ture_entry(void *parameter)
  108. {
  109. int i;
  110. for (i = 0; i < 1000000; i++)
  111. {
  112. rt_atomic_add(&count, 1);
  113. }
  114. rt_sem_release(sem_t);
  115. }
  116. static void test_atomic_add(void)
  117. {
  118. rt_thread_t thread;
  119. size_t i;
  120. sem_t = rt_sem_create("atomic_sem", 0, RT_IPC_FLAG_PRIO);
  121. rt_atomic_store(&count, 0);
  122. thread = rt_thread_create("t1", ture_entry, RT_NULL, THREAD_STACKSIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
  123. rt_thread_startup(thread);
  124. thread = rt_thread_create("t2", ture_entry, RT_NULL, THREAD_STACKSIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
  125. rt_thread_startup(thread);
  126. thread = rt_thread_create("t3", ture_entry, RT_NULL, THREAD_STACKSIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
  127. rt_thread_startup(thread);
  128. for (i = 0; i < 3; i++)
  129. {
  130. rt_sem_take(sem_t, RT_WAITING_FOREVER);
  131. }
  132. i = rt_atomic_load(&count);
  133. uassert_true(i == 3000000);
  134. }
  135. static rt_err_t utest_tc_init(void)
  136. {
  137. return RT_EOK;
  138. }
  139. static rt_err_t utest_tc_cleanup(void)
  140. {
  141. return RT_EOK;
  142. }
  143. static void testcase(void)
  144. {
  145. UTEST_UNIT_RUN(test_atomic_api);
  146. UTEST_UNIT_RUN(test_atomic_add);
  147. }
  148. UTEST_TC_EXPORT(testcase, "testcases.kernel.atomic_tc", utest_tc_init, utest_tc_cleanup, 10);