Use a non-locking initial test in TAS_SPIN on AArch64.
authorNathan Bossart <[email protected]>
Fri, 10 Jan 2025 19:18:04 +0000 (13:18 -0600)
committerNathan Bossart <[email protected]>
Fri, 10 Jan 2025 19:18:04 +0000 (13:18 -0600)
Our testing showed that this is helpful at sufficiently high
contention levels and doesn't hurt performance on smaller machines.
The new TAS_SPIN macro for AArch64 is identical to the ones added
for PPC and x86_64 (see commits bc2a050d40 and b03d196be0).

Reported-by: Salvatore Dipietro
Reviewed-by: Jingtang Zhang, Andres Freund
Tested-by: Tom Lane
Discussion: https://postgr.es/m/ZxgDEb_VpWyNZKB_%40nathan

src/include/storage/s_lock.h

index 516fffc53abd23c9f6ef34674addb1d0d47e82b8..2f73f9fcf57a25a840addf45d0fa9bc8067954c2 100644 (file)
@@ -263,18 +263,24 @@ tas(volatile slock_t *lock)
 
 #define S_UNLOCK(lock) __sync_lock_release(lock)
 
+#if defined(__aarch64__)
+
 /*
- * Using an ISB instruction to delay in spinlock loops appears beneficial on
- * high-core-count ARM64 processors.  It seems mostly a wash for smaller gear,
- * and ISB doesn't exist at all on pre-v7 ARM chips.
+ * On ARM64, it's a win to use a non-locking test before the TAS proper.  It
+ * may be a win on 32-bit ARM, too, but nobody's tested it yet.
  */
-#if defined(__aarch64__)
+#define TAS_SPIN(lock) (*(lock) ? 1 : TAS(lock))
 
 #define SPIN_DELAY() spin_delay()
 
 static __inline__ void
 spin_delay(void)
 {
+       /*
+        * Using an ISB instruction to delay in spinlock loops appears beneficial
+        * on high-core-count ARM64 processors.  It seems mostly a wash for smaller
+        * gear, and ISB doesn't exist at all on pre-v7 ARM chips.
+        */
        __asm__ __volatile__(
                " isb;                          \n");
 }