#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
/*
* 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)
"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"
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 */