Atomic.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #pragma once
  2. #include <stdint.h>
  3. #include "il2cpp-config.h"
  4. namespace il2cpp
  5. {
  6. namespace vm
  7. {
  8. class LIBIL2CPP_CODEGEN_API Atomic
  9. {
  10. public:
  11. static int32_t Add(volatile int32_t* location1, int32_t value);
  12. static int64_t Add64(volatile int64_t* location1, int64_t value);
  13. static int32_t Increment(volatile int32_t* value);
  14. static int64_t Increment64(volatile int64_t* value);
  15. static int32_t Decrement(volatile int32_t* value);
  16. static int64_t Decrement64(volatile int64_t* value);
  17. static int32_t CompareExchange(volatile int32_t* dest, int32_t exchange, int32_t comparand);
  18. static int64_t CompareExchange64(volatile int64_t* dest, int64_t exchange, int64_t comparand);
  19. static void* CompareExchangePointer(void* volatile* dest, void* exchange, void* comparand);
  20. static int32_t Exchange(volatile int32_t* dest, int32_t exchange);
  21. static int64_t Exchange64(volatile int64_t* dest, int64_t exchange);
  22. static void* ExchangePointer(void* volatile* dest, void* exchange);
  23. static int64_t Read64(volatile int64_t* addr);
  24. static void FullMemoryBarrier();
  25. static inline uint32_t Add(volatile uint32_t* location1, uint32_t value)
  26. {
  27. return static_cast<uint32_t>(Add((volatile int32_t*)location1, (int32_t)value));
  28. }
  29. template<typename T>
  30. static inline T* CompareExchangePointer(T* volatile* dest, T* newValue, T* oldValue)
  31. {
  32. return static_cast<T*>(CompareExchangePointer((void*volatile*)dest, newValue, oldValue));
  33. }
  34. template<typename T>
  35. static inline T* ExchangePointer(T* volatile* dest, T* newValue)
  36. {
  37. return static_cast<T*>(ExchangePointer((void*volatile*)dest, newValue));
  38. }
  39. static inline uint64_t Read64(volatile uint64_t* addr)
  40. {
  41. return static_cast<uint64_t>(Read64((volatile int64_t*)addr));
  42. }
  43. template<typename T>
  44. static inline T* ReadPointer(T* volatile* pointer)
  45. {
  46. #if IL2CPP_SIZEOF_VOID_P == 4
  47. return reinterpret_cast<T*>(Add(reinterpret_cast<volatile int32_t*>(pointer), 0));
  48. #else
  49. return reinterpret_cast<T*>(Add64(reinterpret_cast<volatile int64_t*>(pointer), 0));
  50. #endif
  51. }
  52. static inline uint32_t Increment(volatile uint32_t* value)
  53. {
  54. return static_cast<uint32_t>(Increment(reinterpret_cast<volatile int32_t*>(value)));
  55. }
  56. static inline uint64_t Increment64(volatile uint64_t* value)
  57. {
  58. return static_cast<uint64_t>(Increment64(reinterpret_cast<volatile int64_t*>(value)));
  59. }
  60. static inline uint32_t Decrement(volatile uint32_t* value)
  61. {
  62. return static_cast<uint32_t>(Decrement(reinterpret_cast<volatile int32_t*>(value)));
  63. }
  64. static inline uint64_t Decrement64(volatile uint64_t* value)
  65. {
  66. return static_cast<uint64_t>(Decrement64(reinterpret_cast<volatile int64_t*>(value)));
  67. }
  68. static inline uint32_t CompareExchange(volatile uint32_t* value, uint32_t newValue, uint32_t oldValue)
  69. {
  70. return static_cast<uint32_t>(CompareExchange(reinterpret_cast<volatile int32_t*>(value), newValue, oldValue));
  71. }
  72. static inline uint64_t CompareExchange64(volatile uint64_t* value, uint64_t newValue, uint64_t oldValue)
  73. {
  74. return static_cast<uint64_t>(CompareExchange64(reinterpret_cast<volatile int64_t*>(value), newValue, oldValue));
  75. }
  76. static inline uint32_t Exchange(volatile uint32_t* value, uint32_t newValue)
  77. {
  78. return static_cast<uint32_t>(Exchange(reinterpret_cast<volatile int32_t*>(value), newValue));
  79. }
  80. static inline uint64_t Exchange64(volatile uint64_t* value, uint64_t newValue)
  81. {
  82. return static_cast<uint64_t>(Exchange64(reinterpret_cast<volatile int64_t*>(value), newValue));
  83. }
  84. };
  85. } /* namesapce vm */
  86. } /* namespace il2cpp */