@@ -1352,9 +1352,10 @@ BufferAlloc(SMgrRelation smgr, char relpersistence, ForkNumber forkNum,
1352
1352
LWLockRelease (newPartitionLock );
1353
1353
1354
1354
/*
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.
1358
1359
*/
1359
1360
if (StartBufferIO (buf , true))
1360
1361
* foundPtr = false;
@@ -1777,9 +1778,8 @@ UnpinBuffer(BufferDesc *buf, bool fixOwner)
1777
1778
*/
1778
1779
VALGRIND_MAKE_MEM_NOACCESS (BufHdrGetBlock (buf ),BLCKSZ );
1779
1780
1780
- /* I'd better not still holdany locks on the buffer */
1781
+ /* I'd better not still hold the buffer content lock */
1781
1782
Assert (!LWLockHeldByMe (BufferDescriptorGetContentLock (buf )));
1782
- Assert (!LWLockHeldByMe (BufferDescriptorGetIOLock (buf )));
1783
1783
1784
1784
/*
1785
1785
* Decrement the shared reference count.
@@ -2742,9 +2742,9 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
2742
2742
uint32 buf_state ;
2743
2743
2744
2744
/*
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.
2748
2748
*/
2749
2749
if (!StartBufferIO (buf , false))
2750
2750
return ;
@@ -2800,7 +2800,7 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
2800
2800
/*
2801
2801
* Now it's safe to write buffer to disk. Note that no one else should
2802
2802
* have been able to write it while we were busy with log flushing because
2803
- *we have theio_in_progress lock .
2803
+ *only one process at a time can set theBM_IO_IN_PROGRESS bit .
2804
2804
*/
2805
2805
bufBlock = BufHdrGetBlock (buf );
2806
2806
@@ -2835,7 +2835,7 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
2835
2835
2836
2836
/*
2837
2837
* Mark the buffer as clean (unless BM_JUST_DIRTIED has become set) and
2838
- * end theio_in_progress state.
2838
+ * end theBM_IO_IN_PROGRESS state.
2839
2839
*/
2840
2840
TerminateBufferIO (buf , true,0 );
2841
2841
@@ -4271,7 +4271,7 @@ IsBufferCleanupOK(Buffer buffer)
4271
4271
*Functions for buffer I/O handling
4272
4272
*
4273
4273
*Note: We assume that nested buffer I/O never occurs.
4274
- *i.e at most oneio_in_progress lock isheld per proc.
4274
+ *i.e at most oneBM_IO_IN_PROGRESS bit isset per proc.
4275
4275
*
4276
4276
*Also note that these are used only for shared buffers, not local ones.
4277
4277
*/
@@ -4282,13 +4282,9 @@ IsBufferCleanupOK(Buffer buffer)
4282
4282
static void
4283
4283
WaitIO (BufferDesc * buf )
4284
4284
{
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 );
4292
4288
for (;;)
4293
4289
{
4294
4290
uint32 buf_state ;
@@ -4303,9 +4299,9 @@ WaitIO(BufferDesc *buf)
4303
4299
4304
4300
if (!(buf_state & BM_IO_IN_PROGRESS ))
4305
4301
break ;
4306
- LWLockAcquire (BufferDescriptorGetIOLock (buf ),LW_SHARED );
4307
- LWLockRelease (BufferDescriptorGetIOLock (buf ));
4302
+ ConditionVariableSleep (cv ,WAIT_EVENT_BUFFER_IO );
4308
4303
}
4304
+ ConditionVariableCancelSleep ();
4309
4305
}
4310
4306
4311
4307
/*
@@ -4317,7 +4313,7 @@ WaitIO(BufferDesc *buf)
4317
4313
* In some scenarios there are race conditions in which multiple backends
4318
4314
* could attempt the same I/O operation concurrently. If someone else
4319
4315
* 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.
4321
4317
*
4322
4318
* Input operations are only attempted on buffers that are not BM_VALID,
4323
4319
* and output operations only on buffers that are BM_VALID and BM_DIRTY,
@@ -4335,25 +4331,11 @@ StartBufferIO(BufferDesc *buf, bool forInput)
4335
4331
4336
4332
for (;;)
4337
4333
{
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
-
4344
4334
buf_state = LockBufHdr (buf );
4345
4335
4346
4336
if (!(buf_state & BM_IO_IN_PROGRESS ))
4347
4337
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
- */
4355
4338
UnlockBufHdr (buf ,buf_state );
4356
- LWLockRelease (BufferDescriptorGetIOLock (buf ));
4357
4339
WaitIO (buf );
4358
4340
}
4359
4341
@@ -4363,7 +4345,6 @@ StartBufferIO(BufferDesc *buf, bool forInput)
4363
4345
{
4364
4346
/* someone else already did the I/O */
4365
4347
UnlockBufHdr (buf ,buf_state );
4366
- LWLockRelease (BufferDescriptorGetIOLock (buf ));
4367
4348
return false;
4368
4349
}
4369
4350
@@ -4381,7 +4362,6 @@ StartBufferIO(BufferDesc *buf, bool forInput)
4381
4362
*(Assumptions)
4382
4363
*My process is executing IO for the buffer
4383
4364
*BM_IO_IN_PROGRESS bit is set for the buffer
4384
- *We hold the buffer's io_in_progress lock
4385
4365
*The buffer is Pinned
4386
4366
*
4387
4367
* 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)
4413
4393
4414
4394
InProgressBuf = NULL ;
4415
4395
4416
- LWLockRelease ( BufferDescriptorGetIOLock (buf ));
4396
+ ConditionVariableBroadcast ( BufferDescriptorGetIOCV (buf ));
4417
4397
}
4418
4398
4419
4399
/*
@@ -4434,14 +4414,6 @@ AbortBufferIO(void)
4434
4414
{
4435
4415
uint32 buf_state ;
4436
4416
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
-
4445
4417
buf_state = LockBufHdr (buf );
4446
4418
Assert (buf_state & BM_IO_IN_PROGRESS );
4447
4419
if (IsForInput )