libcopp  1.1.0
atomic_int_type_msvc_impl.h
Go to the documentation of this file.
1 
16 #ifndef UTIL_LOCK_ATOMIC_INT_TYPE_MSVC_IMPL_H
17 #define UTIL_LOCK_ATOMIC_INT_TYPE_MSVC_IMPL_H
18 
19 #pragma once
20 
21 #include <Windows.h>
22 
23 #include <stdint.h>
24 
25 namespace util {
26  namespace lock {
27 
28  enum memory_order {
35  };
36 
37  namespace detail {
38 
39  template <int INT_SIZE>
41 
42  template <>
43  struct atomic_msvc_oprs<1> {
44  typedef SHORT opr_t;
45 
46  static opr_t exchange(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) {
47  return InterlockedExchange16(target, value);
48  }
49 
50  static opr_t cas(volatile opr_t *target, opr_t value, opr_t expected, ::util::lock::memory_order order) {
51  switch (order) {
53  return static_cast<opr_t>(InterlockedCompareExchangeNoFence16(target, value, expected));
55  return static_cast<opr_t>(InterlockedCompareExchangeAcquire16(target, value, expected));
57  return static_cast<opr_t>(InterlockedCompareExchangeRelease16(target, value, expected));
58  default:
59  return static_cast<opr_t>(InterlockedCompareExchange16(target, value, expected));
60  }
61  }
62 
63  static opr_t inc(volatile opr_t *target, ::util::lock::memory_order order) { return add(target, 1, order); }
64 
65  static opr_t dec(volatile opr_t *target, ::util::lock::memory_order order) { return sub(target, 1, order); }
66 
67  static opr_t add(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) {
68  // no api just like InterlockedAdd16, use cas to simulate it
69  if (NULL == target || 0 == value) {
70  return 0;
71  }
72 
73  opr_t ret = *target;
74  while (true) {
75  if (ret == cas(target, ret + value, ret, order)) {
76  ret += value;
77  break;
78  }
79  ret = *target;
80  }
81 
82  return ret;
83  }
84 
85  static opr_t sub(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) {
86  // no api just like InterlockedAdd16, use cas to simulate it
87  if (NULL == target || 0 == value) {
88  return 0;
89  }
90 
91  opr_t ret = *target;
92  while (true) {
93  if (ret == cas(target, ret - value, ret, order)) {
94  ret -= value;
95  break;
96  }
97  ret = *target;
98  }
99 
100  return ret;
101  }
102 
103  static opr_t and (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) {
104  return InterlockedAnd16(target, value);
105  }
106 
107  static opr_t or (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) {
108  return InterlockedOr16(target, value);
109  }
110 
111  static opr_t xor
112  (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { return InterlockedXor16(target, value); }
113  };
114 
115  template <>
116  struct atomic_msvc_oprs<2> {
117  typedef SHORT opr_t;
118 
119  static opr_t exchange(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) {
120  return InterlockedExchange16(target, value);
121  }
122 
123  static opr_t cas(volatile opr_t *target, opr_t value, opr_t expected, ::util::lock::memory_order order) {
124  switch (order) {
126  return InterlockedCompareExchangeNoFence16(target, value, expected);
128  return InterlockedCompareExchangeAcquire16(target, value, expected);
130  return InterlockedCompareExchangeRelease16(target, value, expected);
131  default:
132  return InterlockedCompareExchange16(target, value, expected);
133  }
134  }
135 
136  static opr_t inc(volatile opr_t *target, ::util::lock::memory_order order) {
137  switch (order) {
139  return InterlockedIncrementNoFence16(target);
141  return InterlockedIncrementAcquire16(target);
143  return InterlockedIncrementRelease16(target);
144  default:
145  return InterlockedIncrement16(target);
146  }
147  }
148 
149  static opr_t dec(volatile opr_t *target, ::util::lock::memory_order order) {
150  switch (order) {
152  return InterlockedDecrementNoFence16(target);
154  return InterlockedDecrementAcquire16(target);
156  return InterlockedDecrementRelease16(target);
157  default:
158  return InterlockedDecrement16(target);
159  }
160  }
161 
162  static opr_t add(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) {
163  // no api just like InterlockedAdd16, use cas to simulate it
164  if (NULL == target || 0 == value) {
165  return 0;
166  }
167 
168  opr_t ret = *target;
169  while (true) {
170  if (ret == cas(target, ret + value, ret, order)) {
171  ret += value;
172  break;
173  }
174  ret = *target;
175  }
176 
177  return ret;
178  }
179 
180  static opr_t sub(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) {
181  // no api just like InterlockedAdd16, use cas to simulate it
182  if (NULL == target || 0 == value) {
183  return 0;
184  }
185 
186  opr_t ret = *target;
187  while (true) {
188  if (ret == cas(target, ret - value, ret, order)) {
189  ret -= value;
190  break;
191  }
192  ret = *target;
193  }
194 
195  return ret;
196  }
197 
198  static opr_t and (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) {
199  return InterlockedAnd16(target, value);
200  }
201 
202  static opr_t or (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) {
203  return InterlockedOr16(target, value);
204  }
205 
206  static opr_t xor
207  (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) { return InterlockedXor16(target, value); }
208  };
209 
210  template <>
211  struct atomic_msvc_oprs<4> {
212  typedef LONG opr_t;
213 
214  static opr_t exchange(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) {
215  return InterlockedExchange(target, value);
216  }
217 
218  static opr_t cas(volatile opr_t *target, opr_t value, opr_t expected, ::util::lock::memory_order order) {
219  switch (order) {
221  return static_cast<opr_t>(InterlockedCompareExchangeNoFence(target, value, expected));
223  return static_cast<opr_t>(InterlockedCompareExchangeAcquire(target, value, expected));
225  return static_cast<opr_t>(InterlockedCompareExchangeRelease(target, value, expected));
226  default:
227  return static_cast<opr_t>(InterlockedCompareExchange(target, value, expected));
228  }
229  }
230 
231  static opr_t inc(volatile opr_t *target, ::util::lock::memory_order order) { return add(target, 1, order); }
232 
233  static opr_t dec(volatile opr_t *target, ::util::lock::memory_order order) { return sub(target, 1, order); }
234 
235  static opr_t add(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) {
236  // no api just like InterlockedAdd16, use cas to simulate it
237  if (NULL == target || 0 == value) {
238  return 0;
239  }
240 
241  opr_t ret = *target;
242  while (true) {
243  if (ret == cas(target, ret + value, ret, order)) {
244  ret += value;
245  break;
246  }
247  ret = *target;
248  }
249 
250  return ret;
251  }
252 
253  static opr_t sub(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) {
254  // no api just like InterlockedAdd16, use cas to simulate it
255  if (NULL == target || 0 == value) {
256  return 0;
257  }
258 
259  opr_t ret = *target;
260  while (true) {
261  if (ret == cas(target, ret - value, ret, order)) {
262  ret -= value;
263  break;
264  }
265  ret = *target;
266  }
267 
268  return ret;
269  }
270 
271  static opr_t and (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) {
272  return InterlockedAnd(target, value);
273  }
274 
275  static opr_t or (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) {
276  return InterlockedOr(target, value);
277  }
278 
279  static opr_t xor (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) {
280  return InterlockedXor(target, value);
281  }
282  };
283 
284  template <>
285  struct atomic_msvc_oprs<8> {
286  typedef LONGLONG opr_t;
287 
288  static opr_t exchange(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) {
289  switch (order) {
291  return InterlockedExchangeNoFence64(target, value);
293  return InterlockedExchangeAcquire64(target, value);
294  default:
295  return InterlockedExchange64(target, value);
296  }
297  }
298 
299  static opr_t cas(volatile opr_t *target, opr_t value, opr_t expected, ::util::lock::memory_order order) {
300  switch (order) {
302  return InterlockedCompareExchangeNoFence64(target, value, expected);
304  return InterlockedCompareExchangeAcquire64(target, value, expected);
306  return InterlockedCompareExchangeRelease64(target, value, expected);
307  default:
308  return InterlockedCompareExchange64(target, value, expected);
309  }
310  }
311 
312  static opr_t inc(volatile opr_t *target, ::util::lock::memory_order order) {
313  switch (order) {
315  return InterlockedIncrementNoFence64(target);
317  return InterlockedIncrementAcquire64(target);
319  return InterlockedIncrementRelease64(target);
320  default:
321  return InterlockedIncrement64(target);
322  }
323  }
324 
325  static opr_t dec(volatile opr_t *target, ::util::lock::memory_order order) {
326  switch (order) {
328  return InterlockedDecrementNoFence64(target);
330  return InterlockedDecrementAcquire64(target);
332  return InterlockedDecrementRelease64(target);
333  default:
334  return InterlockedDecrement64(target);
335  }
336  }
337 
338  static opr_t add(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) {
339  switch (order) {
341  return InterlockedAddNoFence64(target, value);
343  return InterlockedAddAcquire64(target, value);
345  return InterlockedAddRelease64(target, value);
346  default:
347  return InterlockedAdd64(target, value);
348  }
349  }
350 
351  static opr_t sub(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) {
352  switch (order) {
354  return InterlockedAddNoFence64(target, ~(value - 1));
356  return InterlockedAddAcquire64(target, ~(value - 1));
358  return InterlockedAddRelease64(target, ~(value - 1));
359  default:
360  return InterlockedAdd64(target, ~(value - 1));
361  }
362  }
363 
364  static opr_t and (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) {
365  switch (order) {
367  return InterlockedAnd64NoFence(target, value);
369  return InterlockedAnd64Acquire(target, value);
371  return InterlockedAnd64Release(target, value);
372  default:
373  return InterlockedAnd64(target, value);
374  }
375  }
376 
377  static opr_t or (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) {
378  switch (order) {
380  return InterlockedOr64NoFence(target, value);
382  return InterlockedOr64Acquire(target, value);
384  return InterlockedOr64Release(target, value);
385  default:
386  return InterlockedOr64(target, value);
387  }
388  }
389 
390  static opr_t xor (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) {
391  switch (order) {
393  return InterlockedXor64NoFence(target, value);
395  return InterlockedXor64Acquire(target, value);
397  return InterlockedXor64Release(target, value);
398  default:
399  return InterlockedXor64(target, value);
400  }
401  }
402  };
403 
404  template <int INT_SIZE>
405  struct atomic_msvc_oprs {
406  typedef LONGLONG opr_t;
407 
408  static opr_t exchange(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) {
409  switch (order) {
411  return InterlockedExchangeNoFence(target, value);
413  return InterlockedExchangeAcquire(target, value);
414  default:
415  return InterlockedExchange(target, value);
416  }
417  }
418 
419  static opr_t cas(volatile opr_t *target, opr_t value, opr_t expected, ::util::lock::memory_order order) {
420  switch (order) {
422  return InterlockedCompareExchangeNoFence(target, value, expected);
424  return InterlockedCompareExchangeAcquire(target, value, expected);
426  return InterlockedCompareExchangeRelease(target, value, expected);
427  default:
428  return InterlockedCompareExchange(target, value, expected);
429  }
430  }
431 
432  static opr_t inc(volatile opr_t *target, ::util::lock::memory_order order) {
433  switch (order) {
435  return InterlockedIncrementNoFence(target);
437  return InterlockedIncrementAcquire(target);
439  return InterlockedIncrementRelease(target);
440  default:
441  return InterlockedIncrement(target);
442  }
443  }
444 
445  static opr_t dec(volatile opr_t *target, ::util::lock::memory_order order) {
446  switch (order) {
448  return InterlockedDecrementNoFence(target);
450  return InterlockedDecrementAcquire(target);
452  return InterlockedDecrementRelease(target);
453  default:
454  return InterlockedDecrement(target);
455  }
456  }
457 
458  static opr_t add(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) {
459  switch (order) {
461  return InterlockedAddNoFence(target, value);
463  return InterlockedAddAcquire(target, value);
465  return InterlockedAddRelease(target, value);
466  default:
467  return InterlockedAdd(target, value);
468  }
469  }
470 
471  static opr_t sub(volatile opr_t *target, opr_t value, ::util::lock::memory_order order) {
472  switch (order) {
474  return InterlockedAddNoFence(target, ~(value - 1));
476  return InterlockedAddAcquire(target, ~(value - 1));
478  return InterlockedAddRelease(target, ~(value - 1));
479  default:
480  return InterlockedAdd(target, ~(value - 1));
481  }
482  }
483 
484  static opr_t and (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) {
485  switch (order) {
487  return InterlockedAndNoFence(target, value);
489  return InterlockedAndAcquire(target, value);
491  return InterlockedAndRelease(target, value);
492  default:
493  return InterlockedAnd(target, value);
494  }
495  }
496 
497  static opr_t or (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) {
498  switch (order) {
500  return InterlockedOrNoFence(target, value);
502  return InterlockedOrAcquire(target, value);
504  return InterlockedOrRelease(target, value);
505  default:
506  return InterlockedOr(target, value);
507  }
508  }
509 
510  static opr_t xor (volatile opr_t * target, opr_t value, ::util::lock::memory_order order) {
511  switch (order) {
513  return InterlockedXorNoFence(target, value);
515  return InterlockedXorAcquire(target, value);
517  return InterlockedXorRelease(target, value);
518  default:
519  return InterlockedXor(target, value);
520  }
521  }
522  };
523  } // namespace detail
524  } // namespace lock
525 } // namespace util
526 
527 #endif /* _UTIL_LOCK_ATOMIC_INT_TYPE_MSVC_IMPL_H_ */
static opr_t sub(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t exchange(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t and(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t exchange(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t add(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t and(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t sub(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t sub(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t add(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t or(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t sub(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t exchange(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t inc(volatile opr_t *target,::util::lock::memory_order order)
static opr_t exchange(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t dec(volatile opr_t *target,::util::lock::memory_order order)
static opr_t add(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t or(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t dec(volatile opr_t *target,::util::lock::memory_order order)
static opr_t inc(volatile opr_t *target,::util::lock::memory_order order)
static opr_t and(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t inc(volatile opr_t *target,::util::lock::memory_order order)
static opr_t xor(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t add(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t cas(volatile opr_t *target, opr_t value, opr_t expected,::util::lock::memory_order order)
static opr_t dec(volatile opr_t *target,::util::lock::memory_order order)
static opr_t cas(volatile opr_t *target, opr_t value, opr_t expected,::util::lock::memory_order order)
static opr_t add(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t cas(volatile opr_t *target, opr_t value, opr_t expected,::util::lock::memory_order order)
static opr_t and(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t dec(volatile opr_t *target,::util::lock::memory_order order)
static opr_t inc(volatile opr_t *target,::util::lock::memory_order order)
static opr_t cas(volatile opr_t *target, opr_t value, opr_t expected,::util::lock::memory_order order)
static opr_t or(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t or(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t xor(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t inc(volatile opr_t *target,::util::lock::memory_order order)
static opr_t or(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t xor(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t cas(volatile opr_t *target, opr_t value, opr_t expected,::util::lock::memory_order order)
static opr_t and(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t exchange(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t sub(volatile opr_t *target, opr_t value,::util::lock::memory_order order)
static opr_t dec(volatile opr_t *target,::util::lock::memory_order order)