diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2000-11-28 23:27:57 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2000-11-28 23:27:57 +0000 |
commit | c715fdea267843fd7fae4253aee0ae91e941393c (patch) | |
tree | b19e41edd57afe461ebc3dae271c8a5d17eba710 /src/backend/storage/buffer/bufmgr.c | |
parent | 914822713c9a8ce452860fb895ef79ecfd583746 (diff) | |
download | postgresql-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.c | 104 |
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; } |