*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.76 2000/03/14 22:46:27 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/storage/buffer/bufmgr.c,v 1.77 2000/03/31 02:43:31 tgl Exp $
*
*-------------------------------------------------------------------------
*/
/*
*
* BufferAlloc() -- lookup a buffer in the buffer table. If
- * it isn't there add it, but do not read it into memory.
+ * it isn't there add it, but do not read data into memory.
* This is used when we are about to reinitialize the
* buffer so don't care what the current disk contents are.
- * BufferAlloc() pins the new buffer in memory.
+ * BufferAlloc() also pins the new buffer in memory.
*
- * ReadBuffer() -- same as BufferAlloc() but reads the data
+ * ReadBuffer() -- like BufferAlloc() but reads the data
* on a buffer cache miss.
*
* ReleaseBuffer() -- unpin the buffer
*
* WriteNoReleaseBuffer() -- mark the buffer contents as "dirty"
* but don't unpin. The disk IO is delayed until buffer
- * replacement if WriteMode is BUFFER_LATE_WRITE.
+ * replacement.
*
* WriteBuffer() -- WriteNoReleaseBuffer() + ReleaseBuffer()
*
- * FlushBuffer() -- as above but never delayed write.
+ * FlushBuffer() -- Write buffer immediately. Can unpin, or not,
+ * depending on parameter.
*
* BufferSync() -- flush all dirty buffers in the buffer pool.
*
*/
bool SharedBufferChanged = false;
-static int WriteMode = BUFFER_LATE_WRITE; /* Delayed write is
- * default */
-
static void WaitIO(BufferDesc *buf, SPINLOCK spinlock);
-
static void StartBufferIO(BufferDesc *buf, bool forInput);
static void TerminateBufferIO(BufferDesc *buf);
static void ContinueBufferIO(BufferDesc *buf, bool forInput);
bool bufferLockHeld);
static BufferDesc *BufferAlloc(Relation reln, BlockNumber blockNum,
bool *foundPtr, bool bufferLockHeld);
-static int FlushBuffer(Buffer buffer, bool release);
static void BufferSync(void);
static int BufferReplace(BufferDesc *bufHdr, bool bufferLockHeld);
void PrintBufferDescs(void);
/*
* WriteBuffer
*
- * Pushes buffer contents to disk if WriteMode is BUFFER_FLUSH_WRITE.
- * Otherwise, marks contents as dirty.
+ * Marks buffer contents as dirty (actual write happens later).
*
* Assume that buffer is pinned. Assume that reln is
* valid.
{
BufferDesc *bufHdr;
- if (WriteMode == BUFFER_FLUSH_WRITE)
- return FlushBuffer(buffer, TRUE);
- else
- {
+ if (BufferIsLocal(buffer))
+ return WriteLocalBuffer(buffer, TRUE);
- if (BufferIsLocal(buffer))
- return WriteLocalBuffer(buffer, TRUE);
+ if (BAD_BUFFER_ID(buffer))
+ return FALSE;
- if (BAD_BUFFER_ID(buffer))
- return FALSE;
+ bufHdr = &BufferDescriptors[buffer - 1];
- bufHdr = &BufferDescriptors[buffer - 1];
+ SharedBufferChanged = true;
- SharedBufferChanged = true;
+ SpinAcquire(BufMgrLock);
+ Assert(bufHdr->refcount > 0);
+ bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
+ UnpinBuffer(bufHdr);
+ SpinRelease(BufMgrLock);
+ CommitInfoNeedsSave[buffer - 1] = 0;
- SpinAcquire(BufMgrLock);
- Assert(bufHdr->refcount > 0);
- bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
- UnpinBuffer(bufHdr);
- SpinRelease(BufMgrLock);
- CommitInfoNeedsSave[buffer - 1] = 0;
- }
return TRUE;
}
* 'buffer' is known to be dirty/pinned, so there should not be a
* problem reading the BufferDesc members without the BufMgrLock
* (nobody should be able to change tags, flags, etc. out from under
- * us).
+ * us). Unpin if 'release' is TRUE.
*/
-static int
+int
FlushBuffer(Buffer buffer, bool release)
{
BufferDesc *bufHdr;
/*
* WriteNoReleaseBuffer -- like WriteBuffer, but do not unpin the buffer
* when the operation is complete.
- *
- * We know that the buffer is for a relation in our private cache,
- * because this routine is called only to write out buffers that
- * were changed by the executing backend.
*/
int
WriteNoReleaseBuffer(Buffer buffer)
{
BufferDesc *bufHdr;
- if (WriteMode == BUFFER_FLUSH_WRITE)
- return FlushBuffer(buffer, FALSE);
- else
- {
+ if (BufferIsLocal(buffer))
+ return WriteLocalBuffer(buffer, FALSE);
- if (BufferIsLocal(buffer))
- return WriteLocalBuffer(buffer, FALSE);
+ if (BAD_BUFFER_ID(buffer))
+ return STATUS_ERROR;
- if (BAD_BUFFER_ID(buffer))
- return STATUS_ERROR;
+ bufHdr = &BufferDescriptors[buffer - 1];
- bufHdr = &BufferDescriptors[buffer - 1];
+ SharedBufferChanged = true;
- SharedBufferChanged = true;
+ SpinAcquire(BufMgrLock);
+ bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
+ SpinRelease(BufMgrLock);
+ CommitInfoNeedsSave[buffer - 1] = 0;
- SpinAcquire(BufMgrLock);
- bufHdr->flags |= (BM_DIRTY | BM_JUST_DIRTIED);
- SpinRelease(BufMgrLock);
- CommitInfoNeedsSave[buffer - 1] = 0;
- }
return STATUS_OK;
}
#endif /* BMTRACE */
-int
-SetBufferWriteMode(int mode)
-{
- int old;
-
- old = WriteMode;
- WriteMode = mode;
- return old;
-}
-
void
SetBufferCommitInfoNeedsSave(Buffer buffer)
{
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: bufmgr.h,v 1.34 2000/01/26 05:58:32 momjian Exp $
+ * $Id: bufmgr.h,v 1.35 2000/03/31 02:43:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
extern int ShowPinTrace;
-/*
- * BufferWriteModes (settable via SetBufferWriteMode)
- */
-#define BUFFER_FLUSH_WRITE 0 /* immediate write */
-#define BUFFER_LATE_WRITE 1 /* delayed write: mark as DIRTY */
-
/*
* Buffer context lock modes
*/
extern int WriteNoReleaseBuffer(Buffer buffer);
extern Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation,
BlockNumber blockNum);
+extern int FlushBuffer(Buffer buffer, bool release);
extern void InitBufferPool(IPCKey key);
extern void PrintBufferUsage(FILE *statfp);
extern int BufferShmemSize(void);
extern int ReleaseBuffer(Buffer buffer);
-extern int SetBufferWriteMode(int mode);
extern void SetBufferCommitInfoNeedsSave(Buffer buffer);
extern void UnlockBuffers(void);