aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-12-23 22:15:07 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-12-23 22:15:07 +0000
commitafb09b5a31a558709b7a8c577e447c60ff25ca1b (patch)
treee0d8e777f30ef07e95c94106499336437462d991
parentcd2ad9b944fb236557bfe85999ac56857e0f22cd (diff)
downloadpostgresql-afb09b5a31a558709b7a8c577e447c60ff25ca1b.tar.gz
postgresql-afb09b5a31a558709b7a8c577e447c60ff25ca1b.zip
Use inlined TAS() on PA-RISC, if we are compiling with gcc.
Patch inspired by original submission from ViSolve.
-rw-r--r--src/backend/storage/lmgr/s_lock.c18
-rw-r--r--src/include/storage/s_lock.h38
-rw-r--r--src/template/hpux10
3 files changed, 50 insertions, 16 deletions
diff --git a/src/backend/storage/lmgr/s_lock.c b/src/backend/storage/lmgr/s_lock.c
index e04bfaeea75..e5e372bb39d 100644
--- a/src/backend/storage/lmgr/s_lock.c
+++ b/src/backend/storage/lmgr/s_lock.c
@@ -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 */
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index 2f315bcb07a..e1851fb9cec 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -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 */
diff --git a/src/template/hpux b/src/template/hpux
index 154b5743aa8..775c55a9353 100644
--- a/src/template/hpux
+++ b/src/template/hpux
@@ -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