From cd4eb239d67ef110e0f62a34a5cb720266473477 Mon Sep 17 00:00:00 2001 From: Alexandre Felipe Date: Thu, 1 Oct 2026 11:48:52 +0100 Subject: [PATCH 1/2] Spin-lock protected scalar accessors Helper methods to access variables protected by a spin-lock, with simplifications for single variables that can be stored or loaded atomically. --- src/include/storage/spin.h | 95 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) diff --git a/src/include/storage/spin.h b/src/include/storage/spin.h index 9cf6adb671a..0d2757c2a71 100644 --- a/src/include/storage/spin.h +++ b/src/include/storage/spin.h @@ -45,6 +45,8 @@ #define SPIN_H #include "storage/s_lock.h" +#include "port/atomics.h" +#include "c.h" static inline void SpinLockInit(volatile slock_t *lock) @@ -64,4 +66,97 @@ SpinLockRelease(volatile slock_t *lock) S_UNLOCK(lock); } + +/* + * Load/store a field also guarded by *lock. when the platform can access *p + * with the correct width atomically, the lock is not used. + * On platforms with PG_HAVE_ATOMIC_U64_SIMULATION, 64-bit accesses use *lock. + */ + +#define SLOCK_DEFINE_SCALAR_IMPL(type, typename) \ +static inline typename \ +slock_read_##type##_impl(volatile slock_t *lock, volatile typename *p) \ +{ \ + typename val; \ +\ + (void) lock; \ + AssertPointerAlignment(p, alignof(typename)); \ + __atomic_load(p, &val, __ATOMIC_RELAXED); \ + pg_read_barrier(); \ + return val; \ +} \ +static inline void \ +slock_write_##type##_impl(volatile slock_t *lock, volatile typename *p, typename v) \ +{ \ + (void) lock; \ + AssertPointerAlignment(p, alignof(typename)); \ + __atomic_store(p, &v, __ATOMIC_RELAXED); \ + pg_write_barrier(); \ +} + +#define SLOCK_DEFINE_LOCKED_IMPL(type, typename) \ +static inline typename \ +slock_read_##type##_impl(volatile slock_t *lock, volatile typename *p) \ +{ \ + typename val; \ +\ + SpinLockAcquire(lock); \ + __atomic_load(p, &val, __ATOMIC_RELAXED); \ + SpinLockRelease(lock); \ + return val; \ +} \ +static inline void \ +slock_write_##type##_impl(volatile slock_t *lock, volatile typename *p, typename v) \ +{ \ + SpinLockAcquire(lock); \ + __atomic_store(p, &v, __ATOMIC_RELAXED); \ + SpinLockRelease(lock); \ +} + +#define SLOCK_SCALAR_READ(type, typename, lock, p) \ + (\ + StaticAssertExpr(sizeof(*(p)) == sizeof(typename), "slock_read_" #type " size mismatch"), \ + StaticAssertExpr(sizeof(v) == sizeof(typename), "slock_read_" #type " size mismatch"), \ + slock_read_##type##_impl((lock), (volatile typename *) (p))) + +#define SLOCK_SCALAR_WRITE(type, typename, lock, p, v) \ + ((void) ( \ + StaticAssertExpr(sizeof(*(p)) == sizeof(typename), "slock_write_" #type " size mismatch"), \ + StaticAssertExpr(sizeof((v)) == sizeof(typename), "slock_write_" #type " size mismatch"), \ + slock_write_##type##_impl((lock), (volatile typename *) (p), (typename) (v)))) + +SLOCK_DEFINE_SCALAR_IMPL(u8, unsigned char) +SLOCK_DEFINE_SCALAR_IMPL(u16, unsigned short) +SLOCK_DEFINE_SCALAR_IMPL(u32, unsigned int) +SLOCK_DEFINE_SCALAR_IMPL(ptr, Pointer) + +#if !defined(PG_HAVE_ATOMIC_U64_SIMULATION) +SLOCK_DEFINE_SCALAR_IMPL(u64, uint64) +#else /* PG_HAVE_ATOMIC_U64_SIMULATION */ +SLOCK_DEFINE_LOCKED_IMPL(u64, uint64) +#endif /* PG_HAVE_ATOMIC_U64_SIMULATION */ + +#define slock_read_u8(lock, p) \ + SLOCK_SCALAR_READ(u8, uint8, lock, p) +#define slock_write_u8(lock, p, v) \ + SLOCK_SCALAR_WRITE(u8, uint8, lock, p, v) +#define slock_read_u16(lock, p) \ + SLOCK_SCALAR_READ(u16, uint16, lock, p) +#define slock_write_u16(lock, p, v) \ + SLOCK_SCALAR_WRITE(u16, uint16, lock, p, v) +#define slock_read_u32(lock, p) \ + SLOCK_SCALAR_READ(u32, uint32, lock, p) +#define slock_write_u32(lock, p, v) \ + SLOCK_SCALAR_WRITE(u32, uint32, lock, p, v) +#define slock_read_u64(lock, p) \ + SLOCK_SCALAR_READ(u64, uint64, lock, p) +#define slock_write_u64(lock, p, v) \ + SLOCK_SCALAR_WRITE(u64, uint64, lock, p, v) +#define slock_read_ptr(lock, p) \ + SLOCK_SCALAR_READ(ptr, Pointer, lock, p) +#define slock_write_ptr(lock, p, v) \ + SLOCK_SCALAR_WRITE(ptr, Pointer, lock, p, v) + +#undef SLOCK_DEFINE_SCALAR_IMPL +#undef SLOCK_DEFINE_LOCKED_IMPL #endif /* SPIN_H */ -- 2.53.0