Commit afb09b5a authored by Tom Lane's avatar Tom Lane

Use inlined TAS() on PA-RISC, if we are compiling with gcc.

Patch inspired by original submission from ViSolve.
parent cd2ad9b9
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
* *
* *
* IDENTIFICATION * 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) ...@@ -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__) #if defined(__GNUC__)
/*************************************************************************
/*
* All the gcc flavors that are not inlined * All the gcc flavors that are not inlined
*/ */
...@@ -151,6 +155,7 @@ _success: \n\ ...@@ -151,6 +155,7 @@ _success: \n\
} }
#endif /* __m68k__ */ #endif /* __m68k__ */
#if defined(__mips__) && !defined(__sgi) #if defined(__mips__) && !defined(__sgi)
static void static void
tas_dummy() tas_dummy()
...@@ -178,13 +183,14 @@ fail: \n\ ...@@ -178,13 +183,14 @@ fail: \n\
} }
#endif /* __mips__ && !__sgi */ #endif /* __mips__ && !__sgi */
#else /* not __GNUC__ */ #else /* not __GNUC__ */
/***************************************************************************
/*
* All non gcc * All non gcc
*/ */
#if defined(sun3) #if defined(sun3)
static void static void
tas_dummy() /* really means: extern int tas(slock_t tas_dummy() /* really means: extern int tas(slock_t
...@@ -210,7 +216,6 @@ tas_dummy() /* really means: extern int tas(slock_t ...@@ -210,7 +216,6 @@ tas_dummy() /* really means: extern int tas(slock_t
#endif /* sun3 */ #endif /* sun3 */
#if defined(__sparc__) || defined(__sparc) #if defined(__sparc__) || defined(__sparc)
/* /*
* sparc machines not using gcc * sparc machines not using gcc
...@@ -233,10 +238,9 @@ tas_dummy() /* really means: extern int tas(slock_t ...@@ -233,10 +238,9 @@ tas_dummy() /* really means: extern int tas(slock_t
#endif /* __sparc || __sparc__ */ #endif /* __sparc || __sparc__ */
#endif /* not __GNUC__ */ #endif /* not __GNUC__ */
#endif /* HAVE_SPINLOCKS */
......
...@@ -63,7 +63,7 @@ ...@@ -63,7 +63,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * 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; ...@@ -497,9 +497,12 @@ typedef unsigned long slock_t;
/* /*
* HP's PA-RISC * HP's PA-RISC
* *
* a "set" slock_t has a single word cleared (the one that is on a 16-byte * See src/backend/port/hpux/tas.c.template for details about LDCWX. Because
* boundary; we use a 16-byte struct to ensure there is one). a "clear" * LDCWX requires a 16-byte-aligned address, we declare slock_t as a 16-byte
* slock_t has all words set to non-zero. tas() is in tas.s * 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 #define HAS_TEST_AND_SET
...@@ -508,16 +511,37 @@ typedef struct ...@@ -508,16 +511,37 @@ typedef struct
int sema[4]; int sema[4];
} slock_t; } 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 { \ do { \
volatile slock_t *lock_ = (volatile slock_t *) (lock); \ volatile slock_t *lock_ = (lock); \
lock_->sema[0] = -1; \ lock_->sema[0] = -1; \
lock_->sema[1] = -1; \ lock_->sema[1] = -1; \
lock_->sema[2] = -1; \ lock_->sema[2] = -1; \
lock_->sema[3] = -1; \ lock_->sema[3] = -1; \
} while (0) } 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 */ #endif /* __hppa */
......
...@@ -5,7 +5,13 @@ if test "$GCC" != yes ; then ...@@ -5,7 +5,13 @@ if test "$GCC" != yes ; then
CFLAGS="+O2" CFLAGS="+O2"
fi 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 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 esac
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment