Mixing atomics between C and Rust

Hi, is it legal to use atomics from both C and Rust at the same time?

__atomic_store_n(armed, 1, __ATOMIC_RELEASE);

And then on the same pointer:

armed.load(Ordering::Acquire);

Not C++ !

Yes, this is fine, with two conditions.

The std docs for the atomic module say: "Rust atomics currently follow the same rules as C++20 atomics, specifically the rules from the intro.races section, without the 'consume' memory ordering." GCC's __atomic_* builtins implement that same model, so a C __ATOMIC_RELEASE store paired with a Rust Ordering::Acquire load on the same address is the same release/acquire pair you would get within one language.

The two conditions:

  1. The widths must match. AtomicU32 has the same size and alignment as u32 (4/4 — you can check with size_of/align_of), so pair it with a uint32_t on the C side, not with int or a bool. On the platforms that matter this is the same thing, but say what you mean.
  2. The pointer must be properly aligned and the object must be accessed only atomically on both sides while it is shared. A plain non-atomic read or write in C (*armed = 1;) next to a Rust atomic load is a data race, exactly as it would be within C alone.

On the Rust side the usual way to get there is AtomicU32::from_ptr(p) if C owns the memory, which is safe as long as the alignment and exclusive-atomic-access rules above hold.