Roc Toolkit internal modules
Roc Toolkit: real-time audio streaming
atomic.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Roc Streaming authors
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  */
8 
9 //! @file roc_core/atomic.h
10 //! @brief Atomic.
11 
12 #ifndef ROC_CORE_ATOMIC_H_
13 #define ROC_CORE_ATOMIC_H_
14 
15 #include "roc_core/atomic_ops.h"
16 #include "roc_core/cpu_traits.h"
17 #include "roc_core/noncopyable.h"
18 #include "roc_core/stddefs.h"
19 
20 namespace roc {
21 namespace core {
22 
23 //! Atomic integer.
24 //! Provides sequential consistency.
25 //! For a fine-grained memory order control, see AtomicOps.
26 template <class T> class Atomic : public NonCopyable<> {
27  // Allow only types that are available natively on all architectures.
28  struct TypeCheck {
29  int f : sizeof(T) == 8 || sizeof(T) == 16 || sizeof(T) == 32 ? 1 : -1;
30  };
31 
32 public:
33  //! Initialize with given value.
34  explicit inline Atomic(T val = 0)
35  : var_(val) {
36  }
37 
38  //! Atomic exchange.
39  inline T exchange(T val) {
40  return AtomicOps::exchange_seq_cst(var_, val);
41  }
42 
43  //! Atomic compare-and-swap.
44  inline bool compare_exchange(T exp, T des) {
45  return AtomicOps::compare_exchange_seq_cst(var_, exp, des);
46  }
47 
48  //! Atomic fetch-or.
49  inline T fetch_or(T val) {
50  return AtomicOps::fetch_or_seq_cst(var_, val);
51  }
52 
53  //! Atomic fetch-and.
54  inline T fetch_and(T val) {
55  return AtomicOps::fetch_and_seq_cst(var_, val);
56  }
57 
58  //! Atomic fetch-xor.
59  inline T fetch_xor(T val) {
60  return AtomicOps::fetch_xor_seq_cst(var_, val);
61  }
62 
63  //! Atomic load.
64  inline operator T() const {
65  return AtomicOps::load_seq_cst(var_);
66  }
67 
68  //! Atomic store.
69  inline T operator=(T val) {
70  AtomicOps::store_seq_cst(var_, val);
71  return val;
72  }
73 
74  //! Atomic increment (prefix).
75  inline T operator++() {
76  return AtomicOps::fetch_add_seq_cst(var_, T(1)) + T(1);
77  }
78 
79  //! Atomic increment (postfix).
80  inline T operator++(int) {
81  return AtomicOps::fetch_add_seq_cst(var_, T(1));
82  }
83 
84  //! Atomic decrement (prefix).
85  inline T operator--() {
86  return AtomicOps::fetch_sub_seq_cst(var_, T(1)) - T(1);
87  }
88 
89  //! Atomic decrement (postfix).
90  inline T operator--(int) {
91  return AtomicOps::fetch_sub_seq_cst(var_, T(1));
92  }
93 
94  //! Atomic addition.
95  inline T operator+=(T val) {
96  return AtomicOps::fetch_add_seq_cst(var_, val) + val;
97  }
98 
99  //! Atomic subtraction.
100  inline T operator-=(T val) {
101  return AtomicOps::fetch_sub_seq_cst(var_, val) - val;
102  }
103 
104  //! Atomic bitwise or.
105  inline T operator|=(T val) {
106  return AtomicOps::fetch_or_seq_cst(var_, val) | val;
107  }
108 
109  //! Atomic bitwise and.
110  inline T operator&=(T val) {
111  return AtomicOps::fetch_and_seq_cst(var_, val) & val;
112  }
113 
114  //! Atomic bitwise xor.
115  inline T operator^=(T val) {
116  return AtomicOps::fetch_xor_seq_cst(var_, val) ^ val;
117  }
118 
119 private:
120  T var_;
121 };
122 
123 //! Atomic pointer.
124 //! Provides sequential consistency.
125 //! For a fine-grained memory order control, see AtomicOps.
126 template <class T> class Atomic<T*> : public NonCopyable<> {
127 public:
128  //! Initialize with given value.
129  explicit inline Atomic(T* val = NULL)
130  : var_(val) {
131  }
132 
133  //! Atomic exchange.
134  inline T* exchange(T* val) {
135  return AtomicOps::exchange_seq_cst(var_, val);
136  }
137 
138  //! Atomic compare-and-swap.
139  inline bool compare_exchange(T* exp, T* des) {
140  return AtomicOps::compare_exchange_seq_cst(var_, exp, des);
141  }
142 
143  //! Atomic load.
144  T* operator->() const {
145  return AtomicOps::load_seq_cst(var_);
146  }
147 
148  //! Atomic load.
149  T& operator*() const {
150  return *AtomicOps::load_seq_cst(var_);
151  }
152 
153  //! Atomic load.
154  inline operator T*() const {
155  return AtomicOps::load_seq_cst(var_);
156  }
157 
158  //! Atomic store.
159  inline T* operator=(T* val) {
160  AtomicOps::store_seq_cst(var_, val);
161  return val;
162  }
163 
164  //! Atomic increment (prefix).
165  inline T* operator++() {
166  return AtomicOps::fetch_add_seq_cst(var_, ptrdiff_t(sizeof(T))) + 1;
167  }
168 
169  //! Atomic increment (postfix).
170  inline T* operator++(int) {
171  return AtomicOps::fetch_add_seq_cst(var_, ptrdiff_t(sizeof(T)));
172  }
173 
174  //! Atomic decrement (prefix).
175  inline T* operator--() {
176  return AtomicOps::fetch_sub_seq_cst(var_, ptrdiff_t(sizeof(T))) - 1;
177  }
178 
179  //! Atomic decrement (postfix).
180  inline T* operator--(int) {
181  return AtomicOps::fetch_sub_seq_cst(var_, ptrdiff_t(sizeof(T)));
182  }
183 
184  //! Atomic addition.
185  inline T* operator+=(ptrdiff_t val) {
186  return AtomicOps::fetch_add_seq_cst(var_, val * ptrdiff_t(sizeof(T))) + val;
187  }
188 
189  //! Atomic subtraction.
190  inline T* operator-=(ptrdiff_t val) {
191  return AtomicOps::fetch_sub_seq_cst(var_, val * ptrdiff_t(sizeof(T))) - val;
192  }
193 
194 private:
195  T* var_;
196 };
197 
198 } // namespace core
199 } // namespace roc
200 
201 #endif // ROC_CORE_ATOMIC_H_
static T1 exchange_seq_cst(T1 &var, T2 val)
Atomic exchange (full barrier).
Definition: atomic_ops.h:106
static T1 fetch_sub_seq_cst(T1 &var, T2 val)
Atomic sub-and-fetch (full barrier).
Definition: atomic_ops.h:196
static void store_seq_cst(T1 &var, T2 val)
Atomic store (full barrier).
Definition: atomic_ops.h:76
static T1 fetch_or_seq_cst(T1 &var, T2 val)
Atomic fetch-or (full barrier).
Definition: atomic_ops.h:246
static bool compare_exchange_seq_cst(T1 &var, T1 &exp, T2 des)
Atomic compare-and-swap (full barrier).
Definition: atomic_ops.h:145
static T1 fetch_and_seq_cst(T1 &var, T2 val)
Atomic fetch-and (full barrier).
Definition: atomic_ops.h:221
static T1 fetch_add_seq_cst(T1 &var, T2 val)
Atomic add-and-fetch (full barrier).
Definition: atomic_ops.h:171
static T1 fetch_xor_seq_cst(T1 &var, T2 val)
Atomic fetch-xor (full barrier).
Definition: atomic_ops.h:271
static T load_seq_cst(const T &var)
Atomic load (full barrier).
Definition: atomic_ops.h:56
T * operator--()
Atomic decrement (prefix).
Definition: atomic.h:175
T * operator++(int)
Atomic increment (postfix).
Definition: atomic.h:170
T * operator+=(ptrdiff_t val)
Atomic addition.
Definition: atomic.h:185
Atomic(T *val=NULL)
Initialize with given value.
Definition: atomic.h:129
bool compare_exchange(T *exp, T *des)
Atomic compare-and-swap.
Definition: atomic.h:139
T * operator++()
Atomic increment (prefix).
Definition: atomic.h:165
T * operator-=(ptrdiff_t val)
Atomic subtraction.
Definition: atomic.h:190
T & operator*() const
Atomic load.
Definition: atomic.h:149
T * operator=(T *val)
Atomic store.
Definition: atomic.h:159
T * operator->() const
Atomic load.
Definition: atomic.h:144
T * operator--(int)
Atomic decrement (postfix).
Definition: atomic.h:180
T * exchange(T *val)
Atomic exchange.
Definition: atomic.h:134
Atomic integer. Provides sequential consistency. For a fine-grained memory order control,...
Definition: atomic.h:26
T exchange(T val)
Atomic exchange.
Definition: atomic.h:39
T operator++()
Atomic increment (prefix).
Definition: atomic.h:75
bool compare_exchange(T exp, T des)
Atomic compare-and-swap.
Definition: atomic.h:44
T operator+=(T val)
Atomic addition.
Definition: atomic.h:95
T operator^=(T val)
Atomic bitwise xor.
Definition: atomic.h:115
T operator-=(T val)
Atomic subtraction.
Definition: atomic.h:100
T fetch_xor(T val)
Atomic fetch-xor.
Definition: atomic.h:59
T operator--(int)
Atomic decrement (postfix).
Definition: atomic.h:90
T fetch_or(T val)
Atomic fetch-or.
Definition: atomic.h:49
T fetch_and(T val)
Atomic fetch-and.
Definition: atomic.h:54
Atomic(T val=0)
Initialize with given value.
Definition: atomic.h:34
T operator=(T val)
Atomic store.
Definition: atomic.h:69
T operator|=(T val)
Atomic bitwise or.
Definition: atomic.h:105
T operator&=(T val)
Atomic bitwise and.
Definition: atomic.h:110
T operator--()
Atomic decrement (prefix).
Definition: atomic.h:85
T operator++(int)
Atomic increment (postfix).
Definition: atomic.h:80
Base class for non-copyable objects.
Definition: noncopyable.h:23
Root namespace.
Non-copyable object.
Commonly used types and functions.