Re: MemoryFence()


Paolo Bonzini <pbonzini@...>
 

On 08/02/21 21:44, Ankur Arora wrote:
Since the first two are of unequal power -- volatile for specific
accesses and the compiler fence being a general barrier across which
the compiler does not optimize memory accesses I think we should have
both instead of volatile or compiler fence.
However, instead of volatile, how about read_once(), write_once()
primitives? These, respectively ensure that the compiler emits a
single load or a store and does not combine or mutilate the load/store
in any way.
Well, that could certainly be a next step, but I intentionally left it out of my proposal to Laszlo.

The reason for that is that the fences are already enough to wean the edk2 codebase from volatile declarations and pointers, and that is the big paradigm change---annotating code rather than data.

Once you've done that switch I would certainly agree with (basically) an edk2 flavor of C11-like atomic primitives:

- at the very least, AtomicLoadRelaxed and AtomicStoreRelaxed corresponding to Linux's READ_ONCE/WRITE_ONCE

- and if it is possible to implement them easily on MSVC, AtomicLoadAcquire and AtomicStoreRelease

However, these changes do not have to be done in a single step. Starting with the rationalization of memory fences makes sense because, in addition to enabling the annotation of code rather than data, it is essentially a bugfix.

As an aside, I always stay away from the "memory_order_seq_cst" loads and stores. Those are much more tricky than what their name suggests, and their use cases are much better served by something like

AtomicStoreRelaxed(&a, 1); // atomic_store(mo_relaxed)
MemoryFence(); // atomic_thread_fence(mo_seq_cst)
y = AtomicLoadRelaxed(&b); // atomic_load(mo_relaxed)

Paolo

Join rfc@edk2.groups.io to automatically receive all group messages.