diff --git a/src/backend/storage/lmgr/s_lock.c b/src/backend/storage/lmgr/s_lock.c index bc8d89f..a45fdf6 100644 --- a/src/backend/storage/lmgr/s_lock.c +++ b/src/backend/storage/lmgr/s_lock.c @@ -20,6 +20,8 @@ #include "storage/s_lock.h" +#ifndef USE_PTHREAD_SLOCK + slock_t dummy_spinlock; static int spins_per_delay = DEFAULT_SPINS_PER_DELAY; @@ -200,9 +202,95 @@ update_spins_per_delay(int shared_spins_per_delay) * because the definitions for these are split between this file and s_lock.h. */ +#endif /* !USE_PTHREAD_SLOCK */ #ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */ +#ifdef USE_PTHREAD_SLOCK +#include +void +posix_lock(volatile slock_t *lock, const char *file, int line) +{ + struct slock *s_lock = (slock_t *)lock; + int ret; + + /* XXX error recovery ! */ + + do { + ret = pthread_mutex_lock(&s_lock->mutex); + } while (ret != 0); + s_lock->held = 1; +} + +void +posix_unlock(volatile slock_t *lock, const char *file, int line) +{ + struct slock *s_lock = (slock_t *)lock; + int ret; + + /* XXX error recovery ! */ + + s_lock->held = 0; + do { + ret = pthread_mutex_unlock(&s_lock->mutex); + } while (ret != 0); +} + +void +posix_init(volatile slock_t *lock) +{ + struct slock *s_lock = (slock_t *)lock; + pthread_mutexattr_t attr; + int ret; + + ret = pthread_mutexattr_init(&attr); + Assert(ret == 0); + +#ifdef PTHREAD_MUTEX_ADAPTIVE_NP + (void)pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); +#else + (void)pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); +#endif + +#ifdef USE_PRIO_INHERIT + /* + * looks like this incurs significant syscall overhead on linux + */ + (void)pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT); +#endif + + ret = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); + Assert(ret == 0); + + s_lock->held = 0; + + ret = pthread_mutex_init(&s_lock->mutex, &attr); + Assert(ret == 0); + + pthread_mutexattr_destroy(&attr); +} + +int +posix_lock_free(volatile slock_t *lock) +{ + struct slock *s_lock = (slock_t *)lock; + + return (s_lock->held == 0); +} + +#if 0 +void +posix_lock_free(slock_t *lock) +{ + struct slock *s_lock = lock; + int ret; + + ret = pthread_mutex_destroy(&s_lock->mutex); + Assert(ret == 0); +} +#endif + +#else /* !USE_PTHREAD_SLOCK */ #if defined(__GNUC__) @@ -282,6 +370,7 @@ tas_dummy() /* really means: extern int tas(slock_t } #endif /* sun3 */ #endif /* not __GNUC__ */ +#endif /* USE_PTHREAD_SLOCK */ #endif /* HAVE_SPINLOCKS */ diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h index d4a783f..200af8f 100644 --- a/src/include/storage/s_lock.h +++ b/src/include/storage/s_lock.h @@ -97,6 +97,30 @@ #ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */ +#ifdef USE_PTHREAD_SLOCK +#include +struct slock { + pthread_mutex_t mutex; + int held; +}; + +typedef struct slock slock_t; + +extern void posix_lock(volatile slock_t *lock, const char *file, int line); +extern void posix_unlock(volatile slock_t *lock, const char *file, int line); +extern void posix_init(volatile slock_t *lock); +extern int posix_lock_free(volatile slock_t *lock); + +#define S_LOCK(lock) posix_lock((lock), __FILE__, __LINE__) +#define S_UNLOCK(lock) posix_unlock((lock), __FILE__, __LINE__) +#define S_INIT_LOCK(lock) posix_init(lock) +#define S_LOCK_FREE(lock) posix_lock_free(lock) +#define SPIN_DELAY() ((void) 0) + +#define set_spins_per_delay(s) ((void) 0) +#define update_spins_per_delay(s) (0) +#define DEFAULT_SPINS_PER_DELAY 0 +#else /* !USE_PTHREAD_SLOCK */ #if defined(__GNUC__) || defined(__INTEL_COMPILER) /************************************************************************* @@ -947,7 +971,7 @@ spin_delay(void) #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 - +#endif /* USE_PTHREAD_SLOCK */ #else /* !HAVE_SPINLOCKS */ @@ -968,7 +992,6 @@ 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 /* HAVE_SPINLOCKS */ @@ -996,6 +1019,8 @@ extern int tas_sema(volatile slock_t *lock); #define S_INIT_LOCK(lock) S_UNLOCK(lock) #endif /* S_INIT_LOCK */ +#ifndef USE_PTHREAD_SLOCK + #if !defined(SPIN_DELAY) #define SPIN_DELAY() ((void) 0) #endif /* SPIN_DELAY */ @@ -1004,6 +1029,7 @@ extern int tas_sema(volatile slock_t *lock); extern int tas(volatile slock_t *lock); /* in port/.../tas.s, or * s_lock.c */ + #define TAS(lock) tas(lock) #endif /* TAS */ @@ -1022,5 +1048,6 @@ extern void s_lock(volatile slock_t *lock, const char *file, int line); extern void set_spins_per_delay(int shared_spins_per_delay); extern int update_spins_per_delay(int shared_spins_per_delay); +#endif /* !USE_PTHREAD_SLOCK */ #endif /* S_LOCK_H */