Questions tagged [stdatomic]

std::atomic is a class template in the C++11 Standard Library which provides atomic operations.

std::atomic is a class template in the C++11 Standard Library, defined in the <atomic> header. An atomic object of type std::atomic<X> provides member functions to perform atomic operations on its member of type X.

Like mutexes, atomic objects can be used for synchronization in multi-threaded C++ programs. Unlike mutexes or other locks, atomics can be used to build algorithms that allow concurrent readers and writers.

Atomics can even be used to build custom locking primitives (but that's usually a bad idea on systems with OS-supported locking functions that yield the CPU on contention).

Resources:

591 questions
14
votes
4 answers

How to achieve a StoreLoad barrier in C++11?

I want to write portable code (Intel, ARM, PowerPC...) which solves a variant of a classic problem: Initially: X=Y=0 Thread A: X=1 if(!Y){ do something } Thread B: Y=1 if(!X){ do something } in which the goal is to avoid a situation in…
qbolec
  • 5,374
  • 2
  • 35
  • 44
14
votes
2 answers

How is std::atomic_ref implemented for non-atomic types?

I am wondering how can std::atomic_ref be implemented efficiently (one std::mutex per object) for non-atomic objects as the following property seems rather hard to enforce: Atomic operations applied to an object through an atomic_ref are atomic…
Nonyme
  • 1,220
  • 1
  • 11
  • 22
14
votes
1 answer

C++ shared_mutex implementation

boost::shared_mutex or std::shared_mutex (C++17) can be used for single writer, multiple reader access. As an educational exercise, I put together a simple implementation that uses spinlocking and has other limitations (eg. fairness policy), but is…
LWimsey
  • 6,189
  • 2
  • 25
  • 53
14
votes
4 answers

Will two atomic writes to different locations in different threads always be seen in the same order by other threads?

Similar to my previous question, consider this code -- Initially -- std::atomic x{0}; std::atomic y{0}; -- Thread 1 -- x.store(1, std::memory_order_release); -- Thread 2 -- y.store(2, std::memory_order_release); -- Thread 3 -- int r1 =…
levzettelin
  • 2,600
  • 19
  • 32
13
votes
2 answers

Why set the stop flag using `memory_order_seq_cst`, if you check it with `memory_order_relaxed`?

Herb Sutter, in his "atomic<> weapons" talk, shows several example uses of atomics, and one of them boils down to following: (video link, timestamped) A main thread launches several worker threads. Workers check the stop flag: while…
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207
13
votes
3 answers

C++20: How is the returning from atomic::wait() guaranteed by the standard?

This is a language-lawyer question. First of all, does the a.wait() in the following code always get to return? std::atomic_int a{ 0 }; void f() { a.store(1, std::memory_order_relaxed); a.notify_one(); } int main() { std::thread…
zwhconst
  • 1,352
  • 9
  • 19
13
votes
2 answers

For purposes of ordering, is atomic read-modify-write one operation or two?

Consider an atomic read-modify-write operation such as x.exchange(..., std::memory_order_acq_rel). For purposes of ordering with respect to loads and stores to other objects, is this treated as: a single operation with acquire-release…
Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
13
votes
5 answers

What formally guarantees that non-atomic variables can't see out-of-thin-air values and create a data race like atomic relaxed theoretically can?

This is a question about the formal guarantees of the C++ standard. The standard points out that the rules for std::memory_order_relaxed atomic variables allow "out of thin air" / "out of the blue" values to appear. But for non-atomic variables, can…
curiousguy
  • 8,038
  • 2
  • 40
  • 58
12
votes
2 answers

Can I perform arithmetic operations on an atomic variable directly?

Can I perform arithmetic operations on an atomic variable directly? Since I find the C standard library provides a lot of utility functions like atomic_fetch_add to perform the addition between an atomic variable and a non-atomic variable. But, I am…
Jason Yu
  • 1,886
  • 16
  • 26
12
votes
2 answers

Using std::atomic with futex system call

In C++20, we got the capability to sleep on atomic variables, waiting for their value to change. We do so by using the std::atomic::wait method. Unfortunately, while wait has been standardized, wait_for and wait_until are not. Meaning that we cannot…
David Haim
  • 25,446
  • 3
  • 44
  • 78
12
votes
3 answers

What does memory_order_consume really do?

From the link: What is the difference between load/store relaxed atomic and normal variable? I was deeply impressed by this answer: Using an atomic variable solves the problem - by using atomics all threads are guarantees to read the latest…
12
votes
0 answers

How does libcxx std::counting_semaphore implement "Strongly happens before" for release / acquire?

libc++ std::counting_semaphore uses atomic increment with memory_order_release in release method: void release(ptrdiff_t __update = 1) { if(0 < __a.fetch_add(__update, memory_order_release)) ; else if(__update >…
Alex Guteniev
  • 12,039
  • 2
  • 34
  • 79
12
votes
2 answers

How is std::atomic implemented

I'm studying the difference between mutex and atomic in C++11. As my understanding, mutex is a kind of lock-mechanism, which is implemented based on the OS/kernel. For example, Linux offers a mechanism, which is futex. With the help of futex, we…
Yves
  • 11,597
  • 17
  • 83
  • 180
12
votes
2 answers

GCC reordering up across load with `memory_order_seq_cst`. Is this allowed?

Using a simplified version of a basic seqlock , gcc reorders a nonatomic load up across an atomic load(memory_order_seq_cst) when compiling the code with -O3. This reordering isn't observed when compiling with other optimization levels or when…
Alejandro
  • 3,040
  • 1
  • 21
  • 30
12
votes
2 answers

Does C++11 guarantee memory ordering between a release fence and a consume operation?

Consider the following code: struct payload { std::atomic< int > value; }; std::atomic< payload* > pointer( nullptr ); void thread_a() { payload* p = new payload(); p->value.store( 10, std::memory_order_relaxed ); …