Convert lwlock.c to use the new shmem allocation functions

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.

Reviewed-by: Ashutosh Bapat <ashutosh.bapat.oss@gmail.com>
Reviewed-by: Matthias van de Meent <boekewurm+postgres@gmail.com>
Reviewed-by: Daniel Gustafsson <daniel@yesql.se>
Discussion: https://www.postgresql.org/message-id/CAExHW5vM1bneLYfg0wGeAa=52UiJ3z4vKd3AJ72X8Fw6k3KKrg@mail.gmail.com
This commit is contained in:
Heikki Linnakangas 2026-04-06 02:12:57 +03:00
parent 1fc2e9fbc0
commit a006bc7b16
6 changed files with 87 additions and 93 deletions

View file

@ -956,18 +956,22 @@ PostmasterMain(int argc, char *argv[])
*/
InitializeFastPathLocks();
/*
* Also call any legacy shmem request hooks that might've been installed
* by preloaded libraries.
*
* Note: this must be done before ShmemCallRequestCallbacks(), because the
* hooks may request LWLocks with RequestNamedLWLockTranche(), which in
* turn affects the size of the LWLock array calculated in lwlock.c.
*/
process_shmem_requests();
/*
* Ask all subsystems, including preloaded libraries, to register their
* shared memory needs.
*/
ShmemCallRequestCallbacks();
/*
* Also call any legacy shmem request hooks that might've been installed
* by preloaded libraries.
*/
process_shmem_requests();
/*
* Now that loadable modules have had their chance to request additional
* shared memory, determine the value of any runtime-computed GUCs that

View file

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

View file

@ -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"
@ -189,9 +190,6 @@ 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;
static LWLockTrancheShmemData *LWLockTranches;
@ -212,7 +210,18 @@ typedef struct NamedLWLockTrancheRequest
static List *NamedLWLockTrancheRequests = NIL;
static void InitializeLWLocks(int numLocks);
/* Size of MainLWLockArray. Only valid in postmaster. */
static int num_main_array_locks;
static void LWLockShmemRequest(void *arg);
static void LWLockShmemInit(void *arg);
const ShmemCallbacks LWLockCallbacks = {
.request_fn = LWLockShmemRequest,
.init_fn = LWLockShmemInit,
};
static inline void LWLockReportWaitStart(LWLock *lock);
static inline void LWLockReportWaitEnd(void);
static const char *GetLWTrancheName(uint16 trancheId);
@ -401,68 +410,53 @@ NumLWLocksForNamedTranches(void)
}
/*
* Compute shmem space needed for user-defined tranches and the main LWLock
* array.
*/
Size
LWLockShmemSize(void)
{
Size size;
int numLocks;
/* 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)));
return size;
}
/*
* Allocate shmem space for user-defined tranches and the main LWLock array,
* and initialize it.
*/
void
LWLockShmemInit(void)
{
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();
/* Initialize the dynamic-allocation counter for tranches */
LWLockTranches->num_user_defined = 0;
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);
}
}
/*
* Initialize LWLocks for built-in tranches and those requested with
* RequestNamedLWLockTranche().
* Request shmem space for user-defined tranches and the main LWLock array.
*/
static void
InitializeLWLocks(int numLocks)
LWLockShmemRequest(void *arg)
{
int pos = 0;
size_t size;
/* Space for user-defined tranches */
ShmemRequestStruct(.name = "LWLock tranches",
.size = sizeof(LWLockTrancheShmemData),
.ptr = (void **) &LWLockTranches,
);
/* Space for the LWLock array */
if (!IsUnderPostmaster)
{
num_main_array_locks = NUM_FIXED_LWLOCKS + NumLWLocksForNamedTranches();
size = num_main_array_locks * sizeof(LWLockPadded);
}
else
size = SHMEM_ATTACH_UNKNOWN_SIZE;
ShmemRequestStruct(.name = "Main LWLock array",
.size = size,
.ptr = (void **) &MainLWLockArray,
);
}
/*
* Initialize shmem space for user-defined tranches and the main LWLock array.
*/
static void
LWLockShmemInit(void *arg)
{
int pos;
/* Initialize the dynamic-allocation counter for tranches */
LWLockTranches->num_user_defined = 0;
SpinLockInit(&LWLockTranches->lock);
/*
* Allocate and initialize all LWLocks in the main array. It includes all
* LWLocks for built-in tranches and those requested with
* RequestNamedLWLockTranche().
*/
pos = 0;
/* Initialize all individual LWLocks in main array */
for (int id = 0; id < NUM_INDIVIDUAL_LWLOCKS; id++)
@ -501,8 +495,8 @@ InitializeLWLocks(int numLocks)
LWLockInitialize(&MainLWLockArray[pos++].lock, LWTRANCHE_FIRST_USER_DEFINED + idx);
}
/* Cross-check that we agree on the total size with the caller */
Assert(pos == numLocks);
/* Cross-check that we agree on the total size with LWLockShmemRequest() */
Assert(pos == num_main_array_locks);
}
/*

View file

@ -4158,18 +4158,22 @@ PostgresSingleUserMain(int argc, char *argv[],
/* Initialize size of fast-path lock cache. */
InitializeFastPathLocks();
/*
* Also call any legacy shmem request hooks that might'be been installed
* by preloaded libraries.
*
* Note: this must be done before ShmemCallRequestCallbacks(), because the
* hooks may request LWLocks with RequestNamedLWLockTranche(), which in
* turn affects the size of the LWLock array calculated in lwlock.c.
*/
process_shmem_requests();
/*
* Before computing the total size needed, give all subsystems, including
* add-ins, a chance to chance to adjust their requested shmem sizes.
*/
ShmemCallRequestCallbacks();
/*
* Also call any legacy shmem request hooks that might'be been installed
* by preloaded libraries.
*/
process_shmem_requests();
/*
* Now that loadable modules have had their chance to request additional
* shared memory, determine the value of any runtime-computed GUCs that

View file

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

View file

@ -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 */