diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h index 810be27e813f4790bf26410d0400f1110264d753..ac45ee6426eb32e3dd893f7e3e82d2b98dc9fc03 100644 --- a/src/include/pg_config_manual.h +++ b/src/include/pg_config_manual.h @@ -188,6 +188,17 @@ #endif #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 diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h index 2e5163eabf071fbb451a9c62bf6147bc25023e8a..ff7eb1418e63b19b3396485b4725e1fc06ca8441 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 */