summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/atomic_ops.h79
1 files changed, 31 insertions, 48 deletions
diff --git a/src/common/atomic_ops.h b/src/common/atomic_ops.h
index c18bb33c4..9bf6f2f81 100644
--- a/src/common/atomic_ops.h
+++ b/src/common/atomic_ops.h
@@ -15,25 +15,34 @@ namespace Common {
15 15
16#if _MSC_VER 16#if _MSC_VER
17 17
18[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected) { 18template <typename T>
19[[nodiscard]] inline bool AtomicCompareAndSwap(T* pointer, T value, T expected);
20template <typename T>
21[[nodiscard]] inline bool AtomicCompareAndSwap(T* pointer, T value, T expected, T& actual);
22
23template <>
24[[nodiscard]] inline bool AtomicCompareAndSwap<u8>(u8* pointer, u8 value, u8 expected) {
19 const u8 result = 25 const u8 result =
20 _InterlockedCompareExchange8(reinterpret_cast<volatile char*>(pointer), value, expected); 26 _InterlockedCompareExchange8(reinterpret_cast<volatile char*>(pointer), value, expected);
21 return result == expected; 27 return result == expected;
22} 28}
23 29
24[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected) { 30template <>
31[[nodiscard]] inline bool AtomicCompareAndSwap<u16>(u16* pointer, u16 value, u16 expected) {
25 const u16 result = 32 const u16 result =
26 _InterlockedCompareExchange16(reinterpret_cast<volatile short*>(pointer), value, expected); 33 _InterlockedCompareExchange16(reinterpret_cast<volatile short*>(pointer), value, expected);
27 return result == expected; 34 return result == expected;
28} 35}
29 36
30[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected) { 37template <>
38[[nodiscard]] inline bool AtomicCompareAndSwap<u32>(u32* pointer, u32 value, u32 expected) {
31 const u32 result = 39 const u32 result =
32 _InterlockedCompareExchange(reinterpret_cast<volatile long*>(pointer), value, expected); 40 _InterlockedCompareExchange(reinterpret_cast<volatile long*>(pointer), value, expected);
33 return result == expected; 41 return result == expected;
34} 42}
35 43
36[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected) { 44template <>
45[[nodiscard]] inline bool AtomicCompareAndSwap<u64>(u64* pointer, u64 value, u64 expected) {
37 const u64 result = _InterlockedCompareExchange64(reinterpret_cast<volatile __int64*>(pointer), 46 const u64 result = _InterlockedCompareExchange64(reinterpret_cast<volatile __int64*>(pointer),
38 value, expected); 47 value, expected);
39 return result == expected; 48 return result == expected;
@@ -45,29 +54,32 @@ namespace Common {
45 reinterpret_cast<__int64*>(expected.data())) != 0; 54 reinterpret_cast<__int64*>(expected.data())) != 0;
46} 55}
47 56
48[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected, 57template <>
49 u8& actual) { 58[[nodiscard]] inline bool AtomicCompareAndSwap<u8>(u8* pointer, u8 value, u8 expected, u8& actual) {
50 actual = 59 actual =
51 _InterlockedCompareExchange8(reinterpret_cast<volatile char*>(pointer), value, expected); 60 _InterlockedCompareExchange8(reinterpret_cast<volatile char*>(pointer), value, expected);
52 return actual == expected; 61 return actual == expected;
53} 62}
54 63
55[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected, 64template <>
56 u16& actual) { 65[[nodiscard]] inline bool AtomicCompareAndSwap<u16>(u16* pointer, u16 value, u16 expected,
66 u16& actual) {
57 actual = 67 actual =
58 _InterlockedCompareExchange16(reinterpret_cast<volatile short*>(pointer), value, expected); 68 _InterlockedCompareExchange16(reinterpret_cast<volatile short*>(pointer), value, expected);
59 return actual == expected; 69 return actual == expected;
60} 70}
61 71
62[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected, 72template <>
63 u32& actual) { 73[[nodiscard]] inline bool AtomicCompareAndSwap<u32>(u32* pointer, u32 value, u32 expected,
74 u32& actual) {
64 actual = 75 actual =
65 _InterlockedCompareExchange(reinterpret_cast<volatile long*>(pointer), value, expected); 76 _InterlockedCompareExchange(reinterpret_cast<volatile long*>(pointer), value, expected);
66 return actual == expected; 77 return actual == expected;
67} 78}
68 79
69[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected, 80template <>
70 u64& actual) { 81[[nodiscard]] inline bool AtomicCompareAndSwap<u64>(u64* pointer, u64 value, u64 expected,
82 u64& actual) {
71 actual = _InterlockedCompareExchange64(reinterpret_cast<volatile __int64*>(pointer), value, 83 actual = _InterlockedCompareExchange64(reinterpret_cast<volatile __int64*>(pointer), value,
72 expected); 84 expected);
73 return actual == expected; 85 return actual == expected;
@@ -91,23 +103,12 @@ namespace Common {
91 103
92#else 104#else
93 105
94[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected) { 106template <typename T>
95 return __sync_bool_compare_and_swap(pointer, expected, value); 107[[nodiscard]] inline bool AtomicCompareAndSwap(T* pointer, T value, T expected) {
96}
97
98[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected) {
99 return __sync_bool_compare_and_swap(pointer, expected, value);
100}
101
102[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected) {
103 return __sync_bool_compare_and_swap(pointer, expected, value); 108 return __sync_bool_compare_and_swap(pointer, expected, value);
104} 109}
105 110
106[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected) { 111[[nodiscard]] inline bool AtomicCompareAndSwap(u64* pointer, u128 value, u128 expected) {
107 return __sync_bool_compare_and_swap(pointer, expected, value);
108}
109
110[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected) {
111 unsigned __int128 value_a; 112 unsigned __int128 value_a;
112 unsigned __int128 expected_a; 113 unsigned __int128 expected_a;
113 std::memcpy(&value_a, value.data(), sizeof(u128)); 114 std::memcpy(&value_a, value.data(), sizeof(u128));
@@ -115,31 +116,13 @@ namespace Common {
115 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);
116} 117}
117 118
118[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u8* pointer, u8 value, u8 expected, 119template <typename T>
119 u8& actual) { 120[[nodiscard]] inline bool AtomicCompareAndSwap(T* pointer, T value, T expected, T& actual) {
120 actual = __sync_val_compare_and_swap(pointer, expected, value); 121 actual = __sync_val_compare_and_swap(pointer, expected, value);
121 return actual == expected; 122 return actual == expected;
122} 123}
123 124
124[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u16* pointer, u16 value, u16 expected, 125[[nodiscard]] inline bool AtomicCompareAndSwap(u64* pointer, u128 value, u128 expected,
125 u16& actual) {
126 actual = __sync_val_compare_and_swap(pointer, expected, value);
127 return actual == expected;
128}
129
130[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u32* pointer, u32 value, u32 expected,
131 u32& actual) {
132 actual = __sync_val_compare_and_swap(pointer, expected, value);
133 return actual == expected;
134}
135
136[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u64 value, u64 expected,
137 u64& actual) {
138 actual = __sync_val_compare_and_swap(pointer, expected, value);
139 return actual == expected;
140}
141
142[[nodiscard]] inline bool AtomicCompareAndSwap(volatile u64* pointer, u128 value, u128 expected,
143 u128& actual) { 126 u128& actual) {
144 unsigned __int128 value_a; 127 unsigned __int128 value_a;
145 unsigned __int128 expected_a; 128 unsigned __int128 expected_a;
@@ -151,7 +134,7 @@ namespace Common {
151 return actual_a == expected_a; 134 return actual_a == expected_a;
152} 135}
153 136
154[[nodiscard]] inline u128 AtomicLoad128(volatile u64* pointer) { 137[[nodiscard]] inline u128 AtomicLoad128(u64* pointer) {
155 unsigned __int128 zeros_a = 0; 138 unsigned __int128 zeros_a = 0;
156 unsigned __int128 result_a = 139 unsigned __int128 result_a =
157 __sync_val_compare_and_swap((unsigned __int128*)pointer, zeros_a, zeros_a); 140 __sync_val_compare_and_swap((unsigned __int128*)pointer, zeros_a, zeros_a);