I am studying glibc (The version is 2.32). As for memory barrier, read, write and full barrier for x86 are as follows:
#define atomic_full_barrier() \
__asm __volatile (LOCK_PREFIX "orl $0, (%%" SP_REG ")" ::: "memory")
#define atomic_read_barrier() __asm ("" ::: "memory")
#define atomic_write_barrier() __asm ("" ::: "memory")
As cppreference and this answer say, volatile
tells the compiler don't optimize and reorder this instruction.
Why do write and read barrier not use __asm __volatile
, while full barrier uses it?
An asm
statement with no output operands is implicitly volatile
(GCC manual).
So they're actually all volatile
, which is necessary for them to not be removed by the optimizer.
(non-volatile
asm is assumed to be a pure function with no side effects, run only if needed to produce the outputs. The clobbers are only clobbered if / when the optimizer decides it needs to run the asm statement).
Different authors chose to be more or less explicit. If you git blame
, I expect you'll see those were written at different times and/or by different people.