Skip to content

Commit fe702a7

Browse files
committed
Move each SLRU's lwlocks to a separate tranche.
This makes it significantly easier to identify these lwlocks in LWLOCK_STATS or Trace_lwlocks output. It's also arguably better from a modularity standpoint, since lwlock.c no longer needs to know anything about the LWLock needs of the higher-level SLRU facility. Ildus Kurbangaliev, reviewd by Álvaro Herrera and by me.
1 parent c405918 commit fe702a7

File tree

9 files changed

+41
-43
lines changed

9 files changed

+41
-43
lines changed

src/backend/access/transam/clog.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ void
456456
CLOGShmemInit(void)
457457
{
458458
ClogCtl->PagePrecedes = CLOGPagePrecedes;
459-
SimpleLruInit(ClogCtl, "CLOG Ctl", CLOGShmemBuffers(), CLOG_LSNS_PER_PAGE,
459+
SimpleLruInit(ClogCtl, "clog", CLOGShmemBuffers(), CLOG_LSNS_PER_PAGE,
460460
CLogControlLock, "pg_clog");
461461
}
462462

src/backend/access/transam/commit_ts.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ CommitTsShmemInit(void)
478478
bool found;
479479

480480
CommitTsCtl->PagePrecedes = CommitTsPagePrecedes;
481-
SimpleLruInit(CommitTsCtl, "CommitTs Ctl", CommitTsShmemBuffers(), 0,
481+
SimpleLruInit(CommitTsCtl, "commit_timestamp", CommitTsShmemBuffers(), 0,
482482
CommitTsControlLock, "pg_commit_ts");
483483

484484
commitTsShared = ShmemInitStruct("CommitTs shared",

src/backend/access/transam/multixact.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1838,10 +1838,10 @@ MultiXactShmemInit(void)
18381838
MultiXactMemberCtl->PagePrecedes = MultiXactMemberPagePrecedes;
18391839

18401840
SimpleLruInit(MultiXactOffsetCtl,
1841-
"MultiXactOffset Ctl", NUM_MXACTOFFSET_BUFFERS, 0,
1841+
"multixact_offset", NUM_MXACTOFFSET_BUFFERS, 0,
18421842
MultiXactOffsetControlLock, "pg_multixact/offsets");
18431843
SimpleLruInit(MultiXactMemberCtl,
1844-
"MultiXactMember Ctl", NUM_MXACTMEMBER_BUFFERS, 0,
1844+
"multixact_member", NUM_MXACTMEMBER_BUFFERS, 0,
18451845
MultiXactMemberControlLock, "pg_multixact/members");
18461846

18471847
/* Initialize our shared state struct */

src/backend/access/transam/slru.c

+25-12
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ SimpleLruShmemSize(int nslots, int nlsns)
152152
sz += MAXALIGN(nslots * sizeof(bool)); /* page_dirty[] */
153153
sz += MAXALIGN(nslots * sizeof(int)); /* page_number[] */
154154
sz += MAXALIGN(nslots * sizeof(int)); /* page_lru_count[] */
155-
sz += MAXALIGN(nslots * sizeof(LWLock *)); /* buffer_locks[] */
155+
sz += MAXALIGN(nslots * sizeof(LWLockPadded)); /* buffer_locks[] */
156156

157157
if (nlsns > 0)
158158
sz += MAXALIGN(nslots * nlsns * sizeof(XLogRecPtr)); /* group_lsn[] */
@@ -203,29 +203,42 @@ SimpleLruInit(SlruCtl ctl, const char *name, int nslots, int nlsns,
203203
offset += MAXALIGN(nslots * sizeof(int));
204204
shared->page_lru_count = (int *) (ptr + offset);
205205
offset += MAXALIGN(nslots * sizeof(int));
206-
shared->buffer_locks = (LWLock **) (ptr + offset);
207-
offset += MAXALIGN(nslots * sizeof(LWLock *));
208206

209207
if (nlsns > 0)
210208
{
211209
shared->group_lsn = (XLogRecPtr *) (ptr + offset);
212210
offset += MAXALIGN(nslots * nlsns * sizeof(XLogRecPtr));
213211
}
214212

213+
/* Initialize LWLocks */
214+
shared->buffer_locks = (LWLockPadded *) ShmemAlloc(sizeof(LWLockPadded) * nslots);
215+
216+
Assert(strlen(name) + 1 < SLRU_MAX_NAME_LENGTH);
217+
strlcpy(shared->lwlock_tranche_name, name, SLRU_MAX_NAME_LENGTH);
218+
shared->lwlock_tranche_id = LWLockNewTrancheId();
219+
shared->lwlock_tranche.name = shared->lwlock_tranche_name;
220+
shared->lwlock_tranche.array_base = shared->buffer_locks;
221+
shared->lwlock_tranche.array_stride = sizeof(LWLockPadded);
222+
215223
ptr += BUFFERALIGN(offset);
216224
for (slotno = 0; slotno < nslots; slotno++)
217225
{
226+
LWLockInitialize(&shared->buffer_locks[slotno].lock,
227+
shared->lwlock_tranche_id);
228+
218229
shared->page_buffer[slotno] = ptr;
219230
shared->page_status[slotno] = SLRU_PAGE_EMPTY;
220231
shared->page_dirty[slotno] = false;
221232
shared->page_lru_count[slotno] = 0;
222-
shared->buffer_locks[slotno] = LWLockAssign();
223233
ptr += BLCKSZ;
224234
}
225235
}
226236
else
227237
Assert(found);
228238

239+
/* Register SLRU tranche in the main tranches array */
240+
LWLockRegisterTranche(shared->lwlock_tranche_id, &shared->lwlock_tranche);
241+
229242
/*
230243
* Initialize the unshared control struct, including directory path. We
231244
* assume caller set PagePrecedes.
@@ -308,8 +321,8 @@ SimpleLruWaitIO(SlruCtl ctl, int slotno)
308321

309322
/* See notes at top of file */
310323
LWLockRelease(shared->ControlLock);
311-
LWLockAcquire(shared->buffer_locks[slotno], LW_SHARED);
312-
LWLockRelease(shared->buffer_locks[slotno]);
324+
LWLockAcquire(&shared->buffer_locks[slotno].lock, LW_SHARED);
325+
LWLockRelease(&shared->buffer_locks[slotno].lock);
313326
LWLockAcquire(shared->ControlLock, LW_EXCLUSIVE);
314327

315328
/*
@@ -323,7 +336,7 @@ SimpleLruWaitIO(SlruCtl ctl, int slotno)
323336
if (shared->page_status[slotno] == SLRU_PAGE_READ_IN_PROGRESS ||
324337
shared->page_status[slotno] == SLRU_PAGE_WRITE_IN_PROGRESS)
325338
{
326-
if (LWLockConditionalAcquire(shared->buffer_locks[slotno], LW_SHARED))
339+
if (LWLockConditionalAcquire(&shared->buffer_locks[slotno].lock, LW_SHARED))
327340
{
328341
/* indeed, the I/O must have failed */
329342
if (shared->page_status[slotno] == SLRU_PAGE_READ_IN_PROGRESS)
@@ -333,7 +346,7 @@ SimpleLruWaitIO(SlruCtl ctl, int slotno)
333346
shared->page_status[slotno] = SLRU_PAGE_VALID;
334347
shared->page_dirty[slotno] = true;
335348
}
336-
LWLockRelease(shared->buffer_locks[slotno]);
349+
LWLockRelease(&shared->buffer_locks[slotno].lock);
337350
}
338351
}
339352
}
@@ -402,7 +415,7 @@ SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok,
402415
shared->page_dirty[slotno] = false;
403416

