From: Tom Lane Date: Sat, 16 Oct 2004 18:05:07 +0000 (+0000) Subject: Remove BufferLocks[] array in favor of a single pointer to the buffer X-Git-Tag: REL8_0_0BETA4~82 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1c2de4774620469375e6393fbdbcdaffb0c2d0b5;p=postgresql Remove BufferLocks[] array in favor of a single pointer to the buffer (if any) currently waited for by LockBufferForCleanup(), which is all that we were using it for anymore. Saves some space and eliminates proportional-to-NBuffers slowdown in UnlockBuffers(). --- diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c index 5b727c9a22..a0d7054623 100644 --- a/src/backend/storage/buffer/buf_init.c +++ b/src/backend/storage/buffer/buf_init.c @@ -8,7 +8,7 @@ * * * 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 $ * *------------------------------------------------------------------------- */ @@ -20,9 +20,7 @@ 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; @@ -177,7 +175,6 @@ InitBufferPoolAccess(void) 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 diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index a0f2bf9c11..a8cf506688 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.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 $ * *------------------------------------------------------------------------- */ @@ -66,6 +66,13 @@ long NDirectFileRead; /* some I/O's are direct file access. 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); @@ -1650,48 +1657,38 @@ SetBufferCommitInfoNeedsSave(Buffer buffer) * 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; } /* @@ -1779,9 +1776,9 @@ void LockBufferForCleanup(Buffer buffer) { BufferDesc *bufHdr; - bits8 *buflock; Assert(BufferIsValid(buffer)); + Assert(PinCountWaitBuf == NULL); if (BufferIsLocal(buffer)) { @@ -1799,7 +1796,6 @@ LockBufferForCleanup(Buffer buffer) PrivateRefCount[buffer - 1]); bufHdr = &BufferDescriptors[buffer - 1]; - buflock = &(BufferLocks[buffer - 1]); for (;;) { @@ -1822,12 +1818,12 @@ LockBufferForCleanup(Buffer buffer) } 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 */ } } @@ -1835,11 +1831,9 @@ LockBufferForCleanup(Buffer buffer) /* * 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 diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h index 355859faa3..857d26a22b 100644 --- a/src/include/storage/buf_internals.h +++ b/src/include/storage/buf_internals.h @@ -8,7 +8,7 @@ * 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 $ * *------------------------------------------------------------------------- */ @@ -75,8 +75,7 @@ typedef struct buftag ) /* - * BufferDesc -- shared buffer cache metadata for a single - * shared buffer descriptor. + * BufferDesc -- shared descriptor/state data for a single shared buffer. */ typedef struct sbufdesc { @@ -108,16 +107,6 @@ 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 { @@ -206,7 +195,6 @@ extern void BufTableDelete(BufferTag *tagPtr); /* bufmgr.c */ extern BufferDesc *BufferDescriptors; -extern bits8 *BufferLocks; /* localbuf.c */ extern BufferDesc *LocalBufferDescriptors;