aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/monitoring.sgml52
-rw-r--r--src/backend/access/transam/slru.c6
-rw-r--r--src/backend/access/transam/xlog.c9
-rw-r--r--src/backend/postmaster/pgstat.c10
-rw-r--r--src/backend/replication/logical/origin.c8
-rw-r--r--src/backend/replication/slot.c8
-rw-r--r--src/backend/storage/buffer/buf_init.c16
-rw-r--r--src/backend/storage/ipc/procarray.c9
-rw-r--r--src/backend/storage/lmgr/lwlock.c175
-rw-r--r--src/backend/utils/mmgr/dsa.c15
-rw-r--r--src/backend/utils/probes.d16
-rw-r--r--src/include/access/slru.h1
-rw-r--r--src/include/pgstat.h3
-rw-r--r--src/include/storage/lwlock.h45
14 files changed, 112 insertions, 261 deletions
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 128ee13b5f7..5b58d2e84dc 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -646,18 +646,11 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
<itemizedlist>
<listitem>
<para>
- <literal>LWLockNamed</>: The backend is waiting for a specific named
- lightweight lock. Each such lock protects a particular data
- structure in shared memory. <literal>wait_event</> will contain
- the name of the lightweight lock.
- </para>
- </listitem>
- <listitem>
- <para>
- <literal>LWLockTranche</>: The backend is waiting for one of a
- group of related lightweight locks. All locks in the group perform
- a similar function; <literal>wait_event</> will identify the general
- purpose of locks in that group.
+ <literal>LWLock</>: The backend is waiting for a lightweight lock.
+ Each such lock protects a particular data structure in shared memory.
+ <literal>wait_event</> will contain a name identifying the purpose
+ of the lightweight lock. (Some locks have specific names; others
+ are part of a group of locks each with a similar purpose.)
</para>
</listitem>
<listitem>
@@ -825,7 +818,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
<tbody>
<row>
- <entry morerows="41"><literal>LWLockNamed</></entry>
+ <entry morerows="57"><literal>LWLock</></entry>
<entry><literal>ShmemIndexLock</></entry>
<entry>Waiting to find or allocate space in shared memory.</entry>
</row>
@@ -1011,7 +1004,6 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
<entry>Waiting to read or update old snapshot control information.</entry>
</row>
<row>
- <entry morerows="15"><literal>LWLockTranche</></entry>
<entry><literal>clog</></entry>
<entry>Waiting for I/O on a clog (transaction status) buffer.</entry>
</row>
@@ -1279,7 +1271,7 @@ SELECT pid, wait_event_type, wait_event FROM pg_stat_activity WHERE wait_event i
pid | wait_event_type | wait_event
------+-----------------+---------------
2540 | Lock | relation
- 6644 | LWLockNamed | ProcArrayLock
+ 6644 | LWLock | ProcArrayLock
(2 rows)
</programlisting>
</para>
@@ -3347,55 +3339,49 @@ SELECT pg_stat_get_backend_pid(s.backendid) AS pid,
</row>
<row>
<entry><literal>lwlock-acquire</literal></entry>
- <entry><literal>(char *, int, LWLockMode)</literal></entry>
+ <entry><literal>(char *, LWLockMode)</literal></entry>
<entry>Probe that fires when an LWLock has been acquired.
arg0 is the LWLock's tranche.
- arg1 is the LWLock's offset within its tranche.
- arg2 is the requested lock mode, either exclusive or shared.</entry>
+ arg1 is the requested lock mode, either exclusive or shared.</entry>
</row>
<row>
<entry><literal>lwlock-release</literal></entry>
- <entry><literal>(char *, int)</literal></entry>
+ <entry><literal>(char *)</literal></entry>
<entry>Probe that fires when an LWLock has been released (but note
that any released waiters have not yet been awakened).
- arg0 is the LWLock's tranche.
- arg1 is the LWLock's offset within its tranche.</entry>
+ arg0 is the LWLock's tranche.</entry>
</row>
<row>
<entry><literal>lwlock-wait-start</literal></entry>
- <entry><literal>(char *, int, LWLockMode)</literal></entry>
+ <entry><literal>(char *, LWLockMode)</literal></entry>
<entry>Probe that fires when an LWLock was not immediately available and
a server process has begun to wait for the lock to become available.
arg0 is the LWLock's tranche.
- arg1 is the LWLock's offset within its tranche.
- arg2 is the requested lock mode, either exclusive or shared.</entry>
+ arg1 is the requested lock mode, either exclusive or shared.</entry>
</row>
<row>
<entry><literal>lwlock-wait-done</literal></entry>
- <entry><literal>(char *, int, LWLockMode)</literal></entry>
+ <entry><literal>(char *, LWLockMode)</literal></entry>
<entry>Probe that fires when a server process has been released from its
wait for an LWLock (it does not actually have the lock yet).
arg0 is the LWLock's tranche.
- arg1 is the LWLock's offset within its tranche.
- arg2 is the requested lock mode, either exclusive or shared.</entry>
+ arg1 is the requested lock mode, either exclusive or shared.</entry>
</row>
<row>
<entry><literal>lwlock-condacquire</literal></entry>
- <entry><literal>(char *, int, LWLockMode)</literal></entry>
+ <entry><literal>(char *, LWLockMode)</literal></entry>
<entry>Probe that fires when an LWLock was successfully acquired when the
caller specified no waiting.
arg0 is the LWLock's tranche.
- arg1 is the LWLock's offset within its tranche.
- arg2 is the requested lock mode, either exclusive or shared.</entry>
+ arg1 is the requested lock mode, either exclusive or shared.</entry>
</row>
<row>
<entry><literal>lwlock-condacquire-fail</literal></entry>
- <entry><literal>(char *, int, LWLockMode)</literal></entry>
+ <entry><literal>(char *, LWLockMode)</literal></entry>
<entry>Probe that fires when an LWLock was not successfully acquired when
the caller specified no waiting.
arg0 is the LWLock's tranche.
- arg1 is the LWLock's offset within its tranche.
- arg2 is the requested lock mode, either exclusive or shared.</entry>
+ arg1 is the requested lock mode, either exclusive or shared.</entry>
</row>
<row>
<entry><literal>lock-wait-start</literal></entry>
diff --git a/src/backend/access/transam/slru.c b/src/backend/access/transam/slru.c
index bbae5847f2d..8b95f35dbaf 100644
--- a/src/backend/access/transam/slru.c
+++ b/src/backend/access/transam/slru.c
@@ -216,9 +216,6 @@ SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns,
Assert(strlen(name) + 1 < SLRU_MAX_NAME_LENGTH);
strlcpy(shared->lwlock_tranche_name, name, SLRU_MAX_NAME_LENGTH);
shared->lwlock_tranche_id = tranche_id;
- shared->lwlock_tranche.name = shared->lwlock_tranche_name;
- shared->lwlock_tranche.array_base = shared->buffer_locks;
- shared->lwlock_tranche.array_stride = sizeof(LWLockPadded);
ptr += BUFFERALIGN(offset);
for (slotno = 0; slotno < nslots; slotno++)
@@ -237,7 +234,8 @@ SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns,
Assert(found);
/* Register SLRU tranche in the main tranches array */
- LWLockRegisterTranche(shared->lwlock_tranche_id, &shared->lwlock_tranche);
+ LWLockRegisterTranche(shared->lwlock_tranche_id,
+ shared->lwlock_tranche_name);
/*
* Initialize the unshared control struct, including directory path. We
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c
index 084401d2f23..aa9ee5a0dd8 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -517,7 +517,6 @@ typedef struct XLogCtlInsert
* WAL insertion locks.
*/
WALInsertLockPadded *WALInsertLocks;
- LWLockTranche WALInsertLockTranche;
} XLogCtlInsert;
/*
@@ -4688,7 +4687,7 @@ XLOGShmemInit(void)
/* Initialize local copy of WALInsertLocks and register the tranche */
WALInsertLocks = XLogCtl->Insert.WALInsertLocks;
LWLockRegisterTranche(LWTRANCHE_WAL_INSERT,
- &XLogCtl->Insert.WALInsertLockTranche);
+ "wal_insert");
return;
}
memset(XLogCtl, 0, sizeof(XLogCtlData));
@@ -4711,11 +4710,7 @@ XLOGShmemInit(void)
(WALInsertLockPadded *) allocptr;
allocptr += sizeof(WALInsertLockPadded) * NUM_XLOGINSERT_LOCKS;
- XLogCtl->Insert.WALInsertLockTranche.name = "wal_insert";
- XLogCtl->Insert.WALInsertLockTranche.array_base = WALInsertLocks;
- XLogCtl->Insert.WALInsertLockTranche.array_stride = sizeof(WALInsertLockPadded);
-
- LWLockRegisterTranche(LWTRANCHE_WAL_INSERT, &XLogCtl->Insert.WALInsertLockTranche);
+ LWLockRegisterTranche(LWTRANCHE_WAL_INSERT, "wal_insert");
for (i = 0; i < NUM_XLOGINSERT_LOCKS; i++)
{
LWLockInitialize(&WALInsertLocks[i].l.lock, LWTRANCHE_WAL_INSERT);
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index c7584cb1d34..61e6a2cd339 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -3152,11 +3152,8 @@ pgstat_get_wait_event_type(uint32 wait_event_info)
switch (classId)
{
- case PG_WAIT_LWLOCK_NAMED:
- event_type = "LWLockNamed";
- break;
- case PG_WAIT_LWLOCK_TRANCHE:
- event_type = "LWLockTranche";
+ case PG_WAIT_LWLOCK:
+ event_type = "LWLock";
break;
case PG_WAIT_LOCK:
event_type = "Lock";
@@ -3209,8 +3206,7 @@ pgstat_get_wait_event(uint32 wait_event_info)
switch (classId)
{
- case PG_WAIT_LWLOCK_NAMED:
- case PG_WAIT_LWLOCK_TRANCHE:
+ case PG_WAIT_LWLOCK:
event_name = GetLWLockIdentifier(classId, eventId);
break;
case PG_WAIT_LOCK:
diff --git a/src/backend/replication/logical/origin.c b/src/backend/replication/logical/origin.c
index cc2b5132366..0deec75dc26 100644
--- a/src/backend/replication/logical/origin.c
+++ b/src/backend/replication/logical/origin.c
@@ -143,7 +143,6 @@ typedef struct ReplicationStateOnDisk
typedef struct ReplicationStateCtl
{
int tranche_id;
- LWLockTranche tranche;
ReplicationState states[FLEXIBLE_ARRAY_MEMBER];
} ReplicationStateCtl;
@@ -474,11 +473,6 @@ ReplicationOriginShmemInit(void)
int i;
replication_states_ctl->tranche_id = LWTRANCHE_REPLICATION_ORIGIN;
- replication_states_ctl->tranche.name = "replication_origin";
- replication_states_ctl->tranche.array_base =
- &replication_states[0].lock;
- replication_states_ctl->tranche.array_stride =
- sizeof(ReplicationState);
MemSet(replication_states, 0, ReplicationOriginShmemSize());
@@ -488,7 +482,7 @@ ReplicationOriginShmemInit(void)
}
LWLockRegisterTranche(replication_states_ctl->tranche_id,
- &replication_states_ctl->tranche);
+ "replication_origin");
}
/* ---------------------------------------------------------------------------
diff --git a/src/backend/replication/slot.c b/src/backend/replication/slot.c
index d8ed005e7ec..cf814d11a23 100644
--- a/src/backend/replication/slot.c
+++ b/src/backend/replication/slot.c
@@ -98,8 +98,6 @@ ReplicationSlot *MyReplicationSlot = NULL;
int max_replication_slots = 0; /* the maximum number of replication
* slots */
-static LWLockTranche ReplSlotIOLWLockTranche;
-
static void ReplicationSlotDropAcquired(void);
static void ReplicationSlotDropPtr(ReplicationSlot *slot);
@@ -141,12 +139,8 @@ ReplicationSlotsShmemInit(void)
ShmemInitStruct("ReplicationSlot Ctl", ReplicationSlotsShmemSize(),
&found);
- ReplSlotIOLWLockTranche.name = "replication_slot_io";
- ReplSlotIOLWLockTranche.array_base =
- ((char *) ReplicationSlotCtl) + offsetof(ReplicationSlotCtlData, replication_slots) +offsetof(ReplicationSlot, io_in_progress_lock);
- ReplSlotIOLWLockTranche.array_stride = sizeof(ReplicationSlot);
LWLockRegisterTranche(LWTRANCHE_REPLICATION_SLOT_IO_IN_PROGRESS,
- &ReplSlotIOLWLockTranche);
+ "replication_slot_io");
if (!found)
{
diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c
index a4163cf717d..c507389a050 100644
--- a/src/backend/storage/buffer/buf_init.c
+++ b/src/backend/storage/buffer/buf_init.c
@@ -21,8 +21,6 @@
BufferDescPadded *BufferDescriptors;
char *BufferBlocks;
LWLockMinimallyPadded *BufferIOLWLockArray = NULL;
-LWLockTranche BufferIOLWLockTranche;
-LWLockTranche BufferContentLWLockTranche;
WritebackContext BackendWritebackContext;
CkptSortItem *CkptBufferIds;
@@ -90,18 +88,8 @@ InitBufferPool(void)
NBuffers * (Size) sizeof(LWLockMinimallyPadded),
&foundIOLocks);
- BufferIOLWLockTranche.name = "buffer_io";
- BufferIOLWLockTranche.array_base = BufferIOLWLockArray;
- BufferIOLWLockTranche.array_stride = sizeof(LWLockMinimallyPadded);
- LWLockRegisterTranche(LWTRANCHE_BUFFER_IO_IN_PROGRESS,
- &BufferIOLWLockTranche);
-
- BufferContentLWLockTranche.name = "buffer_content";
- BufferContentLWLockTranche.array_base =
- ((char *) BufferDescriptors) + offsetof(BufferDesc, content_lock);
- BufferContentLWLockTranche.array_stride = sizeof(BufferDescPadded);
- LWLockRegisterTranche(LWTRANCHE_BUFFER_CONTENT,
- &BufferContentLWLockTranche);
+ 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
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index bf38470f01d..0f637556ccb 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -106,9 +106,6 @@ static TransactionId *KnownAssignedXids;
static bool *KnownAssignedXidsValid;
static TransactionId latestObservedXid = InvalidTransactionId;
-/* LWLock tranche for backend locks */
-static LWLockTranche ProcLWLockTranche;
-
/*
* If we're in STANDBY_SNAPSHOT_PENDING state, standbySnapshotPendingXmin is
* the highest xid that might still be running that we don't have in
@@ -266,11 +263,7 @@ CreateSharedProcArray(void)
}
/* Register and initialize fields of ProcLWLockTranche */
- ProcLWLockTranche.name = "proc";
- ProcLWLockTranche.array_base = (char *) (ProcGlobal->allProcs) +
- offsetof(PGPROC, backendLock);
- ProcLWLockTranche.array_stride = sizeof(PGPROC);
- LWLockRegisterTranche(LWTRANCHE_PROC, &ProcLWLockTranche);
+ LWLockRegisterTranche(LWTRANCHE_PROC, "proc");
}
/*
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index 03c4c7825eb..4b381e4e0cc 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -108,18 +108,14 @@ extern slock_t *ShmemLock;
#define LW_SHARED_MASK ((uint32) ((1 << 24)-1))
/*
- * This is indexed by tranche ID and stores metadata for all tranches known
+ * This is indexed by tranche ID and stores the names of all tranches known
* to the current backend.
*/
-static LWLockTranche **LWLockTrancheArray = NULL;
+static char **LWLockTrancheArray = NULL;
static int LWLockTranchesAllocated = 0;
#define T_NAME(lock) \
- (LWLockTrancheArray[(lock)->tranche]->name)
-#define T_ID(lock) \
- ((int) ((((char *) lock) - \
- ((char *) LWLockTrancheArray[(lock)->tranche]->array_base)) / \
- LWLockTrancheArray[(lock)->tranche]->array_stride))
+ (LWLockTrancheArray[(lock)->tranche])
/*
* This points to the main array of LWLocks in shared memory. Backends inherit
@@ -127,10 +123,6 @@ static int LWLockTranchesAllocated = 0;
* where we have special measures to pass it down).
*/
LWLockPadded *MainLWLockArray = NULL;
-static LWLockTranche MainLWLockTranche;
-static LWLockTranche BufMappingLWLockTranche;
-static LWLockTranche LockManagerLWLockTranche;
-static LWLockTranche PredicateLockManagerLWLockTranche;
/*
* We use this structure to keep track of locked LWLocks for release
@@ -175,7 +167,7 @@ static inline void LWLockReportWaitEnd(void);
typedef struct lwlock_stats_key
{
int tranche;
- int instance;
+ void *instance;
} lwlock_stats_key;
typedef struct lwlock_stats
@@ -202,32 +194,18 @@ PRINT_LWDEBUG(const char *where, LWLock *lock, LWLockMode mode)
if (Trace_lwlocks)
{
uint32 state = pg_atomic_read_u32(&lock->state);
- int id = T_ID(lock);
-
- if (lock->tranche == 0 && id < NUM_INDIVIDUAL_LWLOCKS)
- ereport(LOG,
- (errhidestmt(true),
- errhidecontext(true),
- errmsg_internal("%d: %s(%s): excl %u shared %u haswaiters %u waiters %u rOK %d",
- MyProcPid,
- where, MainLWLockNames[id],
- (state & LW_VAL_EXCLUSIVE) != 0,
- state & LW_SHARED_MASK,
- (state & LW_FLAG_HAS_WAITERS) != 0,
- pg_atomic_read_u32(&lock->nwaiters),
- (state & LW_FLAG_RELEASE_OK) != 0)));
- else
- ereport(LOG,
- (errhidestmt(true),
- errhidecontext(true),
- errmsg_internal("%d: %s(%s %d): excl %u shared %u haswaiters %u waiters %u rOK %d",
- MyProcPid,
- where, T_NAME(lock), id,
- (state & LW_VAL_EXCLUSIVE) != 0,
- state & LW_SHARED_MASK,
- (state & LW_FLAG_HAS_WAITERS) != 0,
- pg_atomic_read_u32(&lock->nwaiters),
- (state & LW_FLAG_RELEASE_OK) != 0)));
+
+ ereport(LOG,
+ (errhidestmt(true),
+ errhidecontext(true),
+ errmsg_internal("%d: %s(%s %p): excl %u shared %u haswaiters %u waiters %u rOK %d",
+ MyProcPid,
+ where, T_NAME(lock), lock,
+ (state & LW_VAL_EXCLUSIVE) != 0,
+ state & LW_SHARED_MASK,
+ (state & LW_FLAG_HAS_WAITERS) != 0,
+ pg_atomic_read_u32(&lock->nwaiters),
+ (state & LW_FLAG_RELEASE_OK) != 0)));
}
}
@@ -237,20 +215,11 @@ LOG_LWDEBUG(const char *where, LWLock *lock, const char *msg)
/* hide statement & context here, otherwise the log is just too verbose */
if (Trace_lwlocks)
{
- int id = T_ID(lock);
-
- if (lock->tranche == 0 && id < NUM_INDIVIDUAL_LWLOCKS)
- ereport(LOG,
- (errhidestmt(true),
- errhidecontext(true),
- errmsg_internal("%s(%s): %s", where,
- MainLWLockNames[id], msg)));
- else
- ereport(LOG,
- (errhidestmt(true),
- errhidecontext(true),
- errmsg_internal("%s(%s %d): %s", where,
- T_NAME(lock), id, msg)));
+ ereport(LOG,
+ (errhidestmt(true),
+ errhidecontext(true),
+ errmsg_internal("%s(%s %p): %s", where,
+ T_NAME(lock), lock, msg)));
}
}
@@ -315,8 +284,8 @@ print_lwlock_stats(int code, Datum arg)
while ((lwstats = (lwlock_stats *) hash_seq_search(&scan)) != NULL)
{
fprintf(stderr,
- "PID %d lwlock %s %d: shacq %u exacq %u blk %u spindelay %u dequeue self %u\n",
- MyProcPid, LWLockTrancheArray[lwstats->key.tranche]->name,
+ "PID %d lwlock %s %p: shacq %u exacq %u blk %u spindelay %u dequeue self %u\n",
+ MyProcPid, LWLockTrancheArray[lwstats->key.tranche],
lwstats->key.instance, lwstats->sh_acquire_count,
lwstats->ex_acquire_count, lwstats->block_count,
lwstats->spin_delay_count, lwstats->dequeue_self_count);
@@ -342,7 +311,7 @@ get_lwlock_stats_entry(LWLock *lock)
/* Fetch or create the entry. */
key.tranche = lock->tranche;
- key.instance = T_ID(lock);
+ key.instance = lock;
lwstats = hash_search(lwlock_stats_htab, &key, HASH_ENTER, &found);
if (!found)
{
@@ -464,7 +433,7 @@ InitializeLWLocks(void)
/* Initialize all individual LWLocks in main array */
for (id = 0, lock = MainLWLockArray; id < NUM_INDIVIDUAL_LWLOCKS; id++, lock++)
- LWLockInitialize(&lock->lock, LWTRANCHE_MAIN);
+ LWLockInitialize(&lock->lock, id);
/* Initialize buffer mapping LWLocks in main array */
lock = MainLWLockArray + NUM_INDIVIDUAL_LWLOCKS;
@@ -506,10 +475,8 @@ InitializeLWLocks(void)
name = trancheNames;
trancheNames += strlen(request->tranche_name) + 1;
strcpy(name, request->tranche_name);
- tranche->lwLockTranche.name = name;
tranche->trancheId = LWLockNewTrancheId();
- tranche->lwLockTranche.array_base = lock;
- tranche->lwLockTranche.array_stride = sizeof(LWLockPadded);
+ tranche->trancheName = name;
for (j = 0; j < request->num_lwlocks; j++, lock++)
LWLockInitialize(&lock->lock, tranche->trancheId);
@@ -527,39 +494,25 @@ RegisterLWLockTranches(void)
if (LWLockTrancheArray == NULL)
{
- LWLockTranchesAllocated = 32;
- LWLockTrancheArray = (LWLockTranche **)
+ LWLockTranchesAllocated = 64;
+ LWLockTrancheArray = (char **)
MemoryContextAllocZero(TopMemoryContext,
- LWLockTranchesAllocated * sizeof(LWLockTranche *));
+ LWLockTranchesAllocated * sizeof(char *));
Assert(LWLockTranchesAllocated >= LWTRANCHE_FIRST_USER_DEFINED);
}
- MainLWLockTranche.name = "main";
- MainLWLockTranche.array_base = MainLWLockArray;
- MainLWLockTranche.array_stride = sizeof(LWLockPadded);
- LWLockRegisterTranche(LWTRANCHE_MAIN, &MainLWLockTranche);
+ for (i = 0; i < NUM_INDIVIDUAL_LWLOCKS; ++i)
+ LWLockRegisterTranche(i, MainLWLockNames[i]);
- BufMappingLWLockTranche.name = "buffer_mapping";
- BufMappingLWLockTranche.array_base = MainLWLockArray + NUM_INDIVIDUAL_LWLOCKS;
- BufMappingLWLockTranche.array_stride = sizeof(LWLockPadded);
- LWLockRegisterTranche(LWTRANCHE_BUFFER_MAPPING, &BufMappingLWLockTranche);
-
- LockManagerLWLockTranche.name = "lock_manager";
- LockManagerLWLockTranche.array_base = MainLWLockArray + NUM_INDIVIDUAL_LWLOCKS +
- NUM_BUFFER_PARTITIONS;
- LockManagerLWLockTranche.array_stride = sizeof(LWLockPadded);
- LWLockRegisterTranche(LWTRANCHE_LOCK_MANAGER, &LockManagerLWLockTranche);
-
- PredicateLockManagerLWLockTranche.name = "predicate_lock_manager";
- PredicateLockManagerLWLockTranche.array_base = MainLWLockArray + NUM_INDIVIDUAL_LWLOCKS +
- NUM_BUFFER_PARTITIONS + NUM_LOCK_PARTITIONS;
- PredicateLockManagerLWLockTranche.array_stride = sizeof(LWLockPadded);
- LWLockRegisterTranche(LWTRANCHE_PREDICATE_LOCK_MANAGER, &PredicateLockManagerLWLockTranche);
+ LWLockRegisterTranche(LWTRANCHE_BUFFER_MAPPING, "buffer_mapping");
+ LWLockRegisterTranche(LWTRANCHE_LOCK_MANAGER, "lock_manager");
+ LWLockRegisterTranche(LWTRANCHE_PREDICATE_LOCK_MANAGER,
+ "predicate_lock_manager");
/* Register named tranches. */
for (i = 0; i < NamedLWLockTrancheRequests; i++)
LWLockRegisterTranche(NamedLWLockTrancheArray[i].trancheId,
- &NamedLWLockTrancheArray[i].lwLockTranche);
+ NamedLWLockTrancheArray[i].trancheName);
}
/*
@@ -633,7 +586,7 @@ LWLockNewTrancheId(void)
* (TopMemoryContext, static variable, or similar).
*/
void
-LWLockRegisterTranche(int tranche_id, LWLockTranche *tranche)
+LWLockRegisterTranche(int tranche_id, char *tranche_name)
{
Assert(LWLockTrancheArray != NULL);
@@ -645,15 +598,14 @@ LWLockRegisterTranche(int tranche_id, LWLockTranche *tranche)
while (i <= tranche_id)
i *= 2;
- LWLockTrancheArray = (LWLockTranche **)
- repalloc(LWLockTrancheArray,
- i * sizeof(LWLockTranche *));
+ LWLockTrancheArray = (char **)
+ repalloc(LWLockTrancheArray, i * sizeof(char *));
LWLockTranchesAllocated = i;
while (j < LWLockTranchesAllocated)
LWLockTrancheArray[j++] = NULL;
}
- LWLockTrancheArray[tranche_id] = tranche;
+ LWLockTrancheArray[tranche_id] = tranche_name;
}
/*
@@ -729,12 +681,7 @@ LWLockInitialize(LWLock *lock, int tranche_id)
static inline void
LWLockReportWaitStart(LWLock *lock)
{
- int lockId = T_ID(lock);
-
- if (lock->tranche == 0)
- pgstat_report_wait_start(PG_WAIT_LWLOCK_NAMED | (uint16) lockId);
- else
- pgstat_report_wait_start(PG_WAIT_LWLOCK_TRANCHE | lock->tranche);
+ pgstat_report_wait_start(PG_WAIT_LWLOCK | lock->tranche);
}
/*
@@ -752,10 +699,7 @@ LWLockReportWaitEnd(void)
const char *
GetLWLockIdentifier(uint32 classId, uint16 eventId)
{
- if (classId == PG_WAIT_LWLOCK_NAMED)
- return MainLWLockNames[eventId];
-
- Assert(classId == PG_WAIT_LWLOCK_TRANCHE);
+ Assert(classId == PG_WAIT_LWLOCK);
/*
* It is quite possible that user has registered tranche in one of the
@@ -763,10 +707,10 @@ GetLWLockIdentifier(uint32 classId, uint16 eventId)
* all of them, so we can't assume the tranche is registered here.
*/
if (eventId >= LWLockTranchesAllocated ||
- LWLockTrancheArray[eventId]->name == NULL)
+ LWLockTrancheArray[eventId] == NULL)
return "extension";
- return LWLockTrancheArray[eventId]->name;
+ return LWLockTrancheArray[eventId];
}
/*
@@ -1279,7 +1223,7 @@ LWLockAcquire(LWLock *lock, LWLockMode mode)
#endif
LWLockReportWaitStart(lock);
- TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), T_ID(lock), mode);
+ TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), mode);
for (;;)
{
@@ -1301,7 +1245,7 @@ LWLockAcquire(LWLock *lock, LWLockMode mode)
}
#endif
- TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), T_ID(lock), mode);
+ TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), mode);
LWLockReportWaitEnd();
LOG_LWDEBUG("LWLockAcquire", lock, "awakened");
@@ -1310,7 +1254,7 @@ LWLockAcquire(LWLock *lock, LWLockMode mode)
result = false;
}
- TRACE_POSTGRESQL_LWLOCK_ACQUIRE(T_NAME(lock), T_ID(lock), mode);
+ TRACE_POSTGRESQL_LWLOCK_ACQUIRE(T_NAME(lock), mode);
/* Add lock to list of locks held by this backend */
held_lwlocks[num_held_lwlocks].lock = lock;
@@ -1361,14 +1305,14 @@ LWLockConditionalAcquire(LWLock *lock, LWLockMode mode)
RESUME_INTERRUPTS();
LOG_LWDEBUG("LWLockConditionalAcquire", lock, "failed");
- TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE_FAIL(T_NAME(lock), T_ID(lock), mode);
+ TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE_FAIL(T_NAME(lock), mode);
}
else
{
/* Add lock to list of locks held by this backend */
held_lwlocks[num_held_lwlocks].lock = lock;
held_lwlocks[num_held_lwlocks++].mode = mode;
- TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE(T_NAME(lock), T_ID(lock), mode);
+ TRACE_POSTGRESQL_LWLOCK_CONDACQUIRE(T_NAME(lock), mode);
}
return !mustwait;
}
@@ -1440,7 +1384,7 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode)
#endif
LWLockReportWaitStart(lock);
- TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), T_ID(lock), mode);
+ TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), mode);
for (;;)
{
@@ -1458,7 +1402,7 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode)
Assert(nwaiters < MAX_BACKENDS);
}
#endif
- TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), T_ID(lock), mode);
+ TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), mode);
LWLockReportWaitEnd();
LOG_LWDEBUG("LWLockAcquireOrWait", lock, "awakened");
@@ -1488,8 +1432,7 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode)
/* Failed to get lock, so release interrupt holdoff */
RESUME_INTERRUPTS();
LOG_LWDEBUG("LWLockAcquireOrWait", lock, "failed");
- TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT_FAIL(T_NAME(lock), T_ID(lock),
- mode);
+ TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT_FAIL(T_NAME(lock), mode);
}
else
{
@@ -1497,7 +1440,7 @@ LWLockAcquireOrWait(LWLock *lock, LWLockMode mode)
/* Add lock to list of locks held by this backend */
held_lwlocks[num_held_lwlocks].lock = lock;
held_lwlocks[num_held_lwlocks++].mode = mode;
- TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT(T_NAME(lock), T_ID(lock), mode);
+ TRACE_POSTGRESQL_LWLOCK_ACQUIRE_OR_WAIT(T_NAME(lock), mode);
}
return !mustwait;
@@ -1657,8 +1600,7 @@ LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval)
#endif
LWLockReportWaitStart(lock);
- TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), T_ID(lock),
- LW_EXCLUSIVE);
+ TRACE_POSTGRESQL_LWLOCK_WAIT_START(T_NAME(lock), LW_EXCLUSIVE);
for (;;)
{
@@ -1677,8 +1619,7 @@ LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval)
}
#endif
- TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), T_ID(lock),
- LW_EXCLUSIVE);
+ TRACE_POSTGRESQL_LWLOCK_WAIT_DONE(T_NAME(lock), LW_EXCLUSIVE);
LWLockReportWaitEnd();
LOG_LWDEBUG("LWLockWaitForVar", lock, "awakened");
@@ -1686,7 +1627,7 @@ LWLockWaitForVar(LWLock *lock, uint64 *valptr, uint64 oldval, uint64 *newval)
/* Now loop back and check the status of the lock again. */
}
- TRACE_POSTGRESQL_LWLOCK_ACQUIRE(T_NAME(lock), T_ID(lock), LW_EXCLUSIVE);
+ TRACE_POSTGRESQL_LWLOCK_ACQUIRE(T_NAME(lock), LW_EXCLUSIVE);
/*
* Fix the process wait semaphore's count for any absorbed wakeups.
@@ -1784,7 +1725,7 @@ LWLockRelease(LWLock *lock)
break;
if (i < 0)
- elog(ERROR, "lock %s %d is not held", T_NAME(lock), T_ID(lock));
+ elog(ERROR, "lock %s is not held", T_NAME(lock));
mode = held_lwlocks[i].mode;
@@ -1829,7 +1770,7 @@ LWLockRelease(LWLock *lock)
LWLockWakeup(lock);
}
- TRACE_POSTGRESQL_LWLOCK_RELEASE(T_NAME(lock), T_ID(lock));
+ TRACE_POSTGRESQL_LWLOCK_RELEASE(T_NAME(lock));
/*
* Now okay to allow cancel/die interrupts.
diff --git a/src/backend/utils/mmgr/dsa.c b/src/backend/utils/mmgr/dsa.c
index abe3f1a63d1..988a2970b2d 100644
--- a/src/backend/utils/mmgr/dsa.c
+++ b/src/backend/utils/mmgr/dsa.c
@@ -362,9 +362,6 @@ struct dsa_area
/* Pointer to the control object in shared memory. */
dsa_area_control *control;
- /* The lock tranche for this process. */
- LWLockTranche lwlock_tranche;
-
/* Has the mapping been pinned? */
bool mapping_pinned;
@@ -1207,10 +1204,8 @@ create_internal(void *place, size_t size,
area->mapping_pinned = false;
memset(area->segment_maps, 0, sizeof(dsa_segment_map) * DSA_MAX_SEGMENTS);
area->high_segment_index = 0;
- area->lwlock_tranche.array_base = &area->control->pools[0];
- area->lwlock_tranche.array_stride = sizeof(dsa_area_pool);
- area->lwlock_tranche.name = control->lwlock_tranche_name;
- LWLockRegisterTranche(control->lwlock_tranche_id, &area->lwlock_tranche);
+ LWLockRegisterTranche(control->lwlock_tranche_id,
+ control->lwlock_tranche_name);
LWLockInitialize(&control->lock, control->lwlock_tranche_id);
for (i = 0; i < DSA_NUM_SIZE_CLASSES; ++i)
LWLockInitialize(DSA_SCLASS_LOCK(area, i),
@@ -1267,10 +1262,8 @@ attach_internal(void *place, dsm_segment *segment, dsa_handle handle)
memset(&area->segment_maps[0], 0,
sizeof(dsa_segment_map) * DSA_MAX_SEGMENTS);
area->high_segment_index = 0;
- area->lwlock_tranche.array_base = &area->control->pools[0];
- area->lwlock_tranche.array_stride = sizeof(dsa_area_pool);
- area->lwlock_tranche.name = control->lwlock_tranche_name;
- LWLockRegisterTranche(control->lwlock_tranche_id, &area->lwlock_tranche);
+ LWLockRegisterTranche(control->lwlock_tranche_id,
+ control->lwlock_tranche_name);
/* Set up the segment map for this process's mapping. */
segment_map = &area->segment_maps[0];
diff --git a/src/backend/utils/probes.d b/src/backend/utils/probes.d
index 2f92dfa9adb..adcebe2e055 100644
--- a/src/backend/utils/probes.d
+++ b/src/backend/utils/probes.d
@@ -28,14 +28,14 @@ provider postgresql {
probe transaction__commit(LocalTransactionId);
probe transaction__abort(LocalTransactionId);
- probe lwlock__acquire(const char *, int, LWLockMode);
- probe lwlock__release(const char *, int);
- probe lwlock__wait__start(const char *, int, LWLockMode);
- probe lwlock__wait__done(const char *, int, LWLockMode);
- probe lwlock__condacquire(const char *, int, LWLockMode);
- probe lwlock__condacquire__fail(const char *, int, LWLockMode);
- probe lwlock__acquire__or__wait(const char *, int, LWLockMode);
- probe lwlock__acquire__or__wait__fail(const char *, int, LWLockMode);
+ probe lwlock__acquire(const char *, LWLockMode);
+ probe lwlock__release(const char *);
+ probe lwlock__wait__start(const char *, LWLockMode);
+ probe lwlock__wait__done(const char *, LWLockMode);
+ probe lwlock__condacquire(const char *, LWLockMode);
+ probe lwlock__condacquire__fail(const char *, LWLockMode);
+ probe lwlock__acquire__or__wait(const char *, LWLockMode);
+ probe lwlock__acquire__or__wait__fail(const char *, LWLockMode);
probe lock__wait__start(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE);
probe lock__wait__done(unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, LOCKMODE);
diff --git a/src/include/access/slru.h b/src/include/access/slru.h
index 5fcebc52fba..ca8ab7ba524 100644
--- a/src/include/access/slru.h
+++ b/src/include/access/slru.h
@@ -104,7 +104,6 @@ typedef struct SlruSharedData
/* LWLocks */
int lwlock_tranche_id;
- LWLockTranche lwlock_tranche;
char lwlock_tranche_name[SLRU_MAX_NAME_LENGTH];
LWLockPadded *buffer_locks;
} SlruSharedData;
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index 152ff062085..282f8aeccd2 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -715,8 +715,7 @@ typedef enum BackendState
* Wait Classes
* ----------
*/
-#define PG_WAIT_LWLOCK_NAMED 0x01000000U
-#define PG_WAIT_LWLOCK_TRANCHE 0x02000000U
+#define PG_WAIT_LWLOCK 0x01000000U
#define PG_WAIT_LOCK 0x03000000U
#define PG_WAIT_BUFFER_PIN 0x04000000U
#define PG_WAIT_ACTIVITY 0x05000000U
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index 9a2d86975ca..db1c687e21e 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -25,32 +25,6 @@
struct PGPROC;
/*
- * Prior to PostgreSQL 9.4, every lightweight lock in the system was stored
- * in a single array. For convenience and for compatibility with past
- * releases, we still have a main array, but it's now also permissible to
- * store LWLocks elsewhere in the main shared memory segment or in a dynamic
- * shared memory segment. Each array of lwlocks forms a separate "tranche".
- *
- * It's occasionally necessary to identify a particular LWLock "by name"; e.g.
- * because we wish to report the lock to dtrace. We could store a name or
- * other identifying information in the lock itself, but since it's common
- * to have many nearly-identical locks (e.g. one per buffer) this would end
- * up wasting significant amounts of memory. Instead, each lwlock stores a
- * tranche ID which tells us which array it's part of. Based on that, we can
- * figure out where the lwlock lies within the array using the data structure
- * shown below; the lock is then identified based on the tranche name and
- * computed array index. We need the array stride because the array might not
- * be an array of lwlocks, but rather some larger data structure that includes
- * one or more lwlocks per element.
- */
-typedef struct LWLockTranche
-{
- const char *name;
- void *array_base;
- Size array_stride;
-} LWLockTranche;
-
-/*
* Code outside of lwlock.c should not manipulate the contents of this
* structure directly, but we have to declare it here to allow LWLocks to be
* incorporated into other data structures.
@@ -118,8 +92,8 @@ extern char *MainLWLockNames[];
/* struct for storing named tranche information */
typedef struct NamedLWLockTranche
{
- LWLockTranche lwLockTranche;
int trancheId;
+ char *trancheName;
} NamedLWLockTranche;
extern PGDLLIMPORT NamedLWLockTranche *NamedLWLockTrancheArray;
@@ -199,9 +173,9 @@ 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 appropriate
- * metadata. Finally, LWLockInitialize should be called just once per lwlock,
- * passing the tranche ID as an argument.
+ * 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
@@ -209,17 +183,18 @@ extern LWLockPadded *GetNamedLWLockTranche(const char *tranche_name);
* registration in the main shared memory segment wouldn't work for that case.
*/
extern int LWLockNewTrancheId(void);
-extern void LWLockRegisterTranche(int tranche_id, LWLockTranche *tranche);
+extern void LWLockRegisterTranche(int tranche_id, char *tranche_name);
extern void LWLockInitialize(LWLock *lock, int tranche_id);
/*
- * We reserve a few predefined tranche IDs. A call to LWLockNewTrancheId
- * will never return a value less than LWTRANCHE_FIRST_USER_DEFINED.
+ * Every tranche ID less than NUM_INDIVIDUAL_LWLOCKS is reserved; also,
+ * we reserve additional tranche IDs for builtin tranches not included in
+ * the set of individual LWLocks. A call to LWLockNewTrancheId will never
+ * return a value less than LWTRANCHE_FIRST_USER_DEFINED.
*/
typedef enum BuiltinTrancheIds
{
- LWTRANCHE_MAIN,
- LWTRANCHE_CLOG_BUFFERS,
+ LWTRANCHE_CLOG_BUFFERS = NUM_INDIVIDUAL_LWLOCKS,
LWTRANCHE_COMMITTS_BUFFERS,
LWTRANCHE_SUBTRANS_BUFFERS,
LWTRANCHE_MXACTOFFSET_BUFFERS,