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.

Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
Discussion: https://www.postgresql.org/message-id/47aaf57e-1b7b-4e12-bda2-0316081ff50e@iki.fi
This commit is contained in:
Heikki Linnakangas 2026-03-26 23:47:37 +02:00
parent 06d859aaf4
commit 30d432502b
4 changed files with 25 additions and 24 deletions

View file

@ -99,8 +99,6 @@ typedef struct
#ifdef USE_INJECTION_POINTS
struct InjectionPointsCtl *ActiveInjectionPoints;
#endif
LWLockTrancheShmemData *LWLockTranches;
LWLockPadded *MainLWLockArray;
PROC_HDR *ProcGlobal;
PGPROC *AuxiliaryProcs;
PGPROC *PreparedXactProcs;
@ -726,8 +724,6 @@ save_backend_variables(BackendParameters *param,
param->ActiveInjectionPoints = ActiveInjectionPoints;
#endif
param->LWLockTranches = LWLockTranches;
param->MainLWLockArray = MainLWLockArray;
param->ProcGlobal = ProcGlobal;
param->AuxiliaryProcs = AuxiliaryProcs;
param->PreparedXactProcs = PreparedXactProcs;
@ -982,8 +978,6 @@ restore_backend_variables(BackendParameters *param)
ActiveInjectionPoints = param->ActiveInjectionPoints;
#endif
LWLockTranches = param->LWLockTranches;
MainLWLockArray = param->MainLWLockArray;
ProcGlobal = param->ProcGlobal;
AuxiliaryProcs = param->AuxiliaryProcs;
PreparedXactProcs = param->PreparedXactProcs;

View file

@ -250,9 +250,9 @@ static void
CreateOrAttachShmemStructs(void)
{
/*
* Now initialize LWLocks, which do shared memory allocation.
* Set up LWLocks. They are needed by most other subsystems.
*/
CreateLWLocks();
LWLockShmemInit();
dsm_shmem_init();
DSMRegistryShmemInit();

View file

@ -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;
@ -426,23 +429,32 @@ LWLockShmemSize(void)
* and initialize it.
*/
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);
}
}

View file

@ -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);