aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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 */