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++ !
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:
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.*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.