404417
/* Acquire per-buffer lock (cannot deadlock, see notes at top) */
405-
LWLockAcquire(shared->buffer_locks[slotno], LW_EXCLUSIVE);
418+
LWLockAcquire(&shared->buffer_locks[slotno].lock, LW_EXCLUSIVE);
406419

407420
/* Release control lock while doing I/O */
408421
LWLockRelease(shared->ControlLock);
@@ -422,7 +435,7 @@ SimpleLruReadPage(SlruCtl ctl, int pageno, bool write_ok,
422435

423436
shared->page_status[slotno] = ok ? SLRU_PAGE_VALID : SLRU_PAGE_EMPTY;
424437

425-
LWLockRelease(shared->buffer_locks[slotno]);
438+
LWLockRelease(&shared->buffer_locks[slotno].lock);
426439

427440
/* Now it's okay to ereport if we failed */
428441
if (!ok)
@@ -518,7 +531,7 @@ SlruInternalWritePage(SlruCtl ctl, int slotno, SlruFlush fdata)
518531
shared->page_dirty[slotno] = false;
519532

520533
/* Acquire per-buffer lock (cannot deadlock, see notes at top) */
521-
LWLockAcquire(shared->buffer_locks[slotno], LW_EXCLUSIVE);
534+
LWLockAcquire(&shared->buffer_locks[slotno].lock, LW_EXCLUSIVE);
522535

523536
/* Release control lock while doing I/O */
524537
LWLockRelease(shared->ControlLock);
@@ -547,7 +560,7 @@ SlruInternalWritePage(SlruCtl ctl, int slotno, SlruFlush fdata)
547560

548561
shared->page_status[slotno] = SLRU_PAGE_VALID;
549562

550-
LWLockRelease(shared->buffer_locks[slotno]);
563+
LWLockRelease(&shared->buffer_locks[slotno].lock);
551564

552565
/* Now it's okay to ereport if we failed */
553566
if (!ok)

src/backend/access/transam/subtrans.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ void
178178
SUBTRANSShmemInit(void)
179179
{
180180
SubTransCtl->PagePrecedes = SubTransPagePrecedes;
181-
SimpleLruInit(SubTransCtl, "SUBTRANS Ctl", NUM_SUBTRANS_BUFFERS, 0,
181+
SimpleLruInit(SubTransCtl, "subtrans", NUM_SUBTRANS_BUFFERS, 0,
182182
SubtransControlLock, "pg_subtrans");
183183
/* Override default assumption that writes should be fsync'd */
184184
SubTransCtl->do_fsync = false;

src/backend/commands/async.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ AsyncShmemInit(void)
479479
* Set up SLRU management of the pg_notify data.
480480
*/
481481
AsyncCtl->PagePrecedes = asyncQueuePagePrecedes;
482-
SimpleLruInit(AsyncCtl, "Async Ctl", NUM_ASYNC_BUFFERS, 0,
482+
SimpleLruInit(AsyncCtl, "async", NUM_ASYNC_BUFFERS, 0,
483483
AsyncCtlLock, "pg_notify");
484484
/* Override default assumption that writes should be fsync'd */
485485
AsyncCtl->do_fsync = false;

src/backend/storage/lmgr/lwlock.c

-23
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,6 @@
7676
*/
7777
#include "postgres.h"
7878

79-
#include "access/clog.h"
80-
#include "access/commit_ts.h"
81-
#include "access/multixact.h"
82-
#include "access/subtrans.h"
83-
#include "commands/async.h"
8479
#include "miscadmin.h"
8580
#include "pg_trace.h"
8681
#include "postmaster/postmaster.h"
@@ -364,24 +359,6 @@ NumLWLocks(void)
364359
/* proc.c needs one for each backend or auxiliary process */
365360
numLocks += MaxBackends + NUM_AUXILIARY_PROCS;
366361

367-
/* clog.c needs one per CLOG buffer */
368-
numLocks += CLOGShmemBuffers();
369-
370-
/* commit_ts.c needs one per CommitTs buffer */
371-
numLocks += CommitTsShmemBuffers();
372-
373-
/* subtrans.c needs one per SubTrans buffer */
374-
numLocks += NUM_SUBTRANS_BUFFERS;
375-
376-
/* multixact.c needs two SLRU areas */
377-
numLocks += NUM_MXACTOFFSET_BUFFERS + NUM_MXACTMEMBER_BUFFERS;
378-
379-
/* async.c needs one per Async buffer */
380-
numLocks += NUM_ASYNC_BUFFERS;
381-
382-
/* predicate.c needs one per old serializable xid buffer */
383-
numLocks += NUM_OLDSERXID_BUFFERS;
384-
385362
/* slot.c needs one for each slot */
386363
numLocks += max_replication_slots;
387364

src/backend/storage/lmgr/predicate.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ OldSerXidInit(void)
794794
* Set up SLRU management of the pg_serial data.
795795
*/
796796
OldSerXidSlruCtl->PagePrecedes = OldSerXidPagePrecedesLogically;
797-
SimpleLruInit(OldSerXidSlruCtl, "OldSerXid SLRU Ctl",
797+
SimpleLruInit(OldSerXidSlruCtl, "oldserxid",
798798
NUM_OLDSERXID_BUFFERS, 0, OldSerXidLock, "pg_serial");
799799
/* Override default assumption that writes should be fsync'd */
800800
OldSerXidSlruCtl->do_fsync = false;

src/include/access/slru.h

+9-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
*/
3737
#define SLRU_PAGES_PER_SEGMENT 32
3838

39+
/* Maximum length of an SLRU name */
40+
#define SLRU_MAX_NAME_LENGTH 32
41+
3942
/*
4043
* Page status codes. Note that these do not include the "dirty" bit.
4144
* page_dirty can be TRUE only in the VALID or WRITE_IN_PROGRESS states;
@@ -69,7 +72,6 @@ typedef struct SlruSharedData
6972
bool *page_dirty;
7073
int *page_number;
7174
int *page_lru_count;
72-
LWLock **buffer_locks;
7375

7476
/*
7577
* Optional array of WAL flush LSNs associated with entries in the SLRU
@@ -99,6 +101,12 @@ typedef struct SlruSharedData
99101
* the latest page.
100102
*/
101103
int latest_page_number;
104+
105+
/* LWLocks */
106+
int lwlock_tranche_id;
107+
LWLockTranche lwlock_tranche;
108+
char lwlock_tranche_name[SLRU_MAX_NAME_LENGTH];
109+
LWLockPadded *buffer_locks;
102110
} SlruSharedData;
103111

104112
typedef SlruSharedData *SlruShared;

0 commit comments

Comments
 (0)