atomic_gcc.h 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. #pragma once
  2. #define ATOMIC_COMPILER_BARRIER() __asm__ __volatile__("" \
  3. : \
  4. : \
  5. : "memory")
  6. static inline TAtomicBase AtomicGet(const TAtomic& a) {
  7. TAtomicBase tmp;
  8. #if defined(_arm64_)
  9. __asm__ __volatile__(
  10. "ldar %x[value], %[ptr] \n\t"
  11. : [value] "=r"(tmp)
  12. : [ptr] "Q"(a)
  13. : "memory");
  14. #else
  15. __atomic_load(&a, &tmp, __ATOMIC_ACQUIRE);
  16. #endif
  17. return tmp;
  18. }
  19. static inline void AtomicSet(TAtomic& a, TAtomicBase v) {
  20. #if defined(_arm64_)
  21. __asm__ __volatile__(
  22. "stlr %x[value], %[ptr] \n\t"
  23. : [ptr] "=Q"(a)
  24. : [value] "r"(v)
  25. : "memory");
  26. #else
  27. __atomic_store(&a, &v, __ATOMIC_RELEASE);
  28. #endif
  29. }
  30. static inline intptr_t AtomicIncrement(TAtomic& p) {
  31. return __atomic_add_fetch(&p, 1, __ATOMIC_SEQ_CST);
  32. }
  33. static inline intptr_t AtomicGetAndIncrement(TAtomic& p) {
  34. return __atomic_fetch_add(&p, 1, __ATOMIC_SEQ_CST);
  35. }
  36. static inline intptr_t AtomicDecrement(TAtomic& p) {
  37. return __atomic_sub_fetch(&p, 1, __ATOMIC_SEQ_CST);
  38. }
  39. static inline intptr_t AtomicGetAndDecrement(TAtomic& p) {
  40. return __atomic_fetch_sub(&p, 1, __ATOMIC_SEQ_CST);
  41. }
  42. static inline intptr_t AtomicAdd(TAtomic& p, intptr_t v) {
  43. return __atomic_add_fetch(&p, v, __ATOMIC_SEQ_CST);
  44. }
  45. static inline intptr_t AtomicGetAndAdd(TAtomic& p, intptr_t v) {
  46. return __atomic_fetch_add(&p, v, __ATOMIC_SEQ_CST);
  47. }
  48. static inline intptr_t AtomicSwap(TAtomic* p, intptr_t v) {
  49. (void)p; // disable strange 'parameter set but not used' warning on gcc
  50. intptr_t ret;
  51. __atomic_exchange(p, &v, &ret, __ATOMIC_SEQ_CST);
  52. return ret;
  53. }
  54. static inline bool AtomicCas(TAtomic* a, intptr_t exchange, intptr_t compare) {
  55. (void)a; // disable strange 'parameter set but not used' warning on gcc
  56. return __atomic_compare_exchange(a, &compare, &exchange, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
  57. }
  58. static inline intptr_t AtomicGetAndCas(TAtomic* a, intptr_t exchange, intptr_t compare) {
  59. (void)a; // disable strange 'parameter set but not used' warning on gcc
  60. __atomic_compare_exchange(a, &compare, &exchange, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST);
  61. return compare;
  62. }
  63. static inline intptr_t AtomicOr(TAtomic& a, intptr_t b) {
  64. return __atomic_or_fetch(&a, b, __ATOMIC_SEQ_CST);
  65. }
  66. static inline intptr_t AtomicXor(TAtomic& a, intptr_t b) {
  67. return __atomic_xor_fetch(&a, b, __ATOMIC_SEQ_CST);
  68. }
  69. static inline intptr_t AtomicAnd(TAtomic& a, intptr_t b) {
  70. return __atomic_and_fetch(&a, b, __ATOMIC_SEQ_CST);
  71. }
  72. static inline void AtomicBarrier() {
  73. __sync_synchronize();
  74. }