OnixS C++ CME MDP Premium Market Data Handler 5.9.0
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
248//
249
250template <typename Type>
251struct Atomic
252{
253 static Type read(volatile Type& atomic)
254 {
255 Type value = Type();
256
257 AtomicOps<sizeof(Type)>::read(&atomic, &value);
258
259 return value;
260 }
261
262 static void store(volatile Type& atomic, Type value)
263 {
264 AtomicOps<sizeof(Type)>::store(&atomic, &value);
265 }
266
267 static void exchange(volatile Type& atomic, Type& value)
268 {
269 AtomicOps<sizeof(Type)>::exchange(&atomic, &value);
270 }
271
272 static bool compareStore(volatile Type& atomic, Type comparand, Type value)
273 {
274 return AtomicOps<sizeof(Type)>::compareExchange(&atomic, &comparand, &value);
275 }
276
277 static bool compareExchange(volatile Type& atomic, Type comparand, Type& value)
278 {
279 return AtomicOps<sizeof(Type)>::compareExchange(&atomic, &comparand, &value);
280 }
281};
282
283#elif defined(__GNUC__)
284
285template <typename Type>
286struct Atomic
287{
288 static Type read(volatile Type& atomic)
289 {
290 const Type value = atomic;
291
292 __sync_synchronize();
293
294 return value;
295 }
296
297 static void store(volatile Type& atomic, Type value)
298 {
299 (void) (__sync_lock_test_and_set(&atomic, value));
300 }
301
302 static void exchange(volatile Type& atomic, Type& value)
303 {
304 value = __sync_lock_test_and_set(&atomic, value);
305 }
306
307 static bool compareStore(volatile Type& atomic, Type comparand, Type value)
308 {
309 return __sync_bool_compare_and_swap(&atomic, comparand, value);
310 }
311
312 static bool compareExchange(volatile Type& atomic, Type comparand, Type& value)
313 {
314 const Type oldValue = __sync_val_compare_and_swap(&atomic, comparand, value);
315
316 if (oldValue == comparand)
317 return true;
318
319 value = oldValue;
320
321 return false;
322 }
323};
324
325#endif // Toolset selector.
326
327template <typename Type, Type Value>
329{
330public:
331 AtomicScopedStore(volatile Type& variable)
332 : variable_(variable)
333 {
334 }
335
337 {
338 Atomic<Type>::store(variable_, Value);
339 }
340
341private:
342 volatile Type& variable_;
343
345
346 AtomicScopedStore& operator=(const AtomicScopedStore&);
347};
348
#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:331
bool value(Number &number, const MultiContainer &container, Tag tag)
Finds a tag-value entry in the given collection by the given tag and returns its value component tran...