From: Tom Lane Date: Tue, 23 Dec 2003 22:15:07 +0000 (+0000) Subject: Use inlined TAS() on PA-RISC, if we are compiling with gcc. X-Git-Tag: REL8_0_0BETA1~1450 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=afb09b5a31a558709b7a8c577e447c60ff25ca1b;p=postgresql Use inlined TAS() on PA-RISC, if we are compiling with gcc. Patch inspired by original submission from ViSolve. --- diff --git a/src/backend/storage/lmgr/s_lock.c b/src/backend/storage/lmgr/s_lock.c index e04bfaeea7..e5e372bb39 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 2f315bcb07..e1851fb9ce 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 154b5743aa..775c55a935 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