On Mon, 16 Nov 2015 18:55:55 -0500 Robert Haas <robertmh...@gmail.com> wrote:
> On Mon, Nov 16, 2015 at 7:32 AM, Ildus Kurbangaliev > <i.kurbangal...@postgrespro.ru> wrote: > > What if just create a control struct in shared memory like in other places? > > BufferDescriptors > > and BufferBlocks can be kept there along with tranches definitions > > and lwlocks. Buffer locks that are located in MainLWLockArray by offset > > can be moved there too. > > Yeah, we could do that, but what's the advantage of it? The alignment > of the buffer descriptors is kinda finnicky and matters to > performance, so it seems better not to prefix them with something that > might perturb it. If we just rebase Andres' patch over what I just > committed and add in something so that the buffer numbers are fed from > #defines or an enum instead of being random integers, I think we're > done. I created a little patch on top of Andres' patch as example. I see several advantages: 1) We can avoid constants, and use a standard steps for tranches creation. 2) We have only one global variable (BufferCtl) 3) Tranches moved to shared memory, so we won't need to do an additional work here. 4) Also we can kept buffer locks from MainLWLockArray there (that was done in attached patch). -- Ildus Kurbangaliev Postgres Professional: http://www.postgrespro.com Russian Postgres Company
diff --git a/src/backend/storage/buffer/buf_init.c b/src/backend/storage/buffer/buf_init.c index 3ae2848..e733377 100644 --- a/src/backend/storage/buffer/buf_init.c +++ b/src/backend/storage/buffer/buf_init.c @@ -18,9 +18,7 @@ #include "storage/buf_internals.h" -BufferDescPadded *BufferDescriptors; -char *BufferBlocks; - +BufferCtlBase *BufferCtl; /* * Data Structures: @@ -64,28 +62,49 @@ char *BufferBlocks; void InitBufferPool(void) { - bool foundBufs, - foundDescs; - - /* Align descriptors to a cacheline boundary. */ - BufferDescriptors = (BufferDescPadded *) CACHELINEALIGN( - ShmemInitStruct("Buffer Descriptors", - NBuffers * sizeof(BufferDescPadded) + PG_CACHE_LINE_SIZE, - &foundDescs)); + bool foundCtl; + int i; + BufferCtlData *ctl; - BufferBlocks = (char *) - ShmemInitStruct("Buffer Blocks", - NBuffers * (Size) BLCKSZ, &foundBufs); + ctl = (BufferCtlData *) ShmemInitStruct("BufferCtl", + sizeof(BufferCtlData), &foundCtl); + BufferCtl = (BufferCtlBase *) ctl; - if (foundDescs || foundBufs) - { - /* both should be present or neither */ - Assert(foundDescs && foundBufs); - /* note: this path is only taken in EXEC_BACKEND case */ - } - else + if (!foundCtl) { - int i; + /* Align descriptors to a cacheline boundary. */ + ctl->base.bufferDescriptors = (void *) CACHELINEALIGN(ShmemAlloc( + NBuffers * sizeof(BufferDescPadded) + PG_CACHE_LINE_SIZE)); + + ctl->base.bufferBlocks = (char *) ShmemAlloc(NBuffers * (Size) BLCKSZ); + + strncpy(ctl->IOLWLockTrancheName, "buffer_io", + BUFMGR_MAX_NAME_LENGTH); + strncpy(ctl->contentLWLockTrancheName, "buffer_content", + BUFMGR_MAX_NAME_LENGTH); + strncpy(ctl->blockLWLockTrancheName, "buffer_blocks", + BUFMGR_MAX_NAME_LENGTH); + + ctl->IOLocks = (LWLockMinimallyPadded *) ShmemAlloc( + sizeof(LWLockMinimallyPadded) * NBuffers); + + /* Initialize tranche fields */ + ctl->IOLWLockTranche.array_base = ctl->IOLocks; + ctl->IOLWLockTranche.array_stride = sizeof(LWLockMinimallyPadded); + ctl->IOLWLockTranche.name = ctl->IOLWLockTrancheName; + + ctl->contentLWLockTranche.array_base = + ((char *) ctl->base.bufferDescriptors) + offsetof(BufferDesc, content_lock); + ctl->contentLWLockTranche.array_stride = sizeof(BufferDescPadded); + ctl->contentLWLockTranche.name = ctl->contentLWLockTrancheName; + + ctl->blockLWLockTranche.array_base = &ctl->blockLocks; + ctl->blockLWLockTranche.array_stride = sizeof(LWLockPadded); + ctl->blockLWLockTranche.name = ctl->blockLWLockTrancheName; + + ctl->blockLWLockTrancheId = LWLockNewTrancheId(); + ctl->contentLWLockTrancheId = LWLockNewTrancheId(); + ctl->IOLWLockTrancheId = LWLockNewTrancheId(); /* * Initialize all the buffer headers. @@ -110,16 +129,30 @@ InitBufferPool(void) */ buf->freeNext = i + 1; - buf->io_in_progress_lock = LWLockAssign(); - buf->content_lock = LWLockAssign(); + LWLockInitialize(BufferDescriptorGetContentLock(buf), + ctl->contentLWLockTrancheId); + LWLockInitialize(&ctl->IOLocks[i].lock, + ctl->IOLWLockTrancheId); } + for (i = 0; i < NUM_BUFFER_PARTITIONS; i++) + LWLockInitialize(&ctl->blockLocks[i].lock, + ctl->blockLWLockTrancheId); + /* Correct last entry of linked list */ GetBufferDescriptor(NBuffers - 1)->freeNext = FREENEXT_END_OF_LIST; } + /* Register tranches in main tranches array */ + LWLockRegisterTranche(ctl->IOLWLockTrancheId, + &ctl->IOLWLockTranche); + LWLockRegisterTranche(ctl->contentLWLockTrancheId, + &ctl->contentLWLockTranche); + LWLockRegisterTranche(ctl->blockLWLockTrancheId, + &ctl->blockLWLockTranche); + /* Init other shared buffer-management stuff */ - StrategyInitialize(!foundDescs); + StrategyInitialize(!foundCtl); } /* @@ -144,5 +177,11 @@ BufferShmemSize(void) /* size of stuff controlled by freelist.c */ size = add_size(size, StrategyShmemSize()); + /* size of a control struct */ + size = add_size(size, sizeof(BufferCtlData)); + + /* size of IO lwlocks */ + size = add_size(size, mul_size(NBuffers, sizeof(LWLockMinimallyPadded))); + return size; } diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c index 8c0358e..3e17a42 100644 --- a/src/backend/storage/buffer/bufmgr.c +++ b/src/backend/storage/buffer/bufmgr.c @@ -53,7 +53,7 @@ /* Note: these two macros only work on shared buffers, not local ones! */ -#define BufHdrGetBlock(bufHdr) ((Block) (BufferBlocks + ((Size) (bufHdr)->buf_id) * BLCKSZ)) +#define BufHdrGetBlock(bufHdr) ((Block) (BufferCtl->bufferBlocks + ((Size) (bufHdr)->buf_id) * BLCKSZ)) #define BufferGetLSN(bufHdr) (PageGetLSN(BufHdrGetBlock(bufHdr))) /* Note: this macro only works on local buffers, not shared ones! */ @@ -738,7 +738,7 @@ ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, if (!isLocalBuf) { if (mode == RBM_ZERO_AND_LOCK) - LWLockAcquire(bufHdr->content_lock, LW_EXCLUSIVE); + LWLockAcquire(BufferDescriptorGetContentLock(bufHdr), LW_EXCLUSIVE); else if (mode == RBM_ZERO_AND_CLEANUP_LOCK) LockBufferForCleanup(BufferDescriptorGetBuffer(bufHdr)); } @@ -879,7 +879,7 @@ ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, if ((mode == RBM_ZERO_AND_LOCK || mode == RBM_ZERO_AND_CLEANUP_LOCK) && !isLocalBuf) { - LWLockAcquire(bufHdr->content_lock, LW_EXCLUSIVE); + LWLockAcquire(BufferDescriptorGetContentLock(bufHdr), LW_EXCLUSIVE); } if (isLocalBuf) @@ -1045,7 +1045,7 @@ BufferAlloc(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, * happens to be trying to split the page the first one got from * StrategyGetBuffer.) */ - if (LWLockConditionalAcquire(buf->content_lock, LW_SHARED)) + if (LWLockConditionalAcquire(BufferDescriptorGetContentLock(buf), LW_SHARED)) { /* * If using a nondefault strategy, and writing the buffer @@ -1067,7 +1067,7 @@ BufferAlloc(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, StrategyRejectBuffer(strategy, buf)) { /* Drop lock/pin and loop around for another buffer */ - LWLockRelease(buf->content_lock); + LWLockRelease(BufferDescriptorGetContentLock(buf)); UnpinBuffer(buf, true); continue; } @@ -1080,7 +1080,7 @@ BufferAlloc(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, smgr->smgr_rnode.node.relNode); FlushBuffer(buf, NULL); - LWLockRelease(buf->content_lock); + LWLockRelease(BufferDescriptorGetContentLock(buf)); TRACE_POSTGRESQL_BUFFER_WRITE_DIRTY_DONE(forkNum, blockNum, smgr->smgr_rnode.node.spcNode, @@ -1395,7 +1395,7 @@ MarkBufferDirty(Buffer buffer) Assert(BufferIsPinned(buffer)); /* unfortunately we can't check if the lock is held exclusively */ - Assert(LWLockHeldByMe(bufHdr->content_lock)); + Assert(LWLockHeldByMe(BufferDescriptorGetContentLock(bufHdr))); LockBufHdr(bufHdr); @@ -1595,8 +1595,8 @@ UnpinBuffer(volatile BufferDesc *buf, bool fixOwner) if (ref->refcount == 0) { /* I'd better not still hold any locks on the buffer */ - Assert(!LWLockHeldByMe(buf->content_lock)); - Assert(!LWLockHeldByMe(buf->io_in_progress_lock)); + Assert(!LWLockHeldByMe(BufferDescriptorGetContentLock(buf))); + Assert(!LWLockHeldByMe(BufferDescriptorGetIOLock(buf))); LockBufHdr(buf); @@ -2116,11 +2116,11 @@ SyncOneBuffer(int buf_id, bool skip_recently_used) * buffer is clean by the time we've locked it.) */ PinBuffer_Locked(bufHdr); - LWLockAcquire(bufHdr->content_lock, LW_SHARED); + LWLockAcquire(BufferDescriptorGetContentLock(bufHdr), LW_SHARED); FlushBuffer(bufHdr, NULL); - LWLockRelease(bufHdr->content_lock); + LWLockRelease(BufferDescriptorGetContentLock(bufHdr)); UnpinBuffer(bufHdr, true); return result | BUF_WRITTEN; @@ -2926,9 +2926,9 @@ FlushRelationBuffers(Relation rel) (bufHdr->flags & BM_VALID) && (bufHdr->flags & BM_DIRTY)) { PinBuffer_Locked(bufHdr); - LWLockAcquire(bufHdr->content_lock, LW_SHARED); + LWLockAcquire(BufferDescriptorGetContentLock(bufHdr), LW_SHARED); FlushBuffer(bufHdr, rel->rd_smgr); - LWLockRelease(bufHdr->content_lock); + LWLockRelease(BufferDescriptorGetContentLock(bufHdr)); UnpinBuffer(bufHdr, true); } else @@ -2978,9 +2978,9 @@ FlushDatabaseBuffers(Oid dbid) (bufHdr->flags & BM_VALID) && (bufHdr->flags & BM_DIRTY)) { PinBuffer_Locked(bufHdr); - LWLockAcquire(bufHdr->content_lock, LW_SHARED); + LWLockAcquire(BufferDescriptorGetContentLock(bufHdr), LW_SHARED); FlushBuffer(bufHdr, NULL); - LWLockRelease(bufHdr->content_lock); + LWLockRelease(BufferDescriptorGetContentLock(bufHdr)); UnpinBuffer(bufHdr, true); } else @@ -3080,7 +3080,7 @@ MarkBufferDirtyHint(Buffer buffer, bool buffer_std) Assert(GetPrivateRefCount(buffer) > 0); /* here, either share or exclusive lock is OK */ - Assert(LWLockHeldByMe(bufHdr->content_lock)); + Assert(LWLockHeldByMe(BufferDescriptorGetContentLock(bufHdr))); /* * This routine might get called many times on the same page, if we are @@ -3233,11 +3233,11 @@ LockBuffer(Buffer buffer, int mode) buf = GetBufferDescriptor(buffer - 1); if (mode == BUFFER_LOCK_UNLOCK) - LWLockRelease(buf->content_lock); + LWLockRelease(BufferDescriptorGetContentLock(buf)); else if (mode == BUFFER_LOCK_SHARE) - LWLockAcquire(buf->content_lock, LW_SHARED); + LWLockAcquire(BufferDescriptorGetContentLock(buf), LW_SHARED); else if (mode == BUFFER_LOCK_EXCLUSIVE) - LWLockAcquire(buf->content_lock, LW_EXCLUSIVE); + LWLockAcquire(BufferDescriptorGetContentLock(buf), LW_EXCLUSIVE); else elog(ERROR, "unrecognized buffer lock mode: %d", mode); } @@ -3258,7 +3258,7 @@ ConditionalLockBuffer(Buffer buffer) buf = GetBufferDescriptor(buffer - 1); - return LWLockConditionalAcquire(buf->content_lock, LW_EXCLUSIVE); + return LWLockConditionalAcquire(BufferDescriptorGetContentLock(buf), LW_EXCLUSIVE); } /* @@ -3468,8 +3468,8 @@ WaitIO(volatile BufferDesc *buf) UnlockBufHdr(buf); if (!(sv_flags & BM_IO_IN_PROGRESS)) break; - LWLockAcquire(buf->io_in_progress_lock, LW_SHARED); - LWLockRelease(buf->io_in_progress_lock); + LWLockAcquire(BufferDescriptorGetIOLock(buf), LW_SHARED); + LWLockRelease(BufferDescriptorGetIOLock(buf)); } } @@ -3502,7 +3502,7 @@ StartBufferIO(volatile BufferDesc *buf, bool forInput) * Grab the io_in_progress lock so that other processes can wait for * me to finish the I/O. */ - LWLockAcquire(buf->io_in_progress_lock, LW_EXCLUSIVE); + LWLockAcquire(BufferDescriptorGetIOLock(buf), LW_EXCLUSIVE); LockBufHdr(buf); @@ -3516,7 +3516,7 @@ StartBufferIO(volatile BufferDesc *buf, bool forInput) * him to get unwedged. */ UnlockBufHdr(buf); - LWLockRelease(buf->io_in_progress_lock); + LWLockRelease(BufferDescriptorGetIOLock(buf)); WaitIO(buf); } @@ -3526,7 +3526,7 @@ StartBufferIO(volatile BufferDesc *buf, bool forInput) { /* someone else already did the I/O */ UnlockBufHdr(buf); - LWLockRelease(buf->io_in_progress_lock); + LWLockRelease(BufferDescriptorGetIOLock(buf)); return false; } @@ -3575,7 +3575,7 @@ TerminateBufferIO(volatile BufferDesc *buf, bool clear_dirty, InProgressBuf = NULL; - LWLockRelease(buf->io_in_progress_lock); + LWLockRelease(BufferDescriptorGetIOLock(buf)); } /* @@ -3600,7 +3600,7 @@ AbortBufferIO(void) * we can use TerminateBufferIO. Anyone who's executing WaitIO on the * buffer will be in a busy spin until we succeed in doing this. */ - LWLockAcquire(buf->io_in_progress_lock, LW_EXCLUSIVE); + LWLockAcquire(BufferDescriptorGetIOLock(buf), LW_EXCLUSIVE); LockBufHdr(buf); Assert(buf->flags & BM_IO_IN_PROGRESS); diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c index 6bca02c..cfbea9d 100644 --- a/src/backend/storage/lmgr/lwlock.c +++ b/src/backend/storage/lmgr/lwlock.c @@ -353,9 +353,6 @@ NumLWLocks(void) /* Predefined LWLocks */ numLocks = NUM_FIXED_LWLOCKS; - /* bufmgr.c needs two for each shared buffer */ - numLocks += 2 * NBuffers; - /* proc.c needs one for each backend or auxiliary process */ numLocks += MaxBackends + NUM_AUXILIARY_PROCS; diff --git a/src/include/storage/buf.h b/src/include/storage/buf.h index 1367ac7..8822b11 100644 --- a/src/include/storage/buf.h +++ b/src/include/storage/buf.h @@ -43,4 +43,10 @@ typedef int Buffer; */ typedef struct BufferAccessStrategyData *BufferAccessStrategy; +typedef struct BufferCtlBase +{ + void *bufferDescriptors; + char *bufferBlocks; +} BufferCtlBase; + #endif /* BUF_H */ diff --git a/src/include/storage/buf_internals.h b/src/include/storage/buf_internals.h index 521ee1c..e1795dc 100644 --- a/src/include/storage/buf_internals.h +++ b/src/include/storage/buf_internals.h @@ -95,6 +95,7 @@ typedef struct buftag (a).forkNum == (b).forkNum \ ) + /* * The shared buffer mapping table is partitioned to reduce contention. * To determine which partition lock a given tag requires, compute the tag's @@ -104,10 +105,9 @@ typedef struct buftag #define BufTableHashPartition(hashcode) \ ((hashcode) % NUM_BUFFER_PARTITIONS) #define BufMappingPartitionLock(hashcode) \ - (&MainLWLockArray[BUFFER_MAPPING_LWLOCK_OFFSET + \ - BufTableHashPartition(hashcode)].lock) + (&((BufferCtlData *)BufferCtl)->blockLocks[BufTableHashPartition(hashcode)].lock) #define BufMappingPartitionLockByIndex(i) \ - (&MainLWLockArray[BUFFER_MAPPING_LWLOCK_OFFSET + (i)].lock) + (&((BufferCtlData *)BufferCtl)->blockLocks[i].lock) /* * BufferDesc -- shared descriptor/state data for a single shared buffer. @@ -138,17 +138,15 @@ typedef struct BufferDesc { BufferTag tag; /* ID of page contained in buffer */ BufFlags flags; /* see bit definitions above */ - uint16 usage_count; /* usage counter for clock sweep code */ + uint8 usage_count; /* usage counter for clock sweep code */ + slock_t buf_hdr_lock; /* protects the above fields */ unsigned refcount; /* # of backends holding pins on buffer */ int wait_backend_pid; /* backend PID of pin-count waiter */ - slock_t buf_hdr_lock; /* protects the above fields */ - int buf_id; /* buffer's index number (from 0) */ int freeNext; /* link in freelist chain */ - LWLock *io_in_progress_lock; /* to wait for I/O to complete */ - LWLock *content_lock; /* to lock access to buffer contents */ + LWLock content_lock; /* to lock access to buffer contents */ } BufferDesc; /* @@ -179,10 +177,56 @@ typedef union BufferDescPadded char pad[BUFFERDESC_PAD_TO_SIZE]; } BufferDescPadded; -#define GetBufferDescriptor(id) (&BufferDescriptors[(id)].bufferdesc) +/* Number of partitions of the shared buffer mapping hashtable */ +#define NUM_BUFFER_PARTITIONS 128 + +/* Maximum length of a bufmgr lock name */ +#define BUFMGR_MAX_NAME_LENGTH 32 + +/* + * Base control struct for the buffer manager data + * Located in shared memory. + * + * BufferCtl variable points to BufferCtlBase because of only + * the backend code knows about BufferDescPadded, LWLock and + * others structures and the same time it must be usable in + * the frontend code. + */ +typedef struct BufferCtlData +{ + BufferCtlBase base; + + /* lwlocks */ + int IOLWLockTrancheId; + LWLockTranche IOLWLockTranche; + + int blockLWLockTrancheId; + LWLockTranche blockLWLockTranche; + + int contentLWLockTrancheId; + LWLockTranche contentLWLockTranche; + + char IOLWLockTrancheName[BUFMGR_MAX_NAME_LENGTH]; + char blockLWLockTrancheName[BUFMGR_MAX_NAME_LENGTH]; + char contentLWLockTrancheName[BUFMGR_MAX_NAME_LENGTH]; + + LWLockPadded blockLocks[NUM_BUFFER_PARTITIONS]; + LWLockMinimallyPadded *IOLocks; +} BufferCtlData; + +/* buf_init.c */ +extern PGDLLIMPORT BufferCtlBase *BufferCtl; + + +#define GetBufferDescriptor(id) \ + (&((BufferDescPadded *)(BufferCtl->bufferDescriptors))[(id)].bufferdesc) #define GetLocalBufferDescriptor(id) (&LocalBufferDescriptors[(id)]) #define BufferDescriptorGetBuffer(bdesc) ((bdesc)->buf_id + 1) +#define BufferDescriptorGetIOLock(bdesc) \ + (&(((BufferCtlData *)BufferCtl)->IOLocks[(bdesc)->buf_id]).lock) +#define BufferDescriptorGetContentLock(bdesc) \ + ((LWLock*) (&(bdesc)->content_lock)) /* * The freeNext field is either the index of the next freelist entry, @@ -204,9 +248,6 @@ typedef union BufferDescPadded #define UnlockBufHdr(bufHdr) SpinLockRelease(&(bufHdr)->buf_hdr_lock) -/* in buf_init.c */ -extern PGDLLIMPORT BufferDescPadded *BufferDescriptors; - /* in localbuf.c */ extern BufferDesc *LocalBufferDescriptors; diff --git a/src/include/storage/bufmgr.h b/src/include/storage/bufmgr.h index 0f59201..7276beb 100644 --- a/src/include/storage/bufmgr.h +++ b/src/include/storage/bufmgr.h @@ -48,6 +48,9 @@ typedef enum /* in globals.c ... this duplicates miscadmin.h */ extern PGDLLIMPORT int NBuffers; +/* buf_init.c */ +extern PGDLLIMPORT BufferCtlBase *BufferCtl; + /* in bufmgr.c */ extern bool zero_damaged_pages; extern int bgwriter_lru_maxpages; @@ -55,9 +58,6 @@ extern double bgwriter_lru_multiplier; extern bool track_io_timing; extern int target_prefetch_pages; -/* in buf_init.c */ -extern PGDLLIMPORT char *BufferBlocks; - /* in guc.c */ extern int effective_io_concurrency; @@ -121,7 +121,7 @@ extern PGDLLIMPORT int32 *LocalRefCount; BufferIsLocal(buffer) ? \ LocalBufferBlockPointers[-(buffer) - 1] \ : \ - (Block) (BufferBlocks + ((Size) ((buffer) - 1)) * BLCKSZ) \ + (Block) (BufferCtl->bufferBlocks + ((Size) ((buffer) - 1)) * BLCKSZ) \ ) /* diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h index 4653e09..494e14e 100644 --- a/src/include/storage/lwlock.h +++ b/src/include/storage/lwlock.h @@ -76,22 +76,28 @@ typedef struct LWLock * (Of course, we have to also ensure that the array start address is suitably * aligned.) * - * On a 32-bit platforms a LWLock will these days fit into 16 bytes, but since - * that didn't use to be the case and cramming more lwlocks into a cacheline - * might be detrimental performancewise we still use 32 byte alignment - * there. So, both on 32 and 64 bit platforms, it should fit into 32 bytes - * unless slock_t is really big. We allow for that just in case. + * We pad out the main LWLocks so we have one per cache line to minimize + * contention. Other tranches, with differing usage patterns, are allocated + * differently. */ -#define LWLOCK_PADDED_SIZE (sizeof(LWLock) <= 32 ? 32 : 64) +#define LWLOCK_PADDED_SIZE PG_CACHE_LINE_SIZE +#define LWLOCK_MINIMAL_SIZE (sizeof(LWLock) <= 32 ? 32 : 64) typedef union LWLockPadded { LWLock lock; char pad[LWLOCK_PADDED_SIZE]; } LWLockPadded; + extern PGDLLIMPORT LWLockPadded *MainLWLockArray; extern char *MainLWLockNames[]; +typedef union LWLockMinimallyPadded +{ + LWLock lock; + char pad[LWLOCK_MINIMAL_SIZE]; +} LWLockMinimallyPadded; + /* Names for fixed lwlocks */ #include "storage/lwlocknames.h" @@ -101,9 +107,6 @@ extern char *MainLWLockNames[]; * having this file include lock.h or bufmgr.h would be backwards. */ -/* Number of partitions of the shared buffer mapping hashtable */ -#define NUM_BUFFER_PARTITIONS 128 - /* Number of partitions the shared lock tables are divided into */ #define LOG2_NUM_LOCK_PARTITIONS 4 #define NUM_LOCK_PARTITIONS (1 << LOG2_NUM_LOCK_PARTITIONS) @@ -113,9 +116,7 @@ extern char *MainLWLockNames[]; #define NUM_PREDICATELOCK_PARTITIONS (1 << LOG2_NUM_PREDICATELOCK_PARTITIONS) /* Offsets for various chunks of preallocated lwlocks. */ -#define BUFFER_MAPPING_LWLOCK_OFFSET NUM_INDIVIDUAL_LWLOCKS -#define LOCK_MANAGER_LWLOCK_OFFSET \ - (BUFFER_MAPPING_LWLOCK_OFFSET + NUM_BUFFER_PARTITIONS) +#define LOCK_MANAGER_LWLOCK_OFFSET NUM_INDIVIDUAL_LWLOCKS #define PREDICATELOCK_MANAGER_LWLOCK_OFFSET \ (LOCK_MANAGER_LWLOCK_OFFSET + NUM_LOCK_PARTITIONS) #define NUM_FIXED_LWLOCKS \
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers