diff options
Diffstat (limited to 'src/include/storage/s_lock.h')
-rw-r--r-- | src/include/storage/s_lock.h | 226 |
1 files changed, 148 insertions, 78 deletions
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h index 2456d573b5b..52bbfbebab9 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.119 2003/12/23 00:32:06 momjian Exp $ + * $PostgreSQL: pgsql/src/include/storage/s_lock.h,v 1.120 2003/12/23 03:31:30 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -73,12 +73,11 @@ #include "storage/pg_sema.h" -#if defined(HAS_TEST_AND_SET) - - #if defined(__GNUC__) || defined(__ICC) /************************************************************************* * All the gcc inlines + * Gcc consistently defines the CPU as __cpu__. + * Other compilers use __cpu or __cpu__ so we test for both in those cases. */ /* @@ -95,6 +94,9 @@ #if defined(__i386__) || defined(__x86_64__) /* AMD Opteron */ +typedef unsigned char slock_t; +#define HAS_TEST_AND_SET + #define TAS(lock) tas(lock) static __inline__ int @@ -114,7 +116,10 @@ tas(volatile slock_t *lock) /* Intel Itanium */ -#if defined(__ia64__) || defined(__ia64) +#if defined(__ia64__) || defined(__ia64) /* __ia64 is used by ICC the compiler? */ +typedef unsigned int slock_t; +#define HAS_TEST_AND_SET + #define TAS(lock) tas(lock) static __inline__ int @@ -135,6 +140,9 @@ tas(volatile slock_t *lock) #if defined(__arm__) || defined(__arm) +typedef unsigned char slock_t; +#define HAS_TEST_AND_SET + #define TAS(lock) tas(lock) static __inline__ int @@ -153,9 +161,10 @@ tas(volatile slock_t *lock) #if defined(__s390__) && !defined(__s390x__) -/* - * S/390 Linux - */ +typedef unsigned int slock_t; +#define HAS_TEST_AND_SET + +/* S/390 Linux */ #define TAS(lock) tas(lock) static __inline__ int @@ -179,9 +188,9 @@ tas(volatile slock_t *lock) #endif /* __s390__ */ #if defined(__s390x__) -/* - * S/390x Linux (64-bit zSeries) - */ +typedef unsigned int slock_t; +#define HAS_TEST_AND_SET +/* S/390x Linux (64-bit zSeries) */ #define TAS(lock) tas(lock) static __inline__ int @@ -206,6 +215,8 @@ tas(volatile slock_t *lock) #if defined(__sparc__) +typedef unsigned char slock_t; +#define HAS_TEST_AND_SET #define TAS(lock) tas(lock) static __inline__ int @@ -223,6 +234,14 @@ tas(volatile slock_t *lock) #endif /* __sparc__ */ #if defined(__ppc__) || defined(__powerpc__) || defined(__powerpc64__) +/* Is this correct? */ +#ifndef defined(__powerpc64__) +typedef unsigned int slock_t; +#else +typedef unsigned long slock_t; +#endif +#define HAS_TEST_AND_SET + #define TAS(lock) tas(lock) /* * NOTE: per the Enhanced PowerPC Architecture manual, v1.0 dated 7-May-2002, @@ -255,10 +274,22 @@ tas(volatile slock_t *lock) return _res; } +/* + * PowerPC S_UNLOCK is almost standard but requires a "sync" instruction. + */ +#define S_UNLOCK(lock) \ +do \ +{\ + __asm__ __volatile__ (" sync \n"); \ + *((volatile slock_t *) (lock)) = 0; \ +} while (0) + #endif /* powerpc */ #if defined(__mc68000__) && defined(__linux__) +typedef unsigned char slock_t; +#define HAS_TEST_AND_SET #define TAS(lock) tas(lock) static __inline__ int @@ -280,25 +311,13 @@ tas(volatile slock_t *lock) #endif /* defined(__mc68000__) && defined(__linux__) */ -#if defined(__ppc__) || defined(__powerpc__) || defined(__powerpc64__) -/* - * PowerPC S_UNLOCK is almost standard but requires a "sync" instruction. - */ -#define S_UNLOCK(lock) \ -do \ -{\ - __asm__ __volatile__ (" sync \n"); \ - *((volatile slock_t *) (lock)) = 0; \ -} while (0) - -#endif /* powerpc */ - - -#if defined(NEED_VAX_TAS_ASM) +#if defined(__vax__) /* * VAXen -- even multiprocessor ones * (thanks to Tom Ivar Helbekkmo) */ +typedef unsigned char slock_t; +#define HAS_TEST_AND_SET #define TAS(lock) tas(lock) static __inline__ int @@ -317,10 +336,12 @@ tas(volatile slock_t *lock) return _res; } -#endif /* NEED_VAX_TAS_ASM */ +#endif /* __vax__ */ -#if defined(NEED_NS32K_TAS_ASM) +#if defined(__ns32k__) +typedef unsigned char slock_t; +#define HAS_TEST_AND_SET #define TAS(lock) tas(lock) static __inline__ int @@ -335,54 +356,18 @@ tas(volatile slock_t *lock) return _res; } -#endif /* NEED_NS32K_TAS_ASM */ - - - -#else /* !__GNUC__ */ - -/*************************************************************************** - * All non-gcc inlines - */ - -#if defined(USE_UNIVEL_CC) -#define TAS(lock) tas(lock) - -asm int -tas(volatile slock_t *s_lock) -{ -/* UNIVEL wants %mem in column 1, so we don't pg_indent this file */ -%mem s_lock - pushl %ebx - movl s_lock, %ebx - movl $255, %eax - lock - xchgb %al, (%ebx) - popl %ebx -} - -#endif /* defined(USE_UNIVEL_CC) */ - -#endif /* defined(__GNUC__) */ - - - -/************************************************************************* - * These are the platforms that have only one compiler, or do not use inline - * assembler (and hence have common code for gcc and non-gcc compilers, - * if both are available). - */ +#endif /* __ns32k__ */ #if defined(__alpha) || defined(__alpha__) - /* * Correct multi-processor locking methods are explained in section 5.5.3 * of the Alpha AXP Architecture Handbook, which at this writing can be * found at ftp://ftp.netbsd.org/pub/NetBSD/misc/dec-docs/index.html. * For gcc we implement the handbook's code directly with inline assembler. */ -#if defined(__GNUC__) +typedef unsigned long slock_t; +#define HAS_TEST_AND_SET #define TAS(lock) tas(lock) #define S_UNLOCK(lock) \ @@ -416,8 +401,69 @@ tas(volatile slock_t *lock) return (int) _res; } -#else /* !defined(__GNUC__) */ +#endif /* __alpha || __alpha__ */ + + +/* These live in s_lock.c, but only for gcc */ + +#if defined(__m68k__) +typedef unsigned char slock_t; +#define HAS_TEST_AND_SET +#endif + +#ifdef sinix /* This symbol is not protected with __, for SvR4 port */ +#include "abi_mutex.h" +typedef abilock_t slock_t; +#define HAS_TEST_AND_SET +#endif + + +/* These are in s_lock.c */ + +#if defined(__m68k__) +typedef unsigned char slock_t; +#define HAS_TEST_AND_SET +#endif + +#if defined(__mips__) && !defined(__sgi) +typedef unsigned char slock_t; +#define HAS_TEST_AND_SET +#endif + +#endif /* __GNUC__ */ + + + +/*************************************************************************** + * Uses non-gcc inline assembly: + */ + +#if !defined(HAS_TEST_AND_SET) + +#if defined(USE_UNIVEL_CC) +typedef unsigned char slock_t; +#define HAS_TEST_AND_SET +#define TAS(lock) tas(lock) + +asm int +tas(volatile slock_t *s_lock) +{ +/* UNIVEL wants %mem in column 1, so we don't pg_indent this file */ +%mem s_lock + pushl %ebx + movl s_lock, %ebx + movl $255, %eax + lock + xchgb %al, (%ebx) + popl %ebx +} + +#endif /* defined(USE_UNIVEL_CC) */ + +#if defined(__alpha) || defined(__alpha__) +typedef volatile long slock_t; +#define HAS_TEST_AND_SET /* * The Tru64 compiler doesn't support gcc-style inline asm, but it does * have some builtin functions that accomplish much the same results. @@ -428,17 +474,19 @@ tas(volatile slock_t *lock) */ #include <alpha/builtins.h> - #define S_INIT_LOCK(lock) (*(lock) = 0) #define TAS(lock) (__LOCK_LONG_RETRY((lock), 1) == 0) #define S_UNLOCK(lock) __UNLOCK_LONG(lock) -#endif /* defined(__GNUC__) */ - #endif /* __alpha || __alpha__ */ #if defined(__hppa) +typedef struct +{ + int sema[4]; +} slock_t; +#define HAS_TEST_AND_SET /* * HP's PA-RISC * @@ -462,7 +510,10 @@ tas(volatile slock_t *lock) #endif /* __hppa */ + #if defined(__QNX__) && defined(__WATCOMC__) +typedef unsigned char slock_t; +#define HAS_TEST_AND_SET /* * QNX 4 using WATCOM C */ @@ -490,6 +541,8 @@ extern slock_t wc_tas(volatile slock_t *lock); * assembly from his NECEWS SVR4 port, but we probably ought to retain this * for the R3000 chips out there. */ +typedef unsigned long slock_t; +#define HAS_TEST_AND_SET #include "mutex.h" #define TAS(lock) (test_and_set(lock,1)) #define S_UNLOCK(lock) (test_then_and(lock,0)) @@ -497,6 +550,7 @@ extern slock_t wc_tas(volatile slock_t *lock); #define S_LOCK_FREE(lock) (test_then_add(lock,0) == 0) #endif /* __sgi */ + #if defined(sinix) /* * SINIX / Reliant UNIX @@ -504,6 +558,7 @@ extern slock_t wc_tas(volatile slock_t *lock); * member. (Basically same as SGI) * */ +#define HAS_TEST_AND_SET #define TAS(lock) (!acquire_lock(lock)) #define S_UNLOCK(lock) release_lock(lock) #define S_INIT_LOCK(lock) init_lock(lock) @@ -517,16 +572,15 @@ extern slock_t wc_tas(volatile slock_t *lock); * * Note that slock_t on POWER/POWER2/PowerPC is int instead of char */ +#define HAS_TEST_AND_SET #define TAS(lock) _check_lock(lock, 0, 1) #define S_UNLOCK(lock) _clear_lock(lock, 0) #endif /* _AIX */ #if defined (nextstep) -/* - * NEXTSTEP (mach) - * slock_t is defined as a struct mutex. - */ +typedef struct mutex slock_t; +#define HAS_TEST_AND_SET #define S_LOCK(lock) mutex_lock(lock) #define S_UNLOCK(lock) mutex_unlock(lock) @@ -535,13 +589,28 @@ extern slock_t wc_tas(volatile slock_t *lock); #define S_LOCK_FREE(alock) ((alock)->lock == 0) #endif /* nextstep */ +/* These are in s_lock.c */ +#if defined(sun3) +typedef unsigned char slock_t; +#define HAS_TEST_AND_SET +#endif + +#if defined(__sparc__) || defined(__sparc) +#define HAS_TEST_AND_SET +typedef unsigned char slock_t; +#endif + + +#endif /* !defined(HAS_TEST_AND_SET */ -#else /* HAS_TEST_AND_SET */ + +#ifndef HAS_TEST_AND_SET #ifdef HAVE_SPINLOCKS #error PostgreSQL does not have native spinlock support on this platform. To continue the compilation, rerun configure using --disable-spinlocks. However, performance will be poor. Please report this to pgsql-bugs@postgresql.org. -#endif + +#else /* * Fake spinlock implementation using semaphores --- slow and prone @@ -560,7 +629,8 @@ extern int tas_sema(volatile slock_t *lock); #define S_INIT_LOCK(lock) s_init_lock_sema(lock) #define TAS(lock) tas_sema(lock) -#endif /* HAS_TEST_AND_SET */ +#endif /* HAVE_SPINLOCKS */ +#endif /* HAS_TEST_AND_SET */ |