Honeycomb  0.1
Component-Model Framework
Atomic.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2015 NewGamePlus Inc. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
4 #include "Honey/Core/Core.h"
5 #include <atomic>
6 
8 namespace honey { namespace atomic { namespace platform
9 {
10 
11 typedef int64 SwapMaxType;
12 
13 class Op
14 {
15 public:
16  static int32 load(volatile const int32& val, Order o)
17  {
18  switch(o)
19  {
20  case Order::relaxed:
21  return val; //Read is atomic if val is 32-bit aligned
22  case Order::consume:
23  case Order::acquire:
24  {
25  const int32 _val = val;
26  mt_unused(_val);
27  std::atomic_thread_fence(std::memory_order_acquire); //Prevent compiler moving operations from after acquire to before
28  return val;
29  }
30  case Order::seqCst:
31  default:
32  std::atomic_thread_fence(std::memory_order_seq_cst); //Prevent compiler/hardware re-ordering
33  return val;
34  }
35  }
36 
37  static void store(volatile int32& dst, int32 newVal, Order o)
38  {
39  switch (o)
40  {
41  case Order::relaxed:
42  dst = newVal; //Write is atomic if val is 32-bit aligned
43  break;
44  case Order::release:
45  std::atomic_thread_fence(std::memory_order_release); //Prevent compiler moving operations from before release to after
46  dst = newVal;
47  break;
48  case Order::seqCst:
49  default:
50  swap(dst, newVal); //Swap provides memory barrier
51  break;
52  }
53  }
54 
55  static bool cas(volatile int32& dst, int32 newVal, int32 cmp, Order) { return __sync_bool_compare_and_swap(&dst, cmp, newVal); }
56  static int32 swap(volatile int32& dst, int32 newVal, Order o = Order::seqCst) { int32 v; do { v = dst; } while (!cas(dst, newVal, v, o)); return v; }
57  static int32 inc(volatile int32& val, Order = Order::seqCst) { return __sync_fetch_and_add(&val, 1); }
58  static int32 dec(volatile int32& val, Order = Order::seqCst) { return __sync_fetch_and_sub(&val, 1); }
59 
61  static int64 load(const volatile int64& val, Order) { return __sync_val_compare_and_swap(&val, 0, 0); }
63  static void store(volatile int64& dst, int64 newVal, Order o) { int64 v; do { v = dst; } while (!cas(dst, newVal, v, o)); }
64  static bool cas(volatile int64& dst, int64 newVal, int64 cmp, Order) { return __sync_bool_compare_and_swap(&dst, cmp, newVal); }
65 
66  static void fence(Order o) { std::atomic_thread_fence(static_cast<std::memory_order>(o)); }
67 };
68 
69 } } }
#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.
Order
Atomic memory order for concurrent synchronization between threads.
Definition: Atomic.h:23
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...
platform::SwapMaxType SwapMaxType
Largest atomically-swappable type.
Definition: Atomic.h:105
Global Honeycomb namespace.