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 <atomic>
6 
8 namespace honey { namespace atomic { namespace platform
9 {
10 
11 class Op
12 {
13 public:
14  static int32 load(volatile const int32& val, Order o)
15  {
16  switch(o)
17  {
18  case Order::relaxed:
19  return val; //Read is atomic if val is 32-bit aligned
20  case Order::consume:
21  case Order::acquire:
22  {
23  const int32 _val = val;
24  mt_unused(_val);
25  std::atomic_thread_fence(std::memory_order_acquire); //Prevent compiler moving operations from after acquire to before
26  return val;
27  }
28  case Order::seqCst:
29  default:
30  std::atomic_thread_fence(std::memory_order_seq_cst); //Prevent compiler/hardware re-ordering
31  return val;
32  }
33  }
34 
35  static void store(volatile int32& dst, int32 newVal, Order o)
36  {
37  switch (o)
38  {
39  case Order::relaxed:
40  dst = newVal; //Write is atomic if val is 32-bit aligned
41  break;
42  case Order::release:
43  std::atomic_thread_fence(std::memory_order_release); //Prevent compiler moving operations from before release to after
44  dst = newVal;
45  break;
46  case Order::seqCst:
47  default:
48  swap(dst, newVal); //Swap provides memory barrier
49  break;
50  }
51  }
52 
53  static bool cas(volatile int32& dst, int32 newVal, int32 cmp, Order) { return __sync_bool_compare_and_swap(&dst, cmp, newVal); }
54  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; }
55  static int32 inc(volatile int32& val, Order = Order::seqCst) { return __sync_fetch_and_add(&val, 1); }
56  static int32 dec(volatile int32& val, Order = Order::seqCst) { return __sync_fetch_and_sub(&val, 1); }
57 
59  static int64 load(const volatile int64& val, Order) { return __sync_val_compare_and_swap(&val, 0, 0); }
61  static void store(volatile int64& dst, int64 newVal, Order o) { int64 v; do { v = dst; } while (!cas(dst, newVal, v, o)); }
62  static bool cas(volatile int64& dst, int64 newVal, int64 cmp, Order) { return __sync_bool_compare_and_swap(&dst, cmp, newVal); }
63 
64  static void fence(Order o) { std::atomic_thread_fence(static_cast<std::memory_order>(o)); }
65 };
66 
67 } } }
#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...
Global Honeycomb namespace.