v1-0004-Use-ShmemInitStruct-to-allocate-lwlock.c-s-shared.patch
text/x-patch
Filename: v1-0004-Use-ShmemInitStruct-to-allocate-lwlock.c-s-shared.patch
Type: text/x-patch
Part: 3
Message:
Clean up NamedLWLockTranche stuff
Patch
Format: format-patch
Series: patch v1-0004
Subject: Use ShmemInitStruct to allocate lwlock.c's shared memory
| File | + | − |
|---|---|---|
| src/backend/postmaster/launch_backend.c | 0 | 3 |
| src/backend/storage/ipc/ipci.c | 2 | 4 |
| src/backend/storage/ipc/shmem.c | 10 | 5 |
| src/backend/storage/lmgr/lwlock.c | 26 | 13 |
| src/include/storage/lwlock.h | 1 | 6 |
From d5362cffef3de02259841ce4b049b7bd8898bef9 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Thu, 26 Mar 2026 13:26:59 +0200
Subject: [PATCH v1 4/5] Use ShmemInitStruct to allocate lwlock.c's shared
memory
It's nice to have them show up in pg_shmem_allocations like all other
shmem areas. ShmemInitStruct() depends on ShmemIndexLock, but only
after postmaster startup.
---
src/backend/postmaster/launch_backend.c | 3 --
src/backend/storage/ipc/ipci.c | 6 ++--
src/backend/storage/ipc/shmem.c | 15 ++++++----
src/backend/storage/lmgr/lwlock.c | 39 ++++++++++++++++---------
src/include/storage/lwlock.h | 7 +----
5 files changed, 39 insertions(+), 31 deletions(-)
diff --git a/src/backend/postmaster/launch_backend.c b/src/backend/postmaster/launch_backend.c
index 8c134eaca88..8aaf427df48 100644
--- a/src/backend/postmaster/launch_backend.c
+++ b/src/backend/postmaster/launch_backend.c
@@ -99,7 +99,6 @@ typedef struct
#ifdef USE_INJECTION_POINTS
struct InjectionPointsCtl *ActiveInjectionPoints;
#endif
- LWLockTrancheShmemData *LWLockTranches;
LWLockPadded *MainLWLockArray;
PROC_HDR *ProcGlobal;
PGPROC *AuxiliaryProcs;
@@ -726,7 +725,6 @@ save_backend_variables(BackendParameters *param,
param->ActiveInjectionPoints = ActiveInjectionPoints;
#endif
- param->LWLockTranches = LWLockTranches;
param->MainLWLockArray = MainLWLockArray;
param->ProcGlobal = ProcGlobal;
param->AuxiliaryProcs = AuxiliaryProcs;
@@ -982,7 +980,6 @@ restore_backend_variables(BackendParameters *param)
ActiveInjectionPoints = param->ActiveInjectionPoints;
#endif
- LWLockTranches = param->LWLockTranches;
MainLWLockArray = param->MainLWLockArray;
ProcGlobal = param->ProcGlobal;
AuxiliaryProcs = param->AuxiliaryProcs;
diff --git a/src/backend/storage/ipc/ipci.c b/src/backend/storage/ipc/ipci.c
index 3d3f153809b..036db3fa514 100644
--- a/src/backend/storage/ipc/ipci.c
+++ b/src/backend/storage/ipc/ipci.c
@@ -249,10 +249,8 @@ CreateSharedMemoryAndSemaphores(void)
static void
CreateOrAttachShmemStructs(void)
{
- /*
- * Now initialize LWLocks, which do shared memory allocation.
- */
- CreateLWLocks();
+ /* Start with initializing LWLock tranches */
+ LWLockShmemInit();
dsm_shmem_init();
DSMRegistryShmemInit();
diff --git a/src/backend/storage/ipc/shmem.c b/src/backend/storage/ipc/shmem.c
index f392faa534f..339fbba3404 100644
--- a/src/backend/storage/ipc/shmem.c
+++ b/src/backend/storage/ipc/shmem.c
@@ -379,7 +379,8 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Assert(ShmemIndex != NULL);
- LWLockAcquire(ShmemIndexLock, LW_EXCLUSIVE);
+ if (IsUnderPostmaster)
+ LWLockAcquire(ShmemIndexLock, LW_EXCLUSIVE);
/* look it up in the shmem index */
result = (ShmemIndexEnt *)
@@ -387,7 +388,8 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
if (!result)
{
- LWLockRelease(ShmemIndexLock);
+ if (IsUnderPostmaster)
+ LWLockRelease(ShmemIndexLock);
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("could not create ShmemIndex entry for data structure \"%s\"",
@@ -403,7 +405,8 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
*/
if (result->size != size)
{
- LWLockRelease(ShmemIndexLock);
+ if (IsUnderPostmaster)
+ LWLockRelease(ShmemIndexLock);
ereport(ERROR,
(errmsg("ShmemIndex entry size is wrong for data structure"
" \"%s\": expected %zu, actual %zu",
@@ -421,7 +424,8 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
{
/* out of memory; remove the failed ShmemIndex entry */
hash_search(ShmemIndex, name, HASH_REMOVE, NULL);
- LWLockRelease(ShmemIndexLock);
+ if (IsUnderPostmaster)
+ LWLockRelease(ShmemIndexLock);
ereport(ERROR,
(errcode(ERRCODE_OUT_OF_MEMORY),
errmsg("not enough shared memory for data structure"
@@ -433,7 +437,8 @@ ShmemInitStruct(const char *name, Size size, bool *foundPtr)
result->location = structPtr;
}
- LWLockRelease(ShmemIndexLock);
+ if (IsUnderPostmaster)
+ LWLockRelease(ShmemIndexLock);
Assert(ShmemAddrIsValid(structPtr));
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index 4c01afce2f7..7bb005a5833 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -193,9 +193,12 @@ typedef struct LWLockTrancheShmemData
int num_user_defined; /* 'user_defined' entries in use */
slock_t lock; /* protects the above */
+
+ /* Size of MainLWLockArray */
+ int num_main_array_locks;
} LWLockTrancheShmemData;
-LWLockTrancheShmemData *LWLockTranches;
+static LWLockTrancheShmemData *LWLockTranches;
/* backend-local copy of NamedLWLockTranches->num_user_defined */
static int LocalNumUserDefinedTranches;
@@ -405,7 +408,8 @@ NumLWLocksForNamedTranches(void)
}
/*
- * Compute shmem space needed for LWLocks and named tranches.
+ * Compute shmem space needed for user-defined tranches and the main LWLock
+ * array.
*/
Size
LWLockShmemSize(void)
@@ -424,27 +428,36 @@ LWLockShmemSize(void)
}
/*
- * Allocate shmem space for the main LWLock array and all tranches and
- * initialize it.
+ * Allocate and initialize shmem for user-defined LWLock tranches and the main
+ * LWLock array.
*/
void
-CreateLWLocks(void)
+LWLockShmemInit(void)
{
int numLocks;
+ bool found;
- if (!IsUnderPostmaster)
+ LWLockTranches = (LWLockTrancheShmemData *)
+ ShmemInitStruct("LWLock tranches", sizeof(LWLockTrancheShmemData), &found);
+ if (!found)
{
- /* Allocate space for LWLockTranches */
- LWLockTranches = (LWLockTrancheShmemData *)
- ShmemAlloc(sizeof(LWLockTrancheShmemData));
+ /* Calculate total number of locks needed in the main array */
+ LWLockTranches->num_main_array_locks =
+ NUM_FIXED_LWLOCKS + NumLWLocksForNamedTranches();
/* Initialize the dynamic-allocation counter for tranches */
- SpinLockInit(&LWLockTranches->lock);
LWLockTranches->num_user_defined = 0;
- /* Allocate and initialize the main array */
- numLocks = NUM_FIXED_LWLOCKS + NumLWLocksForNamedTranches();
- MainLWLockArray = (LWLockPadded *) ShmemAlloc(numLocks * sizeof(LWLockPadded));
+ SpinLockInit(&LWLockTranches->lock);
+ }
+
+ /* 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);
}
}
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index 30557631eb8..61f0dbe749a 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -73,11 +73,6 @@ typedef union LWLockPadded
extern PGDLLIMPORT LWLockPadded *MainLWLockArray;
-/* forward declaration of private type for use only by lwlock.c */
-typedef struct LWLockTrancheShmemData LWLockTrancheShmemData;
-
-extern PGDLLIMPORT LWLockTrancheShmemData *LWLockTranches;
-
/*
* It's a bit odd to declare NUM_BUFFER_PARTITIONS and NUM_LOCK_PARTITIONS
* here, but we need them to figure out offsets within MainLWLockArray, and
@@ -132,7 +127,7 @@ extern bool LWLockWaitForVar(LWLock *lock, pg_atomic_uint64 *valptr, uint64 oldv
extern void LWLockUpdateVar(LWLock *lock, pg_atomic_uint64 *valptr, uint64 val);
extern Size LWLockShmemSize(void);
-extern void CreateLWLocks(void);
+extern void LWLockShmemInit(void);
extern void InitLWLockAccess(void);
extern const char *GetLWLockIdentifier(uint32 classId, uint16 eventId);
--
2.47.3