Justicle
Justicle

Reputation: 15143

In C using Clang atomics, how should I perform an atomic pre-increment?

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

Answers (3)

Peter Cordes
Peter Cordes

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

Shawn
Shawn

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

ikegami
ikegami

Reputation: 385655

You can use

v = atomic_fetch_add(&x, 1) + 1;

Upvotes: 6

Related Questions