stdatomic.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*
  2. * Copyright (c) mlibc & plct lab
  3. *
  4. * SPDX-License-Identifier: MIT
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2024/7/22 0Bitbiscuits the first version
  9. */
  10. #ifndef MLIBC_STDATOMIC_H__
  11. #define MLIBC_STDATOMIC_H__
  12. #include <stdint.h>
  13. #include <stdbool.h>
  14. #include <stddef.h>
  15. #include <sys/types.h>
  16. #include <compiler.h>
  17. #include <sys/features.h>
  18. /**
  19. * @brief judge which atomic session we choice
  20. */
  21. #if __GNUC_PREREQ__(4, 7)
  22. #define __GNUC_ATOMICS
  23. #else
  24. #define __HW_ATOMICS
  25. #endif
  26. /**
  27. * @brief atomic type definition
  28. */
  29. #ifdef __GNUC_ATOMICS
  30. #define mlibc_atomic(type) _Atomic(type)
  31. #else
  32. #define mlibc_atomic(type) \
  33. struct \
  34. { \
  35. volatile type value; \
  36. }
  37. #endif /* __HW_ATOMICS */
  38. typedef mlibc_atomic(bool) atomic_bool;
  39. typedef mlibc_atomic(char) atomic_char;
  40. typedef mlibc_atomic(signed char) atomic_schar;
  41. typedef mlibc_atomic(unsigned char) atomic_uchar;
  42. typedef mlibc_atomic(short) atomic_short;
  43. typedef mlibc_atomic(unsigned short) atomic_ushort;
  44. typedef mlibc_atomic(int) atomic_int;
  45. typedef mlibc_atomic(unsigned int) atomic_uint;
  46. typedef mlibc_atomic(long) atomic_long;
  47. typedef mlibc_atomic(unsigned long) atomic_ulong;
  48. typedef mlibc_atomic(long long) atomic_llong;
  49. typedef mlibc_atomic(unsigned long long) atomic_ullong;
  50. typedef mlibc_atomic(uintptr_t) atomic_uintptr_t;
  51. typedef mlibc_atomic(size_t) atomic_size_t;
  52. typedef mlibc_atomic(ptrdiff_t) atomic_ptrdiff_t;
  53. /**
  54. * @brief atomic operation type definition
  55. */
  56. #ifndef __ATOMIC_RELAXED
  57. #define __ATOMIC_RELAXED 0
  58. #endif
  59. #ifndef __ATOMIC_CONSUME
  60. #define __ATOMIC_CONSUME 1
  61. #endif
  62. #ifndef __ATOMIC_ACQUIRE
  63. #define __ATOMIC_ACQUIRE 2
  64. #endif
  65. #ifndef __ATOMIC_RELEASE
  66. #define __ATOMIC_RELEASE 3
  67. #endif
  68. #ifndef __ATOMIC_ACQ_REL
  69. #define __ATOMIC_ACQ_REL 4
  70. #endif
  71. #ifndef __ATOMIC_SEQ_CST
  72. #define __ATOMIC_SEQ_CST 5
  73. #endif
  74. typedef enum {
  75. memory_order_relaxed = __ATOMIC_RELAXED,
  76. memory_order_consume = __ATOMIC_CONSUME,
  77. memory_order_acquire = __ATOMIC_ACQUIRE,
  78. memory_order_release = __ATOMIC_RELEASE,
  79. memory_order_acq_rel = __ATOMIC_ACQ_REL,
  80. memory_order_seq_cst = __ATOMIC_SEQ_CST
  81. } memory_order;
  82. /**
  83. * @brief Definition of explicit atomic operations
  84. */
  85. #ifdef __GNUC_ATOMICS
  86. #define atomic_compare_exchange_strong_explicit(object, expected, \
  87. desired, success, failure) \
  88. __atomic_compare_exchange_n(object, expected, \
  89. desired, 0, success, failure)
  90. #define atomic_compare_exchange_weak_explicit(object, expected, \
  91. desired, success, failure) \
  92. __atomic_compare_exchange_n(object, expected, \
  93. desired, 1, success, failure)
  94. #define atomic_exchange_explicit(object, desired, order) \
  95. __atomic_exchange_n(object, desired, order)
  96. #define atomic_fetch_add_explicit(object, operand, order) \
  97. __atomic_fetch_add(object, operand, order)
  98. #define atomic_fetch_and_explicit(object, operand, order) \
  99. __atomic_fetch_and(object, operand, order)
  100. #define atomic_fetch_or_explicit(object, operand, order) \
  101. __atomic_fetch_or(object, operand, order)
  102. #define atomic_fetch_sub_explicit(object, operand, order) \
  103. __atomic_fetch_sub(object, operand, order)
  104. #define atomic_fetch_xor_explicit(object, operand, order) \
  105. __atomic_fetch_xor(object, operand, order)
  106. #define atomic_load_explicit(object, order) \
  107. __atomic_load_n(object, order)
  108. #define atomic_store_explicit(object, desired, order) \
  109. __atomic_store_n(object, desired, order)
  110. #else
  111. #error "mlibc realization base on arch(todo)"
  112. #endif /* EXPLICIT ATOMIC OPERATION */
  113. /**
  114. * @brief Definition of hidden atomic operations
  115. */
  116. #define atomic_compare_exchange_strong(object, expected, desired) \
  117. atomic_compare_exchange_strong_explicit(object, expected, \
  118. desired, memory_order_seq_cst, memory_order_seq_cst)
  119. #define atomic_compare_exchange_weak(object, expected, desired) \
  120. atomic_compare_exchange_weak_explicit(object, expected, \
  121. desired, memory_order_seq_cst, memory_order_seq_cst)
  122. #define atomic_exchange(object, desired) \
  123. atomic_exchange_explicit(object, desired, memory_order_seq_cst)
  124. #define atomic_fetch_add(object, operand) \
  125. atomic_fetch_add_explicit(object, operand, memory_order_seq_cst)
  126. #define atomic_fetch_and(object, operand) \
  127. atomic_fetch_and_explicit(object, operand, memory_order_seq_cst)
  128. #define atomic_fetch_or(object, operand) \
  129. atomic_fetch_or_explicit(object, operand, memory_order_seq_cst)
  130. #define atomic_fetch_sub(object, operand) \
  131. atomic_fetch_sub_explicit(object, operand, memory_order_seq_cst)
  132. #define atomic_fetch_xor(object, operand) \
  133. atomic_fetch_xor_explicit(object, operand, memory_order_seq_cst)
  134. #define atomic_load(object) \
  135. atomic_load_explicit(object, memory_order_seq_cst)
  136. #define atomic_store(object, desired) \
  137. atomic_store_explicit(object, desired, memory_order_seq_cst)
  138. /**
  139. * @brief Atomic flag type and operations.
  140. */
  141. typedef struct {
  142. atomic_bool __flag;
  143. } atomic_flag;
  144. mlibc_inline bool
  145. atomic_flag_test_and_set_explicit(volatile atomic_flag *__object,
  146. memory_order __order)
  147. {
  148. return (atomic_exchange_explicit(&__object->__flag, 1, __order));
  149. }
  150. mlibc_inline void
  151. atomic_flag_clear_explicit(volatile atomic_flag *__object, memory_order __order)
  152. {
  153. atomic_store_explicit(&__object->__flag, 0, __order);
  154. }
  155. mlibc_inline bool
  156. atomic_flag_test_and_set(volatile atomic_flag *__object)
  157. {
  158. return (atomic_flag_test_and_set_explicit(__object,
  159. memory_order_seq_cst));
  160. }
  161. mlibc_inline void
  162. atomic_flag_clear(volatile atomic_flag *__object)
  163. {
  164. atomic_flag_clear_explicit(__object, memory_order_seq_cst);
  165. }
  166. #endif /* MLIBC_STDATOMIC_H__ */