From 5abfc98ef5dd26e2f3c822cbe51c6038fb4e37bf Mon Sep 17 00:00:00 2001
From: Nathan Bossart <nathan@postgresql.org>
Date: Mon, 8 Sep 2025 13:18:59 -0500
Subject: [PATCH v3 1/1] Move named LWLock tranche request array to shared
 memory.

---
 src/backend/postmaster/launch_backend.c |  3 +++
 src/backend/storage/lmgr/lwlock.c       | 31 +++++++++++++++++++++----
 src/include/storage/lwlock.h            |  4 ++++
 3 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/src/backend/postmaster/launch_backend.c b/src/backend/postmaster/launch_backend.c
index a38979c50e4..c5ef14e1eaa 100644
--- a/src/backend/postmaster/launch_backend.c
+++ b/src/backend/postmaster/launch_backend.c
@@ -101,6 +101,7 @@ typedef struct
 	struct InjectionPointsCtl *ActiveInjectionPoints;
 #endif
 	int			NamedLWLockTrancheRequests;
+	NamedLWLockTrancheRequest *NamedLWLockTrancheRequestArray;
 	char	  **LWLockTrancheNames;
 	int		   *LWLockCounter;
 	LWLockPadded *MainLWLockArray;
@@ -761,6 +762,7 @@ save_backend_variables(BackendParameters *param,
 #endif
 
 	param->NamedLWLockTrancheRequests = NamedLWLockTrancheRequests;
+	param->NamedLWLockTrancheRequestArray = NamedLWLockTrancheRequestArray;
 	param->LWLockTrancheNames = LWLockTrancheNames;
 	param->LWLockCounter = LWLockCounter;
 	param->MainLWLockArray = MainLWLockArray;
@@ -1022,6 +1024,7 @@ restore_backend_variables(BackendParameters *param)
 #endif
 
 	NamedLWLockTrancheRequests = param->NamedLWLockTrancheRequests;
+	NamedLWLockTrancheRequestArray = param->NamedLWLockTrancheRequestArray;
 	LWLockTrancheNames = param->LWLockTrancheNames;
 	LWLockCounter = param->LWLockCounter;
 	MainLWLockArray = param->MainLWLockArray;
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index fcbac5213a5..46c82c63ca5 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -184,14 +184,13 @@ typedef struct NamedLWLockTrancheRequest
 	int			num_lwlocks;
 } NamedLWLockTrancheRequest;
 
-static NamedLWLockTrancheRequest *NamedLWLockTrancheRequestArray = NULL;
-
 /*
- * NamedLWLockTrancheRequests is the valid length of the request array.  This
- * variable is non-static so that postmaster.c can copy them to child processes
- * in EXEC_BACKEND builds.
+ * NamedLWLockTrancheRequests is the valid length of the request array.  These
+ * variables are non-static so that launch_backend.c can copy them to child
+ * processes in EXEC_BACKEND builds.
  */
 int			NamedLWLockTrancheRequests = 0;
+NamedLWLockTrancheRequest *NamedLWLockTrancheRequestArray = NULL;
 
 /* shared memory counter of registered tranches */
 int		   *LWLockCounter = NULL;
@@ -407,6 +406,14 @@ LWLockShmemSize(void)
 	size = add_size(size, mul_size(MAX_NAMED_TRANCHES, sizeof(char *)));
 	size = add_size(size, mul_size(MAX_NAMED_TRANCHES, NAMEDATALEN));
 
+	/*
+	 * Make space for named tranche requests.  This is done for the benefit of
+	 * EXEC_BACKEND builds, which otherwise wouldn't be able to call
+	 * GetNamedLWLockTranche() outside postmaster.
+	 */
+	size = add_size(size, mul_size(NamedLWLockTrancheRequests,
+								   sizeof(NamedLWLockTrancheRequest)));
+
 	/* Space for the LWLock array, plus room for cache line alignment. */
 	size = add_size(size, LWLOCK_PADDED_SIZE);
 	size = add_size(size, mul_size(numLocks, sizeof(LWLockPadded)));
@@ -443,6 +450,20 @@ CreateLWLocks(void)
 			ptr += NAMEDATALEN;
 		}
 
+		/*
+		 * Move named tranche requests to shared memory.  This is done for the
+		 * benefit of EXEC_BACKEND builds, which otherwise wouldn't be able to
+		 * call GetNamedLWLockTranche() outside postmaster.
+		 */
+		if (NamedLWLockTrancheRequests > 0)
+		{
+			memcpy(ptr, NamedLWLockTrancheRequestArray,
+				   NamedLWLockTrancheRequests * sizeof(NamedLWLockTrancheRequest));
+			pfree(NamedLWLockTrancheRequestArray);
+			NamedLWLockTrancheRequestArray = (NamedLWLockTrancheRequest *) ptr;
+			ptr += NamedLWLockTrancheRequests * sizeof(NamedLWLockTrancheRequest);
+		}
+
 		/* Ensure desired alignment of LWLock array */
 		ptr += LWLOCK_PADDED_SIZE - ((uintptr_t) ptr) % LWLOCK_PADDED_SIZE;
 		MainLWLockArray = (LWLockPadded *) ptr;
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index 0e9cf81a4c7..8e0d0d233b4 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -73,8 +73,12 @@ typedef union LWLockPadded
 
 extern PGDLLIMPORT LWLockPadded *MainLWLockArray;
 
+/* forward declaration of private type for use only by lwlock.c */
+typedef struct NamedLWLockTrancheRequest NamedLWLockTrancheRequest;
+
 extern PGDLLIMPORT char **LWLockTrancheNames;
 extern PGDLLIMPORT int NamedLWLockTrancheRequests;
+extern PGDLLIMPORT NamedLWLockTrancheRequest *NamedLWLockTrancheRequestArray;
 extern PGDLLIMPORT int *LWLockCounter;
 
 /*
-- 
2.39.5 (Apple Git-154)

