Skip to content

Commit 3baae90

Browse files
committed
bufmgr: fewer calls to BufferDescriptorGetContentLock
We're planning to merge buffer content locks into BufferDesc.state. To reduce the size of that patch, centralize calls to BufferDescriptorGetContentLock(). The biggest part of the change is in assertions, by introducing BufferIsLockedByMe[InMode]() (and removing BufferIsExclusiveLocked()). This seems like an improvement even without aforementioned plans. Additionally replace some direct calls to LWLockAcquire() with calls to LockBuffer(). Reviewed-by: Matthias van de Meent <boekewurm+postgres@gmail.com> Discussion: https://postgr.es/m/fvfmkr5kk4nyex56ejgxj3uzi63isfxovp2biecb4bspbjrze7@az2pljabhnff
1 parent 2a2e1b4 commit 3baae90

File tree

4 files changed

+61
-18
lines changed

4 files changed

+61
-18
lines changed

src/backend/access/heap/visibilitymap.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,8 @@ visibilitymap_set(Relation rel, BlockNumber heapBlk, Buffer heapBuf,
270270
if (BufferIsValid(heapBuf) && BufferGetBlockNumber(heapBuf) != heapBlk)
271271
elog(ERROR, "wrong heap buffer passed to visibilitymap_set");
272272

273-
Assert(!BufferIsValid(heapBuf) || BufferIsExclusiveLocked(heapBuf));
273+
Assert(!BufferIsValid(heapBuf) ||
274+
BufferIsLockedByMeInMode(heapBuf, BUFFER_LOCK_EXCLUSIVE));
274275

275276
/* Check that we have the right VM page pinned */
276277
if (!BufferIsValid(vmBuf) || BufferGetBlockNumber(vmBuf) != mapBlock)

src/backend/access/transam/xloginsert.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,8 @@ XLogRegisterBuffer(uint8 block_id, Buffer buffer, uint8 flags)
258258
*/
259259
#ifdef USE_ASSERT_CHECKING
260260
if (!(flags & REGBUF_NO_CHANGE))
261-
Assert(BufferIsExclusiveLocked(buffer) && BufferIsDirty(buffer));
261+
Assert(BufferIsLockedByMeInMode(buffer, BUFFER_LOCK_EXCLUSIVE) &&
262+
BufferIsDirty(buffer));
262263
#endif
263264

264265
if (block_id >= max_registered_block_id)

src/backend/storage/buffer/bufmgr.c

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,7 +1068,7 @@ ZeroAndLockBuffer(Buffer buffer, ReadBufferMode mode, bool already_valid)
10681068
* already valid.)
10691069
*/
10701070
if (!isLocalBuf)
1071-
LWLockAcquire(BufferDescriptorGetContentLock(bufHdr), LW_EXCLUSIVE);
1071+
LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE);
10721072

10731073
/* Set BM_VALID, terminate IO, and wake up any waiters */
10741074
if (isLocalBuf)
@@ -2825,7 +2825,7 @@ ExtendBufferedRelShared(BufferManagerRelation bmr,
28252825
}
28262826

28272827
if (lock)
2828-
LWLockAcquire(BufferDescriptorGetContentLock(buf_hdr), LW_EXCLUSIVE);
2828+
LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE);
28292829

28302830
TerminateBufferIO(buf_hdr, false, BM_VALID, true, false);
28312831
}
@@ -2838,14 +2838,40 @@ ExtendBufferedRelShared(BufferManagerRelation bmr,
28382838
}
28392839

28402840
/*
2841-
* BufferIsExclusiveLocked
2841+
* BufferIsLockedByMe
2842+
*
2843+
* Checks if this backend has the buffer locked in any mode.
2844+
*
2845+
* Buffer must be pinned.
2846+
*/
2847+
bool
2848+
BufferIsLockedByMe(Buffer buffer)
2849+
{
2850+
BufferDesc *bufHdr;
2851+
2852+
Assert(BufferIsPinned(buffer));
2853+
2854+
if (BufferIsLocal(buffer))
2855+
{
2856+
/* Content locks are not maintained for local buffers. */
2857+
return true;
2858+
}
2859+
else
2860+
{
2861+
bufHdr = GetBufferDescriptor(buffer - 1);
2862+
return LWLockHeldByMe(BufferDescriptorGetContentLock(bufHdr));
2863+
}
2864+
}
2865+
2866+
/*
2867+
* BufferIsLockedByMeInMode
28422868
*
2843-
* Checks if buffer is exclusive-locked.
2869+
* Checks if this backend has the buffer locked in the specified mode.
28442870
*
28452871
* Buffer must be pinned.
28462872
*/
28472873
bool
2848-
BufferIsExclusiveLocked(Buffer buffer)
2874+
BufferIsLockedByMeInMode(Buffer buffer, int mode)
28492875
{
28502876
BufferDesc *bufHdr;
28512877

@@ -2858,9 +2884,23 @@ BufferIsExclusiveLocked(Buffer buffer)
28582884
}
28592885
else
28602886
{
2887+
LWLockMode lw_mode;
2888+
2889+
switch (mode)
2890+
{
2891+
case BUFFER_LOCK_EXCLUSIVE:
2892+
lw_mode = LW_EXCLUSIVE;
2893+
break;
2894+
case BUFFER_LOCK_SHARE:
2895+
lw_mode = LW_SHARED;
2896+
break;
2897+
default:
2898+
pg_unreachable();
2899+
}
2900+
28612901
bufHdr = GetBufferDescriptor(buffer - 1);
28622902
return LWLockHeldByMeInMode(BufferDescriptorGetContentLock(bufHdr),
2863-
LW_EXCLUSIVE);
2903+
lw_mode);
28642904
}
28652905
}
28662906

