OnixS C++ CME MDP Premium Market Data Handler 5.11.1
Users' manual and API documentation
Loading...
Searching...
No Matches
Atomic.h
Go to the documentation of this file.
1// Copyright Onix Solutions Limited [OnixS]. All rights reserved.
2//
3// This software owned by Onix Solutions Limited [OnixS] and is
4// protected by copyright law and international copyright treaties.
5//
6// Access to and use of the software is governed by the terms of the applicable
7// OnixS Software Services Agreement (the Agreement) and Customer end user license
8// agreements granting a non-assignable, non-transferable and non-exclusive license
9// to use the software for it's own data processing purposes under the terms defined
10// in the Agreement.
11//
12// Except as otherwise granted within the terms of the Agreement, copying or
13// reproduction of any part of this source code or associated reference material
14// to any other location for further reproduction or redistribution, and any
15// amendments to this copyright notice, are expressly prohibited.
16//
17// Any reproduction or redistribution for sale or hiring of the Software not in
18// accordance with the terms of the Agreement is a violation of copyright law.
19//
20
21#pragma once
22
23#include <type_traits>
24
25#if defined(_MSC_VER)
26# include <intrin.h>
27#endif
28
30
32
33#if defined(_MSC_VER)
34
35template <size_t SizeOf>
36class AtomicOps;
37
38template <>
39class AtomicOps<1>
40{
41 typedef char Integral;
42
43public:
44 template <class Atomic, class Target>
45 static void read(volatile Atomic* atomic, Target* target)
46 {
47 *(Integral*) target = *(volatile Integral*) atomic;
48
49 _ReadWriteBarrier();
50 }
51
52 template <class Atomic, class Addend>
53 static void add(volatile Atomic* atomic, Addend* addend)
54 {
55 const Integral addendValue = *static_cast<Integral*>(addend);
56
57 *(Integral*) addend = (_InterlockedExchangeAdd8((volatile Integral*) atomic, addendValue) + addendValue);
58 }
59
60 template <class Atomic, class Value>
61 static void store(volatile Atomic* atomic, const Value* value)
62 {
63 _InterlockedExchange8((volatile Integral*) atomic, *(const Integral*) value);
64 }
65
66 template <class Atomic, class Value>
67 static void exchange(volatile Atomic* atomic, Value* value)
68 {
69 *(Integral*) value = _InterlockedExchange8((volatile Integral*) atomic, *static_cast<Integral*>(value));
70 }
71
72 template <class Atomic, class Comparand, class Value>
73 static bool compareExchange(volatile Atomic* atomic, Comparand* comparand, const Value* value)
74 {
75 const Integral comparandValue = *(Integral*) comparand;
76
77 const Integral previous =
78 _InterlockedCompareExchange8((volatile Integral*) atomic, *(const Integral*) value, comparandValue);
79
80 if (previous == comparandValue)
81 {
82 return true;
83 }
84
85 *(Integral*) value = previous;
86
87 return false;
88 }
89};
90
91template <>
92class AtomicOps<2>
93{
94 typedef short Integral;
95
96public:
97 template <class Atomic, class Target>
98 static void read(volatile Atomic* atomic, Target* target)
99 {
100 *(Integral*) target = *(volatile Integral*) atomic;
101
102 _ReadWriteBarrier();
103 }
104
105 template <class Atomic, class Addend>
106 static void add(volatile Atomic* atomic, Addend* addend)
107 {
108 const Integral addendValue = *static_cast<Integral*>(addend);
109
110 *(Integral*) addend = (_InterlockedExchangeAdd16((volatile Integral*) atomic, addendValue) + addendValue);
111 }
112
113 template <class Atomic, class Value>
114 static void store(volatile Atomic* atomic, const Value* value)
115 {
116 _InterlockedExchange16((volatile Integral*) atomic, *(const Integral*) value);
117 }
118
119 template <class Atomic, class Value>
120 static void exchange(volatile Atomic* atomic, Value* value)
121 {
122 *(Integral*) value = _InterlockedExchange16((volatile Integral*) atomic, *static_cast<Integral*>(value));
123 }
124
125 template <class Atomic, class Comparand, class Value>
126 static bool compareExchange(volatile Atomic* atomic, Comparand* comparand, const Value* value)
127 {
128 const Integral comparandValue = *(Integral*) comparand;
129
130 const Integral previous =
131 _InterlockedCompareExchange16((volatile Integral*) atomic, *(const Integral*) value, comparandValue);
132
133 if (previous == comparandValue)
134 {
135 return true;
136 }
137
138 *(Integral*) value = previous;
139
140 return false;
141 }
142};
143
144template <>
145class AtomicOps<4>
146{
147 typedef long Integral;
148
149public:
150 template <class Atomic, class Target>
151 static void read(volatile Atomic* atomic, Target* target)
152 {
153 *(Integral*) target = *(volatile Integral*) atomic;
154
155 _ReadWriteBarrier();
156 }
157
158 template <class Atomic, class Addend>
159 static void add(volatile Atomic* atomic, Addend* addend)
160 {
161 const Integral addendValue = *static_cast<Integral*>(addend);
162
163 *(Integral*) addend = (_InterlockedExchangeAdd((volatile Integral*) atomic, addendValue) + addendValue);
164 }
165
166 template <class Atomic, class Value>
167 static void store(volatile Atomic* atomic, const Value* value)
168 {
169 _InterlockedExchange((volatile Integral*) atomic, *(const Integral*) value);
170 }
171
172 template <class Atomic, class Value>
173 static void exchange(volatile Atomic* atomic, Value* value)
174 {
175 *(Integral*) value = _InterlockedExchange((volatile Integral*) atomic, *static_cast<Integral*>(value));
176 }
177
178 template <class Atomic, class Comparand, class Value>
179 static bool compareExchange(volatile Atomic* atomic, Comparand* comparand, const Value* value)
180 {
181 const Integral comparandValue = *(Integral*) comparand;
182
183 const Integral previous =
184 _InterlockedCompareExchange((volatile Integral*) atomic, *(const Integral*) value, comparandValue);
185
186 if (previous == comparandValue)
187 {
188 return true;
189 }
190
191 *(Integral*) value = previous;
192
193 return false;
194 }
195};
196
197template <>
198class AtomicOps<8>
199{
200 typedef long long Integral;
201
202public:
203 template <class Atomic, class Target>
204 static void read(volatile Atomic* atomic, Target* target)
205 {
206 *(Integral*) target = *(volatile Integral*) atomic;
207
208 _ReadWriteBarrier();
209 }
210
211 template <class Atomic, class Addend>
212 static void add(volatile Atomic* atomic, Addend* addend)
213 {
214 const Integral addendValue = *static_cast<Integral*>(addend);
215
216 *(Integral*) addend = (_InterlockedExchangeAdd64((volatile Integral*) atomic, addendValue) + addendValue);
217 }
218
219 template <class Atomic, class Value>
220 static void store(volatile Atomic* atomic, const Value* value)
221 {
222 _InterlockedExchange64((volatile Integral*) atomic, *(const Integral*) value);
223 }
224
225 template <class Atomic, class Value>
226 static void exchange(volatile Atomic* atomic, Value* value)
227 {
228 *(Integral*) value = _InterlockedExchange64((volatile Integral*) atomic, *static_cast<Integral*>(value));
229 }
230
231 template <class Atomic, class Comparand, class Value>
232 static bool compareExchange(volatile Atomic* atomic, Comparand* comparand, const Value* value)
233 {
234 const Integral comparandValue = *(Integral*) comparand;
235
236 const Integral previous =
237 _InterlockedCompareExchange64((volatile Integral*) atomic, *(const Integral*) value, comparandValue);
238
239 if (previous == comparandValue)
240 {
241 return true;
242 }
243
244 *(Integral*) value = previous;
245
246 return false;
247 }
248};
249
250template <typename Type>
251struct Atomic
252{
253 static_assert(
254 std::is_integral<Type>::value || std::is_enum<Type>::value || std::is_pointer<Type>::value,
255 "Atomic<T> requires an integral, enumeration, or pointer type"
256 );
257
258 static Type read(volatile Type& atomic) noexcept
259 {
260 Type value = Type();
261
262 AtomicOps<sizeof(Type)>::read(&atomic, &value);
263
264 return value;
265 }
266
267 static void store(volatile Type& atomic, Type value) noexcept
268 {
269 AtomicOps<sizeof(Type)>::store(&atomic, &value);
270 }
271
272 static void exchange(volatile Type& atomic, Type& value) noexcept
273 {
274 AtomicOps<sizeof(Type)>::exchange(&atomic, &value);
275 }
276
277 static bool compareStore(volatile Type& atomic, Type comparand, Type value) noexcept
278 {
279 return AtomicOps<sizeof(Type)>::compareExchange(&atomic, &comparand, &value);
280 }
281
282 static bool compareExchange(volatile Type& atomic, Type comparand, Type& value) noexcept
283 {
284 return AtomicOps<sizeof(Type)>::compareExchange(&atomic, &comparand, &value);
285 }
286};
287
288#elif defined(__GNUC__)
289
290template <typename Type>
291struct Atomic
292{
293 static_assert(
294 std::is_integral<Type>::value || std::is_enum<Type>::value || std::is_pointer<Type>::value,
295 "Atomic<T> requires an integral, enumeration, or pointer type"
296 );
297
298 static Type read(volatile Type& atomic) noexcept
299 {
300 Type value{};
301
302 __atomic_load(&atomic, &value, __ATOMIC_SEQ_CST);
303 __atomic_thread_fence(__ATOMIC_SEQ_CST);
304
305 return value;
306 }
307
308 static void store(volatile Type& atomic, Type value) noexcept
309 {
310 __atomic_store(&atomic, &value, __ATOMIC_SEQ_CST);
311 }
312
313 static void exchange(volatile Type& atomic, Type& value) noexcept
314 {
315 Type previous{};
316
317 __atomic_exchange(&atomic, &value, &previous, __ATOMIC_SEQ_CST);
318
319 value = previous;
320 }
321
322 static bool compareStore(volatile Type& atomic, Type comparand, Type value) noexcept
323 {
324 return compareExchange(atomic, comparand, value);
325 }
326
327 static bool compareExchange(volatile Type& atomic, Type comparand, Type& value) noexcept
328 {
329 if (__atomic_compare_exchange(&atomic, &comparand, &value, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
330 return true;
331
332 value = comparand;
333
334 return false;
335 }
336};
337
338#endif // Toolset selector.
339
340template <typename Type, Type Value>
342{
343public:
344 AtomicScopedStore(volatile Type& variable)
345 : variable_(variable)
346 {
347 }
348
350 {
351 Atomic<Type>::store(variable_, Value);
352 }
353
354private:
355 volatile Type& variable_;
356
358
359 AtomicScopedStore& operator=(const AtomicScopedStore&);
360};
361
#define ONIXS_CMEMDH_NAMESPACE_BEGIN
Definition Bootstrap.h:69
#define ONIXS_CMEMDH_NAMESPACE_END
Definition Bootstrap.h:73
#define ONIXS_CMEMDH_DEPRECATED
Definition Compiler.h:188
AtomicScopedStore(volatile Type &variable)
Definition Atomic.h:344
bool value(Number &number, const MultiContainer &container, Tag tag)