On Thu, Mar 10, 2022 at 09:05:54AM +0000, Visa Hankala wrote: Hello Visa,
> In general, atomic_* functions have not provided implicit memory > barriers on OpenBSD. I've used atomics fairly extensively in other settings. Forgive me if I'm explaining the obvious, but I had a devil of a job making sense of this stuff a few years back, and so perhaps others might find it useful to expand on this point. Quick background: modern CPUs come in two main flavours, weakly ordered (e.g. most Arm systems) and strongly ordered (e.g. x86), which determine the rules of when multiple cores can see the reads/writes of other cores. Weakly ordered systems can move/optimise loads/stores around more than strongly ordered systems (so code that seems to work fine on x86 can then fail on Arm). There are in a sense two "safe" ways to use atomics: to assume that each atomic is isolated and that reading/writing to it tells you nothing about any other location in memory; or that every atomic is fully ordered with respect to every other atomic (i.e. no reorderings of atomic operations are allowed). The former is fast but (without additional operations) can't even express a mutex safely. The latter doesn't have very good performance. C11 thus allows you to do various atomic operations with different memory orderings [1] so that you can choose on a case-by-case basis what you're prepared to tolerate. "relaxed" is the most efficient but has the least guarantees; "seq_cst" is the least efficient but has the most guarantees. I would be very nervous about adding further atomic functions (as in the original diff) to OpenBSD that don't allow the user to specify what ordering they want: it's impossible to pick a memory ordering that suits all use cases. For example, neither READ_ONCE nor the existing atomic_* instructions define an ordering: I suppose I'd have to to assume they're relaxed. I worry that people might assume these atomic operations provide greater guarantees than they actually do. Fortunately since, AFAICT, we already use C11 (or C17?!) for base, and LLVM includes all of the relevant functions (e.g. the compare_exchange family [2]) I don't think we need to add any functions of our own? It might not even be a bad idea to deprecate the current atomic_* functions in base and migrate to the C11 alternatives? Laurie [1] https://en.cppreference.com/w/c/atomic/memory_order [2] https://en.cppreference.com/w/c/atomic/atomic_compare_exchange