OnixS C++ CME MDP Premium Market Data Handler 5.9.0
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#if defined(_MSC_VER)
24# include <intrin.h>
25#endif
26
28
30
31#if defined(_MSC_VER)
32
33template <size_t SizeOf>
34class AtomicOps;
35
36template <>
37class AtomicOps<1>
38{
39 typedef char Integral;
40
41public:
42 template <class Atomic, class Target>
43 static void read(volatile Atomic* atomic, Target* target)
44 {
45 *(Integral*) target = *(volatile Integral*) atomic;
46
47 _ReadWriteBarrier();
48 }
49
50 template <class Atomic, class Addend>
51 static void add(volatile Atomic* atomic, Addend* addend)
52 {
53 const Integral addendValue = *static_cast<Integral*>(addend);
54
55 *(Integral*) addend = (_InterlockedExchangeAdd8((volatile Integral*) atomic, addendValue) + addendValue);
56 }
57
58 template <class Atomic, class Value>
59 static void store(volatile Atomic* atomic, const Value* value)
60 {
61 _InterlockedExchange8((volatile Integral*) atomic, *(const Integral*) value);
62 }
63
64 template <class Atomic, class Value>
65 static void exchange(volatile Atomic* atomic, Value* value)
66 {
67 *(Integral*) value = _InterlockedExchange8((volatile Integral*) atomic, *static_cast<Integral*>(value));
68 }
69
70 template <class Atomic, class Comparand, class Value>
71 static bool compareExchange(volatile Atomic* atomic, Comparand* comparand, const Value* value)
72 {
73 const Integral comparandValue = *(Integral*) comparand;
74
75 const Integral previous =
76 _InterlockedCompareExchange8((volatile Integral*) atomic, *(const Integral*) value, comparandValue);
77
78 if (previous == comparandValue)
79 {
80 return true;
81 }
82
83 *(Integral*) value = previous;
84
85 return false;
86 }
87};
88
89template <>
90class AtomicOps<2>
91{
92 typedef short Integral;
93
94public:
95 template <class Atomic, class Target>
96 static void read(volatile Atomic* atomic, Target* target)
97 {
98 *(Integral*) target = *(volatile Integral*) atomic;
99
100 _ReadWriteBarrier();
101 }
102
103 template <class Atomic, class Addend>
104 static void add(volatile Atomic* atomic, Addend* addend)
105 {
106 const Integral addendValue = *static_cast<Integral*>(addend);
107
108 *(Integral*) addend = (_InterlockedExchangeAdd16((volatile Integral*) atomic, addendValue) + addendValue);
109 }
110
111 template <class Atomic, class Value>
112 static void store(volatile Atomic* atomic, const Value* value)
113 {
114 _InterlockedExchange16((volatile Integral*) atomic, *(const Integral*) value);
115 }
116
117 template <class Atomic, class Value>
118 static void exchange(volatile Atomic* atomic, Value* value)
119 {
120 *(Integral*) value = _InterlockedExchange16((volatile Integral*) atomic, *static_cast<Integral*>(value));
121 }
122
123 template <class Atomic, class Comparand, class Value>
124 static bool compareExchange(volatile Atomic* atomic, Comparand* comparand, const Value* value)
125 {
126 const Integral comparandValue = *(Integral*) comparand;
127
128 const Integral previous =
129 _InterlockedCompareExchange16((volatile Integral*) atomic, *(const Integral*) value, comparandValue);
130
131 if (previous == comparandValue)
132 {
133 return true;
134 }
135
136 *(Integral*) value = previous;
137
138 return false;
139 }
140};
141
142template <>
143class AtomicOps<4>
144{
145 typedef long Integral;
146
147public:
148 template <class Atomic, class Target>
149 static void read(volatile Atomic* atomic, Target* target)
150 {
151 *(Integral*) target = *(volatile Integral*) atomic;
152
153 _ReadWriteBarrier();
154 }
155
156 template <class Atomic, class Addend>
157 static void add(volatile Atomic* atomic, Addend* addend)
158 {
159 const Integral addendValue = *static_cast<Integral*>(addend);
160
161 *(Integral*) addend = (_InterlockedExchangeAdd((volatile Integral*) atomic, addendValue) + addendValue);
162 }
163
164 template <class Atomic, class Value>
165 static void store(volatile Atomic* atomic, const Value* value)
166 {
167 _InterlockedExchange((volatile Integral*) atomic, *(const Integral*) value);
168 }
169
170 template <class Atomic, class Value>
171 static void exchange(volatile Atomic* atomic, Value* value)
172 {
173 *(Integral*) value = _InterlockedExchange((volatile Integral*) atomic, *static_cast<Integral*>(value));
174 }
175
176 template <class Atomic, class Comparand, class Value>
177 static bool compareExchange(volatile Atomic* atomic, Comparand* comparand, const Value* value)
178 {
179 const Integral comparandValue = *(Integral*) comparand;
180
181 const Integral previous =
182 _InterlockedCompareExchange((volatile Integral*) atomic, *(const Integral*) value, comparandValue);
183
184 if (previous == comparandValue)
185 {
186 return true;
187 }
188
189 *(Integral*) value = previous;
190
191 return false;
192 }
193};
194
195template <>
196class AtomicOps<8>
197{
198 typedef long long Integral;
199
200public:
201 template <class Atomic, class Target>
202 static void read(volatile Atomic* atomic, Target* target)
203 {
204 *(Integral*) target = *(volatile Integral*) atomic;
205
206 _ReadWriteBarrier();
207 }
208
209 template <class Atomic, class Addend>
210 static void add(volatile Atomic* atomic, Addend* addend)
211 {
212 const Integral addendValue = *static_cast<Integral*>(addend);
213
214 *(Integral*) addend = (_InterlockedExchangeAdd64((volatile Integral*) atomic, addendValue) + addendValue);
215 }
216
217 template <class Atomic, class Value>
218 static void store(volatile Atomic* atomic, const Value* value)
219 {
220 _InterlockedExchange64((volatile Integral*) atomic, *(const Integral*) value);
221 }
222
223 template <class Atomic, class Value>
224 static void exchange(volatile Atomic* atomic, Value* value)
225 {
226 *(Integral*) value = _InterlockedExchange64((volatile Integral*) atomic, *static_cast<Integral*>(value));
227 }
228
229 template <class Atomic, class Comparand, class Value>
230 static bool compareExchange(volatile Atomic* atomic, Comparand* comparand, const Value* value)
231 {
232 const Integral comparandValue = *(Integral*) comparand;
233
234 const Integral previous =
235 _InterlockedCompareExchange64((volatile Integral*) atomic, *(const Integral*) value, comparandValue);
236
237 if (previous == comparandValue)
238 {
239 return true;
240 }
241
242 *(Integral*) value = previous;
243
244 return false;
245 }
246};
247
248template <typename Type>
249struct Atomic
250{
251 static Type read(volatile Type& atomic)
252 {
253 Type value = Type();
254
255 AtomicOps<sizeof(Type)>::read(&atomic, &value);
256
257 return value;
258 }
259
260 static void store(volatile Type& atomic, Type value)
261 {
262 AtomicOps<sizeof(Type)>::store(&atomic, &value);
263 }
264
265 static void exchange(volatile Type& atomic, Type& value)
266 {
267 AtomicOps<sizeof(Type)>::exchange(&atomic, &value);
268 }
269
270 static bool compareStore(volatile Type& atomic, Type comparand, Type value)
271 {
272 return AtomicOps<sizeof(Type)>::compareExchange(&atomic, &comparand, &value);
273 }
274
275 static bool compareExchange(volatile Type& atomic, Type comparand, Type& value)
276 {
277 return AtomicOps<sizeof(Type)>::compareExchange(&atomic, &comparand, &value);
278 }
279};
280
281#elif defined(__GNUC__)
282
283template <typename Type>
284struct Atomic
285{
286 static Type read(volatile Type& atomic)
287 {
288 const Type value = atomic;
289
290 __sync_synchronize();
291
292 return value;
293 }
294
295 static void store(volatile Type& atomic, Type value)
296 {
297 (void) (__sync_lock_test_and_set(&atomic, value));
298 }
299
300 static void exchange(volatile Type& atomic, Type& value)
301 {
302 value = __sync_lock_test_and_set(&atomic, value);
303 }
304
305 static bool compareStore(volatile Type& atomic, Type comparand, Type value)
306 {
307 return __sync_bool_compare_and_swap(&atomic, comparand, value);
308 }
309
310 static bool compareExchange(volatile Type& atomic, Type comparand, Type& value)
311 {
312 const Type oldValue = __sync_val_compare_and_swap(&atomic, comparand, value);
313
314 if (oldValue == comparand)
315 return true;
316
317 value = oldValue;
318
319 return false;
320 }
321};
322
323#endif // Toolset selector.
324
325template <typename Type, Type Value>
327{
328public:
329 AtomicScopedStore(volatile Type& variable)
330 : variable_(variable)
331 {
332 }
333
335 {
336 Atomic<Type>::store(variable_, Value);
337 }
338
339private:
340 volatile Type& variable_;
341
343
344 AtomicScopedStore& operator=(const AtomicScopedStore&);
345};
346
#define ONIXS_CMEMDH_NAMESPACE_BEGIN
Definition Bootstrap.h:67
#define ONIXS_CMEMDH_NAMESPACE_END
Definition Bootstrap.h:68
AtomicScopedStore(volatile Type &variable)
Definition Atomic.h:329
bool value(Number &number, const MultiContainer &container, Tag tag)