Use inlined TAS() on PA-RISC, if we are compiling with gcc.
authorTom Lane
Tue, 23 Dec 2003 22:15:07 +0000 (22:15 +0000)
committerTom Lane
Tue, 23 Dec 2003 22:15:07 +0000 (22:15 +0000)
Patch inspired by original submission from ViSolve.

src/backend/storage/lmgr/s_lock.c
src/include/storage/s_lock.h
src/template/hpux

index e04bfaeea75c598d63c50461c3f7936431260dc5..e5e372bb39da55d1e2843c0b168c97b4c98d2516 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/storage/lmgr/s_lock.c,v 1.21 2003/12/23 18:13:17 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/storage/lmgr/s_lock.c,v 1.22 2003/12/23 22:15:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -124,8 +124,12 @@ s_lock(volatile slock_t *lock, const char *file, int line)
  */
 
 
+#ifdef HAVE_SPINLOCKS  /* skip spinlocks if requested */
+
+
 #if defined(__GNUC__)
-/*************************************************************************
+
+/*
  * All the gcc flavors that are not inlined
  */
 
@@ -151,6 +155,7 @@ _success:                       \n\
 }
 #endif   /* __m68k__ */
 
+
 #if defined(__mips__) && !defined(__sgi)
 static void
 tas_dummy()
@@ -178,13 +183,14 @@ fail:                         \n\
 }
 #endif   /* __mips__ && !__sgi */
 
+
 #else                          /* not __GNUC__ */
-/***************************************************************************
+
+/*
  * All non gcc
  */
 
 
-
 #if defined(sun3)
 static void
 tas_dummy()                        /* really means: extern int tas(slock_t
@@ -210,7 +216,6 @@ tas_dummy()                     /* really means: extern int tas(slock_t
 #endif   /* sun3 */
 
 
-
 #if defined(__sparc__) || defined(__sparc)
 /*
  * sparc machines not using gcc
@@ -233,10 +238,9 @@ tas_dummy()                        /* really means: extern int tas(slock_t
 #endif   /* __sparc || __sparc__ */
 
 
-
-
 #endif   /* not __GNUC__ */
 
+#endif /* HAVE_SPINLOCKS */
 
 
 
index 2f315bcb07a29bfea9141f503d4f077e1471bd3e..e1851fb9cec8d204aa6a40d58b86690014a1e0bd 100644 (file)
@@ -63,7 +63,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *   $PostgreSQL: pgsql/src/include/storage/s_lock.h,v 1.122 2003/12/23 18:13:17 tgl Exp $
+ *   $PostgreSQL: pgsql/src/include/storage/s_lock.h,v 1.123 2003/12/23 22:15:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -497,9 +497,12 @@ typedef unsigned long slock_t;
 /*
  * HP's PA-RISC
  *
- * a "set" slock_t has a single word cleared (the one that is on a 16-byte
- * boundary; we use a 16-byte struct to ensure there is one).  a "clear"
- * slock_t has all words set to non-zero. tas() is in tas.s
+ * See src/backend/port/hpux/tas.c.template for details about LDCWX.  Because
+ * LDCWX requires a 16-byte-aligned address, we declare slock_t as a 16-byte
+ * struct.  The active word in the struct is whichever has the aligned address;
+ * the other three words just sit at -1.
+ *
+ * When using gcc, we can inline the required assembly code.
  */
 #define HAS_TEST_AND_SET
 
@@ -508,16 +511,37 @@ typedef struct
    int         sema[4];
 } slock_t;
 
-#define S_UNLOCK(lock) \
+#define TAS_ACTIVE_WORD(lock)  ((volatile int *) (((long) (lock) + 15) & ~15))
+
+#if defined(__GNUC__)
+
+static __inline__ int
+tas(volatile slock_t *lock)
+{
+   volatile int *lockword = TAS_ACTIVE_WORD(lock);
+   register int lockval;
+
+   __asm__ __volatile__(
+       "   ldcwx   0(0,%2),%0  \n"
+:      "=r"(lockval), "=m"(*lockword)
+:      "r"(lockword));
+   return (lockval == 0);
+}
+
+#endif /* __GNUC__ */
+
+#define S_UNLOCK(lock) (*TAS_ACTIVE_WORD(lock) = -1)
+
+#define S_INIT_LOCK(lock) \
    do { \
-       volatile slock_t *lock_ = (volatile slock_t *) (lock); \
+       volatile slock_t *lock_ = (lock); \
        lock_->sema[0] = -1; \
        lock_->sema[1] = -1; \
        lock_->sema[2] = -1; \
        lock_->sema[3] = -1; \
    } while (0)
 
-#define S_LOCK_FREE(lock)  ( *(int *) (((long) (lock) + 15) & ~15) != 0)
+#define S_LOCK_FREE(lock)  (*TAS_ACTIVE_WORD(lock) != 0)
 
 #endif  /* __hppa */
 
index 154b5743aa8cba7979ffab33d48473a37eda80e5..775c55a935361b4a5745b5b77d32490877683942 100644 (file)
@@ -5,7 +5,13 @@ if test "$GCC" != yes ; then
   CFLAGS="+O2"
 fi
 
-# Pick right test-and-set (TAS) code.
+# Pick right test-and-set (TAS) code.  We need out-of-line assembler
+# when not using gcc.
 case $host in
-  hppa*-*-hpux*)        need_tas=yes; tas_file=hpux_hppa.s ;;
+  hppa*-*-hpux*)
+   if test "$GCC" != yes ; then
+       need_tas=yes
+       tas_file=hpux_hppa.s
+   fi
+    ;;
 esac