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