@@ -1352,9 +1352,10 @@ BufferAlloc(SMgrRelation smgr, char relpersistence, ForkNumber forkNum,
13521352 LWLockRelease (newPartitionLock );
13531353
13541354 /*
1355- * Buffer contents are currently invalid. Try to get the io_in_progress
1356- * lock. If StartBufferIO returns false, then someone else managed to
1357- * read it before we did, so there's nothing left for BufferAlloc() to do.
1355+ * Buffer contents are currently invalid. Try to obtain the right to
1356+ * start I/O. If StartBufferIO returns false, then someone else managed
1357+ * to read it before we did, so there's nothing left for BufferAlloc() to
1358+ * do.
13581359 */
13591360 if (StartBufferIO (buf , true))
13601361 * foundPtr = false;
@@ -1777,9 +1778,8 @@ UnpinBuffer(BufferDesc *buf, bool fixOwner)
17771778 */
17781779 VALGRIND_MAKE_MEM_NOACCESS (BufHdrGetBlock (buf ), BLCKSZ );
17791780
1780- /* I'd better not still hold any locks on the buffer */
1781+ /* I'd better not still hold the buffer content lock */
17811782 Assert (!LWLockHeldByMe (BufferDescriptorGetContentLock (buf )));
1782- Assert (!LWLockHeldByMe (BufferDescriptorGetIOLock (buf )));
17831783
17841784 /*
17851785 * Decrement the shared reference count.
@@ -2742,9 +2742,9 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
27422742 uint32 buf_state ;
27432743
27442744 /*
2745- * Acquire the buffer's io_in_progress lock . If StartBufferIO returns
2746- * false, then someone else flushed the buffer before we could, so we need
2747- * not do anything.
2745+ * Try to start an I/O operation . If StartBufferIO returns false, then
2746+ * someone else flushed the buffer before we could, so we need not do
2747+ * anything.
27482748 */
27492749 if (!StartBufferIO (buf , false))
27502750 return ;
@@ -2800,7 +2800,7 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
28002800 /*
28012801 * Now it's safe to write buffer to disk. Note that no one else should
28022802 * have been able to write it while we were busy with log flushing because
2803- * we have the io_in_progress lock .
2803+ * only one process at a time can set the BM_IO_IN_PROGRESS bit .
28042804 */
28052805 bufBlock = BufHdrGetBlock (buf );
28062806
@@ -2835,7 +2835,7 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
28352835
28362836 /*
28372837 * Mark the buffer as clean (unless BM_JUST_DIRTIED has become set) and
2838- * end the io_in_progress state.
2838+ * end the BM_IO_IN_PROGRESS state.
28392839 */
28402840 TerminateBufferIO (buf , true, 0 );
28412841
@@ -4271,7 +4271,7 @@ IsBufferCleanupOK(Buffer buffer)
42714271 * Functions for buffer I/O handling
42724272 *
42734273 * Note: We assume that nested buffer I/O never occurs.
4274- * i.e at most one io_in_progress lock is held per proc.
4274+ * i.e at most one BM_IO_IN_PROGRESS bit is set per proc.
42754275 *
42764276 * Also note that these are used only for shared buffers, not local ones.
42774277 */
@@ -4282,13 +4282,9 @@ IsBufferCleanupOK(Buffer buffer)
42824282static void
42834283WaitIO (BufferDesc * buf )
42844284{
4285- /*
4286- * Changed to wait until there's no IO - Inoue 01/13/2000
4287- *
4288- * Note this is *necessary* because an error abort in the process doing
4289- * I/O could release the io_in_progress_lock prematurely. See
4290- * AbortBufferIO.
4291- */
4285+ ConditionVariable * cv = BufferDescriptorGetIOCV (buf );
4286+
4287+ ConditionVariablePrepareToSleep (cv );
42924288 for (;;)
42934289 {
42944290 uint32 buf_state ;
@@ -4303,9 +4299,9 @@ WaitIO(BufferDesc *buf)
43034299
43044300 if (!(buf_state & BM_IO_IN_PROGRESS ))
43054301 break ;
4306- LWLockAcquire (BufferDescriptorGetIOLock (buf ), LW_SHARED );
4307- LWLockRelease (BufferDescriptorGetIOLock (buf ));
4302+ ConditionVariableSleep (cv , WAIT_EVENT_BUFFER_IO );
43084303 }
4304+ ConditionVariableCancelSleep ();
43094305}
43104306
43114307/*
@@ -4317,7 +4313,7 @@ WaitIO(BufferDesc *buf)
43174313 * In some scenarios there are race conditions in which multiple backends
43184314 * could attempt the same I/O operation concurrently. If someone else
43194315 * has already started I/O on this buffer then we will block on the
4320- * io_in_progress lock until he's done.
4316+ * I/O condition variable until he's done.
43214317 *
43224318 * Input operations are only attempted on buffers that are not BM_VALID,
43234319 * and output operations only on buffers that are BM_VALID and BM_DIRTY,
@@ -4335,25 +4331,11 @@ StartBufferIO(BufferDesc *buf, bool forInput)
43354331
43364332 for (;;)
43374333 {
4338- /*
4339- * Grab the io_in_progress lock so that other processes can wait for
4340- * me to finish the I/O.
4341- */
4342- LWLockAcquire (BufferDescriptorGetIOLock (buf ), LW_EXCLUSIVE );
4343-
43444334 buf_state = LockBufHdr (buf );
43454335
43464336 if (!(buf_state & BM_IO_IN_PROGRESS ))
43474337 break ;
4348-
4349- /*
4350- * The only way BM_IO_IN_PROGRESS could be set when the io_in_progress
4351- * lock isn't held is if the process doing the I/O is recovering from
4352- * an error (see AbortBufferIO). If that's the case, we must wait for
4353- * him to get unwedged.
4354- */
43554338 UnlockBufHdr (buf , buf_state );
4356- LWLockRelease (BufferDescriptorGetIOLock (buf ));
43574339 WaitIO (buf );
43584340 }
43594341
@@ -4363,7 +4345,6 @@ StartBufferIO(BufferDesc *buf, bool forInput)
43634345 {
43644346 /* someone else already did the I/O */
43654347 UnlockBufHdr (buf , buf_state );
4366- LWLockRelease (BufferDescriptorGetIOLock (buf ));
43674348 return false;
43684349 }
43694350
@@ -4381,7 +4362,6 @@ StartBufferIO(BufferDesc *buf, bool forInput)
43814362 * (Assumptions)
43824363 * My process is executing IO for the buffer
43834364 * BM_IO_IN_PROGRESS bit is set for the buffer
4384- * We hold the buffer's io_in_progress lock
43854365 * The buffer is Pinned
43864366 *
43874367 * If clear_dirty is true and BM_JUST_DIRTIED is not set, we clear the
@@ -4413,7 +4393,7 @@ TerminateBufferIO(BufferDesc *buf, bool clear_dirty, uint32 set_flag_bits)
44134393
44144394 InProgressBuf = NULL ;
44154395
4416- LWLockRelease ( BufferDescriptorGetIOLock (buf ));
4396+ ConditionVariableBroadcast ( BufferDescriptorGetIOCV (buf ));
44174397}
44184398
44194399/*
@@ -4434,14 +4414,6 @@ AbortBufferIO(void)
44344414 {
44354415 uint32 buf_state ;
44364416
4437- /*
4438- * Since LWLockReleaseAll has already been called, we're not holding
4439- * the buffer's io_in_progress_lock. We have to re-acquire it so that
4440- * we can use TerminateBufferIO. Anyone who's executing WaitIO on the
4441- * buffer will be in a busy spin until we succeed in doing this.
4442- */
4443- LWLockAcquire (BufferDescriptorGetIOLock (buf ), LW_EXCLUSIVE );
4444-
44454417 buf_state = LockBufHdr (buf );
44464418 Assert (buf_state & BM_IO_IN_PROGRESS );
44474419 if (IsForInput )
0 commit comments