Collect built-in LWLock tranche names statically, not dynamically.
There is little point in using the LWLockRegisterTranche mechanism for built-in tranche names. It wastes cycles, it creates opportunities for bugs (since failing to register a tranche name is a very hard-to-detect problem), and the lack of any centralized list of names encourages sloppy nonconformity in name choices. Moreover, since we have a centralized list of the tranches anyway in enum BuiltinTrancheIds, we're certainly not buying any flexibility in return for these disadvantages. Hence, nuke all the backend-internal LWLockRegisterTranche calls, and instead provide a const array of the builtin tranche names. (I have in mind to change a bunch of these names shortly, but this patch is just about getting them into one place.) Discussion: https://postgr.es/m/9056.1589419765@sss.pgh.pa.us
This commit is contained in:
parent
07451e1f1a
commit
29c3e2dd5a
@ -235,9 +235,6 @@ SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns,
|
|||||||
else
|
else
|
||||||
Assert(found);
|
Assert(found);
|
||||||
|
|
||||||
/* Register SLRU tranche in the main tranches array */
|
|
||||||
LWLockRegisterTranche(tranche_id, name);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the unshared control struct, including directory path. We
|
* Initialize the unshared control struct, including directory path. We
|
||||||
* assume caller set PagePrecedes.
|
* assume caller set PagePrecedes.
|
||||||
|
@ -5116,10 +5116,8 @@ XLOGShmemInit(void)
|
|||||||
/* both should be present or neither */
|
/* both should be present or neither */
|
||||||
Assert(foundCFile && foundXLog);
|
Assert(foundCFile && foundXLog);
|
||||||
|
|
||||||
/* Initialize local copy of WALInsertLocks and register the tranche */
|
/* Initialize local copy of WALInsertLocks */
|
||||||
WALInsertLocks = XLogCtl->Insert.WALInsertLocks;
|
WALInsertLocks = XLogCtl->Insert.WALInsertLocks;
|
||||||
LWLockRegisterTranche(LWTRANCHE_WAL_INSERT,
|
|
||||||
"wal_insert");
|
|
||||||
|
|
||||||
if (localControlFile)
|
if (localControlFile)
|
||||||
pfree(localControlFile);
|
pfree(localControlFile);
|
||||||
@ -5155,7 +5153,6 @@ XLOGShmemInit(void)
|
|||||||
(WALInsertLockPadded *) allocptr;
|
(WALInsertLockPadded *) allocptr;
|
||||||
allocptr += sizeof(WALInsertLockPadded) * NUM_XLOGINSERT_LOCKS;
|
allocptr += sizeof(WALInsertLockPadded) * NUM_XLOGINSERT_LOCKS;
|
||||||
|
|
||||||
LWLockRegisterTranche(LWTRANCHE_WAL_INSERT, "wal_insert");
|
|
||||||
for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
|
for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
|
||||||
{
|
{
|
||||||
LWLockInitialize(&WALInsertLocks[i].l.lock, LWTRANCHE_WAL_INSERT);
|
LWLockInitialize(&WALInsertLocks[i].l.lock, LWTRANCHE_WAL_INSERT);
|
||||||
|
@ -517,9 +517,6 @@ ReplicationOriginShmemInit(void)
|
|||||||
ConditionVariableInit(&replication_states[i].origin_cv);
|
ConditionVariableInit(&replication_states[i].origin_cv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LWLockRegisterTranche(replication_states_ctl->tranche_id,
|
|
||||||
"replication_origin");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------------
|
/* ---------------------------------------------------------------------------
|
||||||
|
@ -140,9 +140,6 @@ ReplicationSlotsShmemInit(void)
|
|||||||
ShmemInitStruct("ReplicationSlot Ctl", ReplicationSlotsShmemSize(),
|
ShmemInitStruct("ReplicationSlot Ctl", ReplicationSlotsShmemSize(),
|
||||||
&found);
|
&found);
|
||||||
|
|
||||||
LWLockRegisterTranche(LWTRANCHE_REPLICATION_SLOT_IO_IN_PROGRESS,
|
|
||||||
"replication_slot_io");
|
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -87,9 +87,6 @@ InitBufferPool(void)
|
|||||||
NBuffers * (Size) sizeof(LWLockMinimallyPadded),
|
NBuffers * (Size) sizeof(LWLockMinimallyPadded),
|
||||||
&foundIOLocks);
|
&foundIOLocks);
|
||||||
|
|
||||||
LWLockRegisterTranche(LWTRANCHE_BUFFER_IO_IN_PROGRESS, "buffer_io");
|
|
||||||
LWLockRegisterTranche(LWTRANCHE_BUFFER_CONTENT, "buffer_content");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The array used to sort to-be-checkpointed buffer ids is located in
|
* The array used to sort to-be-checkpointed buffer ids is located in
|
||||||
* shared memory, to avoid having to allocate significant amounts of
|
* shared memory, to avoid having to allocate significant amounts of
|
||||||
|
@ -267,8 +267,6 @@ CreateSharedProcArray(void)
|
|||||||
mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS),
|
mul_size(sizeof(bool), TOTAL_MAX_CACHED_SUBXIDS),
|
||||||
&found);
|
&found);
|
||||||
}
|
}
|
||||||
|
|
||||||
LWLockRegisterTranche(LWTRANCHE_PROC, "proc");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -108,14 +108,85 @@ extern slock_t *ShmemLock;
|
|||||||
#define LW_SHARED_MASK ((uint32) ((1 << 24)-1))
|
#define LW_SHARED_MASK ((uint32) ((1 << 24)-1))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is indexed by tranche ID and stores the names of all tranches known
|
* There are three sorts of LWLock "tranches":
|
||||||
* to the current backend.
|
*
|
||||||
|
* 1. The individually-named locks defined in lwlocknames.h each have their
|
||||||
|
* own tranche. The names of these tranches appear in MainLWLockNames[]
|
||||||
|
* in lwlocknames.c.
|
||||||
|
*
|
||||||
|
* 2. There are some predefined tranches for built-in groups of locks.
|
||||||
|
* These are listed in enum BuiltinTrancheIds in lwlock.h, and their names
|
||||||
|
* appear in BuiltinTrancheNames[] below.
|
||||||
|
*
|
||||||
|
* 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[].
|
||||||
*/
|
*/
|
||||||
static const char **LWLockTrancheArray = NULL;
|
|
||||||
static int LWLockTranchesAllocated = 0;
|
|
||||||
|
|
||||||
#define T_NAME(lock) \
|
static const char *const BuiltinTrancheNames[] = {
|
||||||
(LWLockTrancheArray[(lock)->tranche])
|
/* LWTRANCHE_CLOG_BUFFERS: */
|
||||||
|
"clog",
|
||||||
|
/* LWTRANCHE_COMMITTS_BUFFERS: */
|
||||||
|
"commit_timestamp",
|
||||||
|
/* LWTRANCHE_SUBTRANS_BUFFERS: */
|
||||||
|
"subtrans",
|
||||||
|
/* LWTRANCHE_MXACTOFFSET_BUFFERS: */
|
||||||
|
"multixact_offset",
|
||||||
|
/* LWTRANCHE_MXACTMEMBER_BUFFERS: */
|
||||||
|
"multixact_member",
|
||||||
|
/* LWTRANCHE_ASYNC_BUFFERS: */
|
||||||
|
"async",
|
||||||
|
/* LWTRANCHE_OLDSERXID_BUFFERS: */
|
||||||
|
"oldserxid",
|
||||||
|
/* LWTRANCHE_WAL_INSERT: */
|
||||||
|
"wal_insert",
|
||||||
|
/* LWTRANCHE_BUFFER_CONTENT: */
|
||||||
|
"buffer_content",
|
||||||
|
/* LWTRANCHE_BUFFER_IO_IN_PROGRESS: */
|
||||||
|
"buffer_io",
|
||||||
|
/* LWTRANCHE_REPLICATION_ORIGIN: */
|
||||||
|
"replication_origin",
|
||||||
|
/* LWTRANCHE_REPLICATION_SLOT_IO_IN_PROGRESS: */
|
||||||
|
"replication_slot_io",
|
||||||
|
/* LWTRANCHE_PROC: */
|
||||||
|
"proc",
|
||||||
|
/* LWTRANCHE_BUFFER_MAPPING: */
|
||||||
|
"buffer_mapping",
|
||||||
|
/* LWTRANCHE_LOCK_MANAGER: */
|
||||||
|
"lock_manager",
|
||||||
|
/* LWTRANCHE_PREDICATE_LOCK_MANAGER: */
|
||||||
|
"predicate_lock_manager",
|
||||||
|
/* LWTRANCHE_PARALLEL_HASH_JOIN: */
|
||||||
|
"parallel_hash_join",
|
||||||
|
/* LWTRANCHE_PARALLEL_QUERY_DSA: */
|
||||||
|
"parallel_query_dsa",
|
||||||
|
/* LWTRANCHE_SESSION_DSA: */
|
||||||
|
"session_dsa",
|
||||||
|
/* LWTRANCHE_SESSION_RECORD_TABLE: */
|
||||||
|
"session_record_table",
|
||||||
|
/* LWTRANCHE_SESSION_TYPMOD_TABLE: */
|
||||||
|
"session_typmod_table",
|
||||||
|
/* LWTRANCHE_SHARED_TUPLESTORE: */
|
||||||
|
"shared_tuplestore",
|
||||||
|
/* LWTRANCHE_TBM: */
|
||||||
|
"tbm",
|
||||||
|
/* LWTRANCHE_PARALLEL_APPEND: */
|
||||||
|
"parallel_append",
|
||||||
|
/* LWTRANCHE_SXACT: */
|
||||||
|
"serializable_xact"
|
||||||
|
};
|
||||||
|
|
||||||
|
StaticAssertDecl(lengthof(BuiltinTrancheNames) ==
|
||||||
|
LWTRANCHE_FIRST_USER_DEFINED - NUM_INDIVIDUAL_LWLOCKS,
|
||||||
|
"missing entries in 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.
|
||||||
|
*/
|
||||||
|
static const char **LWLockTrancheNames = NULL;
|
||||||
|
static int LWLockTrancheNamesAllocated = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This points to the main array of LWLocks in shared memory. Backends inherit
|
* This points to the main array of LWLocks in shared memory. Backends inherit
|
||||||
@ -149,19 +220,29 @@ typedef struct NamedLWLockTrancheRequest
|
|||||||
int num_lwlocks;
|
int num_lwlocks;
|
||||||
} NamedLWLockTrancheRequest;
|
} NamedLWLockTrancheRequest;
|
||||||
|
|
||||||
NamedLWLockTrancheRequest *NamedLWLockTrancheRequestArray = NULL;
|
static NamedLWLockTrancheRequest *NamedLWLockTrancheRequestArray = NULL;
|
||||||
static int NamedLWLockTrancheRequestsAllocated = 0;
|
static int NamedLWLockTrancheRequestsAllocated = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NamedLWLockTrancheRequests is both the valid length of the request array,
|
||||||
|
* and the length of the shared-memory NamedLWLockTrancheArray later on.
|
||||||
|
* This variable and NamedLWLockTrancheArray are non-static so that
|
||||||
|
* postmaster.c can copy them to child processes in EXEC_BACKEND builds.
|
||||||
|
*/
|
||||||
int NamedLWLockTrancheRequests = 0;
|
int NamedLWLockTrancheRequests = 0;
|
||||||
|
|
||||||
|
/* points to data in shared memory: */
|
||||||
NamedLWLockTranche *NamedLWLockTrancheArray = NULL;
|
NamedLWLockTranche *NamedLWLockTrancheArray = NULL;
|
||||||
|
|
||||||
static bool lock_named_request_allowed = true;
|
static bool lock_named_request_allowed = true;
|
||||||
|
|
||||||
static void InitializeLWLocks(void);
|
static void InitializeLWLocks(void);
|
||||||
static void RegisterLWLockTranches(void);
|
|
||||||
|
|
||||||
static inline void LWLockReportWaitStart(LWLock *lock);
|
static inline void LWLockReportWaitStart(LWLock *lock);
|
||||||
static inline void LWLockReportWaitEnd(void);
|
static inline void LWLockReportWaitEnd(void);
|
||||||
|
static const char *GetLWTrancheName(uint16 trancheId);
|
||||||
|
|
||||||
|
#define T_NAME(lock) \
|
||||||
|
GetLWTrancheName((lock)->tranche)
|
||||||
|
|
||||||
#ifdef LWLOCK_STATS
|
#ifdef LWLOCK_STATS
|
||||||
typedef struct lwlock_stats_key
|
typedef struct lwlock_stats_key
|
||||||
@ -285,7 +366,7 @@ print_lwlock_stats(int code, Datum arg)
|
|||||||
{
|
{
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"PID %d lwlock %s %p: shacq %u exacq %u blk %u spindelay %u dequeue self %u\n",
|
"PID %d lwlock %s %p: shacq %u exacq %u blk %u spindelay %u dequeue self %u\n",
|
||||||
MyProcPid, LWLockTrancheArray[lwstats->key.tranche],
|
MyProcPid, GetLWTrancheName(lwstats->key.tranche),
|
||||||
lwstats->key.instance, lwstats->sh_acquire_count,
|
lwstats->key.instance, lwstats->sh_acquire_count,
|
||||||
lwstats->ex_acquire_count, lwstats->block_count,
|
lwstats->ex_acquire_count, lwstats->block_count,
|
||||||
lwstats->spin_delay_count, lwstats->dequeue_self_count);
|
lwstats->spin_delay_count, lwstats->dequeue_self_count);
|
||||||
@ -332,7 +413,7 @@ get_lwlock_stats_entry(LWLock *lock)
|
|||||||
* allocated in the main array.
|
* allocated in the main array.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
NumLWLocksByNamedTranches(void)
|
NumLWLocksForNamedTranches(void)
|
||||||
{
|
{
|
||||||
int numLocks = 0;
|
int numLocks = 0;
|
||||||
int i;
|
int i;
|
||||||
@ -353,7 +434,8 @@ LWLockShmemSize(void)
|
|||||||
int i;
|
int i;
|
||||||
int numLocks = NUM_FIXED_LWLOCKS;
|
int numLocks = NUM_FIXED_LWLOCKS;
|
||||||
|
|
||||||
numLocks += NumLWLocksByNamedTranches();
|
/* Calculate total number of locks needed in the main array. */
|
||||||
|
numLocks += NumLWLocksForNamedTranches();
|
||||||
|
|
||||||
/* Space for the LWLock array. */
|
/* Space for the LWLock array. */
|
||||||
size = mul_size(numLocks, sizeof(LWLockPadded));
|
size = mul_size(numLocks, sizeof(LWLockPadded));
|
||||||
@ -368,7 +450,7 @@ LWLockShmemSize(void)
|
|||||||
for (i = 0; i < NamedLWLockTrancheRequests; i++)
|
for (i = 0; i < NamedLWLockTrancheRequests; i++)
|
||||||
size = add_size(size, strlen(NamedLWLockTrancheRequestArray[i].tranche_name) + 1);
|
size = add_size(size, strlen(NamedLWLockTrancheRequestArray[i].tranche_name) + 1);
|
||||||
|
|
||||||
/* Disallow named LWLocks' requests after startup */
|
/* Disallow adding any more named tranches. */
|
||||||
lock_named_request_allowed = false;
|
lock_named_request_allowed = false;
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
@ -376,7 +458,7 @@ LWLockShmemSize(void)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate shmem space for the main LWLock array and all tranches and
|
* Allocate shmem space for the main LWLock array and all tranches and
|
||||||
* initialize it. We also register all the LWLock tranches here.
|
* initialize it. We also register extension LWLock tranches here.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
CreateLWLocks(void)
|
CreateLWLocks(void)
|
||||||
@ -416,8 +498,10 @@ CreateLWLocks(void)
|
|||||||
InitializeLWLocks();
|
InitializeLWLocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register all LWLock tranches */
|
/* Register named extension LWLock tranches in the current process. */
|
||||||
RegisterLWLockTranches();
|
for (int i = 0; i < NamedLWLockTrancheRequests; i++)
|
||||||
|
LWLockRegisterTranche(NamedLWLockTrancheArray[i].trancheId,
|
||||||
|
NamedLWLockTrancheArray[i].trancheName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -426,7 +510,7 @@ CreateLWLocks(void)
|
|||||||
static void
|
static void
|
||||||
InitializeLWLocks(void)
|
InitializeLWLocks(void)
|
||||||
{
|
{
|
||||||
int numNamedLocks = NumLWLocksByNamedTranches();
|
int numNamedLocks = NumLWLocksForNamedTranches();
|
||||||
int id;
|
int id;
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
@ -452,7 +536,10 @@ InitializeLWLocks(void)
|
|||||||
for (id = 0; id < NUM_PREDICATELOCK_PARTITIONS; id++, lock++)
|
for (id = 0; id < NUM_PREDICATELOCK_PARTITIONS; id++, lock++)
|
||||||
LWLockInitialize(&lock->lock, LWTRANCHE_PREDICATE_LOCK_MANAGER);
|
LWLockInitialize(&lock->lock, LWTRANCHE_PREDICATE_LOCK_MANAGER);
|
||||||
|
|
||||||
/* Initialize named tranches. */
|
/*
|
||||||
|
* Copy the info about any named tranches into shared memory (so that
|
||||||
|
* other processes can see it), and initialize the requested LWLocks.
|
||||||
|
*/
|
||||||
if (NamedLWLockTrancheRequests > 0)
|
if (NamedLWLockTrancheRequests > 0)
|
||||||
{
|
{
|
||||||
char *trancheNames;
|
char *trancheNames;
|
||||||
@ -485,51 +572,6 @@ InitializeLWLocks(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Register named tranches and tranches for fixed LWLocks.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
RegisterLWLockTranches(void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (LWLockTrancheArray == NULL)
|
|
||||||
{
|
|
||||||
LWLockTranchesAllocated = 128;
|
|
||||||
LWLockTrancheArray = (const char **)
|
|
||||||
MemoryContextAllocZero(TopMemoryContext,
|
|
||||||
LWLockTranchesAllocated * sizeof(char *));
|
|
||||||
Assert(LWLockTranchesAllocated >= LWTRANCHE_FIRST_USER_DEFINED);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < NUM_INDIVIDUAL_LWLOCKS; ++i)
|
|
||||||
LWLockRegisterTranche(i, MainLWLockNames[i]);
|
|
||||||
|
|
||||||
LWLockRegisterTranche(LWTRANCHE_BUFFER_MAPPING, "buffer_mapping");
|
|
||||||
LWLockRegisterTranche(LWTRANCHE_LOCK_MANAGER, "lock_manager");
|
|
||||||
LWLockRegisterTranche(LWTRANCHE_PREDICATE_LOCK_MANAGER,
|
|
||||||
"predicate_lock_manager");
|
|
||||||
LWLockRegisterTranche(LWTRANCHE_PARALLEL_QUERY_DSA,
|
|
||||||
"parallel_query_dsa");
|
|
||||||
LWLockRegisterTranche(LWTRANCHE_SESSION_DSA,
|
|
||||||
"session_dsa");
|
|
||||||
LWLockRegisterTranche(LWTRANCHE_SESSION_RECORD_TABLE,
|
|
||||||
"session_record_table");
|
|
||||||
LWLockRegisterTranche(LWTRANCHE_SESSION_TYPMOD_TABLE,
|
|
||||||
"session_typmod_table");
|
|
||||||
LWLockRegisterTranche(LWTRANCHE_SHARED_TUPLESTORE,
|
|
||||||
"shared_tuplestore");
|
|
||||||
LWLockRegisterTranche(LWTRANCHE_TBM, "tbm");
|
|
||||||
LWLockRegisterTranche(LWTRANCHE_PARALLEL_APPEND, "parallel_append");
|
|
||||||
LWLockRegisterTranche(LWTRANCHE_PARALLEL_HASH_JOIN, "parallel_hash_join");
|
|
||||||
LWLockRegisterTranche(LWTRANCHE_SXACT, "serializable_xact");
|
|
||||||
|
|
||||||
/* Register named tranches. */
|
|
||||||
for (i = 0; i < NamedLWLockTrancheRequests; i++)
|
|
||||||
LWLockRegisterTranche(NamedLWLockTrancheArray[i].trancheId,
|
|
||||||
NamedLWLockTrancheArray[i].trancheName);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* InitLWLockAccess - initialize backend-local state needed to hold LWLocks
|
* InitLWLockAccess - initialize backend-local state needed to hold LWLocks
|
||||||
*/
|
*/
|
||||||
@ -570,8 +612,7 @@ GetNamedLWLockTranche(const char *tranche_name)
|
|||||||
lock_pos += NamedLWLockTrancheRequestArray[i].num_lwlocks;
|
lock_pos += NamedLWLockTrancheRequestArray[i].num_lwlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i >= NamedLWLockTrancheRequests)
|
elog(ERROR, "requested tranche is not registered");
|
||||||
elog(ERROR, "requested tranche is not registered");
|
|
||||||
|
|
||||||
/* just to keep compiler quiet */
|
/* just to keep compiler quiet */
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -595,32 +636,47 @@ LWLockNewTrancheId(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register a tranche ID in the lookup table for the current process. This
|
* Register a dynamic tranche name in the lookup table of the current process.
|
||||||
* routine will save a pointer to the tranche name passed as an argument,
|
*
|
||||||
|
* 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
|
* so the name should be allocated in a backend-lifetime context
|
||||||
* (TopMemoryContext, static variable, or similar).
|
* (TopMemoryContext, static constant, or similar).
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
LWLockRegisterTranche(int tranche_id, const char *tranche_name)
|
LWLockRegisterTranche(int tranche_id, const char *tranche_name)
|
||||||
{
|
{
|
||||||
Assert(LWLockTrancheArray != NULL);
|
/* This should only be called for user-defined tranches. */
|
||||||
|
if (tranche_id < LWTRANCHE_FIRST_USER_DEFINED)
|
||||||
|
return;
|
||||||
|
|
||||||
if (tranche_id >= LWLockTranchesAllocated)
|
/* Convert to array index. */
|
||||||
|
tranche_id -= LWTRANCHE_FIRST_USER_DEFINED;
|
||||||
|
|
||||||
|
/* If necessary, create or enlarge array. */
|
||||||
|
if (tranche_id >= LWLockTrancheNamesAllocated)
|
||||||
{
|
{
|
||||||
int i = LWLockTranchesAllocated;
|
int newalloc;
|
||||||
int j = LWLockTranchesAllocated;
|
|
||||||
|
|
||||||
while (i <= tranche_id)
|
newalloc = Max(LWLockTrancheNamesAllocated, 8);
|
||||||
i *= 2;
|
while (newalloc <= tranche_id)
|
||||||
|
newalloc *= 2;
|
||||||
|
|
||||||
LWLockTrancheArray = (const char **)
|
if (LWLockTrancheNames == NULL)
|
||||||
repalloc(LWLockTrancheArray, i * sizeof(char *));
|
LWLockTrancheNames = (const char **)
|
||||||
LWLockTranchesAllocated = i;
|
MemoryContextAllocZero(TopMemoryContext,
|
||||||
while (j < LWLockTranchesAllocated)
|
newalloc * sizeof(char *));
|
||||||
LWLockTrancheArray[j++] = NULL;
|
else
|
||||||
|
{
|
||||||
|
LWLockTrancheNames = (const char **)
|
||||||
|
repalloc(LWLockTrancheNames, newalloc * sizeof(char *));
|
||||||
|
memset(LWLockTrancheNames + LWLockTrancheNamesAllocated,
|
||||||
|
0,
|
||||||
|
(newalloc - LWLockTrancheNamesAllocated) * sizeof(char *));
|
||||||
|
}
|
||||||
|
LWLockTrancheNamesAllocated = newalloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
LWLockTrancheArray[tranche_id] = tranche_name;
|
LWLockTrancheNames[tranche_id] = tranche_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -666,8 +722,8 @@ RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks)
|
|||||||
}
|
}
|
||||||
|
|
||||||
request = &NamedLWLockTrancheRequestArray[NamedLWLockTrancheRequests];
|
request = &NamedLWLockTrancheRequestArray[NamedLWLockTrancheRequests];
|
||||||
Assert(strlen(tranche_name) + 1 < NAMEDATALEN);
|
Assert(strlen(tranche_name) + 1 <= NAMEDATALEN);
|
||||||
StrNCpy(request->tranche_name, tranche_name, NAMEDATALEN);
|
strlcpy(request->tranche_name, tranche_name, NAMEDATALEN);
|
||||||
request->num_lwlocks = num_lwlocks;
|
request->num_lwlocks = num_lwlocks;
|
||||||
NamedLWLockTrancheRequests++;
|
NamedLWLockTrancheRequests++;
|
||||||
}
|
}
|
||||||
@ -708,6 +764,34 @@ LWLockReportWaitEnd(void)
|
|||||||
pgstat_report_wait_end();
|
pgstat_report_wait_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return the name of an LWLock tranche.
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
GetLWTrancheName(uint16 trancheId)
|
||||||
|
{
|
||||||
|
/* Individual LWLock? */
|
||||||
|
if (trancheId < NUM_INDIVIDUAL_LWLOCKS)
|
||||||
|
return MainLWLockNames[trancheId];
|
||||||
|
|
||||||
|
/* Built-in tranche? */
|
||||||
|
if (trancheId < LWTRANCHE_FIRST_USER_DEFINED)
|
||||||
|
return BuiltinTrancheNames[trancheId - NUM_INDIVIDUAL_LWLOCKS];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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".
|
||||||
|
*/
|
||||||
|
trancheId -= LWTRANCHE_FIRST_USER_DEFINED;
|
||||||
|
|
||||||
|
if (trancheId >= LWLockTrancheNamesAllocated ||
|
||||||
|
LWLockTrancheNames[trancheId] == NULL)
|
||||||
|
return "extension";
|
||||||
|
|
||||||
|
return LWLockTrancheNames[trancheId];
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return an identifier for an LWLock based on the wait class and event.
|
* Return an identifier for an LWLock based on the wait class and event.
|
||||||
*/
|
*/
|
||||||
@ -715,17 +799,8 @@ const char *
|
|||||||
GetLWLockIdentifier(uint32 classId, uint16 eventId)
|
GetLWLockIdentifier(uint32 classId, uint16 eventId)
|
||||||
{
|
{
|
||||||
Assert(classId == PG_WAIT_LWLOCK);
|
Assert(classId == PG_WAIT_LWLOCK);
|
||||||
|
/* The event IDs are just tranche numbers. */
|
||||||
/*
|
return GetLWTrancheName(eventId);
|
||||||
* It is quite possible that user has registered tranche in one of the
|
|
||||||
* backends (e.g. by allocating lwlocks in dynamic shared memory) but not
|
|
||||||
* all of them, so we can't assume the tranche is registered here.
|
|
||||||
*/
|
|
||||||
if (eventId >= LWLockTranchesAllocated ||
|
|
||||||
LWLockTrancheArray[eventId] == NULL)
|
|
||||||
return "extension";
|
|
||||||
|
|
||||||
return LWLockTrancheArray[eventId];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user