#include "utils/hsearch.h"
Go to the source code of this file.
#define SHMEM_INDEX_SIZE (64) |
Definition at line 53 of file shmem.h.
Referenced by CreateSharedMemoryAndSemaphores(), and InitShmemIndex().
Definition at line 418 of file shmem.c.
References ereport, errcode(), errmsg(), and ERROR.
Referenced by AsyncShmemInit(), AsyncShmemSize(), AutoVacuumShmemSize(), BackendStatusShmemSize(), BTreeShmemSize(), BufferShmemSize(), CheckpointerShmemSize(), CreateSharedInvalidationState(), CreateSharedMemoryAndSemaphores(), CreateSharedProcArray(), hash_estimate_size(), LockShmemSize(), LWLockShmemSize(), MultiXactShmemSize(), pgss_memsize(), PMSignalShmemSize(), PredicateLockShmemSize(), ProcArrayShmemSize(), ProcGlobalShmemSize(), RequestAddinShmemSpace(), SInvalShmemSize(), StrategyShmemSize(), TwoPhaseShmemSize(), WalRcvShmemSize(), WalSndShmemSize(), and XLOGShmemSize().
void InitShmemAccess | ( | void * | seghdr | ) |
Definition at line 97 of file shmem.c.
References ShmemBase, ShmemEnd, and PGShmemHeader::totalsize.
Referenced by CreateSharedMemoryAndSemaphores().
{ PGShmemHeader *shmhdr = (PGShmemHeader *) seghdr; ShmemSegHdr = shmhdr; ShmemBase = (void *) shmhdr; ShmemEnd = (char *) ShmemBase + shmhdr->totalsize; }
void InitShmemAllocation | ( | void | ) |
Definition at line 112 of file shmem.c.
References Assert, MAXALIGN, NULL, ShmemAlloc(), ShmemLock, ShmemVariableCache, and SpinLockInit.
Referenced by CreateSharedMemoryAndSemaphores().
{ PGShmemHeader *shmhdr = ShmemSegHdr; Assert(shmhdr != NULL); /* * Initialize the spinlock used by ShmemAlloc. We have to do the space * allocation the hard way, since obviously ShmemAlloc can't be called * yet. */ ShmemLock = (slock_t *) (((char *) shmhdr) + shmhdr->freeoffset); shmhdr->freeoffset += MAXALIGN(sizeof(slock_t)); Assert(shmhdr->freeoffset <= shmhdr->totalsize); SpinLockInit(ShmemLock); /* ShmemIndex can't be set up yet (need LWLocks first) */ shmhdr->index = NULL; ShmemIndex = (HTAB *) NULL; /* * Initialize ShmemVariableCache for transaction manager. (This doesn't * really belong here, but not worth moving.) */ ShmemVariableCache = (VariableCache) ShmemAlloc(sizeof(*ShmemVariableCache)); memset(ShmemVariableCache, 0, sizeof(*ShmemVariableCache)); }
void InitShmemIndex | ( | void | ) |
Definition at line 210 of file shmem.c.
References HASHCTL::entrysize, HASHCTL::keysize, SHMEM_INDEX_SIZE, and ShmemInitHash().
Referenced by CreateSharedMemoryAndSemaphores().
{ HASHCTL info; int hash_flags; /* * Create the shared memory shmem index. * * Since ShmemInitHash calls ShmemInitStruct, which expects the ShmemIndex * hashtable to exist already, we have a bit of a circularity problem in * initializing the ShmemIndex itself. The special "ShmemIndex" hash * table name will tell ShmemInitStruct to fake it. */ info.keysize = SHMEM_INDEX_KEYSIZE; info.entrysize = sizeof(ShmemIndexEnt); hash_flags = HASH_ELEM; ShmemIndex = ShmemInitHash("ShmemIndex", SHMEM_INDEX_SIZE, SHMEM_INDEX_SIZE, &info, hash_flags); }
Definition at line 435 of file shmem.c.
References ereport, errcode(), errmsg(), and ERROR.
Referenced by AsyncShmemInit(), AsyncShmemSize(), AutoVacuumShmemSize(), BackendStatusShmemSize(), BTreeShmemSize(), BufferShmemSize(), CheckpointerShmemSize(), CreateSharedBackendStatus(), CreateSharedInvalidationState(), CreateSharedProcArray(), hash_estimate_size(), InitPredicateLocks(), LWLockShmemSize(), PMSignalShmemSize(), PredicateLockShmemSize(), ProcArrayShmemSize(), ProcGlobalShmemSize(), SInvalShmemSize(), TwoPhaseShmemSize(), WalSndShmemSize(), and XLOGShmemSize().
void RequestAddinShmemSpace | ( | Size | size | ) |
Definition at line 61 of file ipci.c.
References add_size(), addin_request_allowed, IsUnderPostmaster, and total_addin_request.
Referenced by _PG_init().
{ if (IsUnderPostmaster || !addin_request_allowed) return; /* too late */ total_addin_request = add_size(total_addin_request, size); }
bool ShmemAddrIsValid | ( | const void * | addr | ) |
Definition at line 201 of file shmem.c.
References ShmemBase, and ShmemEnd.
Referenced by NextPredXact(), ReleasePredXact(), ShmemInitStruct(), SHMQueueDelete(), SHMQueueElemInit(), SHMQueueEmpty(), SHMQueueInit(), SHMQueueInsertAfter(), SHMQueueInsertBefore(), SHMQueueIsDetached(), SHMQueueNext(), and SHMQueuePrev().
void* ShmemAlloc | ( | Size | size | ) |
Definition at line 152 of file shmem.c.
References Assert, BUFFERALIGN, ereport, errcode(), errmsg(), PGShmemHeader::freeoffset, MAXALIGN, NULL, ShmemBase, ShmemLock, SpinLockAcquire, SpinLockRelease, totalsize, and WARNING.
Referenced by CreateLWLocks(), InitPredicateLocks(), InitProcGlobal(), InitShmemAllocation(), and ShmemInitStruct().
{ Size newStart; Size newFree; void *newSpace; /* use volatile pointer to prevent code rearrangement */ volatile PGShmemHeader *shmemseghdr = ShmemSegHdr; /* * ensure all space is adequately aligned. */ size = MAXALIGN(size); Assert(shmemseghdr != NULL); SpinLockAcquire(ShmemLock); newStart = shmemseghdr->freeoffset; /* extra alignment for large requests, since they are probably buffers */ if (size >= BLCKSZ) newStart = BUFFERALIGN(newStart); newFree = newStart + size; if (newFree <= shmemseghdr->totalsize) { newSpace = (void *) ((char *) ShmemBase + newStart); shmemseghdr->freeoffset = newFree; } else newSpace = NULL; SpinLockRelease(ShmemLock); if (!newSpace) ereport(WARNING, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("out of shared memory"))); return newSpace; }
HTAB* ShmemInitHash | ( | const char * | name, | |
long | init_size, | |||
long | max_size, | |||
HASHCTL * | infoP, | |||
int | hash_flags | |||
) |
Definition at line 255 of file shmem.c.
References HASHCTL::alloc, HASHCTL::dsize, HASH_ALLOC, hash_create(), hash_get_shared_size(), hash_select_dirsize(), HASH_SHARED_MEM, HASHCTL::hctl, HASHCTL::max_dsize, and ShmemInitStruct().
Referenced by InitBufTable(), InitLocks(), InitPredicateLocks(), InitShmemIndex(), and pgss_shmem_startup().
{ bool found; void *location; /* * Hash tables allocated in shared memory have a fixed directory; it can't * grow or other backends wouldn't be able to find it. So, make sure we * make it big enough to start with. * * The shared memory allocator must be specified too. */ infoP->dsize = infoP->max_dsize = hash_select_dirsize(max_size); infoP->alloc = ShmemAlloc; hash_flags |= HASH_SHARED_MEM | HASH_ALLOC | HASH_DIRSIZE; /* look it up in the shmem index */ location = ShmemInitStruct(name, hash_get_shared_size(infoP, hash_flags), &found); /* * if it already exists, attach to it rather than allocate and initialize * new space */ if (found) hash_flags |= HASH_ATTACH; /* Pass location of hashtable header to hash_create */ infoP->hctl = (HASHHDR *) location; return hash_create(name, init_size, infoP, hash_flags); }
Definition at line 310 of file shmem.c.
References Assert, ereport, errcode(), errmsg(), ERROR, HASH_ENTER_NULL, HASH_REMOVE, hash_search(), PGShmemHeader::index, IsUnderPostmaster, ShmemIndexEnt::location, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), NULL, ShmemAddrIsValid(), ShmemAlloc(), ShmemIndexLock, and ShmemIndexEnt::size.
Referenced by AsyncShmemInit(), AutoVacuumShmemInit(), BTreeShmemInit(), CheckpointerShmemInit(), CreateSharedBackendStatus(), CreateSharedInvalidationState(), CreateSharedProcArray(), InitBufferPool(), InitLocks(), InitPredicateLocks(), InitProcGlobal(), MultiXactShmemInit(), OldSerXidInit(), pgss_shmem_startup(), PMSignalShmemInit(), ProcSignalShmemInit(), ShmemInitHash(), SimpleLruInit(), StrategyInitialize(), SyncScanShmemInit(), TwoPhaseShmemInit(), WalRcvShmemInit(), WalSndShmemInit(), and XLOGShmemInit().
{ ShmemIndexEnt *result; void *structPtr; LWLockAcquire(ShmemIndexLock, LW_EXCLUSIVE); if (!ShmemIndex) { PGShmemHeader *shmemseghdr = ShmemSegHdr; /* Must be trying to create/attach to ShmemIndex itself */ Assert(strcmp(name, "ShmemIndex") == 0); if (IsUnderPostmaster) { /* Must be initializing a (non-standalone) backend */ Assert(shmemseghdr->index != NULL); structPtr = shmemseghdr->index; *foundPtr = TRUE; } else { /* * If the shmem index doesn't exist, we are bootstrapping: we must * be trying to init the shmem index itself. * * Notice that the ShmemIndexLock is released before the shmem * index has been initialized. This should be OK because no other * process can be accessing shared memory yet. */ Assert(shmemseghdr->index == NULL); structPtr = ShmemAlloc(size); if (structPtr == NULL) ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("not enough shared memory for data structure" " \"%s\" (%lu bytes requested)", name, (unsigned long) size))); shmemseghdr->index = structPtr; *foundPtr = FALSE; } LWLockRelease(ShmemIndexLock); return structPtr; } /* look it up in the shmem index */ result = (ShmemIndexEnt *) hash_search(ShmemIndex, name, HASH_ENTER_NULL, foundPtr); if (!result) { LWLockRelease(ShmemIndexLock); ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("could not create ShmemIndex entry for data structure \"%s\"", name))); } if (*foundPtr) { /* * Structure is in the shmem index so someone else has allocated it * already. The size better be the same as the size we are trying to * initialize to, or there is a name conflict (or worse). */ if (result->size != size) { LWLockRelease(ShmemIndexLock); ereport(ERROR, (errmsg("ShmemIndex entry size is wrong for data structure" " \"%s\": expected %lu, actual %lu", name, (unsigned long) size, (unsigned long) result->size))); } structPtr = result->location; } else { /* It isn't in the table yet. allocate and initialize it */ structPtr = ShmemAlloc(size); if (structPtr == NULL) { /* out of memory; remove the failed ShmemIndex entry */ hash_search(ShmemIndex, name, HASH_REMOVE, NULL); LWLockRelease(ShmemIndexLock); ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg("not enough shared memory for data structure" " \"%s\" (%lu bytes requested)", name, (unsigned long) size))); } result->size = size; result->location = structPtr; } LWLockRelease(ShmemIndexLock); Assert(ShmemAddrIsValid(structPtr)); return structPtr; }
void SHMQueueDelete | ( | SHM_QUEUE * | queue | ) |
Definition at line 68 of file shmqueue.c.
References Assert, SHM_QUEUE::next, SHM_QUEUE::prev, and ShmemAddrIsValid().
Referenced by CheckTargetForConflictsIn(), CleanUpLock(), ClearOldPredicateLocks(), CreatePredXact(), DeleteChildTargetLocks(), DeleteLockTarget(), DropAllPredicateLocksFromTable(), LockAcquireExtended(), PostPrepare_Locks(), ProcWakeup(), ReleaseOneSerializableXact(), ReleasePredXact(), ReleaseRWConflict(), RemoveFromWaitQueue(), SetPossibleUnsafeConflict(), SetRWConflict(), SummarizeOldestCommittedSxact(), SyncRepCancelWait(), SyncRepCleanupAtProcExit(), SyncRepWakeQueue(), and TransferPredicateLocksToNewTarget().
void SHMQueueElemInit | ( | SHM_QUEUE * | queue | ) |
Definition at line 57 of file shmqueue.c.
References Assert, SHM_QUEUE::next, SHM_QUEUE::prev, and ShmemAddrIsValid().
Referenced by GetSerializableTransactionSnapshotInt(), InitAuxiliaryProcess(), InitProcess(), MarkAsPreparing(), and predicatelock_twophase_recover().
{ Assert(ShmemAddrIsValid(queue)); queue->prev = queue->next = NULL; }
Definition at line 180 of file shmqueue.c.
References Assert, SHM_QUEUE::next, SHM_QUEUE::prev, and ShmemAddrIsValid().
Referenced by CheckForSerializableConflictOut(), CleanUpLock(), GetSafeSnapshot(), InitAuxiliaryProcess(), InitProcess(), lock_twophase_recover(), ProcKill(), ReleasePredicateLocks(), RemoveTargetIfNoLongerUsed(), RWConflictExists(), SetupLockInTable(), SummarizeOldestCommittedSxact(), and TransferPredicateLocksToNewTarget().
{ Assert(ShmemAddrIsValid(queue)); if (queue->prev == queue) { Assert(queue->next == queue); return TRUE; } return FALSE; }
void SHMQueueInit | ( | SHM_QUEUE * | queue | ) |
Definition at line 36 of file shmqueue.c.
References Assert, SHM_QUEUE::next, SHM_QUEUE::prev, and ShmemAddrIsValid().
Referenced by CreatePredicateLock(), DropAllPredicateLocksFromTable(), GetSerializableTransactionSnapshotInt(), InitPredicateLocks(), InitProcGlobal(), lock_twophase_recover(), MarkAsPreparing(), predicatelock_twophase_recover(), ProcQueueInit(), ReleaseOneSerializableXact(), SetupLockInTable(), TransferPredicateLocksToNewTarget(), and WalSndShmemInit().
{ Assert(ShmemAddrIsValid(queue)); queue->prev = queue->next = queue; }
Definition at line 108 of file shmqueue.c.
References Assert, SHM_QUEUE::next, SHM_QUEUE::prev, and ShmemAddrIsValid().
Referenced by SyncRepQueueInsert().
Definition at line 89 of file shmqueue.c.
References Assert, SHM_QUEUE::next, SHM_QUEUE::prev, and ShmemAddrIsValid().
Referenced by CreatePredicateLock(), CreatePredXact(), DeadLockCheck(), DropAllPredicateLocksFromTable(), InitPredicateLocks(), lock_twophase_recover(), PostPrepare_Locks(), ProcSleep(), ReleaseOneSerializableXact(), ReleasePredicateLocks(), ReleasePredXact(), ReleaseRWConflict(), SetPossibleUnsafeConflict(), SetRWConflict(), SetupLockInTable(), and TransferPredicateLocksToNewTarget().
Definition at line 47 of file shmqueue.c.
References Assert, NULL, SHM_QUEUE::prev, and ShmemAddrIsValid().
Referenced by SyncRepCancelWait(), SyncRepCleanupAtProcExit(), and SyncRepWaitForLSN().
{ Assert(ShmemAddrIsValid(queue)); return (queue->prev == NULL); }
Definition at line 145 of file shmqueue.c.
References Assert, SHM_QUEUE::next, and ShmemAddrIsValid().
Referenced by AtPrepare_PredicateLocks(), CheckTableForSerializableConflictIn(), CheckTargetForConflictsIn(), ClearOldPredicateLocks(), CreatePredXact(), DeleteChildTargetLocks(), DeleteLockTarget(), DropAllPredicateLocksFromTable(), FindLockCycleRecurse(), FirstPredXact(), FlagSxactUnsafe(), GetLockConflicts(), LockReleaseAll(), NextPredXact(), OnConflict_CheckForSerializationFailure(), PostPrepare_Locks(), PreCommit_CheckForSerializationFailure(), ReleaseOneSerializableXact(), ReleasePredicateLocks(), RWConflictExists(), SetPossibleUnsafeConflict(), SetRWConflict(), SummarizeOldestCommittedSxact(), SyncRepWakeQueue(), and TransferPredicateLocksToNewTarget().
{ SHM_QUEUE *elemPtr = curElem->next; Assert(ShmemAddrIsValid(curElem)); if (elemPtr == queue) /* back to the queue head? */ return NULL; return (Pointer) (((char *) elemPtr) - linkOffset); }
Definition at line 164 of file shmqueue.c.
References Assert, SHM_QUEUE::prev, and ShmemAddrIsValid().
Referenced by SyncRepQueueInsert().
{ SHM_QUEUE *elemPtr = curElem->prev; Assert(ShmemAddrIsValid(curElem)); if (elemPtr == queue) /* back to the queue head? */ return NULL; return (Pointer) (((char *) elemPtr) - linkOffset); }