diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/atomic_ops.h | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/common/atomic_ops.h b/src/common/atomic_ops.h index b963e7b99..69fde8421 100644 --- a/src/common/atomic_ops.h +++ b/src/common/atomic_ops.h | |||
| @@ -46,6 +46,43 @@ namespace Common { | |||
| 46 | reinterpret_cast<__int64*>(expected.data())) != 0; | 46 | reinterpret_cast<__int64*>(expected.data())) != 0; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected, | ||
| 50 | u8& actual) { | ||
| 51 | actual = | ||
| 52 | _InterlockedCompareExchange8(reinterpret_cast<volatile char*>(pointer), value, expected); | ||
| 53 | return actual == expected; | ||
| 54 | } | ||
| 55 | |||
| 56 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected, | ||
| 57 | u16& actual) { | ||
| 58 | actual = | ||
| 59 | _InterlockedCompareExchange16(reinterpret_cast<volatile short*>(pointer), value, expected); | ||
| 60 | return actual == expected; | ||
| 61 | } | ||
| 62 | |||
| 63 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected, | ||
| 64 | u32& actual) { | ||
| 65 | actual = | ||
| 66 | _InterlockedCompareExchange(reinterpret_cast<volatile long*>(pointer), value, expected); | ||
| 67 | return actual == expected; | ||
| 68 | } | ||
| 69 | |||
| 70 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected, | ||
| 71 | u64& actual) { | ||
| 72 | actual = _InterlockedCompareExchange64(reinterpret_cast<volatile __int64*>(pointer), value, | ||
| 73 | expected); | ||
| 74 | return actual == expected; | ||
| 75 | } | ||
| 76 | |||
| 77 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected, | ||
| 78 | u128& actual) { | ||
| 79 | const bool result = | ||
| 80 | _InterlockedCompareExchange128(reinterpret_cast<volatile __int64*>(pointer), value[1], | ||
| 81 | value[0], reinterpret_cast<__int64*>(expected.data())) != 0; | ||
| 82 | actual = expected; | ||
| 83 | return result; | ||
| 84 | } | ||
| 85 | |||
| 49 | [[nodiscard]] inline u128 AtomicLoad128(volatile u64* pointer) { | 86 | [[nodiscard]] inline u128 AtomicLoad128(volatile u64* pointer) { |
| 50 | u128 result{}; | 87 | u128 result{}; |
| 51 | _InterlockedCompareExchange128(reinterpret_cast<volatile __int64*>(pointer), result[1], | 88 | _InterlockedCompareExchange128(reinterpret_cast<volatile __int64*>(pointer), result[1], |
| @@ -79,6 +116,42 @@ namespace Common { | |||
| 79 | return __sync_bool_compare_and_swap((unsigned __int128*)pointer, expected_a, value_a); | 116 | return __sync_bool_compare_and_swap((unsigned __int128*)pointer, expected_a, value_a); |
| 80 | } | 117 | } |
| 81 | 118 | ||
| 119 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected, | ||
| 120 | u8& actual) { | ||
| 121 | actual = __sync_val_compare_and_swap(pointer, expected, value); | ||
| 122 | return actual == expected; | ||
| 123 | } | ||
| 124 | |||
| 125 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected, | ||
| 126 | u16& actual) { | ||
| 127 | actual = __sync_val_compare_and_swap(pointer, expected, value); | ||
| 128 | return actual == expected; | ||
| 129 | } | ||
| 130 | |||
| 131 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected, | ||
| 132 | u32& actual) { | ||
| 133 | actual = __sync_val_compare_and_swap(pointer, expected, value); | ||
| 134 | return actual == expected; | ||
| 135 | } | ||
| 136 | |||
| 137 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected, | ||
| 138 | u64& actual) { | ||
| 139 | actual = __sync_val_compare_and_swap(pointer, expected, value); | ||
| 140 | return actual == expected; | ||
| 141 | } | ||
| 142 | |||
| 143 | [[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected, | ||
| 144 | u128& actual) { | ||
| 145 | unsigned __int128 value_a; | ||
| 146 | unsigned __int128 expected_a; | ||
| 147 | unsigned __int128 actual_a; | ||
| 148 | std::memcpy(&value_a, value.data(), sizeof(u128)); | ||
| 149 | std::memcpy(&expected_a, expected.data(), sizeof(u128)); | ||
| 150 | actual_a = __sync_val_compare_and_swap((unsigned __int128*)pointer, expected_a, value_a); | ||
| 151 | std::memcpy(actual.data(), &actual_a, sizeof(u128)); | ||
| 152 | return actual_a == expected_a; | ||
| 153 | } | ||
| 154 | |||
| 82 | [[nodiscard]] inline u128 AtomicLoad128(volatile u64* pointer) { | 155 | [[nodiscard]] inline u128 AtomicLoad128(volatile u64* pointer) { |
| 83 | unsigned __int128 zeros_a = 0; | 156 | unsigned __int128 zeros_a = 0; |
| 84 | unsigned __int128 result_a = | 157 | unsigned __int128 result_a = |