Skip to content

Commit afb09b5

Browse files
committed
Use inlined TAS() on PA-RISC, if we are compiling with gcc.
Patch inspired by original submission from ViSolve.
1 parent cd2ad9b commit afb09b5

File tree

3 files changed

+50
-16
lines changed

3 files changed

+50
-16
lines changed

src/backend/storage/lmgr/s_lock.c

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/storage/lmgr/s_lock.c,v 1.21 2003/12/23 18:13:17 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/storage/lmgr/s_lock.c,v 1.22 2003/12/23 22:15:07 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -124,8 +124,12 @@ s_lock(volatile slock_t *lock, const char *file, int line)
124124
*/
125125

126126

127+
#ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */
128+
129+
127130
#if defined(__GNUC__)
128-
/*************************************************************************
131+
132+
/*
129133
* All the gcc flavors that are not inlined
130134
*/
131135

@@ -151,6 +155,7 @@ _success: \n\
151155
}
152156
#endif /* __m68k__ */
153157

158+
154159
#if defined(__mips__) && !defined(__sgi)
155160
static void
156161
tas_dummy()
@@ -178,13 +183,14 @@ fail: \n\
178183
}
179184
#endif /* __mips__ && !__sgi */
180185

186+
181187
#else /* not __GNUC__ */
182-
/***************************************************************************
188+
189+
/*
183190
* All non gcc
184191
*/
185192

186193

187-
188194
#if defined(sun3)
189195
static void
190196
tas_dummy() /* really means: extern int tas(slock_t
@@ -210,7 +216,6 @@ tas_dummy() /* really means: extern int tas(slock_t
210216
#endif /* sun3 */
211217

212218

213-
214219
#if defined(__sparc__) || defined(__sparc)
215220
/*
216221
* sparc machines not using gcc
@@ -233,10 +238,9 @@ tas_dummy() /* really means: extern int tas(slock_t
233238
#endif /* __sparc || __sparc__ */
234239

235240

236-
237-
238241
#endif /* not __GNUC__ */
239242

243+
#endif /* HAVE_SPINLOCKS */
240244

241245

242246

src/include/storage/s_lock.h

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
6464
* Portions Copyright (c) 1994, Regents of the University of California
6565
*
66-
* $PostgreSQL: pgsql/src/include/storage/s_lock.h,v 1.122 2003/12/23 18:13:17 tgl Exp $
66+
* $PostgreSQL: pgsql/src/include/storage/s_lock.h,v 1.123 2003/12/23 22:15:07 tgl Exp $
6767
*
6868
*-------------------------------------------------------------------------
6969
*/
@@ -497,9 +497,12 @@ typedef unsigned long slock_t;
497497
/*
498498
* HP's PA-RISC
499499
*
500-
* a "set" slock_t has a single word cleared (the one that is on a 16-byte
501-
* boundary; we use a 16-byte struct to ensure there is one). a "clear"
502-
* slock_t has all words set to non-zero. tas() is in tas.s
500+
* See src/backend/port/hpux/tas.c.template for details about LDCWX. Because
501+
* LDCWX requires a 16-byte-aligned address, we declare slock_t as a 16-byte
502+
* struct. The active word in the struct is whichever has the aligned address;
503+
* the other three words just sit at -1.
504+
*
505+
* When using gcc, we can inline the required assembly code.
503506
*/
504507
#define HAS_TEST_AND_SET
505508

@@ -508,16 +511,37 @@ typedef struct
508511
int sema[4];
509512
} slock_t;
510513

511-
#define S_UNLOCK(lock) \
514+
#define TAS_ACTIVE_WORD(lock) ((volatile int *) (((long) (lock) + 15) & ~15))
515+
516+
#if defined(__GNUC__)
517+
518+
static __inline__ int
519+
tas(volatile slock_t *lock)
520+
{
521+
volatile int *lockword = TAS_ACTIVE_WORD(lock);
522+
register int lockval;
523+
524+
__asm__ __volatile__(
525+
" ldcwx 0(0,%2),%0 \n"
526+
: "=r"(lockval), "=m"(*lockword)
527+
: "r"(lockword));
528+
return (lockval == 0);
529+
}
530+
531+
#endif /* __GNUC__ */
532+
533+
#define S_UNLOCK(lock) (*TAS_ACTIVE_WORD(lock) = -1)
534+
535+
#define S_INIT_LOCK(lock) \
512536
do { \
513-
volatile slock_t *lock_ = (volatile slock_t *) (lock); \
537+
volatile slock_t *lock_ = (lock); \
514538
lock_->sema[0] = -1; \
515539
lock_->sema[1] = -1; \
516540
lock_->sema[2] = -1; \
517541
lock_->sema[3] = -1; \
518542
} while (0)
519543

520-
#define S_LOCK_FREE(lock) ( *(int *) (((long) (lock) + 15) & ~15) != 0)
544+
#define S_LOCK_FREE(lock) (*TAS_ACTIVE_WORD(lock) != 0)
521545

522546
#endif /* __hppa */
523547

src/template/hpux

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@ if test "$GCC" != yes ; then
55
CFLAGS="+O2"
66
fi
77

8-
# Pick right test-and-set (TAS) code.
8+
# Pick right test-and-set (TAS) code. We need out-of-line assembler
9+
# when not using gcc.
910
case $host in
10-
hppa*-*-hpux*) need_tas=yes; tas_file=hpux_hppa.s ;;
11+
hppa*-*-hpux*)
12+
if test "$GCC" != yes ; then
13+
need_tas=yes
14+
tas_file=hpux_hppa.s
15+
fi
16+
;;
1117
esac

0 commit comments

Comments
 (0)