Hi Alexandre,

> #define SLOCK_DEFINE_SCALAR_ACCESSORS(typename) \

> static inline typename \

> slock_read_barrier_##typename(volatile slock_t *lock, volatile typename
*p) \

> { \

> typename val; \

> \

> (void) lock; \

> AssertPointerAlignment(p, alignof(typename)); \

> val = *p; \

> pg_read_barrier(); \

> return val; \

> } \

> static inline void \

> slock_write_barrier_##typename(volatile slock_t *lock, volatile typename
*p, typename v) \

> { \

> (void) lock; \

> AssertPointerAlignment(p, alignof(typename)); \

> *p = v; \

> pg_write_barrier(); \

>

> }


On x86 pg_read_barrier() and pg_write_barrier() are only compiler
barriers, so v1 ends up as a plain load and a plain store there. That
hides problems. ARM, RISC-V and POWER are weakly ordered, and on those
a write barrier placed after the store does not order it against the
stores before it. The spinlock version does not have that problem.

I think the safer route is what recent commits like df3978c2340 did,
convert the field to pg_atomic and use pg_atomic_read_membarrier_u32()
and pg_atomic_write_membarrier_u32().

Thanks,
Shihao

Reply via email to