]> granicus.if.org Git - postgresql/blobdiff - src/include/storage/s_lock.h
Add spinlock support for Itanium processor with Intel compiler.
[postgresql] / src / include / storage / s_lock.h
index 0725fd06d24caed01607a74bd1b9dbc511e0e8cf..49bb9f64c210e4a5e06c567f95233442b90b57f6 100644 (file)
  *     when using the SysV semaphore code.
  *
  *
- * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *       $PostgreSQL: pgsql/src/include/storage/s_lock.h,v 1.126 2004/06/19 23:02:32 tgl Exp $
+ *       $PostgreSQL: pgsql/src/include/storage/s_lock.h,v 1.134 2005/03/10 21:41:01 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -138,6 +138,29 @@ tas(volatile slock_t *lock)
 static __inline__ void
 spin_delay(void)
 {
+       /*
+        * This sequence is equivalent to the PAUSE instruction ("rep" is
+        * ignored by old IA32 processors if the following instruction is
+        * not a string operation); the IA-32 Architecture Software
+        * Developer's Manual, Vol. 3, Section 7.7.2 describes why using
+        * PAUSE in the inner loop of a spin lock is necessary for good
+        * performance:
+        *
+        *     The PAUSE instruction improves the performance of IA-32
+        *     processors supporting Hyper-Threading Technology when
+        *     executing spin-wait loops and other routines where one
+        *     thread is accessing a shared lock or semaphore in a tight
+        *     polling loop. When executing a spin-wait loop, the
+        *     processor can suffer a severe performance penalty when
+        *     exiting the loop because it detects a possible memory order
+        *     violation and flushes the core processor's pipeline. The
+        *     PAUSE instruction provides a hint to the processor that the
+        *     code sequence is a spin-wait loop. The processor uses this
+        *     hint to avoid the memory order violation and prevent the
+        *     pipeline flush. In addition, the PAUSE instruction
+        *     de-pipelines the spin-wait loop to prevent it from
+        *     consuming execution resources excessively.
+        */
        __asm__ __volatile__(
                " rep; nop                      \n");
 }
@@ -145,7 +168,7 @@ spin_delay(void)
 #endif  /* __i386__ || __x86_64__ */
 
 
-#if defined(__ia64__) || defined(__ia64)  /* __ia64 used by ICC compiler? */
+#if defined(__ia64__) || defined(__ia64)
 /* Intel Itanium */
 #define HAS_TEST_AND_SET
 
@@ -153,6 +176,8 @@ typedef unsigned int slock_t;
 
 #define TAS(lock) tas(lock)
 
+#ifndef __INTEL_COMPILER
+
 static __inline__ int
 tas(volatile slock_t *lock)
 {
@@ -166,6 +191,19 @@ tas(volatile slock_t *lock)
        return (int) ret;
 }
 
+#else
+
+static __inline__ int
+tas(volatile slock_t *lock)
+{
+       int             ret;
+
+       ret = _InterlockedExchange(lock,1);     /* this is a xchg asm macro */
+
+       return ret;
+}
+
+#endif
 #endif  /* __ia64__ || __ia64 */
 
 
@@ -428,7 +466,7 @@ typedef unsigned char slock_t;
 #if defined(__mips__) && !defined(__sgi)
 #define HAS_TEST_AND_SET
 
-typedef unsigned char slock_t;
+typedef unsigned int slock_t;
 #endif
 
 
@@ -541,6 +579,18 @@ tas(volatile slock_t *lock)
 #endif  /* __hppa || __hppa__ */
 
 
+#if defined(__hpux) && defined(__ia64) && !defined(__GNUC__)
+
+#define HAS_TEST_AND_SET
+
+typedef unsigned int slock_t;
+
+#include <ia64/sys/inline.h>
+#define TAS(lock) _Asm_xchg(_SZ_W, lock, 1, _LDHINT_NONE)
+
+#endif /* HPUX on IA64, non gcc */
+
+
 #if defined(__QNX__) && defined(__WATCOMC__)
 /*
  * QNX 4 using WATCOM C
@@ -646,6 +696,18 @@ typedef unsigned char slock_t;
 #endif
 
 
+/* out-of-line assembler from src/backend/port/tas/foo.s */
+
+#if defined(__sun) && defined(__i386)
+/*
+ * Solaris/386 (we only get here for non-gcc case)
+ */
+#define HAS_TEST_AND_SET
+
+typedef unsigned char slock_t;
+#endif
+
+
 #endif /* !defined(HAS_TEST_AND_SET) */