From 14426e26138a58c827d0bf95ab42d39e0ab0da1e Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 21 Aug 2025 21:26:52 +0000 Subject: [PATCH v11 1/2] Improve LWLock tranche registration Previously, tranche tracking was done in a backend local array. If a backend did not explicitly register a tranche with LWLockRegisterTranche, querying pg_stat_activity would show "extension" instead of the tranche name. This change moves the NamedLWLockTrancheArray into a fixed size shared memory allocated from MainLWLockArray. Tranche creation is now centralized, and a user only needs to call LWLockNewTrancheId with a tranche name, and the tranche is stored in shared memory. Backends look up tranche IDs locally, syncing their cache from shared memory on a cache miss. A new LWLock protects NamedLWLockTrancheArray during reads and writes, ensuring consistency across backends. Discussion: https://www.postgresql.org/message-id/CAA5RZ0vvED3naph8My8Szv6DL4AxOVK3eTPS0qXsaKi%3DbVdW2A%40mail.gmail.com --- contrib/pg_prewarm/autoprewarm.c | 3 +- doc/src/sgml/xfunc.sgml | 18 +- src/backend/postmaster/launch_backend.c | 4 +- src/backend/storage/ipc/dsm_registry.c | 16 +- src/backend/storage/lmgr/lwlock.c | 208 +++++++++--------- .../utils/activity/wait_event_names.txt | 1 + src/include/storage/lwlock.h | 18 +- src/include/storage/lwlocklist.h | 1 + src/test/modules/test_dsa/test_dsa.c | 6 +- .../test_dsm_registry/test_dsm_registry.c | 3 +- .../modules/test_radixtree/test_radixtree.c | 9 +- src/test/modules/test_slru/test_slru.c | 6 +- .../modules/test_tidstore/test_tidstore.c | 3 +- 13 files changed, 133 insertions(+), 163 deletions(-) diff --git a/contrib/pg_prewarm/autoprewarm.c b/contrib/pg_prewarm/autoprewarm.c index c01b9c7e6a4..880e897796a 100644 --- a/contrib/pg_prewarm/autoprewarm.c +++ b/contrib/pg_prewarm/autoprewarm.c @@ -864,7 +864,7 @@ apw_init_state(void *ptr) { AutoPrewarmSharedState *state = (AutoPrewarmSharedState *) ptr; - LWLockInitialize(&state->lock, LWLockNewTrancheId()); + LWLockInitialize(&state->lock, LWLockNewTrancheId("autoprewarm")); state->bgworker_pid = InvalidPid; state->pid_using_dumpfile = InvalidPid; } @@ -883,7 +883,6 @@ apw_init_shmem(void) sizeof(AutoPrewarmSharedState), apw_init_state, &found); - LWLockRegisterTranche(apw_state->lock.tranche, "autoprewarm"); return found; } diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index f116d0648e5..20b0767f204 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -3757,9 +3757,10 @@ LWLockPadded *GetNamedLWLockTranche(const char *tranche_name) There is another, more flexible method of obtaining LWLocks that can be done after server startup and outside a shmem_request_hook. To do so, first allocate a - tranche_id by calling: + tranche_id with an associated tranche_name + by calling: -int LWLockNewTrancheId(void) +int LWLockNewTrancheId(const char *tranche_name) Next, initialize each LWLock, passing the new tranche_id as an argument: @@ -3777,17 +3778,8 @@ void LWLockInitialize(LWLock *lock, int tranche_id) - Finally, each backend using the tranche_id should - associate it with a tranche_name by calling: - -void LWLockRegisterTranche(int tranche_id, const char *tranche_name) - - - - - A complete usage example of LWLockNewTrancheId, - LWLockInitialize, and - LWLockRegisterTranche can be found in + A complete usage example of LWLockNewTrancheId and + LWLockInitialize can be found in contrib/pg_prewarm/autoprewarm.c in the PostgreSQL source tree. diff --git a/src/backend/postmaster/launch_backend.c b/src/backend/postmaster/launch_backend.c index bf6b55ee830..51832ed19fe 100644 --- a/src/backend/postmaster/launch_backend.c +++ b/src/backend/postmaster/launch_backend.c @@ -101,8 +101,8 @@ typedef struct struct InjectionPointsCtl *ActiveInjectionPoints; #endif int NamedLWLockTrancheRequests; - NamedLWLockTranche *NamedLWLockTrancheArray; LWLockPadded *MainLWLockArray; + const char *NamedLWLockTrancheArray; slock_t *ProcStructLock; PROC_HDR *ProcGlobal; PGPROC *AuxiliaryProcs; @@ -760,8 +760,8 @@ save_backend_variables(BackendParameters *param, #endif param->NamedLWLockTrancheRequests = NamedLWLockTrancheRequests; - param->NamedLWLockTrancheArray = NamedLWLockTrancheArray; param->MainLWLockArray = MainLWLockArray; + param->NamedLWLockTrancheArray = NamedLWLockTrancheArray; param->ProcStructLock = ProcStructLock; param->ProcGlobal = ProcGlobal; param->AuxiliaryProcs = AuxiliaryProcs; diff --git a/src/backend/storage/ipc/dsm_registry.c b/src/backend/storage/ipc/dsm_registry.c index 1682cc6d34c..8f9595e8730 100644 --- a/src/backend/storage/ipc/dsm_registry.c +++ b/src/backend/storage/ipc/dsm_registry.c @@ -307,9 +307,8 @@ GetNamedDSA(const char *name, bool *found) entry->type = DSMR_ENTRY_TYPE_DSA; /* Initialize the LWLock tranche for the DSA. */ - state->tranche = LWLockNewTrancheId(); + state->tranche = LWLockNewTrancheId(state->tranche_name); strcpy(state->tranche_name, name); - LWLockRegisterTranche(state->tranche, state->tranche_name); /* Initialize the DSA. */ ret = dsa_create(state->tranche); @@ -330,9 +329,6 @@ GetNamedDSA(const char *name, bool *found) ereport(ERROR, (errmsg("requested DSA already attached to current process"))); - /* Initialize existing LWLock tranche for the DSA. */ - LWLockRegisterTranche(state->tranche, state->tranche_name); - /* Attach to existing DSA. */ ret = dsa_attach(state->handle); dsa_pin_mapping(ret); @@ -389,14 +385,12 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found) entry->type = DSMR_ENTRY_TYPE_DSH; /* Initialize the LWLock tranche for the DSA. */ - dsa_state->tranche = LWLockNewTrancheId(); + dsa_state->tranche = LWLockNewTrancheId(dsa_state->tranche_name); sprintf(dsa_state->tranche_name, "%s%s", name, DSMR_DSA_TRANCHE_SUFFIX); - LWLockRegisterTranche(dsa_state->tranche, dsa_state->tranche_name); /* Initialize the LWLock tranche for the dshash table. */ - dsh_state->tranche = LWLockNewTrancheId(); + dsh_state->tranche = LWLockNewTrancheId(dsh_state->tranche_name); strcpy(dsh_state->tranche_name, name); - LWLockRegisterTranche(dsh_state->tranche, dsh_state->tranche_name); /* Initialize the DSA for the hash table. */ dsa = dsa_create(dsa_state->tranche); @@ -427,10 +421,6 @@ GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found) ereport(ERROR, (errmsg("requested DSHash already attached to current process"))); - /* Initialize existing LWLock tranches for the DSA and dshash table. */ - LWLockRegisterTranche(dsa_state->tranche, dsa_state->tranche_name); - LWLockRegisterTranche(dsh_state->tranche, dsh_state->tranche_name); - /* Attach to existing DSA for the hash table. */ dsa = dsa_attach(dsa_state->handle); dsa_pin_mapping(dsa); diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c index c80b43f1f55..717583d7237 100644 --- a/src/backend/storage/lmgr/lwlock.c +++ b/src/backend/storage/lmgr/lwlock.c @@ -105,6 +105,9 @@ #define LW_SHARED_MASK MAX_BACKENDS #define LW_LOCK_MASK (MAX_BACKENDS | LW_VAL_EXCLUSIVE) +#define MAX_NAMED_TRANCHES 1024 +#define MAX_NAMED_TRANCHES_NAME_LEN NAMEDATALEN + StaticAssertDecl(((MAX_BACKENDS + 1) & MAX_BACKENDS) == 0, "MAX_BACKENDS + 1 needs to be a power of 2"); @@ -125,9 +128,10 @@ StaticAssertDecl((LW_VAL_EXCLUSIVE & LW_FLAG_MASK) == 0, * 2. There are some predefined tranches for built-in groups of locks defined * in lwlocklist.h. We absorb the names of these tranches, too. * - * 3. Extensions can create new tranches, via either RequestNamedLWLockTranche - * or LWLockRegisterTranche. The names of these that are known in the current - * process appear in LWLockTrancheNames[]. + * 3. Extensions can create new tranches using either RequestNamedLWLockTranche + * or LWLockNewTrancheId. The names of these tranches are first stored in the + * shared NamedLWLockTrancheArray, and then cached locally in LWLockTrancheNames[] + * to avoid accessing shared memory on every lookup. * * All these names are user-visible as wait event names, so choose with care * ... and do not forget to update the documentation's list of wait events. @@ -146,11 +150,18 @@ StaticAssertDecl(lengthof(BuiltinTrancheNames) == /* * This is indexed by tranche ID minus LWTRANCHE_FIRST_USER_DEFINED, and - * stores the names of all dynamically-created tranches known to the current - * process. Any unused entries in the array will contain NULL. + * stores the names of all dynamically created tranches in shared memory. + * Any unused entries in the array will contain NULL. This variable is + * non-static so that postmaster.c can copy it to child processes in + * EXEC_BACKEND builds. + */ +const char *NamedLWLockTrancheArray = NULL; + +/* + * This is a local copy of NamedLWLockTrancheArray to avoid repeated access + * to shared memory when lookig up a tranche with GetLWTrancheName. */ static const char **LWLockTrancheNames = NULL; -static int LWLockTrancheNamesAllocated = 0; /* * This points to the main array of LWLocks in shared memory. Backends inherit @@ -179,12 +190,11 @@ static LWLockHandle held_lwlocks[MAX_SIMUL_LWLOCKS]; /* struct representing the LWLock tranche request for named tranche */ typedef struct NamedLWLockTrancheRequest { - char tranche_name[NAMEDATALEN]; + char tranche_name[MAX_NAMED_TRANCHES_NAME_LEN]; int num_lwlocks; } NamedLWLockTrancheRequest; static NamedLWLockTrancheRequest *NamedLWLockTrancheRequestArray = NULL; -static int NamedLWLockTrancheRequestsAllocated = 0; /* * NamedLWLockTrancheRequests is both the valid length of the request array, @@ -194,8 +204,6 @@ static int NamedLWLockTrancheRequestsAllocated = 0; */ int NamedLWLockTrancheRequests = 0; -/* points to data in shared memory: */ -NamedLWLockTranche *NamedLWLockTrancheArray = NULL; static void InitializeLWLocks(void); static inline void LWLockReportWaitStart(LWLock *lock); @@ -391,7 +399,6 @@ Size LWLockShmemSize(void) { Size size; - int i; int numLocks = NUM_FIXED_LWLOCKS; /* Calculate total number of locks needed in the main array. */ @@ -403,19 +410,18 @@ LWLockShmemSize(void) /* Space for dynamic allocation counter, plus room for alignment. */ size = add_size(size, sizeof(int) + LWLOCK_PADDED_SIZE); - /* space for named tranches. */ + /* Space for named tranches. */ size = add_size(size, mul_size(NamedLWLockTrancheRequests, sizeof(NamedLWLockTranche))); - /* space for name of each tranche. */ - for (i = 0; i < NamedLWLockTrancheRequests; i++) - size = add_size(size, strlen(NamedLWLockTrancheRequestArray[i].tranche_name) + 1); + /* Space for name of each tranche. */ + size = add_size(size, mul_size(MAX_NAMED_TRANCHES, MAX_NAMED_TRANCHES)); return size; } /* * Allocate shmem space for the main LWLock array and all tranches and - * initialize it. We also register extension LWLock tranches here. + * initialize it. */ void CreateLWLocks(void) @@ -447,11 +453,6 @@ CreateLWLocks(void) /* Initialize all LWLocks */ InitializeLWLocks(); } - - /* Register named extension LWLock tranches in the current process. */ - for (int i = 0; i < NamedLWLockTrancheRequests; i++) - LWLockRegisterTranche(NamedLWLockTrancheArray[i].trancheId, - NamedLWLockTrancheArray[i].trancheName); } /* @@ -485,38 +486,27 @@ InitializeLWLocks(void) for (id = 0; id < NUM_PREDICATELOCK_PARTITIONS; id++, lock++) LWLockInitialize(&lock->lock, LWTRANCHE_PREDICATE_LOCK_MANAGER); - /* - * Copy the info about any named tranches into shared memory (so that - * other processes can see it), and initialize the requested LWLocks. - */ + NamedLWLockTrancheArray = (const char *) + &MainLWLockArray[NUM_FIXED_LWLOCKS + numNamedLocks]; + + /* Register LWLocks requested with RequestNamedLWLockTranch */ if (NamedLWLockTrancheRequests > 0) { - char *trancheNames; - - NamedLWLockTrancheArray = (NamedLWLockTranche *) - &MainLWLockArray[NUM_FIXED_LWLOCKS + numNamedLocks]; - - trancheNames = (char *) NamedLWLockTrancheArray + - (NamedLWLockTrancheRequests * sizeof(NamedLWLockTranche)); lock = &MainLWLockArray[NUM_FIXED_LWLOCKS]; for (i = 0; i < NamedLWLockTrancheRequests; i++) { NamedLWLockTrancheRequest *request; - NamedLWLockTranche *tranche; - char *name; + int tranche_id; request = &NamedLWLockTrancheRequestArray[i]; - tranche = &NamedLWLockTrancheArray[i]; - name = trancheNames; - trancheNames += strlen(request->tranche_name) + 1; - strcpy(name, request->tranche_name); - tranche->trancheId = LWLockNewTrancheId(); - tranche->trancheName = name; + /* Allocate a new tranche ID */ + tranche_id = LWLockNewTrancheId(request->tranche_name); + /* Initialize the requested amount of LWLocks */ for (j = 0; j < request->num_lwlocks; j++, lock++) - LWLockInitialize(&lock->lock, tranche->trancheId); + LWLockInitialize(&lock->lock, tranche_id); } } } @@ -571,58 +561,44 @@ GetNamedLWLockTranche(const char *tranche_name) * Allocate a new tranche ID. */ int -LWLockNewTrancheId(void) +LWLockNewTrancheId(const char *tranche_name) { - int result; + int tranche_id; + int index; + Size tranche_name_length = strlen(tranche_name) + 1; int *LWLockCounter; + const char *slot; + + /* The supplied tranche name is too long */ + if (tranche_name_length > MAX_NAMED_TRANCHES_NAME_LEN) + elog(ERROR, "tranche name too long"); LWLockCounter = (int *) ((char *) MainLWLockArray - sizeof(int)); - /* We use the ShmemLock spinlock to protect LWLockCounter */ - SpinLockAcquire(ShmemLock); - result = (*LWLockCounter)++; - SpinLockRelease(ShmemLock); - return result; -} + LWLockAcquire(NamedLWLockTrancheArrayLock, LW_EXCLUSIVE); -/* - * Register a dynamic tranche name in the lookup table of the current process. - * - * This routine will save a pointer to the tranche name passed as an argument, - * so the name should be allocated in a backend-lifetime context - * (shared memory, TopMemoryContext, static constant, or similar). - * - * The tranche name will be user-visible as a wait event name, so try to - * use a name that fits the style for those. - */ -void -LWLockRegisterTranche(int tranche_id, const char *tranche_name) -{ - /* This should only be called for user-defined tranches. */ - if (tranche_id < LWTRANCHE_FIRST_USER_DEFINED) - return; + /* Get the next tranche ID while holding an Exclusive lock */ + tranche_id = (*LWLockCounter)++; - /* Convert to array index. */ - tranche_id -= LWTRANCHE_FIRST_USER_DEFINED; + /* Get the NamedLWLockTrancheArray index for the tranche ID */ + index = tranche_id - LWTRANCHE_FIRST_USER_DEFINED; - /* If necessary, create or enlarge array. */ - if (tranche_id >= LWLockTrancheNamesAllocated) + /* Extensions registered too many tranches */ + if (index > MAX_NAMED_TRANCHES) { - int newalloc; - - newalloc = pg_nextpower2_32(Max(8, tranche_id + 1)); + LWLockRelease(NamedLWLockTrancheArrayLock); - if (LWLockTrancheNames == NULL) - LWLockTrancheNames = (const char **) - MemoryContextAllocZero(TopMemoryContext, - newalloc * sizeof(char *)); - else - LWLockTrancheNames = - repalloc0_array(LWLockTrancheNames, const char *, LWLockTrancheNamesAllocated, newalloc); - LWLockTrancheNamesAllocated = newalloc; + elog(ERROR, "too many LWLock tranches registered"); } - LWLockTrancheNames[tranche_id] = tranche_name; + /* Get the index location from the NamedLWLockTrancheArray array */ + slot = NamedLWLockTrancheArray + (index * MAX_NAMED_TRANCHES_NAME_LEN); + + strcpy((char *) slot, tranche_name); + + LWLockRelease(NamedLWLockTrancheArrayLock); + + return tranche_id; } /* @@ -641,42 +617,41 @@ void RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks) { NamedLWLockTrancheRequest *request; + Size tranche_name_length = strlen(tranche_name) + 1; if (!process_shmem_requests_in_progress) elog(FATAL, "cannot request additional LWLocks outside shmem_request_hook"); + if (tranche_name_length > MAX_NAMED_TRANCHES_NAME_LEN) + elog(FATAL, "tranche name too long"); + if (NamedLWLockTrancheRequestArray == NULL) { - NamedLWLockTrancheRequestsAllocated = 16; NamedLWLockTrancheRequestArray = (NamedLWLockTrancheRequest *) MemoryContextAlloc(TopMemoryContext, - NamedLWLockTrancheRequestsAllocated + MAX_NAMED_TRANCHES * sizeof(NamedLWLockTrancheRequest)); } - if (NamedLWLockTrancheRequests >= NamedLWLockTrancheRequestsAllocated) - { - int i = pg_nextpower2_32(NamedLWLockTrancheRequests + 1); - - NamedLWLockTrancheRequestArray = (NamedLWLockTrancheRequest *) - repalloc(NamedLWLockTrancheRequestArray, - i * sizeof(NamedLWLockTrancheRequest)); - NamedLWLockTrancheRequestsAllocated = i; - } + if (NamedLWLockTrancheRequests >= MAX_NAMED_TRANCHES) + elog(FATAL, "too many dynamic LWLock tranches registered"); request = &NamedLWLockTrancheRequestArray[NamedLWLockTrancheRequests]; - Assert(strlen(tranche_name) + 1 <= NAMEDATALEN); - strlcpy(request->tranche_name, tranche_name, NAMEDATALEN); + strlcpy(request->tranche_name, tranche_name, tranche_name_length); request->num_lwlocks = num_lwlocks; NamedLWLockTrancheRequests++; } /* * LWLockInitialize - initialize a new lwlock; it's initially unlocked + * If the tranche was never registered, GetLWTrancheName will return + * and error. */ void LWLockInitialize(LWLock *lock, int tranche_id) { + GetLWTrancheName(tranche_id); + pg_atomic_init_u32(&lock->state, LW_FLAG_RELEASE_OK); #ifdef LOCK_DEBUG pg_atomic_init_u32(&lock->nwaiters, 0); @@ -713,22 +688,51 @@ LWLockReportWaitEnd(void) static const char * GetLWTrancheName(uint16 trancheId) { + int index = 0; + /* Built-in tranche or individual LWLock? */ if (trancheId < LWTRANCHE_FIRST_USER_DEFINED) return BuiltinTrancheNames[trancheId]; /* - * It's an extension tranche, so look in LWLockTrancheNames[]. However, - * it's possible that the tranche has never been registered in the current - * process, in which case give up and return "extension". + * This is an extension tranche. Look it up in LWLockTrancheNames[], and + * synchronize from NamedLWLockTrancheArray[] if necessary. If the tranche + * has never been registered by the extension, raise an error. + */ + index = trancheId - LWTRANCHE_FIRST_USER_DEFINED; + + /* + * Can't find the tranche in the local array, so we need to sync it from + * the shared array. */ - trancheId -= LWTRANCHE_FIRST_USER_DEFINED; + if (LWLockTrancheNames == NULL || LWLockTrancheNames[index] == NULL) + { + int *LWLockCounter; + + LWLockCounter = (int *) ((char *) MainLWLockArray - sizeof(int)); + + /* first time, let's initialize the local array */ + if (LWLockTrancheNames == NULL) + LWLockTrancheNames = (const char **) + MemoryContextAllocZero(TopMemoryContext, + MAX_NAMED_TRANCHES * sizeof(char *)); + + /* + * Sync the backend local array from the shared array. A shared lock + * is held on the shared array while syncing. + */ + LWLockAcquire(NamedLWLockTrancheArrayLock, LW_SHARED); + for (int i = 0; i < *LWLockCounter - LWTRANCHE_FIRST_USER_DEFINED; i++) + LWLockTrancheNames[i] = NamedLWLockTrancheArray + (i * MAX_NAMED_TRANCHES_NAME_LEN); + LWLockRelease(NamedLWLockTrancheArrayLock); + } - if (trancheId >= LWLockTrancheNamesAllocated || - LWLockTrancheNames[trancheId] == NULL) - return "extension"; + /* Still can't find the tranche, raise an error */ + if (!LWLockTrancheNames[index]) + elog(ERROR, "LWLock tranche is not registered"); - return LWLockTrancheNames[trancheId]; + /* We have a tranche name, return it */ + return LWLockTrancheNames[index]; } /* diff --git a/src/backend/utils/activity/wait_event_names.txt b/src/backend/utils/activity/wait_event_names.txt index 5427da5bc1b..2eed0a0682d 100644 --- a/src/backend/utils/activity/wait_event_names.txt +++ b/src/backend/utils/activity/wait_event_names.txt @@ -352,6 +352,7 @@ DSMRegistry "Waiting to read or update the dynamic shared memory registry." InjectionPoint "Waiting to read or update information related to injection points." SerialControl "Waiting to read or update shared pg_serial state." AioWorkerSubmissionQueue "Waiting to access AIO worker submission queue." +NamedLWLockTrancheArray "Waiting to access the named LWLock tranches array." # # END OF PREDEFINED LWLOCKS (DO NOT CHANGE THIS LINE) diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h index 5e717765764..1ba77cb3658 100644 --- a/src/include/storage/lwlock.h +++ b/src/include/storage/lwlock.h @@ -80,7 +80,7 @@ typedef struct NamedLWLockTranche char *trancheName; } NamedLWLockTranche; -extern PGDLLIMPORT NamedLWLockTranche *NamedLWLockTrancheArray; +extern PGDLLIMPORT const char *NamedLWLockTrancheArray; extern PGDLLIMPORT int NamedLWLockTrancheRequests; /* @@ -157,19 +157,11 @@ extern LWLockPadded *GetNamedLWLockTranche(const char *tranche_name); /* * There is another, more flexible method of obtaining lwlocks. First, call - * LWLockNewTrancheId just once to obtain a tranche ID; this allocates from - * a shared counter. Next, each individual process using the tranche should - * call LWLockRegisterTranche() to associate that tranche ID with a name. - * Finally, LWLockInitialize should be called just once per lwlock, passing - * the tranche ID as an argument. - * - * It may seem strange that each process using the tranche must register it - * separately, but dynamic shared memory segments aren't guaranteed to be - * mapped at the same address in all coordinating backends, so storing the - * registration in the main shared memory segment wouldn't work for that case. + * LWLockNewTrancheId with an associated tranche name just once to obtain a + * tranche ID; this allocates from a shared counter. Finally, LWLockInitialize + * should be called just once per lwlock, passing the tranche ID as an argument. */ -extern int LWLockNewTrancheId(void); -extern void LWLockRegisterTranche(int tranche_id, const char *tranche_name); +extern int LWLockNewTrancheId(const char *tranche_name); extern void LWLockInitialize(LWLock *lock, int tranche_id); /* diff --git a/src/include/storage/lwlocklist.h b/src/include/storage/lwlocklist.h index 06a1ffd4b08..0b00c5a4b3f 100644 --- a/src/include/storage/lwlocklist.h +++ b/src/include/storage/lwlocklist.h @@ -85,6 +85,7 @@ PG_LWLOCK(50, DSMRegistry) PG_LWLOCK(51, InjectionPoint) PG_LWLOCK(52, SerialControl) PG_LWLOCK(53, AioWorkerSubmissionQueue) +PG_LWLOCK(54, NamedLWLockTrancheArray) /* * There also exist several built-in LWLock tranches. As with the predefined diff --git a/src/test/modules/test_dsa/test_dsa.c b/src/test/modules/test_dsa/test_dsa.c index cd24d0f4873..01d5c6fa67f 100644 --- a/src/test/modules/test_dsa/test_dsa.c +++ b/src/test/modules/test_dsa/test_dsa.c @@ -29,8 +29,7 @@ test_dsa_basic(PG_FUNCTION_ARGS) dsa_pointer p[100]; /* XXX: this tranche is leaked */ - tranche_id = LWLockNewTrancheId(); - LWLockRegisterTranche(tranche_id, "test_dsa"); + tranche_id = LWLockNewTrancheId("test_dsa"); a = dsa_create(tranche_id); for (int i = 0; i < 100; i++) @@ -70,8 +69,7 @@ test_dsa_resowners(PG_FUNCTION_ARGS) ResourceOwner childowner; /* XXX: this tranche is leaked */ - tranche_id = LWLockNewTrancheId(); - LWLockRegisterTranche(tranche_id, "test_dsa"); + tranche_id = LWLockNewTrancheId("test_dsa"); /* Create DSA in parent resource owner */ a = dsa_create(tranche_id); diff --git a/src/test/modules/test_dsm_registry/test_dsm_registry.c b/src/test/modules/test_dsm_registry/test_dsm_registry.c index 141c8ed1b34..4cc2ccdac3f 100644 --- a/src/test/modules/test_dsm_registry/test_dsm_registry.c +++ b/src/test/modules/test_dsm_registry/test_dsm_registry.c @@ -48,7 +48,7 @@ init_tdr_dsm(void *ptr) { TestDSMRegistryStruct *dsm = (TestDSMRegistryStruct *) ptr; - LWLockInitialize(&dsm->lck, LWLockNewTrancheId()); + LWLockInitialize(&dsm->lck, LWLockNewTrancheId("test_dsm_registry")); dsm->val = 0; } @@ -61,7 +61,6 @@ tdr_attach_shmem(void) sizeof(TestDSMRegistryStruct), init_tdr_dsm, &found); - LWLockRegisterTranche(tdr_dsm->lck.tranche, "test_dsm_registry"); if (tdr_dsa == NULL) tdr_dsa = GetNamedDSA("test_dsm_registry_dsa", &found); diff --git a/src/test/modules/test_radixtree/test_radixtree.c b/src/test/modules/test_radixtree/test_radixtree.c index 80ad0296164..787162c8793 100644 --- a/src/test/modules/test_radixtree/test_radixtree.c +++ b/src/test/modules/test_radixtree/test_radixtree.c @@ -124,10 +124,9 @@ test_empty(void) rt_iter *iter; uint64 key; #ifdef TEST_SHARED_RT - int tranche_id = LWLockNewTrancheId(); + int tranche_id = LWLockNewTrancheId("test_radix_tree"); dsa_area *dsa; - LWLockRegisterTranche(tranche_id, "test_radix_tree"); dsa = dsa_create(tranche_id); radixtree = rt_create(dsa, tranche_id); #else @@ -167,10 +166,9 @@ test_basic(rt_node_class_test_elem *test_info, int shift, bool asc) uint64 *keys; int children = test_info->nkeys; #ifdef TEST_SHARED_RT - int tranche_id = LWLockNewTrancheId(); + int tranche_id = LWLockNewTrancheId("test_radix_tree"); dsa_area *dsa; - LWLockRegisterTranche(tranche_id, "test_radix_tree"); dsa = dsa_create(tranche_id); radixtree = rt_create(dsa, tranche_id); #else @@ -304,10 +302,9 @@ test_random(void) int num_keys = 100000; uint64 *keys; #ifdef TEST_SHARED_RT - int tranche_id = LWLockNewTrancheId(); + int tranche_id = LWLockNewTrancheId("test_radix_tree"); dsa_area *dsa; - LWLockRegisterTranche(tranche_id, "test_radix_tree"); dsa = dsa_create(tranche_id); radixtree = rt_create(dsa, tranche_id); #else diff --git a/src/test/modules/test_slru/test_slru.c b/src/test/modules/test_slru/test_slru.c index 32750930e43..8c0367eeee4 100644 --- a/src/test/modules/test_slru/test_slru.c +++ b/src/test/modules/test_slru/test_slru.c @@ -232,11 +232,9 @@ test_slru_shmem_startup(void) (void) MakePGDirectory(slru_dir_name); /* initialize the SLRU facility */ - test_tranche_id = LWLockNewTrancheId(); - LWLockRegisterTranche(test_tranche_id, "test_slru_tranche"); + test_tranche_id = LWLockNewTrancheId("test_slru_tranche"); - test_buffer_tranche_id = LWLockNewTrancheId(); - LWLockRegisterTranche(test_tranche_id, "test_buffer_tranche"); + test_buffer_tranche_id = LWLockNewTrancheId("test_buffer_tranche"); TestSlruCtl->PagePrecedes = test_slru_page_precedes_logically; SimpleLruInit(TestSlruCtl, "TestSLRU", diff --git a/src/test/modules/test_tidstore/test_tidstore.c b/src/test/modules/test_tidstore/test_tidstore.c index eb16e0fbfa6..0c8f43867e5 100644 --- a/src/test/modules/test_tidstore/test_tidstore.c +++ b/src/test/modules/test_tidstore/test_tidstore.c @@ -103,8 +103,7 @@ test_create(PG_FUNCTION_ARGS) { int tranche_id; - tranche_id = LWLockNewTrancheId(); - LWLockRegisterTranche(tranche_id, "test_tidstore"); + tranche_id = LWLockNewTrancheId("test_tidstore"); tidstore = TidStoreCreateShared(tidstore_max_size, tranche_id); -- 2.39.5 (Apple Git-154)