From: Nathan Bossart <nathandbossart@gmail.com>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: pgsql-hackers@postgresql.org
Subject: Re: small cleanup for s_lock.h
Date: Thu, 7 May 2026 16:28:09 -0500
Message-ID: <af0D6fhLfVmG2fr7@nathan> (raw)
In-Reply-To: <af0AKUfzjGDvQdBk@nathan>
References: <afkUeI7UhacZ5ZFm@nathan>
<369933.1777933007@sss.pgh.pa.us>
<afoWBgsygtkCNCRQ@nathan>
<532705.1778000169@sss.pgh.pa.us>
<afovdi61nybDRbC3@nathan>
<afz5FHWr6rOB7bsL@nathan>
<af0AKUfzjGDvQdBk@nathan>
On Thu, May 07, 2026 at 04:12:09PM -0500, Nathan Bossart wrote:
> On Thu, May 07, 2026 at 03:41:56PM -0500, Nathan Bossart wrote:
>> +/*
>> + * We can only define TAS_SPIN if TAS was defined. Otherwise, the platform
>> + * defined its own S_LOCK without TAS, and therefore is responsible for
>> + * defining its own TAS_SPIN as well. (Note that we currently do not have any
>> + * platforms that don't define TAS.)
>> + */
>> #if !defined(TAS_SPIN)
>> +#if defined(TAS)
>> #define TAS_SPIN(lock) TAS(lock)
>> -#endif /* TAS_SPIN */
>> +#else
>> +#error Neither TAS nor TAS_SPIN defined on this platform. Please report this to pgsql-bugs@lists.postgresql.org.
>> +#endif /* TAS */
>> +#endif /* ! TAS_SPIN */
>
> Wait, this isn't right. TAS_SPIN is only used by s_lock(), which is only
> used by the default S_LOCK. We should just not compile s_lock() if the
> platform defines its own S_LOCK, and we shouldn't #error here if TAS is not
> defined.
Should be fixed in v5, sorry for the noise.
--
nathan
From 595bbb48a7de3dd191023d617dc2c7f4725ed2d0 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
Date: Mon, 4 May 2026 16:04:04 -0500
Subject: [PATCH v5 1/3] Remove fallback declaration for tas().
The last definition of tas() in s_lock.c was removed in commit
718aa43a4e, and the last tas.s file was removed in commit
25f36066dd, so this is dead code.
---
src/backend/Makefile | 2 +-
src/backend/port/.gitignore | 1 -
src/backend/port/meson.build | 2 +-
src/include/storage/s_lock.h | 7 -------
4 files changed, 2 insertions(+), 10 deletions(-)
diff --git a/src/backend/Makefile b/src/backend/Makefileindex 162d3f1f2a9..4bb76d3d397 100644--- a/src/backend/Makefile+++ b/src/backend/Makefile@@ -301,7 +301,7 @@ endif
distclean: clean
# generated by configure
- rm -f port/tas.s port/pg_sema.c port/pg_shmem.c+ rm -f port/pg_sema.c port/pg_shmem.c
##########################################################################
diff --git a/src/backend/port/.gitignore b/src/backend/port/.gitignoreindex 4ef36b82c77..6c5067a4a9f 100644--- a/src/backend/port/.gitignore+++ b/src/backend/port/.gitignore@@ -1,3 +1,2 @@
/pg_sema.c
/pg_shmem.c
-/tas.sdiff --git a/src/backend/port/meson.build b/src/backend/port/meson.buildindex e8b7da8d281..29e88ef3541 100644--- a/src/backend/port/meson.build+++ b/src/backend/port/meson.build@@ -30,4 +30,4 @@ if host_system == 'windows'
endif
# autoconf generates the file there, ensure we get a conflict
-generated_sources_ac += {'src/backend/port': ['pg_sema.c', 'pg_shmem.c', 'tas.s']}+generated_sources_ac += {'src/backend/port': ['pg_sema.c', 'pg_shmem.c']}diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.hindex c9e52511990..dcfec8ce2af 100644--- a/src/include/storage/s_lock.h+++ b/src/include/storage/s_lock.h@@ -697,13 +697,6 @@ extern void s_unlock(volatile slock_t *lock);
#define SPIN_DELAY() ((void) 0)
#endif /* SPIN_DELAY */
-#if !defined(TAS)-extern int tas(volatile slock_t *lock); /* in port/.../tas.s, or- * s_lock.c */--#define TAS(lock) tas(lock)-#endif /* TAS */-
#if !defined(TAS_SPIN)
#define TAS_SPIN(lock) TAS(lock)
#endif /* TAS_SPIN */
--
2.50.1 (Apple Git-155)
From ea055e53d64b97e74a87b02d424dee48fc66333b Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
Date: Mon, 4 May 2026 16:24:30 -0500
Subject: [PATCH v5 2/3] Remove HAS_TEST_AND_SET.
This is only set when TAS is defined, so we can just check whether
TAS is defined directly instead.
---
src/include/storage/s_lock.h | 20 +++++---------------
1 file changed, 5 insertions(+), 15 deletions(-)
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.hindex dcfec8ce2af..fb872edd2f0 100644--- a/src/include/storage/s_lock.h+++ b/src/include/storage/s_lock.h@@ -124,7 +124,6 @@
#ifdef __i386__ /* 32-bit i386 */
-#define HAS_TEST_AND_SET
typedef unsigned char slock_t;
@@ -194,7 +193,6 @@ spin_delay(void)
#ifdef __x86_64__ /* AMD Opteron, Intel EM64T */
-#define HAS_TEST_AND_SET
typedef unsigned char slock_t;
@@ -249,7 +247,6 @@ spin_delay(void)
*/
#if defined(__arm__) || defined(__arm) || defined(__aarch64__)
#ifdef HAVE_GCC__SYNC_INT32_TAS
-#define HAS_TEST_AND_SET
#define TAS(lock) tas(lock)
@@ -292,7 +289,6 @@ spin_delay(void)
/* S/390 and S/390x Linux (32- and 64-bit zSeries) */
#if defined(__s390__) || defined(__s390x__)
-#define HAS_TEST_AND_SET
typedef unsigned int slock_t;
@@ -321,7 +317,6 @@ tas(volatile slock_t *lock)
* acquire/release semantics. The CPU will treat superfluous members as
* NOPs, so it's just code space.
*/
-#define HAS_TEST_AND_SET
typedef unsigned char slock_t;
@@ -392,7 +387,6 @@ do \
/* PowerPC */
#if defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__)
-#define HAS_TEST_AND_SET
typedef unsigned int slock_t;
@@ -453,7 +447,6 @@ do \
#if defined(__mips__) && !defined(__sgi) /* non-SGI MIPS */
-#define HAS_TEST_AND_SET
typedef unsigned int slock_t;
@@ -531,10 +524,9 @@ do \
* grounds that that's known to be more likely to work in the ARM ecosystem.
* (But we dealt with ARM above.)
*/
-#if !defined(HAS_TEST_AND_SET)+#if !defined(TAS)
#if defined(HAVE_GCC__SYNC_INT32_TAS)
-#define HAS_TEST_AND_SET
#define TAS(lock) tas(lock)
@@ -549,7 +541,6 @@ tas(volatile slock_t *lock)
#define S_UNLOCK(lock) __sync_lock_release(lock)
#elif defined(HAVE_GCC__SYNC_CHAR_TAS)
-#define HAS_TEST_AND_SET
#define TAS(lock) tas(lock)
@@ -565,7 +556,7 @@ tas(volatile slock_t *lock)
#endif /* HAVE_GCC__SYNC_INT32_TAS */
-#endif /* !defined(HAS_TEST_AND_SET) */+#endif /* !defined(TAS) */
/*
@@ -592,12 +583,11 @@ tas(volatile slock_t *lock)
* ---------------------------------------------------------------------
*/
-#if !defined(HAS_TEST_AND_SET) /* We didn't trigger above, let's try here */+#if !defined(TAS) /* We didn't trigger above, let's try here */
#ifdef _MSC_VER
typedef LONG slock_t;
-#define HAS_TEST_AND_SET
#define TAS(lock) (InterlockedCompareExchange(lock, 1, 0))
#define SPIN_DELAY() spin_delay()
@@ -649,11 +639,11 @@ spin_delay(void)
#endif
-#endif /* !defined(HAS_TEST_AND_SET) */+#endif /* !defined(TAS) */
/* Blow up if we didn't have any way to do spinlocks */
-#ifndef HAS_TEST_AND_SET+#ifndef TAS
#error PostgreSQL does not have spinlock support on this platform. Please report this to pgsql-bugs@lists.postgresql.org.
#endif
--
2.50.1 (Apple Git-155)
From 572c8fae484955bcbcecc97d63536ce5c9f5ee10 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
Date: Thu, 7 May 2026 15:32:50 -0500
Subject: [PATCH v5 3/3] Better express platform requirements in s_lock.h.
---
src/backend/storage/lmgr/s_lock.c | 2 ++
src/include/storage/s_lock.h | 59 +++++++++++++++++--------------
2 files changed, 35 insertions(+), 26 deletions(-)
diff --git a/src/backend/storage/lmgr/s_lock.c b/src/backend/storage/lmgr/s_lock.cindex 6df568eccb3..34c6de66773 100644--- a/src/backend/storage/lmgr/s_lock.c+++ b/src/backend/storage/lmgr/s_lock.c@@ -91,6 +91,7 @@ s_lock_stuck(const char *file, int line, const char *func)
#endif
}
+#ifdef USE_DEFAULT_S_LOCK
/*
* s_lock(lock) - platform-independent portion of waiting for a spinlock.
*/
@@ -110,6 +111,7 @@ s_lock(volatile slock_t *lock, const char *file, int line, const char *func)
return delayStatus.delays;
}
+#endif
#ifdef USE_DEFAULT_S_UNLOCK
void
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.hindex fb872edd2f0..65f00c06518 100644--- a/src/include/storage/s_lock.h+++ b/src/include/storage/s_lock.h@@ -44,23 +44,16 @@
* atomic test-and-set only when it appears free.
*
* TAS() and TAS_SPIN() are NOT part of the API, and should never be called
- * directly.- *- * CAUTION: on some platforms TAS() and/or TAS_SPIN() may sometimes report- * failure to acquire a lock even when the lock is not locked. For example,- * on Alpha TAS() will "fail" if interrupted. Therefore a retry loop must- * always be used, even if you are certain the lock is free.+ * directly. If a platform-specific TAS() is defined, the platform must+ * _not_ define its own S_LOCK(). Conversely, if a platform-specific+ * S_LOCK() is defined, the platform must _not_ define its own TAS().+ * Currently, all supported platforms define TAS() and use the default+ * S_LOCK() implementation, so that is probably a good place to start if+ * adding a new one.
*
* It is the responsibility of these macros to make sure that the compiler
* does not re-order accesses to shared memory to precede the actual lock
- * acquisition, or follow the lock release. Prior to PostgreSQL 9.5, this- * was the caller's responsibility, which meant that callers had to use- * volatile-qualified pointers to refer to both the spinlock itself and the- * shared data being accessed within the spinlocked critical section. This- * was notationally awkward, easy to forget (and thus error-prone), and- * prevented some useful compiler optimizations. For these reasons, we- * now require that the macros themselves prevent compiler re-ordering,- * so that the caller doesn't need to take special precautions.+ * acquisition, or follow the lock release.
*
* On platforms with weak memory ordering, the TAS(), TAS_SPIN(), and
* S_UNLOCK() macros must further include hardware-level memory fence
@@ -72,7 +65,7 @@
*
* On most supported platforms, TAS() uses a tas() function written
* in assembly language to execute a hardware atomic-test-and-set
- * instruction. Equivalent OS-supplied mutex routines could be used too.+ * instruction. Equivalent compiler intrinsics are another popular option.
*
*
* Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
@@ -642,20 +635,27 @@ spin_delay(void)
#endif /* !defined(TAS) */
-/* Blow up if we didn't have any way to do spinlocks */-#ifndef TAS-#error PostgreSQL does not have spinlock support on this platform. Please report this to pgsql-bugs@lists.postgresql.org.-#endif--
/*
* Default Definitions - override these above as needed.
*/
-#if !defined(S_LOCK)+/*+ * Make sure S_LOCK is defined, either explicitly for the platform or via a TAS+ * macro for the platform. Exactly one of either S_LOCK or TAS should be+ * defined for a supported platform at this point in the file.+ */+#if defined(S_LOCK)+#if defined(TAS)+#error Both TAS and S_LOCK defined on this platform. Please report this to pgsql-bugs@lists.postgresql.org.+#endif+#elif defined(TAS)+#define USE_DEFAULT_S_LOCK+extern int s_lock(volatile slock_t *lock, const char *file, int line, const char *func);
#define S_LOCK(lock) \
(TAS(lock) ? s_lock((lock), __FILE__, __LINE__, __func__) : 0)
-#endif /* S_LOCK */+#else+#error Neither TAS nor S_LOCK defined on this platform. Please report this to pgsql-bugs@lists.postgresql.org.+#endif
#if !defined(S_UNLOCK)
/*
@@ -687,15 +687,22 @@ extern void s_unlock(volatile slock_t *lock);
#define SPIN_DELAY() ((void) 0)
#endif /* SPIN_DELAY */
-#if !defined(TAS_SPIN)+/*+ * We can only define TAS_SPIN if TAS was defined. Otherwise, the platform+ * defined its own S_LOCK without TAS. Since TAS_SPIN is only used by the+ * default S_LOCK's helper function, there's no need to define TAS_SPIN at all+ * in that case, unless you plan to use it in a platform-specific S_LOCK helper+ * function. (Note that we currently do not have any platforms that don't+ * define TAS.)+ */+#if !defined(TAS_SPIN) && defined(TAS)
#define TAS_SPIN(lock) TAS(lock)
-#endif /* TAS_SPIN */+#endif /* ! TAS_SPIN && TAS */
/*
* Platform-independent out-of-line support routines
*/
-extern int s_lock(volatile slock_t *lock, const char *file, int line, const char *func);
/* Support for dynamic adjustment of spins_per_delay */
#define DEFAULT_SPINS_PER_DELAY 100
--
2.50.1 (Apple Git-155)
Attachments:
[text/plain] v5-0001-Remove-fallback-declaration-for-tas.patch (2.2K, ../af0D6fhLfVmG2fr7@nathan/2-v5-0001-Remove-fallback-declaration-for-tas.patch)
download | inline diff:
From 595bbb48a7de3dd191023d617dc2c7f4725ed2d0 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
Date: Mon, 4 May 2026 16:04:04 -0500
Subject: [PATCH v5 1/3] Remove fallback declaration for tas().
The last definition of tas() in s_lock.c was removed in commit
718aa43a4e, and the last tas.s file was removed in commit
25f36066dd, so this is dead code.
---
src/backend/Makefile | 2 +-
src/backend/port/.gitignore | 1 -
src/backend/port/meson.build | 2 +-
src/include/storage/s_lock.h | 7 -------
4 files changed, 2 insertions(+), 10 deletions(-)
diff --git a/src/backend/Makefile b/src/backend/Makefileindex 162d3f1f2a9..4bb76d3d397 100644--- a/src/backend/Makefile+++ b/src/backend/Makefile@@ -301,7 +301,7 @@ endif
distclean: clean
# generated by configure
- rm -f port/tas.s port/pg_sema.c port/pg_shmem.c+ rm -f port/pg_sema.c port/pg_shmem.c
##########################################################################
diff --git a/src/backend/port/.gitignore b/src/backend/port/.gitignoreindex 4ef36b82c77..6c5067a4a9f 100644--- a/src/backend/port/.gitignore+++ b/src/backend/port/.gitignore@@ -1,3 +1,2 @@
/pg_sema.c
/pg_shmem.c
-/tas.sdiff --git a/src/backend/port/meson.build b/src/backend/port/meson.buildindex e8b7da8d281..29e88ef3541 100644--- a/src/backend/port/meson.build+++ b/src/backend/port/meson.build@@ -30,4 +30,4 @@ if host_system == 'windows'
endif
# autoconf generates the file there, ensure we get a conflict
-generated_sources_ac += {'src/backend/port': ['pg_sema.c', 'pg_shmem.c', 'tas.s']}+generated_sources_ac += {'src/backend/port': ['pg_sema.c', 'pg_shmem.c']}diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.hindex c9e52511990..dcfec8ce2af 100644--- a/src/include/storage/s_lock.h+++ b/src/include/storage/s_lock.h@@ -697,13 +697,6 @@ extern void s_unlock(volatile slock_t *lock);
#define SPIN_DELAY() ((void) 0)
#endif /* SPIN_DELAY */
-#if !defined(TAS)-extern int tas(volatile slock_t *lock); /* in port/.../tas.s, or- * s_lock.c */--#define TAS(lock) tas(lock)-#endif /* TAS */-
#if !defined(TAS_SPIN)
#define TAS_SPIN(lock) TAS(lock)
#endif /* TAS_SPIN */
--
2.50.1 (Apple Git-155)
[text/plain] v5-0002-Remove-HAS_TEST_AND_SET.patch (3.2K, ../af0D6fhLfVmG2fr7@nathan/3-v5-0002-Remove-HAS_TEST_AND_SET.patch)
download | inline diff:
From ea055e53d64b97e74a87b02d424dee48fc66333b Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
Date: Mon, 4 May 2026 16:24:30 -0500
Subject: [PATCH v5 2/3] Remove HAS_TEST_AND_SET.
This is only set when TAS is defined, so we can just check whether
TAS is defined directly instead.
---
src/include/storage/s_lock.h | 20 +++++---------------
1 file changed, 5 insertions(+), 15 deletions(-)
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.hindex dcfec8ce2af..fb872edd2f0 100644--- a/src/include/storage/s_lock.h+++ b/src/include/storage/s_lock.h@@ -124,7 +124,6 @@
#ifdef __i386__ /* 32-bit i386 */
-#define HAS_TEST_AND_SET
typedef unsigned char slock_t;
@@ -194,7 +193,6 @@ spin_delay(void)
#ifdef __x86_64__ /* AMD Opteron, Intel EM64T */
-#define HAS_TEST_AND_SET
typedef unsigned char slock_t;
@@ -249,7 +247,6 @@ spin_delay(void)
*/
#if defined(__arm__) || defined(__arm) || defined(__aarch64__)
#ifdef HAVE_GCC__SYNC_INT32_TAS
-#define HAS_TEST_AND_SET
#define TAS(lock) tas(lock)
@@ -292,7 +289,6 @@ spin_delay(void)
/* S/390 and S/390x Linux (32- and 64-bit zSeries) */
#if defined(__s390__) || defined(__s390x__)
-#define HAS_TEST_AND_SET
typedef unsigned int slock_t;
@@ -321,7 +317,6 @@ tas(volatile slock_t *lock)
* acquire/release semantics. The CPU will treat superfluous members as
* NOPs, so it's just code space.
*/
-#define HAS_TEST_AND_SET
typedef unsigned char slock_t;
@@ -392,7 +387,6 @@ do \
/* PowerPC */
#if defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__)
-#define HAS_TEST_AND_SET
typedef unsigned int slock_t;
@@ -453,7 +447,6 @@ do \
#if defined(__mips__) && !defined(__sgi) /* non-SGI MIPS */
-#define HAS_TEST_AND_SET
typedef unsigned int slock_t;
@@ -531,10 +524,9 @@ do \
* grounds that that's known to be more likely to work in the ARM ecosystem.
* (But we dealt with ARM above.)
*/
-#if !defined(HAS_TEST_AND_SET)+#if !defined(TAS)
#if defined(HAVE_GCC__SYNC_INT32_TAS)
-#define HAS_TEST_AND_SET
#define TAS(lock) tas(lock)
@@ -549,7 +541,6 @@ tas(volatile slock_t *lock)
#define S_UNLOCK(lock) __sync_lock_release(lock)
#elif defined(HAVE_GCC__SYNC_CHAR_TAS)
-#define HAS_TEST_AND_SET
#define TAS(lock) tas(lock)
@@ -565,7 +556,7 @@ tas(volatile slock_t *lock)
#endif /* HAVE_GCC__SYNC_INT32_TAS */
-#endif /* !defined(HAS_TEST_AND_SET) */+#endif /* !defined(TAS) */
/*
@@ -592,12 +583,11 @@ tas(volatile slock_t *lock)
* ---------------------------------------------------------------------
*/
-#if !defined(HAS_TEST_AND_SET) /* We didn't trigger above, let's try here */+#if !defined(TAS) /* We didn't trigger above, let's try here */
#ifdef _MSC_VER
typedef LONG slock_t;
-#define HAS_TEST_AND_SET
#define TAS(lock) (InterlockedCompareExchange(lock, 1, 0))
#define SPIN_DELAY() spin_delay()
@@ -649,11 +639,11 @@ spin_delay(void)
#endif
-#endif /* !defined(HAS_TEST_AND_SET) */+#endif /* !defined(TAS) */
/* Blow up if we didn't have any way to do spinlocks */
-#ifndef HAS_TEST_AND_SET+#ifndef TAS
#error PostgreSQL does not have spinlock support on this platform. Please report this to pgsql-bugs@lists.postgresql.org.
#endif
--
2.50.1 (Apple Git-155)
[text/plain] v5-0003-Better-express-platform-requirements-in-s_lock.h.patch (5.3K, ../af0D6fhLfVmG2fr7@nathan/4-v5-0003-Better-express-platform-requirements-in-s_lock.h.patch)
download | inline diff:
From 572c8fae484955bcbcecc97d63536ce5c9f5ee10 Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
Date: Thu, 7 May 2026 15:32:50 -0500
Subject: [PATCH v5 3/3] Better express platform requirements in s_lock.h.
---
src/backend/storage/lmgr/s_lock.c | 2 ++
src/include/storage/s_lock.h | 59 +++++++++++++++++--------------
2 files changed, 35 insertions(+), 26 deletions(-)
diff --git a/src/backend/storage/lmgr/s_lock.c b/src/backend/storage/lmgr/s_lock.cindex 6df568eccb3..34c6de66773 100644--- a/src/backend/storage/lmgr/s_lock.c+++ b/src/backend/storage/lmgr/s_lock.c@@ -91,6 +91,7 @@ s_lock_stuck(const char *file, int line, const char *func)
#endif
}
+#ifdef USE_DEFAULT_S_LOCK
/*
* s_lock(lock) - platform-independent portion of waiting for a spinlock.
*/
@@ -110,6 +111,7 @@ s_lock(volatile slock_t *lock, const char *file, int line, const char *func)
return delayStatus.delays;
}
+#endif
#ifdef USE_DEFAULT_S_UNLOCK
void
diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.hindex fb872edd2f0..65f00c06518 100644--- a/src/include/storage/s_lock.h+++ b/src/include/storage/s_lock.h@@ -44,23 +44,16 @@
* atomic test-and-set only when it appears free.
*
* TAS() and TAS_SPIN() are NOT part of the API, and should never be called
- * directly.- *- * CAUTION: on some platforms TAS() and/or TAS_SPIN() may sometimes report- * failure to acquire a lock even when the lock is not locked. For example,- * on Alpha TAS() will "fail" if interrupted. Therefore a retry loop must- * always be used, even if you are certain the lock is free.+ * directly. If a platform-specific TAS() is defined, the platform must+ * _not_ define its own S_LOCK(). Conversely, if a platform-specific+ * S_LOCK() is defined, the platform must _not_ define its own TAS().+ * Currently, all supported platforms define TAS() and use the default+ * S_LOCK() implementation, so that is probably a good place to start if+ * adding a new one.
*
* It is the responsibility of these macros to make sure that the compiler
* does not re-order accesses to shared memory to precede the actual lock
- * acquisition, or follow the lock release. Prior to PostgreSQL 9.5, this- * was the caller's responsibility, which meant that callers had to use- * volatile-qualified pointers to refer to both the spinlock itself and the- * shared data being accessed within the spinlocked critical section. This- * was notationally awkward, easy to forget (and thus error-prone), and- * prevented some useful compiler optimizations. For these reasons, we- * now require that the macros themselves prevent compiler re-ordering,- * so that the caller doesn't need to take special precautions.+ * acquisition, or follow the lock release.
*
* On platforms with weak memory ordering, the TAS(), TAS_SPIN(), and
* S_UNLOCK() macros must further include hardware-level memory fence
@@ -72,7 +65,7 @@
*
* On most supported platforms, TAS() uses a tas() function written
* in assembly language to execute a hardware atomic-test-and-set
- * instruction. Equivalent OS-supplied mutex routines could be used too.+ * instruction. Equivalent compiler intrinsics are another popular option.
*
*
* Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
@@ -642,20 +635,27 @@ spin_delay(void)
#endif /* !defined(TAS) */
-/* Blow up if we didn't have any way to do spinlocks */-#ifndef TAS-#error PostgreSQL does not have spinlock support on this platform. Please report this to pgsql-bugs@lists.postgresql.org.-#endif--
/*
* Default Definitions - override these above as needed.
*/
-#if !defined(S_LOCK)+/*+ * Make sure S_LOCK is defined, either explicitly for the platform or via a TAS+ * macro for the platform. Exactly one of either S_LOCK or TAS should be+ * defined for a supported platform at this point in the file.+ */+#if defined(S_LOCK)+#if defined(TAS)+#error Both TAS and S_LOCK defined on this platform. Please report this to pgsql-bugs@lists.postgresql.org.+#endif+#elif defined(TAS)+#define USE_DEFAULT_S_LOCK+extern int s_lock(volatile slock_t *lock, const char *file, int line, const char *func);
#define S_LOCK(lock) \
(TAS(lock) ? s_lock((lock), __FILE__, __LINE__, __func__) : 0)
-#endif /* S_LOCK */+#else+#error Neither TAS nor S_LOCK defined on this platform. Please report this to pgsql-bugs@lists.postgresql.org.+#endif
#if !defined(S_UNLOCK)
/*
@@ -687,15 +687,22 @@ extern void s_unlock(volatile slock_t *lock);
#define SPIN_DELAY() ((void) 0)
#endif /* SPIN_DELAY */
-#if !defined(TAS_SPIN)+/*+ * We can only define TAS_SPIN if TAS was defined. Otherwise, the platform+ * defined its own S_LOCK without TAS. Since TAS_SPIN is only used by the+ * default S_LOCK's helper function, there's no need to define TAS_SPIN at all+ * in that case, unless you plan to use it in a platform-specific S_LOCK helper+ * function. (Note that we currently do not have any platforms that don't+ * define TAS.)+ */+#if !defined(TAS_SPIN) && defined(TAS)
#define TAS_SPIN(lock) TAS(lock)
-#endif /* TAS_SPIN */+#endif /* ! TAS_SPIN && TAS */
/*
* Platform-independent out-of-line support routines
*/
-extern int s_lock(volatile slock_t *lock, const char *file, int line, const char *func);
/* Support for dynamic adjustment of spins_per_delay */
#define DEFAULT_SPINS_PER_DELAY 100
--
2.50.1 (Apple Git-155)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: nathandbossart@gmail.com, tgl@sss.pgh.pa.us
Subject: Re: small cleanup for s_lock.h
In-Reply-To: <af0D6fhLfVmG2fr7@nathan>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox