0002-Add-implementation-of-spinlocks-using-the-atomics.h-.patch
text/x-patch
Filename: 0002-Add-implementation-of-spinlocks-using-the-atomics.h-.patch
Type: text/x-patch
Part: 1
Message:
Re: better atomics - v0.6
Patch
Format: unified
Series: patch 0002
| File | + | − |
|---|---|---|
| src/include/pg_config_manual.h | 6 | 0 |
| src/include/storage/s_lock.h | 18 | 26 |
>From 7a02b4d4ce1b744b244f7e4f0e2716f379301b39 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Thu, 18 Sep 2014 12:45:41 +0200
Subject: [PATCH 2/5] Add implementation of spinlocks using the atomics.h API.
Use the new atomics.h API to provide s_lock.h spinlock functions if no
os/architecture specific implementation exists. Eventually we might
want to replace the entirety of s_lock.h with the new API, but given
how critical it is, it seems better to do it in smaller steps.
As the s_lock.h ARM implementation is the same as the atomics
implementation, remove it.
The FORCE_ATOMICS_BASED_SPINLOCKS define can be used to force the
usage of the atomics.h based spinlocks.
---
src/include/pg_config_manual.h | 6 ++++++
src/include/storage/s_lock.h | 44 +++++++++++++++++-------------------------
2 files changed, 24 insertions(+), 26 deletions(-)
diff --git a/src/include/pg_config_manual.h b/src/include/pg_config_manual.h
index 195fb26..4bc591a 100644
--- a/src/include/pg_config_manual.h
+++ b/src/include/pg_config_manual.h
@@ -73,6 +73,12 @@
#define NUM_ATOMICS_SEMAPHORES 64
/*
+ * Force usage of atomics.h based spinlocks even if s_lock.h has its own
+ * support for the target platform.
+ */
+#undef FORCE_ATOMICS_BASED_SPINLOCKS
+
+/*
* Define this if you want to allow the lo_import and lo_export SQL
* functions to be executed by ordinary users. By default these
* functions are only available to the Postgres superuser. CAUTION:
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h
index e7ae330..f49d17f 100644
--- a/src/include/storage/s_lock.h
+++ b/src/include/storage/s_lock.h
@@ -98,6 +98,8 @@
#ifdef HAVE_SPINLOCKS /* skip spinlocks if requested */
+#if !defined(FORCE_ATOMICS_BASED_SPINLOCKS)
+
#if defined(__GNUC__) || defined(__INTEL_COMPILER)
/*************************************************************************
* All the gcc inlines
@@ -302,32 +304,6 @@ tas(volatile slock_t *lock)
#endif /* __INTEL_COMPILER */
#endif /* __ia64__ || __ia64 */
-/*
- * On ARM and ARM64, we use __sync_lock_test_and_set(int *, int) if available.
- *
- * We use the int-width variant of the builtin because it works on more chips
- * than other widths.
- */
-#if defined(__arm__) || defined(__arm) || defined(__aarch64__) || defined(__aarch64)
-#ifdef HAVE_GCC_INT_ATOMICS
-#define HAS_TEST_AND_SET
-
-#define TAS(lock) tas(lock)
-
-typedef int slock_t;
-
-static __inline__ int
-tas(volatile slock_t *lock)
-{
- return __sync_lock_test_and_set(lock, 1);
-}
-
-#define S_UNLOCK(lock) __sync_lock_release(lock)
-
-#endif /* HAVE_GCC_INT_ATOMICS */
-#endif /* __arm__ || __arm || __aarch64__ || __aarch64 */
-
-
/* S/390 and S/390x Linux (32- and 64-bit zSeries) */
#if defined(__s390__) || defined(__s390x__)
#define HAS_TEST_AND_SET
@@ -870,6 +846,22 @@ spin_delay(void)
#endif /* !defined(HAS_TEST_AND_SET) */
+#endif /* !defined(FORCE_ATOMICS_BASED_SPINLOCKS) */
+
+
+#if !defined(HAS_TEST_AND_SET) && defined(HAVE_ATOMICS)
+#include "port/atomics.h"
+
+#ifndef PG_HAVE_ATOMIC_FLAG_SIMULATION
+#define HAS_TEST_AND_SET
+typedef pg_atomic_flag slock_t;
+#define TAS(lock) (pg_atomic_test_set_flag(lock) ? 0 : 1)
+#define TAS_SPIN(lock) (pg_atomic_unlocked_test_flag(lock) ? TAS(lock) : 1)
+#define S_UNLOCK(lock) pg_atomic_clear_flag(lock)
+#define S_INIT_LOCK(lock) pg_atomic_init_flag(lock)
+#define SPIN_DELAY() pg_spin_delay()
+#endif /* !PG_HAVE_ATOMIC_FLAG_SIMULATION */
+#endif /* !defined(HAS_TEST_AND_SET) && defined(HAVE_ATOMICS) */
/* Blow up if we didn't have any way to do spinlocks */
#ifndef HAS_TEST_AND_SET
--
2.0.0.rc2.4.g1dc51c6.dirty