From: Heikki Linnakangas Date: Sun, 5 Apr 2026 23:12:57 +0000 (+0300) Subject: Convert lwlock.c to use the new shmem allocation functions X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a006bc7b1699d952afcb6d786343e8bf0ecc61d6;p=thirdparty%2Fpostgresql.git 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 Reviewed-by: Matthias van de Meent Reviewed-by: Daniel Gustafsson Discussion: https://www.postgresql.org/message-id/CAExHW5vM1bneLYfg0wGeAa=52UiJ3z4vKd3AJ72X8Fw6k3KKrg@mail.gmail.com --- diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index a2de96a9a8e..6f13e8f40a0 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -956,18 +956,22 @@ PostmasterMain(int argc, char *argv[]) */ InitializeFastPathLocks(); - /* - * 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. + * + * 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(); + /* * Now that loadable modules have had their chance to request additional * shared memory, determine the value of any runtime-computed GUCs that 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 98138cb09d1..b1ad396ba79 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" @@ -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. + * 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_t size; /* Space for user-defined tranches */ - size = sizeof(LWLockTrancheShmemData); + ShmemRequestStruct(.name = "LWLock tranches", + .size = sizeof(LWLockTrancheShmemData), + .ptr = (void **) &LWLockTranches, + ); /* 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) + if (!IsUnderPostmaster) { - /* 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); + num_main_array_locks = NUM_FIXED_LWLOCKS + NumLWLocksForNamedTranches(); + size = num_main_array_locks * sizeof(LWLockPadded); } + else + size = SHMEM_ATTACH_UNKNOWN_SIZE; - /* 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); - } + ShmemRequestStruct(.name = "Main LWLock array", + .size = size, + .ptr = (void **) &MainLWLockArray, + ); } /* - * Initialize LWLocks for built-in tranches and those requested with - * RequestNamedLWLockTranche(). + * Initialize shmem space for user-defined tranches and the main LWLock array. */ static void -InitializeLWLocks(int numLocks) +LWLockShmemInit(void *arg) { - int pos = 0; + 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); } /* diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 6a9ff3ad225..95496654714 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -4158,18 +4158,22 @@ PostgresSingleUserMain(int argc, char *argv[], /* Initialize size of fast-path lock cache. */ InitializeFastPathLocks(); - /* - * 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. + * + * 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(); + /* * Now that loadable modules have had their chance to request additional * shared memory, determine the value of any runtime-computed GUCs that 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 */