OnixS C++ CME MDP Premium Market Data Handler  5.8.3
API Documentation
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 
33 template <size_t SizeOf>
34 class AtomicOps;
35 
36 template <>
37 class AtomicOps<1>
38 {
39  typedef char Integral;
40 
41 public:
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 
89 template <>
90 class AtomicOps<2>
91 {
92  typedef short Integral;
93 
94 public:
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 
142 template <>
143 class AtomicOps<4>
144 {
145  typedef long Integral;
146 
147 public:
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 
195 template <>
196 class AtomicOps<8>
197 {
198  typedef long long Integral;
199 
200 public:
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 
250 template <typename Type>
251 struct 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 
285 template <typename Type>
286 struct 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 
327 template <typename Type, Type Value>
329 {
330 public:
331  AtomicScopedStore(volatile Type& variable)
332  : variable_(variable)
333  {
334  }
335 
337  {
338  Atomic<Type>::store(variable_, Value);
339  }
340 
341 private:
342  volatile Type& variable_;
343 
345 
346  AtomicScopedStore& operator=(const AtomicScopedStore&);
347 };
348 
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...
#define ONIXS_CMEMDH_NAMESPACE_BEGIN
Definition: Bootstrap.h:67
#define ONIXS_CMEMDH_NAMESPACE_END
Definition: Bootstrap.h:68