Search code examples
cgccglibcinline-assemblymemory-barriers

Why do read and write barrier for x86 in glibc not use __volatile asm?


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?


Solution

  • 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.