@@ -2889,8 +2929,7 @@ BufferIsDirty(Buffer buffer)
28892929
else
28902930
{
28912931
bufHdr = GetBufferDescriptor(buffer - 1);
2892-
Assert(LWLockHeldByMeInMode(BufferDescriptorGetContentLock(bufHdr),
2893-
LW_EXCLUSIVE));
2932+
Assert(BufferIsLockedByMeInMode(buffer, BUFFER_LOCK_EXCLUSIVE));
28942933
}
28952934

28962935
return pg_atomic_read_u32(&bufHdr->state) & BM_DIRTY;
@@ -2924,8 +2963,7 @@ MarkBufferDirty(Buffer buffer)
29242963
bufHdr = GetBufferDescriptor(buffer - 1);
29252964

29262965
Assert(BufferIsPinned(buffer));
2927-
Assert(LWLockHeldByMeInMode(BufferDescriptorGetContentLock(bufHdr),
2928-
LW_EXCLUSIVE));
2966+
Assert(BufferIsLockedByMeInMode(buffer, BUFFER_LOCK_EXCLUSIVE));
29292967

29302968
old_buf_state = pg_atomic_read_u32(&bufHdr->state);
29312969
for (;;)
@@ -3259,7 +3297,10 @@ UnpinBufferNoOwner(BufferDesc *buf)
32593297
*/
32603298
VALGRIND_MAKE_MEM_NOACCESS(BufHdrGetBlock(buf), BLCKSZ);
32613299

3262-
/* I'd better not still hold the buffer content lock */
3300+
/*
3301+
* I'd better not still hold the buffer content lock. Can't use
3302+
* BufferIsLockedByMe(), as that asserts the buffer is pinned.
3303+
*/
32633304
Assert(!LWLockHeldByMe(BufferDescriptorGetContentLock(buf)));
32643305

32653306
/*
@@ -5324,7 +5365,7 @@ FlushOneBuffer(Buffer buffer)
53245365

53255366
bufHdr = GetBufferDescriptor(buffer - 1);
53265367

5327-
Assert(LWLockHeldByMe(BufferDescriptorGetContentLock(bufHdr)));
5368+
Assert(BufferIsLockedByMe(buffer));
53285369

53295370
FlushBuffer(bufHdr, NULL, IOOBJECT_RELATION, IOCONTEXT_NORMAL);
53305371
}
@@ -5415,7 +5456,7 @@ MarkBufferDirtyHint(Buffer buffer, bool buffer_std)
54155456

54165457
Assert(GetPrivateRefCount(buffer) > 0);
54175458
/* here, either share or exclusive lock is OK */
5418-
Assert(LWLockHeldByMe(BufferDescriptorGetContentLock(bufHdr)));
5459+
Assert(BufferIsLockedByMe(buffer));
54195460

54205461
/*
54215462
* This routine might get called many times on the same page, if we are
@@ -5898,8 +5939,7 @@ IsBufferCleanupOK(Buffer buffer)
58985939
bufHdr = GetBufferDescriptor(buffer - 1);
58995940

59005941
/* caller must hold exclusive lock on buffer */
5901-
Assert(LWLockHeldByMeInMode(BufferDescriptorGetContentLock(bufHdr),
5902-
LW_EXCLUSIVE));
5942+
Assert(BufferIsLockedByMeInMode(buffer, BUFFER_LOCK_EXCLUSIVE));
59035943

59045944
buf_state = LockBufHdr(bufHdr);
59055945

src/include/storage/bufmgr.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,8 @@ extern void WaitReadBuffers(ReadBuffersOperation *operation);
230230

231231
extern void ReleaseBuffer(Buffer buffer);
232232
extern void UnlockReleaseBuffer(Buffer buffer);
233-
extern bool BufferIsExclusiveLocked(Buffer buffer);
233+
extern bool BufferIsLockedByMe(Buffer buffer);
234+
extern bool BufferIsLockedByMeInMode(Buffer buffer, int mode);
234235
extern bool BufferIsDirty(Buffer buffer);
235236
extern void MarkBufferDirty(Buffer buffer);
236237
extern void IncrBufferRefCount(Buffer buffer);

0 commit comments

Comments
 (0)