Atomic.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. #pragma once
  2. #include <stdint.h>
  3. #include "utils/NonCopyable.h"
  4. #include "c-api/Atomic-c-api.h"
  5. namespace il2cpp
  6. {
  7. namespace os
  8. {
  9. class Atomic : public il2cpp::utils::NonCopyable
  10. {
  11. public:
  12. // All 32bit atomics must be performed on 4-byte aligned addresses. All 64bit atomics must be
  13. // performed on 8-byte aligned addresses.
  14. // Add and Add64 return the *result* of the addition, not the old value! (i.e. they work like
  15. // InterlockedAdd and __sync_add_and_fetch).
  16. static inline void FullMemoryBarrier()
  17. {
  18. UnityPalFullMemoryBarrier();
  19. }
  20. static inline int32_t Add(int32_t* location1, int32_t value)
  21. {
  22. return UnityPalAdd(location1, value);
  23. }
  24. static inline uint32_t Add(uint32_t* location1, uint32_t value)
  25. {
  26. return (uint32_t)Add((int32_t*)location1, (int32_t)value);
  27. }
  28. #if IL2CPP_ENABLE_INTERLOCKED_64_REQUIRED_ALIGNMENT
  29. static inline int64_t Add64(int64_t* location1, int64_t value)
  30. {
  31. return UnityPalAdd64(location1, value);
  32. }
  33. #endif
  34. template<typename T>
  35. static inline T* CompareExchangePointer(T** dest, T* newValue, T* oldValue)
  36. {
  37. return static_cast<T*>(UnityPalCompareExchangePointer((void**)dest, newValue, oldValue));
  38. }
  39. template<typename T>
  40. static inline T* ExchangePointer(T** dest, T* newValue)
  41. {
  42. return static_cast<T*>(UnityPalExchangePointer((void**)dest, newValue));
  43. }
  44. static inline int64_t Read64(int64_t* addr)
  45. {
  46. return UnityPalRead64(addr);
  47. }
  48. static inline uint64_t Read64(uint64_t* addr)
  49. {
  50. return (uint64_t)Read64((int64_t*)addr);
  51. }
  52. template<typename T>
  53. static inline T* ReadPointer(T** pointer)
  54. {
  55. #if IL2CPP_SIZEOF_VOID_P == 4
  56. return reinterpret_cast<T*>(Add(reinterpret_cast<int32_t*>(pointer), 0));
  57. #else
  58. return reinterpret_cast<T*>(Read64(reinterpret_cast<int64_t*>(pointer)));
  59. #endif
  60. }
  61. static inline int32_t Increment(int32_t* value)
  62. {
  63. return UnityPalIncrement(value);
  64. }
  65. static inline uint32_t Increment(uint32_t* value)
  66. {
  67. return (uint32_t)Increment((int32_t*)value);
  68. }
  69. #if IL2CPP_ENABLE_INTERLOCKED_64_REQUIRED_ALIGNMENT
  70. static inline int64_t Increment64(int64_t* value)
  71. {
  72. return UnityPalIncrement64(value);
  73. }
  74. static inline uint64_t Increment64(uint64_t* value)
  75. {
  76. return (uint64_t)Increment64((int64_t*)value);
  77. }
  78. #endif
  79. static inline int32_t Decrement(int32_t* value)
  80. {
  81. return UnityPalDecrement(value);
  82. }
  83. static inline uint32_t Decrement(uint32_t* value)
  84. {
  85. return (uint32_t)Decrement((int32_t*)value);
  86. }
  87. #if IL2CPP_ENABLE_INTERLOCKED_64_REQUIRED_ALIGNMENT
  88. static inline int64_t Decrement64(int64_t* value)
  89. {
  90. return UnityPalDecrement64(value);
  91. }
  92. static inline uint64_t Decrement64(uint64_t* value)
  93. {
  94. return (uint64_t)Decrement64((int64_t*)value);
  95. }
  96. #endif
  97. static inline int32_t CompareExchange(int32_t* dest, int32_t exchange, int32_t comparand)
  98. {
  99. return UnityPalCompareExchange(dest, exchange, comparand);
  100. }
  101. static inline uint32_t CompareExchange(uint32_t* value, uint32_t newValue, uint32_t oldValue)
  102. {
  103. return (uint32_t)CompareExchange((int32_t*)value, newValue, oldValue);
  104. }
  105. static inline int64_t CompareExchange64(int64_t* dest, int64_t exchange, int64_t comparand)
  106. {
  107. return UnityPalCompareExchange64(dest, exchange, comparand);
  108. }
  109. static inline uint64_t CompareExchange64(uint64_t* value, uint64_t newValue, uint64_t oldValue)
  110. {
  111. return (uint64_t)CompareExchange64((int64_t*)value, newValue, oldValue);
  112. }
  113. static inline int32_t Exchange(int32_t* dest, int32_t exchange)
  114. {
  115. return UnityPalExchange(dest, exchange);
  116. }
  117. static inline uint32_t Exchange(uint32_t* value, uint32_t newValue)
  118. {
  119. return (uint32_t)Exchange((int32_t*)value, newValue);
  120. }
  121. #if IL2CPP_ENABLE_INTERLOCKED_64_REQUIRED_ALIGNMENT
  122. static inline int64_t Exchange64(int64_t* dest, int64_t exchange)
  123. {
  124. return UnityPalExchange64(dest, exchange);
  125. }
  126. static inline uint64_t Exchange64(uint64_t* value, uint64_t newValue)
  127. {
  128. return (uint64_t)Exchange64((int64_t*)value, newValue);
  129. }
  130. #endif
  131. };
  132. }
  133. }