1 /** \file boost/atomic.hpp */
3 // Copyright (c) 2009 Helge Bahmann
5 // Distributed under the Boost Software License, Version 1.0.
6 // See accompanying file LICENSE_1_0.txt or copy at
7 // http://www.boost.org/LICENSE_1_0.txt)
9 /* this is just a pseudo-header file fed to doxygen
10 to more easily generate the class documentation; will
11 be replaced by proper documentation down the road */
16 \brief Memory ordering constraints
18 This defines the relative order of one atomic operation
19 and other memory operations (loads, stores, other atomic operations)
20 executed by the same thread.
22 The order of operations specified by the programmer in the
23 source code ("program order") does not necessarily match
24 the order in which they are actually executed on the target system:
25 Both compiler as well as processor may reorder operations
26 quite arbitrarily. <B>Specifying the wrong ordering
27 constraint will therefore generally result in an incorrect program.</B>
32 Atomic operation and other memory operations may be reordered freely.
36 \brief Data dependence constraint
37 Atomic operation must strictly precede any memory operation that
38 computationally depends on the outcome of the atomic operation.
43 Atomic operation must strictly precede all memory operations that
44 follow in program order.
49 Atomic operation must strictly follow all memory operations that precede
54 \brief Acquire and release memory
55 Combines the effects of \ref memory_order_acquire and \ref memory_order_release
59 \brief Sequentially consistent
60 Produces the same result \ref memory_order_acq_rel, but additionally
61 enforces globally sequential consistent execution
67 \brief Atomic datatype
69 An atomic variable. Provides methods to modify this variable atomically.
70 Valid template parameters are:
72 - integral data types (char, short, int, ...)
74 - any other data type that has a non-throwing default
75 constructor and that can be copied via <TT>memcpy</TT>
77 Unless specified otherwise, any memory ordering constraint can be used
78 with any of the atomic operations.
80 template<typename Type>
84 \brief The constant equals to \c true if the atomic type's operations
85 are always lock-free and \c false otherwise.
87 If this constant is \c true then \c is_lock_free() shall always
88 return \c true for any object of this atomic type.
90 static constexpr bool is_always_lock_free;
93 \brief Create uninitialized atomic variable
94 Creates an atomic variable. Its initial value is undefined.
98 \brief Create an initialize atomic variable
99 \param value Initial value
100 Creates and initializes an atomic variable.
102 explicit atomic(Type value);
105 \brief Returns \c true if the object's operations are lock-free
106 and \c false otherwise.
108 bool is_lock_free() const noexcept;
112 \brief Read the current value of the atomic variable
113 \param order Memory ordering constraint, see \ref memory_order
114 \return Current value of the variable
116 Valid memory ordering constraints are:
117 - @c memory_order_relaxed
118 - @c memory_order_consume
119 - @c memory_order_acquire
120 - @c memory_order_seq_cst
122 Type load(memory_order order=memory_order_seq_cst) const;
125 \brief Write new value to atomic variable
126 \param value New value
127 \param order Memory ordering constraint, see \ref memory_order
129 Valid memory ordering constraints are:
130 - @c memory_order_relaxed
131 - @c memory_order_release
132 - @c memory_order_seq_cst
134 void store(Type value, memory_order order=memory_order_seq_cst);
137 \brief Atomically compare and exchange variable
138 \param expected Expected old value
139 \param desired Desired new value
140 \param order Memory ordering constraint, see \ref memory_order
141 \return @c true if value was changed
143 Atomically performs the following operation
146 if (variable==expected) {
155 This operation may fail "spuriously", i.e. the state of the variable
156 is unchanged even though the expected value was found (this is the
157 case on architectures using "load-linked"/"store conditional" to
158 implement the operation).
160 The established memory order will be @c order if the operation
161 is successful. If the operation is unsuccessful, the
164 - @c memory_order_relaxed if @c order is @c memory_order_acquire ,
165 @c memory_order_relaxed or @c memory_order_consume
166 - @c memory_order_release if @c order is @c memory_order_acq_release
167 or @c memory_order_release
168 - @c memory_order_seq_cst if @c order is @c memory_order_seq_cst
170 bool compare_exchange_weak(
173 memory_order order=memory_order_seq_cst);
176 \brief Atomically compare and exchange variable
177 \param expected Expected old value
178 \param desired Desired new value
179 \param success_order Memory ordering constraint if operation
181 \param failure_order Memory ordering constraint if operation is unsuccessful
182 \return @c true if value was changed
184 Atomically performs the following operation
187 if (variable==expected) {
196 This operation may fail "spuriously", i.e. the state of the variable
197 is unchanged even though the expected value was found (this is the
198 case on architectures using "load-linked"/"store conditional" to
199 implement the operation).
201 The constraint imposed by @c success_order may not be
202 weaker than the constraint imposed by @c failure_order.
204 bool compare_exchange_weak(
207 memory_order success_order,
208 memory_order failure_order);
210 \brief Atomically compare and exchange variable
211 \param expected Expected old value
212 \param desired Desired new value
213 \param order Memory ordering constraint, see \ref memory_order
214 \return @c true if value was changed
216 Atomically performs the following operation
219 if (variable==expected) {
228 In contrast to \ref compare_exchange_weak, this operation will never
229 fail spuriously. Since compare-and-swap must generally be retried
230 in a loop, implementors are advised to prefer \ref compare_exchange_weak
233 The established memory order will be @c order if the operation
234 is successful. If the operation is unsuccessful, the
237 - @c memory_order_relaxed if @c order is @c memory_order_acquire ,
238 @c memory_order_relaxed or @c memory_order_consume
239 - @c memory_order_release if @c order is @c memory_order_acq_release
240 or @c memory_order_release
241 - @c memory_order_seq_cst if @c order is @c memory_order_seq_cst
243 bool compare_exchange_strong(
246 memory_order order=memory_order_seq_cst);
249 \brief Atomically compare and exchange variable
250 \param expected Expected old value
251 \param desired Desired new value
252 \param success_order Memory ordering constraint if operation
254 \param failure_order Memory ordering constraint if operation is unsuccessful
255 \return @c true if value was changed
257 Atomically performs the following operation
260 if (variable==expected) {
269 In contrast to \ref compare_exchange_weak, this operation will never
270 fail spuriously. Since compare-and-swap must generally be retried
271 in a loop, implementors are advised to prefer \ref compare_exchange_weak
274 The constraint imposed by @c success_order may not be
275 weaker than the constraint imposed by @c failure_order.
277 bool compare_exchange_strong(
280 memory_order success_order,
281 memory_order failure_order);
283 \brief Atomically exchange variable
284 \param value New value
285 \param order Memory ordering constraint, see \ref memory_order
286 \return Old value of the variable
288 Atomically exchanges the value of the variable with the new
289 value and returns its old value.
291 Type exchange(Type value, memory_order order=memory_order_seq_cst);
294 \brief Atomically add and return old value
295 \param operand Operand
296 \param order Memory ordering constraint, see \ref memory_order
297 \return Old value of the variable
299 Atomically adds operand to the variable and returns its
302 Type fetch_add(Type operand, memory_order order=memory_order_seq_cst);
304 \brief Atomically subtract and return old value
305 \param operand Operand
306 \param order Memory ordering constraint, see \ref memory_order
307 \return Old value of the variable
309 Atomically subtracts operand from the variable and returns its
312 This method is available only if \c Type is an integral type
313 or a non-void pointer type. If it is a pointer type,
314 @c operand is of type @c ptrdiff_t and the operation
315 is performed following the rules for pointer arithmetic
318 Type fetch_sub(Type operand, memory_order order=memory_order_seq_cst);
321 \brief Atomically perform bitwise "AND" and return old value
322 \param operand Operand
323 \param order Memory ordering constraint, see \ref memory_order
324 \return Old value of the variable
326 Atomically performs bitwise "AND" with the variable and returns its
329 This method is available only if \c Type is an integral type
330 or a non-void pointer type. If it is a pointer type,
331 @c operand is of type @c ptrdiff_t and the operation
332 is performed following the rules for pointer arithmetic
335 Type fetch_and(Type operand, memory_order order=memory_order_seq_cst);
338 \brief Atomically perform bitwise "OR" and return old value
339 \param operand Operand
340 \param order Memory ordering constraint, see \ref memory_order
341 \return Old value of the variable
343 Atomically performs bitwise "OR" with the variable and returns its
346 This method is available only if \c Type is an integral type.
348 Type fetch_or(Type operand, memory_order order=memory_order_seq_cst);
351 \brief Atomically perform bitwise "XOR" and return old value
352 \param operand Operand
353 \param order Memory ordering constraint, see \ref memory_order
354 \return Old value of the variable
356 Atomically performs bitwise "XOR" with the variable and returns its
359 This method is available only if \c Type is an integral type.
361 Type fetch_xor(Type operand, memory_order order=memory_order_seq_cst);
365 \return Current value of the variable
367 The same as <tt>load(memory_order_seq_cst)</tt>. Avoid using
368 the implicit conversion operator, use \ref load with
369 an explicit memory ordering constraint.
371 operator Type(void) const;
373 \brief Implicit store
374 \param value New value
375 \return Copy of @c value
377 The same as <tt>store(value, memory_order_seq_cst)</tt>. Avoid using
378 the implicit conversion operator, use \ref store with
379 an explicit memory ordering constraint.
381 Type operator=(Type v);
384 \brief Atomically perform bitwise "AND" and return new value
385 \param operand Operand
386 \return New value of the variable
388 The same as <tt>fetch_and(operand, memory_order_seq_cst)&operand</tt>.
389 Avoid using the implicit bitwise "AND" operator, use \ref fetch_and
390 with an explicit memory ordering constraint.
392 Type operator&=(Type operand);
395 \brief Atomically perform bitwise "OR" and return new value
396 \param operand Operand
397 \return New value of the variable
399 The same as <tt>fetch_or(operand, memory_order_seq_cst)|operand</tt>.
400 Avoid using the implicit bitwise "OR" operator, use \ref fetch_or
401 with an explicit memory ordering constraint.
403 This method is available only if \c Type is an integral type.
405 Type operator|=(Type operand);
408 \brief Atomically perform bitwise "XOR" and return new value
409 \param operand Operand
410 \return New value of the variable
412 The same as <tt>fetch_xor(operand, memory_order_seq_cst)^operand</tt>.
413 Avoid using the implicit bitwise "XOR" operator, use \ref fetch_xor
414 with an explicit memory ordering constraint.
416 This method is available only if \c Type is an integral type.
418 Type operator^=(Type operand);
421 \brief Atomically add and return new value
422 \param operand Operand
423 \return New value of the variable
425 The same as <tt>fetch_add(operand, memory_order_seq_cst)+operand</tt>.
426 Avoid using the implicit add operator, use \ref fetch_add
427 with an explicit memory ordering constraint.
429 This method is available only if \c Type is an integral type
430 or a non-void pointer type. If it is a pointer type,
431 @c operand is of type @c ptrdiff_t and the operation
432 is performed following the rules for pointer arithmetic
435 Type operator+=(Type operand);
438 \brief Atomically subtract and return new value
439 \param operand Operand
440 \return New value of the variable
442 The same as <tt>fetch_sub(operand, memory_order_seq_cst)-operand</tt>.
443 Avoid using the implicit subtract operator, use \ref fetch_sub
444 with an explicit memory ordering constraint.
446 This method is available only if \c Type is an integral type
447 or a non-void pointer type. If it is a pointer type,
448 @c operand is of type @c ptrdiff_t and the operation
449 is performed following the rules for pointer arithmetic
452 Type operator-=(Type operand);
455 \brief Atomically increment and return new value
456 \return New value of the variable
458 The same as <tt>fetch_add(1, memory_order_seq_cst)+1</tt>.
459 Avoid using the implicit increment operator, use \ref fetch_add
460 with an explicit memory ordering constraint.
462 This method is available only if \c Type is an integral type
463 or a non-void pointer type. If it is a pointer type,
465 is performed following the rules for pointer arithmetic
468 Type operator++(void);
470 \brief Atomically increment and return old value
471 \return Old value of the variable
473 The same as <tt>fetch_add(1, memory_order_seq_cst)</tt>.
474 Avoid using the implicit increment operator, use \ref fetch_add
475 with an explicit memory ordering constraint.
477 This method is available only if \c Type is an integral type
478 or a non-void pointer type. If it is a pointer type,
480 is performed following the rules for pointer arithmetic
483 Type operator++(int);
485 \brief Atomically subtract and return new value
486 \return New value of the variable
488 The same as <tt>fetch_sub(1, memory_order_seq_cst)-1</tt>.
489 Avoid using the implicit increment operator, use \ref fetch_sub
490 with an explicit memory ordering constraint.
492 This method is available only if \c Type is an integral type
493 or a non-void pointer type. If it is a pointer type,
495 is performed following the rules for pointer arithmetic
498 Type operator--(void);
500 \brief Atomically subtract and return old value
501 \return Old value of the variable
503 The same as <tt>fetch_sub(1, memory_order_seq_cst)</tt>.
504 Avoid using the implicit increment operator, use \ref fetch_sub
505 with an explicit memory ordering constraint.
507 This method is available only if \c Type is an integral type
508 or a non-void pointer type. If it is a pointer type,
510 is performed following the rules for pointer arithmetic
513 Type operator--(int);
515 /** \brief Deleted copy constructor */
516 atomic(const atomic &) = delete;
517 /** \brief Deleted copy assignment */
518 const atomic & operator=(const atomic &) = delete;
522 \brief Insert explicit fence for thread synchronization
523 \param order Memory ordering constraint
525 Inserts an explicit fence. The exact semantic depends on the
526 type of fence inserted:
528 - \c memory_order_relaxed: No operation
529 - \c memory_order_release: Performs a "release" operation
530 - \c memory_order_acquire or \c memory_order_consume: Performs an
532 - \c memory_order_acq_rel: Performs both an "acquire" and a "release"
534 - \c memory_order_seq_cst: Performs both an "acquire" and a "release"
535 operation and in addition there exists a global total order of
536 all \c memory_order_seq_cst operations
539 void atomic_thread_fence(memory_order order);
542 \brief Insert explicit fence for synchronization with a signal handler
543 \param order Memory ordering constraint
545 Inserts an explicit fence to synchronize with a signal handler called within
546 the context of the same thread. The fence ensures the corresponding operations
547 around it are complete and/or not started. The exact semantic depends on the
548 type of fence inserted:
550 - \c memory_order_relaxed: No operation
551 - \c memory_order_release: Ensures the operations before the fence are complete
552 - \c memory_order_acquire or \c memory_order_consume: Ensures the operations
553 after the fence are not started.
554 - \c memory_order_acq_rel or \c memory_order_seq_cst: Ensures the operations
555 around the fence do not cross it.
557 Note that this call does not affect visibility order of the memory operations
558 to other threads. It is functionally similar to \c atomic_thread_fence, only
559 it does not generate any instructions to synchronize hardware threads.
561 void atomic_signal_fence(memory_order order);