*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.68 2004/08/29 05:06:47 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/buffer/buf_init.c,v 1.69 2004/10/16 18:05:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
BufferDesc *BufferDescriptors;
Block *BufferBlockPointers;
-
-int32 *PrivateRefCount; /* also used in freelist.c */
-bits8 *BufferLocks; /* flag bits showing locks I have set */
+int32 *PrivateRefCount;
/* statistics counters */
long int ReadBufferCount;
sizeof(*BufferBlockPointers));
PrivateRefCount = (int32 *) calloc(NBuffers,
sizeof(*PrivateRefCount));
- BufferLocks = (bits8 *) calloc(NBuffers, sizeof(*BufferLocks));
/*
* Convert shmem offsets into addresses as seen by this process. This
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.178 2004/10/15 22:39:59 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.179 2004/10/16 18:05:06 tgl Exp $
*
*-------------------------------------------------------------------------
*/
long NDirectFileWrite; /* e.g., I/O in psort and hashjoin. */
+/* local state for StartBufferIO and related functions */
+static BufferDesc *InProgressBuf = NULL;
+static bool IsForInput;
+/* local state for LockBufferForCleanup */
+static BufferDesc *PinCountWaitBuf = NULL;
+
+
static void PinBuffer(BufferDesc *buf, bool fixOwner);
static void UnpinBuffer(BufferDesc *buf, bool fixOwner);
static void WaitIO(BufferDesc *buf);
* Release buffer context locks for shared buffers.
*
* Used to clean up after errors.
+ *
+ * Currently, we can expect that lwlock.c's LWLockReleaseAll() took care
+ * of releasing buffer context locks per se; the only thing we need to deal
+ * with here is clearing any PIN_COUNT request that was in progress.
*/
void
UnlockBuffers(void)
{
- BufferDesc *buf;
- int i;
+ BufferDesc *buf = PinCountWaitBuf;
- for (i = 0; i < NBuffers; i++)
+ if (buf)
{
- bits8 buflocks = BufferLocks[i];
-
- if (buflocks == 0)
- continue;
-
- buf = &(BufferDescriptors[i]);
-
HOLD_INTERRUPTS(); /* don't want to die() partway through... */
+ LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
+
/*
- * The buffer's cntx_lock has already been released by lwlock.c.
+ * Don't complain if flag bit not set; it could have been
+ * reset but we got a cancel/die interrupt before getting the
+ * signal.
*/
+ if ((buf->flags & BM_PIN_COUNT_WAITER) != 0 &&
+ buf->wait_backend_id == MyBackendId)
+ buf->flags &= ~BM_PIN_COUNT_WAITER;
+ LWLockRelease(BufMgrLock);
- if (buflocks & BL_PIN_COUNT_LOCK)
- {
- LWLockAcquire(BufMgrLock, LW_EXCLUSIVE);
-
- /*
- * Don't complain if flag bit not set; it could have been
- * reset but we got a cancel/die interrupt before getting the
- * signal.
- */
- if ((buf->flags & BM_PIN_COUNT_WAITER) != 0 &&
- buf->wait_backend_id == MyBackendId)
- buf->flags &= ~BM_PIN_COUNT_WAITER;
- LWLockRelease(BufMgrLock);
- ProcCancelWaitForSignal();
- }
-
- BufferLocks[i] = 0;
+ ProcCancelWaitForSignal();
RESUME_INTERRUPTS();
}
+
+ PinCountWaitBuf = NULL;
}
/*
LockBufferForCleanup(Buffer buffer)
{
BufferDesc *bufHdr;
- bits8 *buflock;
Assert(BufferIsValid(buffer));
+ Assert(PinCountWaitBuf == NULL);
if (BufferIsLocal(buffer))
{
PrivateRefCount[buffer - 1]);
bufHdr = &BufferDescriptors[buffer - 1];
- buflock = &(BufferLocks[buffer - 1]);
for (;;)
{
}
bufHdr->wait_backend_id = MyBackendId;
bufHdr->flags |= BM_PIN_COUNT_WAITER;
- *buflock |= BL_PIN_COUNT_LOCK;
+ PinCountWaitBuf = bufHdr;
LWLockRelease(BufMgrLock);
LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
/* Wait to be signaled by UnpinBuffer() */
ProcWaitForSignal();
- *buflock &= ~BL_PIN_COUNT_LOCK;
+ PinCountWaitBuf = NULL;
/* Loop back and try again */
}
}
/*
* Functions for IO error handling
*
- * Note : We assume that nested buffer IO never occur.
+ * Note: We assume that nested buffer IO never occurs.
* i.e at most one io_in_progress lock is held per proc.
-*/
-static BufferDesc *InProgressBuf = NULL;
-static bool IsForInput;
+ */
/*
* Function:StartBufferIO
* Portions Copyright (c) 1996-2004, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.73 2004/08/29 05:06:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/storage/buf_internals.h,v 1.74 2004/10/16 18:05:07 tgl Exp $
*
*-------------------------------------------------------------------------
*/
)
/*
- * BufferDesc -- shared buffer cache metadata for a single
- * shared buffer descriptor.
+ * BufferDesc -- shared descriptor/state data for a single shared buffer.
*/
typedef struct sbufdesc
{
#define BufferDescriptorGetBuffer(bdesc) ((bdesc)->buf_id + 1)
-
-/*
- * Each backend has its own BufferLocks[] array holding flag bits
- * showing what locks it has set on each buffer.
- *
- * We have to free these locks during ereport(ERROR)...
- */
-#define BL_IO_IN_PROGRESS (1 << 0) /* unimplemented */
-#define BL_PIN_COUNT_LOCK (1 << 1)
-
/* entry for buffer lookup hashtable */
typedef struct
{
/* bufmgr.c */
extern BufferDesc *BufferDescriptors;
-extern bits8 *BufferLocks;
/* localbuf.c */
extern BufferDesc *LocalBufferDescriptors;