Reputation: 15143
Expanding from this question (How to do an atomic increment and fetch in C?)
In C, using Clang compiler, how can I do the atomic equivalent of
const int v = ++x
As I understand it, v = atomic_fetch_add(&x, 1)
will return the original value (ie v = x++
), which is a post-increment.
How do I return the updated value of x instead?
Note: this question is about C, and any replies with "use std::atomic<>" will be downvoted accordingly.
Upvotes: 0
Views: 1756
Reputation: 364160
For _Atomic int x;
, your example local = ++shared;
already does work atomically, like GNU C __atomic_add_fetch
(not ..._fetch_add
). ISO C11 is no different for this than ISO C++.
The downside is that you can't specify a memory-order weaker than seq_cst, and there's no equivalent for other operators, unlike GNU C __atomic_or_fetch
.
Compilers are generally decent at optimising ISO C atomic_fetch_add(&x, 1) + 1
, although it wasn't until GCC12 that GCC managed to make the same asm for this as for using the return value of ++x
. Before that, on LL/SC machines (like ARM, and AArch64 before ARMv8.1), it would do fetch_add
but then not using the incremented value it had in a register, doing a separate add
after the loop on the load result. (Godbolt)
Upvotes: 2
Reputation: 52344
You can use the clang
/gcc
intrinsic function __atomic_add_fetch()
, which first adds to a number then returns the new value (There's also __atomic_fetch_add()
which acts like the C11 atomic_fetch_add()
):
int x = 1;
const int v = __atomic_add_fetch(&x, 1, __ATOMIC_SEQ_CST); // v is 2
Upvotes: 3