I wrote: > So about like this, then. After actually testing (by removing the ARM stanza on a macOS machine), it seems that placement doesn't work, because of the default definition of S_UNLOCK at the bottom of the "#if defined(__GNUC__)" stuff. Putting it inside that test works, and seems like it should be fine, since this is a GCC-ism.
regards, tom lane
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h index 4225d9b7fc..8b19ab160f 100644 --- a/src/include/storage/s_lock.h +++ b/src/include/storage/s_lock.h @@ -293,29 +293,6 @@ spin_delay(void) #endif /* __arm__ || __arm || __aarch64__ */ -/* - * RISC-V likewise uses __sync_lock_test_and_set(int *, int) if available. - */ -#if defined(__riscv) -#ifdef HAVE_GCC__SYNC_INT32_TAS -#define HAS_TEST_AND_SET - -#define TAS(lock) tas(lock) - -typedef int slock_t; - -static __inline__ int -tas(volatile slock_t *lock) -{ - return __sync_lock_test_and_set(lock, 1); -} - -#define S_UNLOCK(lock) __sync_lock_release(lock) - -#endif /* HAVE_GCC__SYNC_INT32_TAS */ -#endif /* __riscv */ - - /* S/390 and S/390x Linux (32- and 64-bit zSeries) */ #if defined(__s390__) || defined(__s390x__) #define HAS_TEST_AND_SET @@ -619,6 +596,50 @@ tas(volatile slock_t *lock) #endif /* __hppa || __hppa__ */ +/* + * If we have no platform-specific knowledge, but we found that the compiler + * provides __sync_lock_test_and_set(), use that. Prefer the int-width + * version over the char-width version if we have both, on the rather dubious + * grounds that that's known to be more likely to work in the ARM ecosystem. + * (But we dealt with ARM above.) + */ +#if !defined(HAS_TEST_AND_SET) + +#if defined(HAVE_GCC__SYNC_INT32_TAS) +#define HAS_TEST_AND_SET + +#define TAS(lock) tas(lock) + +typedef int slock_t; + +static __inline__ int +tas(volatile slock_t *lock) +{ + return __sync_lock_test_and_set(lock, 1); +} + +#define S_UNLOCK(lock) __sync_lock_release(lock) + +#elif defined(HAVE_GCC__SYNC_CHAR_TAS) +#define HAS_TEST_AND_SET + +#define TAS(lock) tas(lock) + +typedef char slock_t; + +static __inline__ int +tas(volatile slock_t *lock) +{ + return __sync_lock_test_and_set(lock, 1); +} + +#define S_UNLOCK(lock) __sync_lock_release(lock) + +#endif /* HAVE_GCC__SYNC_INT32_TAS */ + +#endif /* !defined(HAS_TEST_AND_SET) */ + + /* * Default implementation of S_UNLOCK() for gcc/icc. *