From ea55eca0d105597b08d9a77f1055bbb088972515 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Thu, 2 Apr 2026 00:18:05 +0300
Subject: [PATCH v20260405 06/15] Convert lwlock.c to use the new interface

It seems like a good candidate to convert first because it needs to
initialized before any other subsystem, but other than that it's
nothing special.
---
 src/backend/storage/ipc/ipci.c      | 13 ------
 src/backend/storage/lmgr/lwlock.c   | 71 +++++++++++++++--------------
 src/include/storage/lwlock.h        |  2 -
 src/include/storage/subsystemlist.h |  9 +++-
 4 files changed, 45 insertions(+), 50 deletions(-)

diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index e4a6a52f12d..de65a9ef33c 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -121,7 +121,6 @@ CalculateShmemSize(void)
 	size = add_size(size, TwoPhaseShmemSize());
 	size = add_size(size, BackgroundWorkerShmemSize());
 	size = add_size(size, MultiXactShmemSize());
-	size = add_size(size, LWLockShmemSize());
 	size = add_size(size, ProcArrayShmemSize());
 	size = add_size(size, BackendStatusShmemSize());
 	size = add_size(size, SharedInvalShmemSize());
@@ -179,11 +178,6 @@ AttachSharedMemoryStructs(void)
 	 */
 	InitializeFastPathLocks();
 
-	/*
-	 * Attach to LWLocks first. They are needed by most other subsystems.
-	 */
-	LWLockShmemInit();
-
 	/* Establish pointers to all shared memory areas in this backend */
 	ShmemAttachRequested();
 	CreateOrAttachShmemStructs();
@@ -230,13 +224,6 @@ CreateSharedMemoryAndSemaphores(void)
 	 */
 	InitShmemAllocator(seghdr);
 
-	/*
-	 * Initialize LWLocks first, in case any of the shmem init function use
-	 * LWLocks.  (Nothing else can be running during startup, so they don't
-	 * need to do any locking yet, but we nevertheless allow it.)
-	 */
-	LWLockShmemInit();
-
 	/* Initialize all shmem areas */
 	ShmemInitRequested();
 
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index 5cb696490d6..30b715ab051 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -84,6 +84,7 @@
 #include "storage/proclist.h"
 #include "storage/procnumber.h"
 #include "storage/spin.h"
+#include "storage/subsystems.h"
 #include "utils/memutils.h"
 #include "utils/wait_event.h"
 
@@ -212,6 +213,15 @@ typedef struct NamedLWLockTrancheRequest
 
 static List *NamedLWLockTrancheRequests = NIL;
 
+static void LWLockShmemRequest(void *arg);
+static void LWLockShmemInit(void *arg);
+
+const ShmemCallbacks LWLockCallbacks = {
+	.request_fn = LWLockShmemRequest,
+	.init_fn = LWLockShmemInit,
+};
+
+
 static void InitializeLWLocks(int numLocks);
 static inline void LWLockReportWaitStart(LWLock *lock);
 static inline void LWLockReportWaitEnd(void);
@@ -401,58 +411,51 @@ NumLWLocksForNamedTranches(void)
 }
 
 /*
- * Compute shmem space needed for user-defined tranches and the main LWLock
- * array.
+ * Request shmem space for user-defined tranches and the main LWLock array.
  */
-Size
-LWLockShmemSize(void)
+static void
+LWLockShmemRequest(void *arg)
 {
-	Size		size;
 	int			numLocks;
+	Size		size;
+
+	numLocks = NUM_FIXED_LWLOCKS + NumLWLocksForNamedTranches();
 
 	/* Space for user-defined tranches */
 	size = sizeof(LWLockTrancheShmemData);
-
-	/* Space for the LWLock array */
-	numLocks = NUM_FIXED_LWLOCKS + NumLWLocksForNamedTranches();
 	size = add_size(size, mul_size(numLocks, sizeof(LWLockPadded)));
+	ShmemRequestStruct(.name = "LWLock tranches",
+					   .size = size,
+					   .ptr = (void **) &LWLockTranches,
+		);
 
-	return size;
+	/* Space for the LWLock array */
+	ShmemRequestStruct(.name = "Main LWLock array",
+					   .size = numLocks * sizeof(LWLockPadded),
+					   .ptr = (void **) &MainLWLockArray,
+		);
 }
 
 /*
- * Allocate shmem space for user-defined tranches and the main LWLock array,
- * and initialize it.
+ * Initialize shmem space for user-defined tranches and the main LWLock array.
  */
-void
-LWLockShmemInit(void)
+static void
+LWLockShmemInit(void *arg)
 {
 	int			numLocks;
-	bool		found;
 
-	LWLockTranches = (LWLockTrancheShmemData *)
-		ShmemInitStruct("LWLock tranches", sizeof(LWLockTrancheShmemData), &found);
-	if (!found)
-	{
-		/* Calculate total number of locks needed in the main array */
-		LWLockTranches->num_main_array_locks =
-			NUM_FIXED_LWLOCKS + NumLWLocksForNamedTranches();
+	numLocks = NUM_FIXED_LWLOCKS + NumLWLocksForNamedTranches();
 
-		/* Initialize the dynamic-allocation counter for tranches */
-		LWLockTranches->num_user_defined = 0;
+	/* Remember total number of locks needed in the main array */
+	LWLockTranches->num_main_array_locks = numLocks;
 
-		SpinLockInit(&LWLockTranches->lock);
-	}
+	/* Initialize the dynamic-allocation counter for tranches */
+	LWLockTranches->num_user_defined = 0;
 
-	/* Allocate and initialize the main array */
-	numLocks = LWLockTranches->num_main_array_locks;
-	MainLWLockArray = (LWLockPadded *)
-		ShmemInitStruct("Main LWLock array", numLocks * sizeof(LWLockPadded), &found);
-	if (!found)
-	{
-		/* Initialize all LWLocks */
-		InitializeLWLocks(numLocks);
-	}
+	SpinLockInit(&LWLockTranches->lock);
+
+	/* Allocate and initialize all LWLocks in the main array */
+	InitializeLWLocks(numLocks);
 }
 
 /*
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index 61f0dbe749a..efa5b427e9f 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -126,8 +126,6 @@ extern bool LWLockHeldByMeInMode(LWLock *lock, LWLockMode mode);
 extern bool LWLockWaitForVar(LWLock *lock, pg_atomic_uint64 *valptr, uint64 oldval, uint64 *newval);
 extern void LWLockUpdateVar(LWLock *lock, pg_atomic_uint64 *valptr, uint64 val);
 
-extern Size LWLockShmemSize(void);
-extern void LWLockShmemInit(void);
 extern void InitLWLockAccess(void);
 
 extern const char *GetLWLockIdentifier(uint32 classId, uint16 eventId);
diff --git a/src/include/storage/subsystemlist.h b/src/include/storage/subsystemlist.h
index ed43c90bcc3..f0cf01f5a85 100644
--- a/src/include/storage/subsystemlist.h
+++ b/src/include/storage/subsystemlist.h
@@ -20,4 +20,11 @@
  * of these matter.
  */
 
-/* TODO: empty for now */
+/*
+ * LWLocks first, in case any of the other shmem init functions use LWLocks.
+ * (Nothing else can be running during startup, so they don't need to do any
+ * locking yet, but we nevertheless allow it.)
+ */
+PG_SHMEM_SUBSYSTEM(LWLockCallbacks)
+
+/* TODO: nothing else for now */
-- 
2.34.1

