]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Convert lwlock.c to use the new shmem allocation functions
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Sun, 5 Apr 2026 23:12:57 +0000 (02:12 +0300)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Sun, 5 Apr 2026 23:12:57 +0000 (02:12 +0300)
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

src/backend/postmaster/postmaster.c
src/backend/storage/ipc/ipci.c
src/backend/storage/lmgr/lwlock.c
src/backend/tcop/postgres.c
src/include/storage/lwlock.h
src/include/storage/subsystemlist.h

index a2de96a9a8eae97ed5f5bf597cde2d90c651149b..6f13e8f40a0be00802001e618acc20ddab1d95d9 100644 (file)
@@ -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
index e4a6a52f12db7d096e035862812cdd952b50d972..de65a9ef33c6c6c3d3891560ff5be320ee529276 100644 (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();
 
index 98138cb09d10af52b5203c88eea05e74bff35014..b1ad396ba79878911ee7de39fe344d0ff41ec33a 100644 (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.
+ * 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);
 }
 
 /*
index 6a9ff3ad225dcbd477ea814780434decdaf69452..95496654714d78631cf0a7d209c9c00fd5112a5f 100644 (file)
@@ -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
index 61f0dbe749ae8478adf71a80f78db06bd0c7439f..efa5b427e9f22128c92740a056d2888e8a706095 100644 (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);
index ed43c90bcc3686a30c09007b6b79a14d87fab11a..f0cf01f5a8510f344848a9dbfcf8d7bc9cb90a00 100644 (file)
  * 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 */