*/
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
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());
*/
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();
*/
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();
#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"
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;
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);
}
/*
- * 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++)
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);
}
/*
/* 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