experimental_linux_pthread_mutex_instead_of_spinlick.patch
text/plain
Filename: experimental_linux_pthread_mutex_instead_of_spinlick.patch
Type: text/plain
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/storage/lmgr/s_lock.c | 89 | 0 |
| src/include/storage/s_lock.h | 29 | 2 |
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 <pthread.h>
+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 <pthread.h>
+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 */