atomic.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. /* Copyright (C) 2003-2017 Free Software Foundation, Inc.
  2. Copyright (C) 2023 Kalray Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library. If not, see
  14. <http://www.gnu.org/licenses/>. */
  15. /* Mostly copied from aarch64 atomic.h */
  16. #ifndef _KVX_BITS_ATOMIC_H
  17. #define _KVX_BITS_ATOMIC_H
  18. #define typeof __typeof__
  19. #include <stdint.h>
  20. #include <sysdep.h>
  21. typedef int8_t atomic8_t;
  22. typedef uint8_t uatomic8_t;
  23. typedef int_fast8_t atomic_fast8_t;
  24. typedef uint_fast8_t uatomic_fast8_t;
  25. typedef int16_t atomic16_t;
  26. typedef uint16_t uatomic16_t;
  27. typedef int_fast16_t atomic_fast16_t;
  28. typedef uint_fast16_t uatomic_fast16_t;
  29. typedef int32_t atomic32_t;
  30. typedef uint32_t uatomic32_t;
  31. typedef int_fast32_t atomic_fast32_t;
  32. typedef uint_fast32_t uatomic_fast32_t;
  33. typedef int64_t atomic64_t;
  34. typedef uint64_t uatomic64_t;
  35. typedef int_fast64_t atomic_fast64_t;
  36. typedef uint_fast64_t uatomic_fast64_t;
  37. typedef intptr_t atomicptr_t;
  38. typedef uintptr_t uatomicptr_t;
  39. typedef intmax_t atomic_max_t;
  40. typedef uintmax_t uatomic_max_t;
  41. #ifndef atomic_full_barrier
  42. # define atomic_full_barrier() do { atomic_read_barrier(); \
  43. atomic_write_barrier(); } while(0)
  44. #endif
  45. #ifndef atomic_read_barrier
  46. # define atomic_read_barrier() __builtin_kvx_dinval()
  47. #endif
  48. #ifndef atomic_write_barrier
  49. # define atomic_write_barrier() __builtin_kvx_fence()
  50. #endif
  51. #define __HAVE_64B_ATOMICS 1
  52. #define USE_ATOMIC_COMPILER_BUILTINS 1
  53. /* Compare and exchange.
  54. For all "bool" routines, we return FALSE if exchange succesful. */
  55. # define __arch_compare_and_exchange_bool_8_int(mem, newval, oldval, model) \
  56. ({ \
  57. typeof (*mem) __oldval = (oldval); \
  58. !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
  59. model, __ATOMIC_RELAXED); \
  60. })
  61. # define __arch_compare_and_exchange_bool_16_int(mem, newval, oldval, model) \
  62. ({ \
  63. typeof (*mem) __oldval = (oldval); \
  64. !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
  65. model, __ATOMIC_RELAXED); \
  66. })
  67. # define __arch_compare_and_exchange_bool_32_int(mem, newval, oldval, model) \
  68. ({ \
  69. typeof (*mem) __oldval = (oldval); \
  70. !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
  71. model, __ATOMIC_RELAXED); \
  72. })
  73. # define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \
  74. ({ \
  75. typeof (*mem) __oldval = (oldval); \
  76. !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
  77. model, __ATOMIC_RELAXED); \
  78. })
  79. # define __arch_compare_and_exchange_val_8_int(mem, newval, oldval, model) \
  80. ({ \
  81. typeof (*mem) __oldval = (oldval); \
  82. __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
  83. model, __ATOMIC_RELAXED); \
  84. __oldval; \
  85. })
  86. # define __arch_compare_and_exchange_val_16_int(mem, newval, oldval, model) \
  87. ({ \
  88. typeof (*mem) __oldval = (oldval); \
  89. __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
  90. model, __ATOMIC_RELAXED); \
  91. __oldval; \
  92. })
  93. # define __arch_compare_and_exchange_val_32_int(mem, newval, oldval, model) \
  94. ({ \
  95. typeof (*mem) __oldval = (oldval); \
  96. __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
  97. model, __ATOMIC_RELAXED); \
  98. __oldval; \
  99. })
  100. # define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \
  101. ({ \
  102. typeof (*mem) __oldval = (oldval); \
  103. __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
  104. model, __ATOMIC_RELAXED); \
  105. __oldval; \
  106. })
  107. /* Compare and exchange with "acquire" semantics, ie barrier after. */
  108. # define atomic_compare_and_exchange_bool_acq(mem, new, old) \
  109. __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
  110. mem, new, old, __ATOMIC_ACQUIRE)
  111. # define atomic_compare_and_exchange_val_acq(mem, new, old) \
  112. __atomic_val_bysize (__arch_compare_and_exchange_val, int, \
  113. mem, new, old, __ATOMIC_ACQUIRE)
  114. /* Compare and exchange with "release" semantics, ie barrier before. */
  115. # define atomic_compare_and_exchange_val_rel(mem, new, old) \
  116. __atomic_val_bysize (__arch_compare_and_exchange_val, int, \
  117. mem, new, old, __ATOMIC_RELEASE)
  118. /* Atomic exchange (without compare). */
  119. # define __arch_exchange_8_int(mem, newval, model) \
  120. __atomic_exchange_n (mem, newval, model)
  121. # define __arch_exchange_16_int(mem, newval, model) \
  122. __atomic_exchange_n (mem, newval, model)
  123. # define __arch_exchange_32_int(mem, newval, model) \
  124. __atomic_exchange_n (mem, newval, model)
  125. # define __arch_exchange_64_int(mem, newval, model) \
  126. __atomic_exchange_n (mem, newval, model)
  127. # define atomic_exchange_acq(mem, value) \
  128. __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_ACQUIRE)
  129. # define atomic_exchange_rel(mem, value) \
  130. __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_RELEASE)
  131. /* Atomically add value and return the previous (unincremented) value. */
  132. # define __arch_exchange_and_add_8_int(mem, value, model) \
  133. __atomic_fetch_add (mem, value, model)
  134. # define __arch_exchange_and_add_16_int(mem, value, model) \
  135. __atomic_fetch_add (mem, value, model)
  136. # define __arch_exchange_and_add_32_int(mem, value, model) \
  137. __atomic_fetch_add (mem, value, model)
  138. # define __arch_exchange_and_add_64_int(mem, value, model) \
  139. __atomic_fetch_add (mem, value, model)
  140. # define atomic_exchange_and_add_acq(mem, value) \
  141. __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \
  142. __ATOMIC_ACQUIRE)
  143. # define atomic_exchange_and_add_rel(mem, value) \
  144. __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \
  145. #endif