atomic.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /* Copyright (C) 2024 uClibc-ng contributors.
  2. Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
  3. */
  4. #ifndef _LOONGARCH64_ATOMIC_MACHINE_H
  5. #define _LOONGARCH64_ATOMIC_MACHINE_H 1
  6. #define typeof __typeof__
  7. #include <stdint.h>
  8. #include <sysdep.h>
  9. typedef int8_t atomic8_t;
  10. typedef int16_t atomic16_t;
  11. typedef int32_t atomic32_t;
  12. typedef int64_t atomic64_t;
  13. typedef uint8_t uatomic8_t;
  14. typedef uint16_t uatomic16_t;
  15. typedef uint32_t uatomic32_t;
  16. typedef uint64_t uatomic64_t;
  17. typedef intptr_t atomicptr_t;
  18. typedef uintptr_t uatomicptr_t;
  19. typedef intmax_t atomic_max_t;
  20. typedef uintmax_t uatomic_max_t;
  21. #define __HAVE_64B_ATOMICS 1
  22. #define USE_ATOMIC_COMPILER_BUILTINS 1
  23. /* Compare and exchange.
  24. For all "bool" routines, we return FALSE if exchange succesful. */
  25. # define __arch_compare_and_exchange_bool_8_int(mem, newval, oldval, model) \
  26. ({ \
  27. typeof (*mem) __oldval = (oldval); \
  28. !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
  29. model, __ATOMIC_RELAXED); \
  30. })
  31. # define __arch_compare_and_exchange_bool_16_int(mem, newval, oldval, model) \
  32. ({ \
  33. typeof (*mem) __oldval = (oldval); \
  34. !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
  35. model, __ATOMIC_RELAXED); \
  36. })
  37. # define __arch_compare_and_exchange_bool_32_int(mem, newval, oldval, model) \
  38. ({ \
  39. typeof (*mem) __oldval = (oldval); \
  40. !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
  41. model, __ATOMIC_RELAXED); \
  42. })
  43. # define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \
  44. ({ \
  45. typeof (*mem) __oldval = (oldval); \
  46. !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
  47. model, __ATOMIC_RELAXED); \
  48. })
  49. # define __arch_compare_and_exchange_val_8_int(mem, newval, oldval, model) \
  50. ({ \
  51. typeof (*mem) __oldval = (oldval); \
  52. __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
  53. model, __ATOMIC_RELAXED); \
  54. __oldval; \
  55. })
  56. # define __arch_compare_and_exchange_val_16_int(mem, newval, oldval, model) \
  57. ({ \
  58. typeof (*mem) __oldval = (oldval); \
  59. __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
  60. model, __ATOMIC_RELAXED); \
  61. __oldval; \
  62. })
  63. # define __arch_compare_and_exchange_val_32_int(mem, newval, oldval, model) \
  64. ({ \
  65. typeof (*mem) __oldval = (oldval); \
  66. __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
  67. model, __ATOMIC_RELAXED); \
  68. __oldval; \
  69. })
  70. # define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \
  71. ({ \
  72. typeof (*mem) __oldval = (oldval); \
  73. __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
  74. model, __ATOMIC_RELAXED); \
  75. __oldval; \
  76. })
  77. /* Compare and exchange with "acquire" semantics, ie barrier after. */
  78. # define atomic_compare_and_exchange_bool_acq(mem, new, old) \
  79. __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
  80. mem, new, old, __ATOMIC_ACQUIRE)
  81. # define atomic_compare_and_exchange_val_acq(mem, new, old) \
  82. __atomic_val_bysize (__arch_compare_and_exchange_val, int, \
  83. mem, new, old, __ATOMIC_ACQUIRE)
  84. /* Compare and exchange with "release" semantics, ie barrier before. */
  85. # define atomic_compare_and_exchange_val_rel(mem, new, old) \
  86. __atomic_val_bysize (__arch_compare_and_exchange_val, int, \
  87. mem, new, old, __ATOMIC_RELEASE)
  88. /* Atomic exchange (without compare). */
  89. # define __arch_exchange_8_int(mem, newval, model) \
  90. __atomic_exchange_n (mem, newval, model)
  91. # define __arch_exchange_16_int(mem, newval, model) \
  92. __atomic_exchange_n (mem, newval, model)
  93. # define __arch_exchange_32_int(mem, newval, model) \
  94. __atomic_exchange_n (mem, newval, model)
  95. # define __arch_exchange_64_int(mem, newval, model) \
  96. __atomic_exchange_n (mem, newval, model)
  97. # define atomic_exchange_acq(mem, value) \
  98. __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_ACQUIRE)
  99. # define atomic_exchange_rel(mem, value) \
  100. __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_RELEASE)
  101. /* Atomically add value and return the previous (unincremented) value. */
  102. # define __arch_exchange_and_add_8_int(mem, value, model) \
  103. __atomic_fetch_add (mem, value, model)
  104. # define __arch_exchange_and_add_16_int(mem, value, model) \
  105. __atomic_fetch_add (mem, value, model)
  106. # define __arch_exchange_and_add_32_int(mem, value, model) \
  107. __atomic_fetch_add (mem, value, model)
  108. # define __arch_exchange_and_add_64_int(mem, value, model) \
  109. __atomic_fetch_add (mem, value, model)
  110. # define atomic_exchange_and_add_acq(mem, value) \
  111. __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \
  112. __ATOMIC_ACQUIRE)
  113. # define atomic_exchange_and_add_rel(mem, value) \
  114. __atomic_val_bysize (__arch_exchange_and_add, int, mem, value, \
  115. __ATOMIC_RELEASE)
  116. /* Barrier macro. */
  117. #define atomic_full_barrier() __sync_synchronize()
  118. #endif