aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2012-01-02 00:01:33 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2012-01-02 00:02:02 -0500
commit631beeac3598a73dee2c2afa38fa2e734148031b (patch)
tree0e2eaa2bb84bef297e9f4ab8e68a00de683b53bd /src/include
parent8496c6cd77e2f5f105fc47315680174157d66647 (diff)
downloadpostgresql-631beeac3598a73dee2c2afa38fa2e734148031b.tar.gz
postgresql-631beeac3598a73dee2c2afa38fa2e734148031b.zip
Use LWSYNC in place of SYNC/ISYNC in PPC spinlocks, where possible.
This is allegedly a win, at least on some PPC implementations, according to the PPC ISA documents. However, as with LWARX hints, some PPC platforms give an illegal-instruction failure. Use the same trick as before of assuming that PPC64 platforms will accept it; we might need to refine that based on experience, but there are other projects doing likewise according to google. I did not add an assembler compatibility test because LWSYNC has been around much longer than hint bits, and it seems unlikely that any toolchains currently in use don't recognize it.
Diffstat (limited to 'src/include')
-rw-r--r--src/include/pg_config_manual.h11
-rw-r--r--src/include/storage/s_lock.h19
2 files changed, 29 insertions, 1 deletions
diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h
index 810be27e813..ac45ee6426e 100644
--- a/src/include/pg_config_manual.h
+++ b/src/include/pg_config_manual.h
@@ -189,6 +189,17 @@
#endif
/*
+ * On PPC machines, decide whether to use LWSYNC instructions in place of
+ * ISYNC and SYNC. This provides slightly better performance, but will
+ * result in illegal-instruction failures on some pre-POWER4 machines.
+ * By default we use LWSYNC when building for 64-bit PPC, which should be
+ * safe in nearly all cases.
+ */
+#if defined(__ppc64__) || defined(__powerpc64__)
+#define USE_PPC_LWSYNC
+#endif
+
+/*
*------------------------------------------------------------------------
* The following symbols are for enabling debugging code, not for
* controlling user-visible features or resource limits.
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index 2e5163eabf0..ff7eb1418e6 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -361,6 +361,7 @@ typedef unsigned int slock_t;
/*
* NOTE: per the Enhanced PowerPC Architecture manual, v1.0 dated 7-May-2002,
* an isync is a sufficient synchronization barrier after a lwarx/stwcx loop.
+ * On newer machines, we can use lwsync instead for better performance.
*/
static __inline__ int
tas(volatile slock_t *lock)
@@ -382,7 +383,11 @@ tas(volatile slock_t *lock)
"1: li %1,1 \n"
" b 3f \n"
"2: \n"
+#ifdef USE_PPC_LWSYNC
+" lwsync \n"
+#else
" isync \n"
+#endif
" li %1,0 \n"
"3: \n"
@@ -392,13 +397,25 @@ tas(volatile slock_t *lock)
return _res;
}
-/* PowerPC S_UNLOCK is almost standard but requires a "sync" instruction */
+/*
+ * PowerPC S_UNLOCK is almost standard but requires a "sync" instruction.
+ * On newer machines, we can use lwsync instead for better performance.
+ */
+#ifdef USE_PPC_LWSYNC
+#define S_UNLOCK(lock) \
+do \
+{ \
+ __asm__ __volatile__ (" lwsync \n"); \
+ *((volatile slock_t *) (lock)) = 0; \
+} while (0)
+#else
#define S_UNLOCK(lock) \
do \
{ \
__asm__ __volatile__ (" sync \n"); \
*((volatile slock_t *) (lock)) = 0; \
} while (0)
+#endif /* USE_PPC_LWSYNC */
#endif /* powerpc */