Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1xAD53-00000002VrM-0WJk for pgsql-hackers@arkaria.postgresql.org; Fri, 25 Sep 2026 21:03:41 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.98.2) (envelope-from ) id 1xAD50-00000002eGO-0PIh for pgsql-hackers@arkaria.postgresql.org; Fri, 25 Sep 2026 21:03:38 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1xAD4z-00000002eGG-2ZoO for pgsql-hackers@lists.postgresql.org; Fri, 25 Sep 2026 21:03:37 +0000 Received: from mail-qv2-x29.google.com ([2607:f8b0:4864:33::29]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1xAD4w-00000001FzI-3als for pgsql-hackers@postgresql.org; Fri, 25 Sep 2026 21:03:36 +0000 Received: by mail-qv2-x29.google.com with SMTP id 6a1803df08f44-91235f46716so12343316d6.1 for ; Fri, 25 Sep 2026 14:03:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1790370213; x=1790975013; darn=postgresql.org; h=in-reply-to:content-disposition:content-type:mime-version :references:message-id:subject:cc:to:from:date:from:to:cc:subject :date:message-id:reply-to:content-type; bh=LzljCM0htlX20JyLM3WcyufqrtsmEImTnqvU3qf5vyU=; b=km7BMbONvXxkWWVJhVkwQRR6eFggch422xigcJ9nsbFGeHZRWKllxWZIcsjVEVG0BK yvtfK1kjJWWu6wjQiK8w/P+NBkhev/32u4rKYvf5FCLOfjKh0EPLrNeTl8ys3wNPmGKn BnuXOtOQ1CKoljUaWWytUI7jQrk5V9YZRIMS6TyacDDa4cfotol0ILf6HK1G0SSjlOXz LQX1yhTGoK3zLBfT0H2h+O+i+9jLf1eDxSpTbzKfqZnTGitzPx0DT0RMP8iR+OFiqkzE 0QM/06hB6GRsHx2co2i7FH85Lhzp+jQEyo57k/L/bZQTfKG9MAqerriVZjp2SKD8NN48 pnGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1790370213; x=1790975013; h=in-reply-to:content-disposition:content-type:mime-version :references:message-id:subject:cc:to:from:date:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=LzljCM0htlX20JyLM3WcyufqrtsmEImTnqvU3qf5vyU=; b=Kxe2BYPdLMb++IAVftxftGxworFLRVScQvI5Wipka7H911Gr6F/nyBqyDKg+TQh5Nh 2vWttlXlf/aPYDG7UgFXyJNvQw19aAd1mbws8M1iomQZITuR/VwcBx+ugNu2RcPcQQWx PArunaF+SJpoFo6J51UJSdwT6xpooO9c2l28U61XwKcFnJs6l3+VUW8sRCmzlSlg5x2z J1BU4X/DiE0Wm8FUDy5im7//jJt3oM7Va84cXLUe4nfzwQRjUv8xJRNQvkxOU5NkNbOO /g4BbIjEMOhXuhsJ9WkqDoqdYTSa4oAeeX2YcB6Ge+Z/30y0ItV+3vJ/MvJlpv+CeF4L +ozA== X-Gm-Message-State: AFuF++me2ybgO/EubVAiQLNw0lXOe4Jx2bTzCC0SvP4X+oAWrBn/DDtY ads11VIqGLPNHjBF1BJQW2U88C8p6zfJ4fCpZEjF7xR8DQVAfi3awJqyOh9nrw== X-Gm-Gg: AYBFou0KfUzrO7msX5pkE1NcBFaE71RA/LTAVh9DZp0yc8VyzVrzVniFjeRuiNqXyxt +J1NqcVEBMMzFFb7xlYFc2MiDTYgUG+nZESsBNG8YzN4arsxg8E9n7rgGHKSaAc0q81wGgdizQ9 cjX/QDUECnhJNAzo8I/di/6kykFphl3aM590k3iKvyKBDSQ+WDNWA8ZGCKd8ftC5nojP5bQdaw8 xedJf9TV7td8qB1qmfwgj0QczF1tfAztCMB1hhiUsrmcDbumRrBGejtNiDmIrD5qU42d4o8rGNp 7nW5tehi4hcR9RN5i/3wIJ8TT75X6WeuJV76vlm3IW/Jkny5qAKw5hQAV9KlIar5LZJSHhkSGgY DD8j9Wlf9S+msTWiT6YuCYvdgx2pAhklmpo/wF35HGCa9SAKlCdpgezTHycMjEJlAkX8krHnQDO HbQZwlbx9FRA6DkNJc1CPOYGTiq87A4+tTEvwUMqI9Xqkx4PqmqP2QGp4ZX+Qk1+rHKU8tS8OGE HAGSFMBMeQ8jni9oiOHZEgDUrew7pFiDr55GH6AZamw0FdDThjMmvxkEmjkE2XX4wbNtEDDzhML ZihTW37IEZQIfiUj6ErA2ddSVQ== X-Received: by 2002:a05:620a:40ce:b0:939:46d7:4b4e with SMTP id af79cd13be357-93c43c30d72mr704621285a.7.1790370213396; Fri, 25 Sep 2026 14:03:33 -0700 (PDT) Received: from nathan (162-195-168-172.lightspeed.stlsmo.sbcglobal.net. [162.195.168.172]) by smtp.gmail.com with ESMTPSA id af79cd13be357-93c4497be6bsm268659285a.40.2026.09.25.14.03.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 25 Sep 2026 14:03:32 -0700 (PDT) Date: Fri, 25 Sep 2026 16:03:30 -0500 From: Nathan Bossart To: Tom Lane Cc: pgsql-hackers@postgresql.org Subject: Re: small cleanup for s_lock.h Message-ID: References: <369933.1777933007@sss.pgh.pa.us> <532705.1778000169@sss.pgh.pa.us> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="l5ZOTuYWV5JBYH16" Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --l5ZOTuYWV5JBYH16 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline I've committed v5-{0001,0002} and attached a rebased version of 0003. Besides fixing some small things discovered during LLM review, I decided to remove the restriction that only one of TAS or S_LOCK can be defined. Having both doesn't break anything; we just use the platform's S_LOCK in that case. -- nathan --l5ZOTuYWV5JBYH16 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=v6-0001-Better-express-platform-requirements-in-s_lock.h.patch From fe366a26ea50a50f0e810a8dd51069285ceefcf9 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Fri, 25 Sep 2026 16:01:13 -0500 Subject: [PATCH v6 1/1] Better express platform requirements in s_lock.h. Presently, s_lock.h insists that every platform provide TAS(), and its header comment doesn't say which of the macros a new platform actually needs to supply. The real contract is that a platform must provide either S_LOCK() or a TAS() for the default S_LOCK() to be built on. To better express that, this commit moves the "no spinlock support" error to where the default S_LOCK() is defined, compiles s_lock() only when the default S_LOCK() is in use, and provides a default TAS_SPIN() only when there is a TAS() to base it on. The direct callers of s_lock() in the spinlock tests are adjusted to match. The header comment is reworked accordingly, dropping the note about pre-9.5 volatile requirements and the caution about TAS() spuriously failing along the way. The latter was added by commit 7f60b81e1a for a long-unsupported platform, and it only matters to callers outside this file, which commit 499abb0c0f disallowed. Co-authored-by: Tom Lane Discussion: https://postgr.es/m/afkUeI7UhacZ5ZFm%40nathan --- src/backend/storage/lmgr/s_lock.c | 4 ++- src/include/storage/s_lock.h | 46 +++++++++++++++---------------- src/test/regress/regress.c | 2 +- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/backend/storage/lmgr/s_lock.c b/src/backend/storage/lmgr/s_lock.c index 6df568eccb3..795aeed1028 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 @@ -291,7 +293,7 @@ main() printf(" if S_LOCK() and TAS() are working.\n"); fflush(stdout); - s_lock(&test_lock.lock, __FILE__, __LINE__, __func__); + S_LOCK(&test_lock.lock); printf("S_LOCK_TEST: failed, lock not locked\n"); return 1; diff --git a/src/include/storage/s_lock.h b/src/include/storage/s_lock.h index 17edc058b74..7e049dfac18 100644 --- a/src/include/storage/s_lock.h +++ b/src/include/storage/s_lock.h @@ -44,23 +44,14 @@ * 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. A platform must provide either S_LOCK() or a TAS() for the + * default S_LOCK() to be built on. Currently, all supported platforms do + * the latter, so that is probably the best 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 +63,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,19 +633,23 @@ 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. */ +/* + * Make sure S_LOCK is defined, either explicitly for the platform or via a TAS + * macro for the platform. + */ #if !defined(S_LOCK) +#ifdef 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) +#else +#error PostgreSQL does not have spinlock support on this platform. Please report this to pgsql-bugs@lists.postgresql.org. +#endif /* TAS */ #endif /* S_LOCK */ #if !defined(S_UNLOCK) @@ -687,15 +682,18 @@ extern void s_unlock(volatile slock_t *lock); #define SPIN_DELAY() ((void) 0) #endif /* SPIN_DELAY */ -#if !defined(TAS_SPIN) +/* + * TAS_SPIN is only needed by the default S_LOCK's helper function (s_lock()), + * so we only provide a default when there is a TAS to base it on. + */ +#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 diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c index c72ee31cdce..3deb4ed7203 100644 --- a/src/test/regress/regress.c +++ b/src/test/regress/regress.c @@ -675,7 +675,7 @@ test_spinlock(void) S_UNLOCK(&struct_w_lock.lock); /* and that "contended" acquisition works */ - s_lock(&struct_w_lock.lock, "testfile", 17, "testfunc"); + S_LOCK(&struct_w_lock.lock); S_UNLOCK(&struct_w_lock.lock); /* -- 2.55.0 --l5ZOTuYWV5JBYH16--