aboutsummaryrefslogtreecommitdiff
path: root/src/backend/storage/buffer/bufmgr.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2000-11-28 23:27:57 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2000-11-28 23:27:57 +0000
commitc715fdea267843fd7fae4253aee0ae91e941393c (patch)
treeb19e41edd57afe461ebc3dae271c8a5d17eba710 /src/backend/storage/buffer/bufmgr.c
parent914822713c9a8ce452860fb895ef79ecfd583746 (diff)
downloadpostgresql-c715fdea267843fd7fae4253aee0ae91e941393c.tar.gz
postgresql-c715fdea267843fd7fae4253aee0ae91e941393c.zip
Significant cleanups in SysV IPC handling (shared mem and semaphores).
IPC key assignment will now work correctly even when multiple postmasters are using same logical port number (which is possible given -k switch). There is only one shared-mem segment per postmaster now, not 3. Rip out broken code for non-TAS case in bufmgr and xlog, substitute a complete S_LOCK emulation using semaphores in spin.c. TAS and non-TAS logic is now exactly the same. When deadlock is detected, "Deadlock detected" is now the elog(ERROR) message, rather than a NOTICE that comes out before an unhelpful ERROR.
Diffstat (limited to 'src/backend/storage/buffer/bufmgr.c')
-rw-r--r--src/backend/storage/buffer/bufmgr.c104
1 files changed, 4 insertions, 100 deletions
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 907e8194743..8ed03138fac 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.94 2000/11/20 16:47:31 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.95 2000/11/28 23:27:55 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -93,12 +93,6 @@ extern void AbortBufferIO(void);
*/
#define BUFFER_IS_BROKEN(buf) ((buf->flags & BM_IO_ERROR) && !(buf->flags & BM_DIRTY))
-#ifndef HAS_TEST_AND_SET
-static void SignalIO(BufferDesc *buf);
-extern long *NWaitIOBackendP; /* defined in buf_init.c */
-
-#endif /* HAS_TEST_AND_SET */
-
static Buffer ReadBufferWithBufferLock(Relation relation, BlockNumber blockNum,
bool bufferLockHeld);
static BufferDesc *BufferAlloc(Relation reln, BlockNumber blockNum,
@@ -1187,27 +1181,7 @@ BufferSync()
*
* Should be entered with buffer manager spinlock held; releases it before
* waiting and re-acquires it afterwards.
- *
- * OLD NOTES:
- * Because IO_IN_PROGRESS conflicts are
- * expected to be rare, there is only one BufferIO
- * lock in the entire system. All processes block
- * on this semaphore when they try to use a buffer
- * that someone else is faulting in. Whenever a
- * process finishes an IO and someone is waiting for
- * the buffer, BufferIO is signaled (SignalIO). All
- * waiting processes then wake up and check to see
- * if their buffer is now ready. This implementation
- * is simple, but efficient enough if WaitIO is
- * rarely called by multiple processes simultaneously.
- *
- * NEW NOTES:
- * The above is true only on machines without test-and-set
- * semaphores (which we hope are few, these days). On better
- * hardware, each buffer has a spinlock that we can wait on.
*/
-#ifdef HAS_TEST_AND_SET
-
static void
WaitIO(BufferDesc *buf, SPINLOCK spinlock)
{
@@ -1224,43 +1198,6 @@ WaitIO(BufferDesc *buf, SPINLOCK spinlock)
}
}
-#else /* !HAS_TEST_AND_SET */
-
-IpcSemaphoreId WaitIOSemId;
-IpcSemaphoreId WaitCLSemId;
-
-static void
-WaitIO(BufferDesc *buf, SPINLOCK spinlock)
-{
- bool inProgress;
-
- for (;;)
- {
-
- /* wait until someone releases IO lock */
- (*NWaitIOBackendP)++;
- SpinRelease(spinlock);
- IpcSemaphoreLock(WaitIOSemId, 0, 1);
- SpinAcquire(spinlock);
- inProgress = (buf->flags & BM_IO_IN_PROGRESS);
- if (!inProgress)
- break;
- }
-}
-
-/*
- * SignalIO
- */
-static void
-SignalIO(BufferDesc *buf)
-{
- /* somebody better be waiting. */
- Assert(buf->refcount > 1);
- IpcSemaphoreUnlock(WaitIOSemId, 0, *NWaitIOBackendP);
- *NWaitIOBackendP = 0;
-}
-
-#endif /* HAS_TEST_AND_SET */
long NDirectFileRead; /* some I/O's are direct file access.
* bypass bufmgr */
@@ -2297,11 +2234,7 @@ UnlockBuffers()
Assert(BufferIsValid(i + 1));
buf = &(BufferDescriptors[i]);
-#ifdef HAS_TEST_AND_SET
S_LOCK(&(buf->cntx_lock));
-#else
- IpcSemaphoreLock(WaitCLSemId, 0, IpcExclusiveLock);
-#endif
if (BufferLocks[i] & BL_R_LOCK)
{
@@ -2324,11 +2257,9 @@ UnlockBuffers()
Assert(buf->w_lock);
buf->w_lock = false;
}
-#ifdef HAS_TEST_AND_SET
+
S_UNLOCK(&(buf->cntx_lock));
-#else
- IpcSemaphoreUnlock(WaitCLSemId, 0, IpcExclusiveLock);
-#endif
+
BufferLocks[i] = 0;
}
}
@@ -2346,11 +2277,7 @@ LockBuffer(Buffer buffer, int mode)
buf = &(BufferDescriptors[buffer - 1]);
buflock = &(BufferLocks[buffer - 1]);
-#ifdef HAS_TEST_AND_SET
S_LOCK(&(buf->cntx_lock));
-#else
- IpcSemaphoreLock(WaitCLSemId, 0, IpcExclusiveLock);
-#endif
if (mode == BUFFER_LOCK_UNLOCK)
{
@@ -2380,15 +2307,9 @@ LockBuffer(Buffer buffer, int mode)
Assert(!(*buflock & (BL_R_LOCK | BL_W_LOCK | BL_RI_LOCK)));
while (buf->ri_lock || buf->w_lock)
{
-#ifdef HAS_TEST_AND_SET
S_UNLOCK(&(buf->cntx_lock));
s_lock_sleep(i++);
S_LOCK(&(buf->cntx_lock));
-#else
- IpcSemaphoreUnlock(WaitCLSemId, 0, IpcExclusiveLock);
- s_lock_sleep(i++);
- IpcSemaphoreLock(WaitCLSemId, 0, IpcExclusiveLock);
-#endif
}
(buf->r_locks)++;
*buflock |= BL_R_LOCK;
@@ -2412,15 +2333,9 @@ LockBuffer(Buffer buffer, int mode)
*buflock |= BL_RI_LOCK;
buf->ri_lock = true;
}
-#ifdef HAS_TEST_AND_SET
S_UNLOCK(&(buf->cntx_lock));
s_lock_sleep(i++);
S_LOCK(&(buf->cntx_lock));
-#else
- IpcSemaphoreUnlock(WaitCLSemId, 0, IpcExclusiveLock);
- s_lock_sleep(i++);
- IpcSemaphoreLock(WaitCLSemId, 0, IpcExclusiveLock);
-#endif
}
buf->w_lock = true;
*buflock |= BL_W_LOCK;
@@ -2438,12 +2353,7 @@ LockBuffer(Buffer buffer, int mode)
else
elog(ERROR, "LockBuffer: unknown lock mode %d", mode);
-#ifdef HAS_TEST_AND_SET
S_UNLOCK(&(buf->cntx_lock));
-#else
- IpcSemaphoreUnlock(WaitCLSemId, 0, IpcExclusiveLock);
-#endif
-
}
/*
@@ -2471,7 +2381,6 @@ StartBufferIO(BufferDesc *buf, bool forInput)
Assert(!InProgressBuf);
Assert(!(buf->flags & BM_IO_IN_PROGRESS));
buf->flags |= BM_IO_IN_PROGRESS;
-#ifdef HAS_TEST_AND_SET
/*
* There used to be
@@ -2485,7 +2394,7 @@ StartBufferIO(BufferDesc *buf, bool forInput)
* happen -- tgl
*/
S_LOCK(&(buf->io_in_progress_lock));
-#endif /* HAS_TEST_AND_SET */
+
InProgressBuf = buf;
IsForInput = forInput;
}
@@ -2502,12 +2411,7 @@ static void
TerminateBufferIO(BufferDesc *buf)
{
Assert(buf == InProgressBuf);
-#ifdef HAS_TEST_AND_SET
S_UNLOCK(&(buf->io_in_progress_lock));
-#else
- if (buf->refcount > 1)
- SignalIO(buf);
-#endif /* HAS_TEST_AND_SET */
InProgressBuf = (BufferDesc *) 0;
}