summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/pg_buffercache/pg_buffercache_pages.c27
-rw-r--r--src/backend/storage/buffer/bufmgr.c89
-rw-r--r--src/backend/storage/buffer/freelist.c8
-rw-r--r--src/include/storage/buf_internals.h11
4 files changed, 64 insertions, 71 deletions
diff --git a/contrib/pg_buffercache/pg_buffercache_pages.c b/contrib/pg_buffercache/pg_buffercache_pages.c
index e55aff991dc..e511c0df9ad 100644
--- a/contrib/pg_buffercache/pg_buffercache_pages.c
+++ b/contrib/pg_buffercache/pg_buffercache_pages.c
@@ -3,7 +3,7 @@
* pg_buffercache_pages.c
* display some contents of the buffer cache
*
- * $PostgreSQL: pgsql/contrib/pg_buffercache/pg_buffercache_pages.c,v 1.4 2005/05/31 00:07:47 tgl Exp $
+ * $PostgreSQL: pgsql/contrib/pg_buffercache/pg_buffercache_pages.c,v 1.5 2005/10/12 16:45:13 tgl Exp $
*-------------------------------------------------------------------------
*/
#include "postgres.h"
@@ -72,10 +72,8 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
if (SRF_IS_FIRSTCALL())
{
- RelFileNode rnode;
uint32 i;
- BufferDesc *bufHdr;
-
+ volatile BufferDesc *bufHdr;
funcctx = SRF_FIRSTCALL_INIT();
@@ -136,35 +134,24 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
/* Lock each buffer header before inspecting. */
LockBufHdr(bufHdr);
- rnode = bufHdr->tag.rnode;
-
fctx->record[i].bufferid = BufferDescriptorGetBuffer(bufHdr);
- fctx->record[i].relfilenode = rnode.relNode;
- fctx->record[i].reltablespace = rnode.spcNode;
- fctx->record[i].reldatabase = rnode.dbNode;
+ fctx->record[i].relfilenode = bufHdr->tag.rnode.relNode;
+ fctx->record[i].reltablespace = bufHdr->tag.rnode.spcNode;
+ fctx->record[i].reldatabase = bufHdr->tag.rnode.dbNode;
fctx->record[i].blocknum = bufHdr->tag.blockNum;
- if ( bufHdr->flags & BM_DIRTY)
- {
+ if (bufHdr->flags & BM_DIRTY)
fctx->record[i].isdirty = true;
- }
else
- {
fctx->record[i].isdirty = false;
- }
/* Note if the buffer is valid, and has storage created */
- if ( (bufHdr->flags & BM_VALID) && (bufHdr->flags & BM_TAG_VALID))
- {
+ if ((bufHdr->flags & BM_VALID) && (bufHdr->flags & BM_TAG_VALID))
fctx->record[i].isvalid = true;
- }
else
- {
fctx->record[i].isvalid = false;
- }
UnlockBufHdr(bufHdr);
-
}
/* Release Buffer map. */
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index 51b3f56c810..fb3efcbca96 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.195 2005/08/12 23:13:54 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.196 2005/10/12 16:45:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -76,24 +76,24 @@ long NDirectFileWrite; /* e.g., I/O in psort and hashjoin. */
/* local state for StartBufferIO and related functions */
-static BufferDesc *InProgressBuf = NULL;
+static volatile BufferDesc *InProgressBuf = NULL;
static bool IsForInput;
/* local state for LockBufferForCleanup */
-static BufferDesc *PinCountWaitBuf = NULL;
+static volatile BufferDesc *PinCountWaitBuf = NULL;
-static bool PinBuffer(BufferDesc *buf);
-static void PinBuffer_Locked(BufferDesc *buf);
-static void UnpinBuffer(BufferDesc *buf, bool fixOwner, bool trashOK);
+static bool PinBuffer(volatile BufferDesc *buf);
+static void PinBuffer_Locked(volatile BufferDesc *buf);
+static void UnpinBuffer(volatile BufferDesc *buf, bool fixOwner, bool trashOK);
static bool SyncOneBuffer(int buf_id, bool skip_pinned);
-static void WaitIO(BufferDesc *buf);
-static bool StartBufferIO(BufferDesc *buf, bool forInput);
-static void TerminateBufferIO(BufferDesc *buf, bool clear_dirty,
+static void WaitIO(volatile BufferDesc *buf);
+static bool StartBufferIO(volatile BufferDesc *buf, bool forInput);
+static void TerminateBufferIO(volatile BufferDesc *buf, bool clear_dirty,
int set_flag_bits);
static void buffer_write_error_callback(void *arg);
-static BufferDesc *BufferAlloc(Relation reln, BlockNumber blockNum,
+static volatile BufferDesc *BufferAlloc(Relation reln, BlockNumber blockNum,
bool *foundPtr);
-static void FlushBuffer(BufferDesc *buf, SMgrRelation reln);
+static void FlushBuffer(volatile BufferDesc *buf, SMgrRelation reln);
static void AtProcExit_Buffers(int code, Datum arg);
static void write_buffer(Buffer buffer, bool unpin);
@@ -116,7 +116,7 @@ static void write_buffer(Buffer buffer, bool unpin);
Buffer
ReadBuffer(Relation reln, BlockNumber blockNum)
{
- BufferDesc *bufHdr;
+ volatile BufferDesc *bufHdr;
Block bufBlock;
bool found;
bool isExtend;
@@ -255,7 +255,7 @@ ReadBuffer(Relation reln, BlockNumber blockNum)
*
* No locks are held either at entry or exit.
*/
-static BufferDesc *
+static volatile BufferDesc *
BufferAlloc(Relation reln,
BlockNumber blockNum,
bool *foundPtr)
@@ -264,7 +264,7 @@ BufferAlloc(Relation reln,
BufferTag oldTag;
BufFlags oldFlags;
int buf_id;
- BufferDesc *buf;
+ volatile BufferDesc *buf;
bool valid;
/* create a tag so we can lookup the buffer */
@@ -512,7 +512,7 @@ BufferAlloc(Relation reln,
* to acquire the necessary locks; if so, don't mess it up.
*/
static void
-InvalidateBuffer(BufferDesc *buf)
+InvalidateBuffer(volatile BufferDesc *buf)
{
BufferTag oldTag;
BufFlags oldFlags;
@@ -602,7 +602,7 @@ retry:
static void
write_buffer(Buffer buffer, bool unpin)
{
- BufferDesc *bufHdr;
+ volatile BufferDesc *bufHdr;
if (!BufferIsValid(buffer))
elog(ERROR, "bad buffer id: %d", buffer);
@@ -679,7 +679,7 @@ ReleaseAndReadBuffer(Buffer buffer,
Relation relation,
BlockNumber blockNum)
{
- BufferDesc *bufHdr;
+ volatile BufferDesc *bufHdr;
if (BufferIsValid(buffer))
{
@@ -722,7 +722,7 @@ ReleaseAndReadBuffer(Buffer buffer,
* some callers to avoid an extra spinlock cycle.
*/
static bool
-PinBuffer(BufferDesc *buf)
+PinBuffer(volatile BufferDesc *buf)
{
int b = buf->buf_id;
bool result;
@@ -760,7 +760,7 @@ PinBuffer(BufferDesc *buf)
* its state can change under us.
*/
static void
-PinBuffer_Locked(BufferDesc *buf)
+PinBuffer_Locked(volatile BufferDesc *buf)
{
int b = buf->buf_id;
@@ -787,7 +787,7 @@ PinBuffer_Locked(BufferDesc *buf)
* used recently, and trashOK is true, send the buffer to the freelist.
*/
static void
-UnpinBuffer(BufferDesc *buf, bool fixOwner, bool trashOK)
+UnpinBuffer(volatile BufferDesc *buf, bool fixOwner, bool trashOK)
{
int b = buf->buf_id;
@@ -967,7 +967,7 @@ BgBufferSync(void)
static bool
SyncOneBuffer(int buf_id, bool skip_pinned)
{
- BufferDesc *bufHdr = &BufferDescriptors[buf_id];
+ volatile BufferDesc *bufHdr = &BufferDescriptors[buf_id];
/*
* Check whether buffer needs writing.
@@ -1114,7 +1114,7 @@ AtProcExit_Buffers(int code, Datum arg)
{
if (PrivateRefCount[i] != 0)
{
- BufferDesc *buf = &(BufferDescriptors[i]);
+ volatile BufferDesc *buf = &(BufferDescriptors[i]);
/*
* We don't worry about updating ResourceOwner; if we even got
@@ -1136,7 +1136,7 @@ AtProcExit_Buffers(int code, Datum arg)
void
PrintBufferLeakWarning(Buffer buffer)
{
- BufferDesc *buf;
+ volatile BufferDesc *buf;
int32 loccount;
Assert(BufferIsValid(buffer));
@@ -1199,7 +1199,7 @@ BufmgrCommit(void)
BlockNumber
BufferGetBlockNumber(Buffer buffer)
{
- BufferDesc *bufHdr;
+ volatile BufferDesc *bufHdr;
Assert(BufferIsPinned(buffer));
@@ -1222,7 +1222,7 @@ BufferGetBlockNumber(Buffer buffer)
RelFileNode
BufferGetFileNode(Buffer buffer)
{
- BufferDesc *bufHdr;
+ volatile BufferDesc *bufHdr;
if (BufferIsLocal(buffer))
bufHdr = &(LocalBufferDescriptors[-buffer - 1]);
@@ -1252,7 +1252,7 @@ BufferGetFileNode(Buffer buffer)
* as the second parameter. If not, pass NULL.
*/
static void
-FlushBuffer(BufferDesc *buf, SMgrRelation reln)
+FlushBuffer(volatile BufferDesc *buf, SMgrRelation reln)
{
XLogRecPtr recptr;
ErrorContextCallback errcontext;
@@ -1267,7 +1267,7 @@ FlushBuffer(BufferDesc *buf, SMgrRelation reln)
/* Setup error traceback support for ereport() */
errcontext.callback = buffer_write_error_callback;
- errcontext.arg = buf;
+ errcontext.arg = (void *) buf;
errcontext.previous = error_context_stack;
error_context_stack = &errcontext;
@@ -1375,7 +1375,7 @@ DropRelFileNodeBuffers(RelFileNode rnode, bool istemp,
BlockNumber firstDelBlock)
{
int i;
- BufferDesc *bufHdr;
+ volatile BufferDesc *bufHdr;
if (istemp)
{
@@ -1427,7 +1427,7 @@ void
DropBuffers(Oid dbid)
{
int i;
- BufferDesc *bufHdr;
+ volatile BufferDesc *bufHdr;
/*
* We needn't consider local buffers, since by assumption the target
@@ -1457,7 +1457,7 @@ void
PrintBufferDescs(void)
{
int i;
- BufferDesc *buf = BufferDescriptors;
+ volatile BufferDesc *buf = BufferDescriptors;
for (i = 0; i < NBuffers; ++i, ++buf)
{
@@ -1479,7 +1479,7 @@ void
PrintPinnedBufs(void)
{
int i;
- BufferDesc *buf = BufferDescriptors;
+ volatile BufferDesc *buf = BufferDescriptors;
for (i = 0; i < NBuffers; ++i, ++buf)
{
@@ -1522,7 +1522,7 @@ void
FlushRelationBuffers(Relation rel)
{
int i;
- BufferDesc *bufHdr;
+ volatile BufferDesc *bufHdr;
/* Open rel at the smgr level if not already done */
RelationOpenSmgr(rel);
@@ -1539,7 +1539,7 @@ FlushRelationBuffers(Relation rel)
/* Setup error traceback support for ereport() */
errcontext.callback = buffer_write_error_callback;
- errcontext.arg = bufHdr;
+ errcontext.arg = (void *) bufHdr;
errcontext.previous = error_context_stack;
error_context_stack = &errcontext;
@@ -1586,7 +1586,7 @@ FlushRelationBuffers(Relation rel)
void
ReleaseBuffer(Buffer buffer)
{
- BufferDesc *bufHdr;
+ volatile BufferDesc *bufHdr;
if (!BufferIsValid(buffer))
elog(ERROR, "bad buffer id: %d", buffer);
@@ -1657,7 +1657,7 @@ IncrBufferRefCount(Buffer buffer)
void
SetBufferCommitInfoNeedsSave(Buffer buffer)
{
- BufferDesc *bufHdr;
+ volatile BufferDesc *bufHdr;
if (!BufferIsValid(buffer))
elog(ERROR, "bad buffer id: %d", buffer);
@@ -1694,7 +1694,7 @@ SetBufferCommitInfoNeedsSave(Buffer buffer)
void
UnlockBuffers(void)
{
- BufferDesc *buf = PinCountWaitBuf;
+ volatile BufferDesc *buf = PinCountWaitBuf;
if (buf)
{
@@ -1727,7 +1727,7 @@ UnlockBuffers(void)
void
LockBuffer(Buffer buffer, int mode)
{
- BufferDesc *buf;
+ volatile BufferDesc *buf;
Assert(BufferIsValid(buffer));
if (BufferIsLocal(buffer))
@@ -1765,7 +1765,7 @@ LockBuffer(Buffer buffer, int mode)
bool
ConditionalLockBuffer(Buffer buffer)
{
- BufferDesc *buf;
+ volatile BufferDesc *buf;
Assert(BufferIsValid(buffer));
if (BufferIsLocal(buffer))
@@ -1809,7 +1809,7 @@ ConditionalLockBuffer(Buffer buffer)
void
LockBufferForCleanup(Buffer buffer)
{
- BufferDesc *bufHdr;
+ volatile BufferDesc *bufHdr;
Assert(BufferIsValid(buffer));
Assert(PinCountWaitBuf == NULL);
@@ -1875,7 +1875,7 @@ LockBufferForCleanup(Buffer buffer)
* WaitIO -- Block until the IO_IN_PROGRESS flag on 'buf' is cleared.
*/
static void
-WaitIO(BufferDesc *buf)
+WaitIO(volatile BufferDesc *buf)
{
/*
* Changed to wait until there's no IO - Inoue 01/13/2000
@@ -1922,7 +1922,7 @@ WaitIO(BufferDesc *buf)
* FALSE if someone else already did the work.
*/
static bool
-StartBufferIO(BufferDesc *buf, bool forInput)
+StartBufferIO(volatile BufferDesc *buf, bool forInput)
{
Assert(!InProgressBuf);
@@ -1989,7 +1989,8 @@ StartBufferIO(BufferDesc *buf, bool forInput)
* be 0, or BM_VALID if we just finished reading in the page.
*/
static void
-TerminateBufferIO(BufferDesc *buf, bool clear_dirty, int set_flag_bits)
+TerminateBufferIO(volatile BufferDesc *buf, bool clear_dirty,
+ int set_flag_bits)
{
Assert(buf == InProgressBuf);
@@ -2021,7 +2022,7 @@ TerminateBufferIO(BufferDesc *buf, bool clear_dirty, int set_flag_bits)
void
AbortBufferIO(void)
{
- BufferDesc *buf = InProgressBuf;
+ volatile BufferDesc *buf = InProgressBuf;
if (buf)
{
@@ -2075,7 +2076,7 @@ AbortBufferIO(void)
static void
buffer_write_error_callback(void *arg)
{
- BufferDesc *bufHdr = (BufferDesc *) arg;
+ volatile BufferDesc *bufHdr = (volatile BufferDesc *) arg;
/* Buffer is pinned, so we can read the tag without locking the spinlock */
if (bufHdr != NULL)
diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c
index 906165638b6..4739512ad36 100644
--- a/src/backend/storage/buffer/freelist.c
+++ b/src/backend/storage/buffer/freelist.c
@@ -9,7 +9,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.52 2005/08/20 23:26:17 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/buffer/freelist.c,v 1.53 2005/10/12 16:45:13 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -55,10 +55,10 @@ bool strategy_hint_vacuum = false;
* means that we return with the BufFreelistLock still held, as well;
* the caller must release that lock once the spinlock is dropped.
*/
-BufferDesc *
+volatile BufferDesc *
StrategyGetBuffer(void)
{
- BufferDesc *buf;
+ volatile BufferDesc *buf;
int trycounter;
LWLockAcquire(BufFreelistLock, LW_EXCLUSIVE);
@@ -138,7 +138,7 @@ StrategyGetBuffer(void)
* quickly the buffer is reused.
*/
void
-StrategyFreeBuffer(BufferDesc *buf, bool at_head)
+StrategyFreeBuffer(volatile BufferDesc *buf, bool at_head)
{
LWLockAcquire(BufFreelistLock, LW_EXCLUSIVE);
diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h
index 6e083be21ba..e75f24a6ced 100644
--- a/src/include/storage/buf_internals.h
+++ b/src/include/storage/buf_internals.h
@@ -8,7 +8,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.79 2005/08/20 23:26:33 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.80 2005/10/12 16:45:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -145,6 +145,11 @@ typedef struct sbufdesc
* NoHoldoff cases may be used when we know that we hold some LWLock
* and therefore interrupts are already held off. Do not apply these
* to local buffers!
+ *
+ * Note: as a general coding rule, if you are using these then you probably
+ * want to be using a volatile-qualified pointer to the buffer header, to
+ * ensure that the compiler doesn't rearrange accesses to the header to
+ * occur before or after the spinlock is acquired/released.
*/
#define LockBufHdr(bufHdr) \
SpinLockAcquire(&(bufHdr)->buf_hdr_lock)
@@ -179,8 +184,8 @@ extern long int LocalBufferFlushCount;
*/
/* freelist.c */
-extern BufferDesc *StrategyGetBuffer(void);
-extern void StrategyFreeBuffer(BufferDesc *buf, bool at_head);
+extern volatile BufferDesc *StrategyGetBuffer(void);
+extern void StrategyFreeBuffer(volatile BufferDesc *buf, bool at_head);
extern int StrategySyncStart(void);
extern Size StrategyShmemSize(void);
extern void StrategyInitialize(bool init);