Honeycomb  0.1
Component-Model Framework
Atomic.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2013 Daniel Carter. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
4 #include "Honey/Core/Core.h"
5 #include <intrin.h>
6 
8 namespace honey { namespace atomic { namespace platform
9 {
10 
12 
23 class Op
24 {
25 public:
26  static int32 load(volatile const int32& val, Order::t o)
27  {
28  switch(o)
29  {
30  case Order::relaxed:
31  return val; //Read is atomic if val is 32-bit aligned
32  case Order::consume:
33  case Order::acquire:
34  {
35  const int32 _val = val;
36  mt_unused(_val);
37  _ReadWriteBarrier(); //Prevent compiler moving operations from after acquire to before
38  return val;
39  }
40  case Order::seqCst:
41  default:
42  MemoryBarrier(); //Prevent compiler/hardware re-ordering
43  return val;
44  }
45  }
46 
47  static void store(volatile int32& dst, int32 newVal, Order::t o)
48  {
49  switch (o)
50  {
51  case Order::relaxed:
52  dst = newVal; //Write is atomic if val is 32-bit aligned
53  break;
54  case Order::release:
55  _ReadWriteBarrier(); //Prevent compiler moving operations from before release to after
56  dst = newVal;
57  break;
58  case Order::seqCst:
59  default:
60  swap(dst, newVal); //Swap provides memory barrier
61  break;
62  }
63  }
64 
65  static bool cas(volatile int32& dst, int32 newVal, int32 cmp, Order::t) { return InterlockedCompareExchange(reinterpret_cast<volatile LONG*>(&dst), newVal, cmp) == cmp; }
67  static int32 swap(volatile int32& dst, int32 newVal, Order::t = Order::seqCst) { return InterlockedExchange(reinterpret_cast<volatile LONG*>(&dst), newVal); }
68  static int32 inc(volatile int32& val, Order::t = Order::seqCst) { return InterlockedIncrement(reinterpret_cast<volatile LONG*>(&val))-1; }
69  static int32 dec(volatile int32& val, Order::t = Order::seqCst) { return InterlockedDecrement(reinterpret_cast<volatile LONG*>(&val))+1; }
70 
72  static int64 load(const volatile int64& val, Order::t) { return _InterlockedCompareExchange64(const_cast<volatile LONGLONG*>(&val), 0, 0); }
74  static void store(volatile int64& dst, int64 newVal, Order::t o) { int64 v; do { v = dst; } while (!cas(dst, newVal, v, o)); }
75  static bool cas(volatile int64& dst, int64 newVal, int64 cmp, Order::t) { return _InterlockedCompareExchange64(static_cast<volatile LONGLONG*>(&dst), newVal, cmp) == cmp; }
76 
77  static void fence(Order::t o)
78  {
79  switch (o)
80  {
81  case Order::consume:
82  case Order::acquire:
83  _ReadBarrier(); //Prevent compiler re-ordering
84  break;
85  case Order::release:
86  _WriteBarrier(); //Prevent compiler re-ordering
87  break;
88  case Order::acqRel:
89  _ReadWriteBarrier(); //Prevent compiler re-ordering
90  break;
91  case Order::seqCst:
92  MemoryBarrier(); //Prevent compiler/hardware re-ordering
93  break;
94  }
95  }
96 };
97 
98 } } }
#define mt_unused(Param)
Remove the unused parameter warning.
Definition: Meta.h:20
Must be a store op. Synchronize with a later acquire in another thread.
ostream & dec(ostream &os)
Use decimal encoding (big-endian integer) when writing bytes to a string stream.
Definition: Encode.h:66
Must be a load op. Synchronize with a prior release in another thread.
No order constraint, same as plain load/store. Unsafe but best performance.
int int32
Definition: Core.h:15
#define swap(a, i, j)
Op
Definition: Unique.h:16
long long int64
Definition: Core.h:21
Sequential consistency, safe total order but least performance.
Must be a load op. Synchronize with a prior release in another thread, but only synchronize ops depen...
Must be a load-modify-store op. Performs both acquire and release.
Global Honeycomb namespace.