PostgreSQL Source Code git master
shmem.h File Reference
#include "storage/spin.h"
#include "utils/hsearch.h"
Include dependency graph for shmem.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ShmemIndexEnt
 

Macros

#define SHMEM_INDEX_KEYSIZE   (48)
 
#define SHMEM_INDEX_SIZE   (64)
 

Typedefs

typedef struct PGShmemHeader PGShmemHeader
 

Functions

void InitShmemAccess (PGShmemHeader *seghdr)
 
void InitShmemAllocation (void)
 
void * ShmemAlloc (Size size)
 
void * ShmemAllocNoError (Size size)
 
bool ShmemAddrIsValid (const void *addr)
 
void InitShmemIndex (void)
 
HTABShmemInitHash (const char *name, int64 init_size, int64 max_size, HASHCTL *infoP, int hash_flags)
 
void * ShmemInitStruct (const char *name, Size size, bool *foundPtr)
 
Size add_size (Size s1, Size s2)
 
Size mul_size (Size s1, Size s2)
 
PGDLLIMPORT Size pg_get_shmem_pagesize (void)
 
void RequestAddinShmemSpace (Size size)
 

Variables

PGDLLIMPORT slock_t * ShmemLock
 

Macro Definition Documentation

◆ SHMEM_INDEX_KEYSIZE

#define SHMEM_INDEX_KEYSIZE   (48)

Definition at line 51 of file shmem.h.

◆ SHMEM_INDEX_SIZE

#define SHMEM_INDEX_SIZE   (64)

Definition at line 53 of file shmem.h.

Typedef Documentation

◆ PGShmemHeader

typedef struct PGShmemHeader PGShmemHeader

Definition at line 30 of file shmem.h.

Function Documentation

◆ add_size()

Size add_size ( Size  s1,
Size  s2 
)

Definition at line 494 of file shmem.c.

495{
496 Size result;
497
498 result = s1 + s2;
499 /* We are assuming Size is an unsigned type here... */
500 if (result < s1 || result < s2)
502 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
503 errmsg("requested shared memory size overflows size_t")));
504 return result;
505}
size_t Size
Definition: c.h:614
int errcode(int sqlerrcode)
Definition: elog.c:863
int errmsg(const char *fmt,...)
Definition: elog.c:1080
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150
char * s1
char * s2

References ereport, errcode(), errmsg(), ERROR, s1, and s2.

Referenced by _brin_parallel_estimate_shared(), _bt_parallel_estimate_shared(), _gin_parallel_estimate_shared(), AioShmemSize(), ApplyLauncherShmemSize(), AsyncShmemInit(), AsyncShmemSize(), AutoVacuumShmemSize(), BackendStatusShmemSize(), BackgroundWorkerShmemSize(), btestimateparallelscan(), BTreeShmemSize(), BufferManagerShmemSize(), CalculateShmemSize(), CheckpointerShmemSize(), estimate_variable_size(), EstimateClientConnectionInfoSpace(), EstimateComboCIDStateSpace(), EstimateGUCStateSpace(), EstimateLibraryStateSpace(), EstimateParamExecSpace(), EstimateParamListSpace(), EstimateSnapshotSpace(), EstimateTransactionStateSpace(), ExecAggEstimate(), ExecAppendEstimate(), ExecBitmapHeapEstimate(), ExecBitmapHeapInitializeDSM(), ExecHashEstimate(), ExecIncrementalSortEstimate(), ExecMemoizeEstimate(), ExecSortEstimate(), expand_planner_arrays(), FastPathLockShmemSize(), hash_estimate_size(), index_parallelscan_estimate(), index_parallelscan_initialize(), InitializeShmemGUCs(), InjectionPointShmemSize(), LockManagerShmemSize(), LWLockShmemSize(), MultiXactShmemSize(), pgaio_worker_shmem_size(), PgArchShmemSize(), PGProcShmemSize(), pgss_memsize(), PMSignalShmemSize(), PredicateLockShmemInit(), PredicateLockShmemSize(), ProcArrayShmemInit(), ProcArrayShmemSize(), ProcGlobalShmemSize(), ProcSignalShmemSize(), ReplicationOriginShmemSize(), ReplicationSlotsShmemSize(), RequestAddinShmemSpace(), SerializeTransactionState(), SharedInvalShmemSize(), shm_toc_estimate(), StatsShmemSize(), StrategyShmemSize(), table_parallelscan_estimate(), tuplesort_estimate_shared(), TwoPhaseShmemSize(), WaitEventCustomShmemSize(), WaitLSNShmemSize(), WalRcvShmemSize(), WalSndShmemSize(), and XLOGShmemSize().

◆ InitShmemAccess()

void InitShmemAccess ( PGShmemHeader seghdr)

Definition at line 103 of file shmem.c.

104{
105 ShmemSegHdr = seghdr;
106 ShmemBase = seghdr;
107 ShmemEnd = (char *) ShmemBase + seghdr->totalsize;
108}
static void * ShmemBase
Definition: shmem.c:85
static void * ShmemEnd
Definition: shmem.c:87
static PGShmemHeader * ShmemSegHdr
Definition: shmem.c:83
Size totalsize
Definition: pg_shmem.h:34

References ShmemBase, ShmemEnd, ShmemSegHdr, and PGShmemHeader::totalsize.

Referenced by CreateSharedMemoryAndSemaphores().

◆ InitShmemAllocation()

void InitShmemAllocation ( void  )

Definition at line 116 of file shmem.c.

117{
118 PGShmemHeader *shmhdr = ShmemSegHdr;
119 char *aligned;
120
121 Assert(shmhdr != NULL);
122
123 /*
124 * Initialize the spinlock used by ShmemAlloc. We must use
125 * ShmemAllocUnlocked, since obviously ShmemAlloc can't be called yet.
126 */
127 ShmemLock = (slock_t *) ShmemAllocUnlocked(sizeof(slock_t));
128
130
131 /*
132 * Allocations after this point should go through ShmemAlloc, which
133 * expects to allocate everything on cache line boundaries. Make sure the
134 * first allocation begins on a cache line boundary.
135 */
136 aligned = (char *)
137 (CACHELINEALIGN((((char *) shmhdr) + shmhdr->freeoffset)));
138 shmhdr->freeoffset = aligned - (char *) shmhdr;
139
140 /* ShmemIndex can't be set up yet (need LWLocks first) */
141 shmhdr->index = NULL;
142 ShmemIndex = (HTAB *) NULL;
143}
#define CACHELINEALIGN(LEN)
Definition: c.h:817
Assert(PointerIsAligned(start, uint64))
slock_t * ShmemLock
Definition: shmem.c:89
static HTAB * ShmemIndex
Definition: shmem.c:92
static void * ShmemAllocUnlocked(Size size)
Definition: shmem.c:239
#define SpinLockInit(lock)
Definition: spin.h:57
Definition: dynahash.c:222

References Assert(), CACHELINEALIGN, PGShmemHeader::freeoffset, PGShmemHeader::index, ShmemAllocUnlocked(), ShmemIndex, ShmemLock, ShmemSegHdr, and SpinLockInit.

Referenced by CreateSharedMemoryAndSemaphores().

◆ InitShmemIndex()

void InitShmemIndex ( void  )

Definition at line 284 of file shmem.c.

285{
286 HASHCTL info;
287
288 /*
289 * Create the shared memory shmem index.
290 *
291 * Since ShmemInitHash calls ShmemInitStruct, which expects the ShmemIndex
292 * hashtable to exist already, we have a bit of a circularity problem in
293 * initializing the ShmemIndex itself. The special "ShmemIndex" hash
294 * table name will tell ShmemInitStruct to fake it.
295 */
297 info.entrysize = sizeof(ShmemIndexEnt);
298
299 ShmemIndex = ShmemInitHash("ShmemIndex",
301 &info,
303}
#define HASH_STRINGS
Definition: hsearch.h:96
#define HASH_ELEM
Definition: hsearch.h:95
HTAB * ShmemInitHash(const char *name, int64 init_size, int64 max_size, HASHCTL *infoP, int hash_flags)
Definition: shmem.c:333
#define SHMEM_INDEX_SIZE
Definition: shmem.h:53
#define SHMEM_INDEX_KEYSIZE
Definition: shmem.h:51
Size keysize
Definition: hsearch.h:75
Size entrysize
Definition: hsearch.h:76

References HASHCTL::entrysize, HASH_ELEM, HASH_STRINGS, HASHCTL::keysize, SHMEM_INDEX_KEYSIZE, SHMEM_INDEX_SIZE, ShmemIndex, and ShmemInitHash().

Referenced by CreateOrAttachShmemStructs().

◆ mul_size()

Size mul_size ( Size  s1,
Size  s2 
)

Definition at line 511 of file shmem.c.

512{
513 Size result;
514
515 if (s1 == 0 || s2 == 0)
516 return 0;
517 result = s1 * s2;
518 /* We are assuming Size is an unsigned type here... */
519 if (result / s2 != s1)
521 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
522 errmsg("requested shared memory size overflows size_t")));
523 return result;
524}

References ereport, errcode(), errmsg(), ERROR, s1, and s2.

Referenced by _brin_begin_parallel(), _bt_begin_parallel(), _gin_begin_parallel(), AioBackendShmemSize(), AioHandleDataShmemSize(), AioHandleIOVShmemSize(), AioHandleShmemSize(), ApplyLauncherShmemSize(), AsyncShmemInit(), AsyncShmemSize(), AutoVacuumShmemSize(), BackendStatusShmemInit(), BackendStatusShmemSize(), BackgroundWorkerShmemSize(), BTreeShmemSize(), BufferManagerShmemSize(), CheckpointerShmemSize(), EstimateComboCIDStateSpace(), EstimatePendingSyncsSpace(), EstimateReindexStateSpace(), EstimateSnapshotSpace(), EstimateTransactionStateSpace(), ExecAggEstimate(), ExecBitmapHeapEstimate(), ExecBitmapHeapInitializeDSM(), ExecHashEstimate(), ExecIncrementalSortEstimate(), ExecInitParallelPlan(), ExecMemoizeEstimate(), ExecParallelRetrieveInstrumentation(), ExecParallelRetrieveJitInstrumentation(), ExecParallelSetupTupleQueues(), ExecSortEstimate(), FastPathLockShmemSize(), hash_estimate_size(), InitializeParallelDSM(), LWLockShmemSize(), parallel_vacuum_init(), PGProcShmemSize(), PGSemaphoreShmemSize(), PMSignalShmemSize(), PredicateLockShmemInit(), PredicateLockShmemSize(), ProcArrayShmemInit(), ProcArrayShmemSize(), ProcSignalShmemSize(), ReplicationOriginShmemSize(), ReplicationSlotsShmemSize(), SharedInvalShmemSize(), shm_toc_estimate(), tuplesort_estimate_shared(), TwoPhaseShmemSize(), WaitLSNShmemSize(), WalSndShmemSize(), and XLOGShmemSize().

◆ pg_get_shmem_pagesize()

PGDLLIMPORT Size pg_get_shmem_pagesize ( void  )

Definition at line 738 of file shmem.c.

739{
740 Size os_page_size;
741#ifdef WIN32
742 SYSTEM_INFO sysinfo;
743
744 GetSystemInfo(&sysinfo);
745 os_page_size = sysinfo.dwPageSize;
746#else
747 os_page_size = sysconf(_SC_PAGESIZE);
748#endif
749
752
754 GetHugePageSize(&os_page_size, NULL);
755
756 return os_page_size;
757}
bool IsUnderPostmaster
Definition: globals.c:120
int huge_pages_status
Definition: guc_tables.c:582
@ HUGE_PAGES_UNKNOWN
Definition: pg_shmem.h:56
@ HUGE_PAGES_ON
Definition: pg_shmem.h:54
void GetHugePageSize(Size *hugepagesize, int *mmap_flags)
Definition: sysv_shmem.c:479

References Assert(), GetHugePageSize(), HUGE_PAGES_ON, huge_pages_status, HUGE_PAGES_UNKNOWN, and IsUnderPostmaster.

Referenced by pg_buffercache_numa_pages(), and pg_get_shmem_allocations_numa().

◆ RequestAddinShmemSpace()

void RequestAddinShmemSpace ( Size  size)

Definition at line 75 of file ipci.c.

76{
78 elog(FATAL, "cannot request additional shared memory outside shmem_request_hook");
80}
#define FATAL
Definition: elog.h:41
#define elog(elevel,...)
Definition: elog.h:226
static Size total_addin_request
Definition: ipci.c:61
bool process_shmem_requests_in_progress
Definition: miscinit.c:1790
Size add_size(Size s1, Size s2)
Definition: shmem.c:494

References add_size(), elog, FATAL, process_shmem_requests_in_progress, and total_addin_request.

Referenced by injection_shmem_request(), pgss_shmem_request(), test_aio_shmem_request(), and test_slru_shmem_request().

◆ ShmemAddrIsValid()

bool ShmemAddrIsValid ( const void *  addr)

Definition at line 275 of file shmem.c.

276{
277 return (addr >= ShmemBase) && (addr < ShmemEnd);
278}

References ShmemBase, and ShmemEnd.

Referenced by ReleasePredXact(), and ShmemInitStruct().

◆ ShmemAlloc()

void * ShmemAlloc ( Size  size)

Definition at line 153 of file shmem.c.

154{
155 void *newSpace;
156 Size allocated_size;
157
158 newSpace = ShmemAllocRaw(size, &allocated_size);
159 if (!newSpace)
161 (errcode(ERRCODE_OUT_OF_MEMORY),
162 errmsg("out of shared memory (%zu bytes requested)",
163 size)));
164 return newSpace;
165}
static void * ShmemAllocRaw(Size size, Size *allocated_size)
Definition: shmem.c:187

References ereport, errcode(), errmsg(), ERROR, and ShmemAllocRaw().

Referenced by CreateLWLocks(), PGReserveSemaphores(), ShmemInitStruct(), and StatsShmemInit().

◆ ShmemAllocNoError()

void * ShmemAllocNoError ( Size  size)

Definition at line 173 of file shmem.c.

174{
175 Size allocated_size;
176
177 return ShmemAllocRaw(size, &allocated_size);
178}

References ShmemAllocRaw().

Referenced by ShmemInitHash().

◆ ShmemInitHash()

HTAB * ShmemInitHash ( const char *  name,
int64  init_size,
int64  max_size,
HASHCTL infoP,
int  hash_flags 
)

Definition at line 333 of file shmem.c.

338{
339 bool found;
340 void *location;
341
342 /*
343 * Hash tables allocated in shared memory have a fixed directory; it can't
344 * grow or other backends wouldn't be able to find it. So, make sure we
345 * make it big enough to start with.
346 *
347 * The shared memory allocator must be specified too.
348 */
349 infoP->dsize = infoP->max_dsize = hash_select_dirsize(max_size);
350 infoP->alloc = ShmemAllocNoError;
351 hash_flags |= HASH_SHARED_MEM | HASH_ALLOC | HASH_DIRSIZE;
352
353 /* look it up in the shmem index */
354 location = ShmemInitStruct(name,
355 hash_get_shared_size(infoP, hash_flags),
356 &found);
357
358 /*
359 * if it already exists, attach to it rather than allocate and initialize
360 * new space
361 */
362 if (found)
363 hash_flags |= HASH_ATTACH;
364
365 /* Pass location of hashtable header to hash_create */
366 infoP->hctl = (HASHHDR *) location;
367
368 return hash_create(name, init_size, infoP, hash_flags);
369}
HTAB * hash_create(const char *tabname, int64 nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:358
Size hash_get_shared_size(HASHCTL *info, int flags)
Definition: dynahash.c:854
int64 hash_select_dirsize(int64 num_entries)
Definition: dynahash.c:830
#define HASH_ALLOC
Definition: hsearch.h:101
#define HASH_DIRSIZE
Definition: hsearch.h:94
#define HASH_ATTACH
Definition: hsearch.h:104
#define HASH_SHARED_MEM
Definition: hsearch.h:103
void * ShmemAllocNoError(Size size)
Definition: shmem.c:173
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:388
HashAllocFunc alloc
Definition: hsearch.h:84
int64 max_dsize
Definition: hsearch.h:73
HASHHDR * hctl
Definition: hsearch.h:88
int64 dsize
Definition: hsearch.h:72
const char * name

References HASHCTL::alloc, HASHCTL::dsize, HASH_ALLOC, HASH_ATTACH, hash_create(), HASH_DIRSIZE, hash_get_shared_size(), hash_select_dirsize(), HASH_SHARED_MEM, HASHCTL::hctl, HASHCTL::max_dsize, name, ShmemAllocNoError(), and ShmemInitStruct().

Referenced by InitBufTable(), InitShmemIndex(), LockManagerShmemInit(), pgss_shmem_startup(), PredicateLockShmemInit(), and WaitEventCustomShmemInit().

◆ ShmemInitStruct()

void * ShmemInitStruct ( const char *  name,
Size  size,
bool *  foundPtr 
)

Definition at line 388 of file shmem.c.

389{
390 ShmemIndexEnt *result;
391 void *structPtr;
392
393 LWLockAcquire(ShmemIndexLock, LW_EXCLUSIVE);
394
395 if (!ShmemIndex)
396 {
397 PGShmemHeader *shmemseghdr = ShmemSegHdr;
398
399 /* Must be trying to create/attach to ShmemIndex itself */
400 Assert(strcmp(name, "ShmemIndex") == 0);
401
403 {
404 /* Must be initializing a (non-standalone) backend */
405 Assert(shmemseghdr->index != NULL);
406 structPtr = shmemseghdr->index;
407 *foundPtr = true;
408 }
409 else
410 {
411 /*
412 * If the shmem index doesn't exist, we are bootstrapping: we must
413 * be trying to init the shmem index itself.
414 *
415 * Notice that the ShmemIndexLock is released before the shmem
416 * index has been initialized. This should be OK because no other
417 * process can be accessing shared memory yet.
418 */
419 Assert(shmemseghdr->index == NULL);
420 structPtr = ShmemAlloc(size);
421 shmemseghdr->index = structPtr;
422 *foundPtr = false;
423 }
424 LWLockRelease(ShmemIndexLock);
425 return structPtr;
426 }
427
428 /* look it up in the shmem index */
429 result = (ShmemIndexEnt *)
431
432 if (!result)
433 {
434 LWLockRelease(ShmemIndexLock);
436 (errcode(ERRCODE_OUT_OF_MEMORY),
437 errmsg("could not create ShmemIndex entry for data structure \"%s\"",
438 name)));
439 }
440
441 if (*foundPtr)
442 {
443 /*
444 * Structure is in the shmem index so someone else has allocated it
445 * already. The size better be the same as the size we are trying to
446 * initialize to, or there is a name conflict (or worse).
447 */
448 if (result->size != size)
449 {
450 LWLockRelease(ShmemIndexLock);
452 (errmsg("ShmemIndex entry size is wrong for data structure"
453 " \"%s\": expected %zu, actual %zu",
454 name, size, result->size)));
455 }
456 structPtr = result->location;
457 }
458 else
459 {
460 Size allocated_size;
461
462 /* It isn't in the table yet. allocate and initialize it */
463 structPtr = ShmemAllocRaw(size, &allocated_size);
464 if (structPtr == NULL)
465 {
466 /* out of memory; remove the failed ShmemIndex entry */
468 LWLockRelease(ShmemIndexLock);
470 (errcode(ERRCODE_OUT_OF_MEMORY),
471 errmsg("not enough shared memory for data structure"
472 " \"%s\" (%zu bytes requested)",
473 name, size)));
474 }
475 result->size = size;
476 result->allocated_size = allocated_size;
477 result->location = structPtr;
478 }
479
480 LWLockRelease(ShmemIndexLock);
481
482 Assert(ShmemAddrIsValid(structPtr));
483
484 Assert(structPtr == (void *) CACHELINEALIGN(structPtr));
485
486 return structPtr;
487}
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:952
@ HASH_REMOVE
Definition: hsearch.h:115
@ HASH_ENTER_NULL
Definition: hsearch.h:116
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1174
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1894
@ LW_EXCLUSIVE
Definition: lwlock.h:112
bool ShmemAddrIsValid(const void *addr)
Definition: shmem.c:275
void * ShmemAlloc(Size size)
Definition: shmem.c:153
void * index
Definition: pg_shmem.h:37
void * location
Definition: shmem.h:59
Size size
Definition: shmem.h:60
Size allocated_size
Definition: shmem.h:61

References ShmemIndexEnt::allocated_size, Assert(), CACHELINEALIGN, ereport, errcode(), errmsg(), ERROR, HASH_ENTER_NULL, HASH_REMOVE, hash_search(), PGShmemHeader::index, IsUnderPostmaster, ShmemIndexEnt::location, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), name, ShmemAddrIsValid(), ShmemAlloc(), ShmemAllocRaw(), ShmemIndex, ShmemSegHdr, and ShmemIndexEnt::size.

Referenced by AioShmemInit(), ApplyLauncherShmemInit(), AsyncShmemInit(), AutoVacuumShmemInit(), BackendStatusShmemInit(), BackgroundWorkerShmemInit(), BTreeShmemInit(), BufferManagerShmemInit(), CheckpointerShmemInit(), CommitTsShmemInit(), dsm_shmem_init(), DSMRegistryShmemInit(), InitProcGlobal(), injection_shmem_startup(), InjectionPointShmemInit(), LockManagerShmemInit(), MultiXactShmemInit(), pgaio_worker_shmem_init(), PgArchShmemInit(), pgss_shmem_startup(), PMSignalShmemInit(), PredicateLockShmemInit(), ProcArrayShmemInit(), ProcSignalShmemInit(), ReplicationOriginShmemInit(), ReplicationSlotsShmemInit(), SerialInit(), SharedInvalShmemInit(), ShmemInitHash(), SimpleLruInit(), SlotSyncShmemInit(), StatsShmemInit(), StrategyInitialize(), SyncScanShmemInit(), test_aio_shmem_startup(), TwoPhaseShmemInit(), VarsupShmemInit(), WaitEventCustomShmemInit(), WaitLSNShmemInit(), WalRcvShmemInit(), WalSndShmemInit(), WalSummarizerShmemInit(), XLogPrefetchShmemInit(), XLogRecoveryShmemInit(), and XLOGShmemInit().

Variable Documentation

◆ ShmemLock

PGDLLIMPORT slock_t* ShmemLock
extern

Definition at line 89 of file shmem.c.

Referenced by GetLWTrancheName(), InitShmemAllocation(), LWLockNewTrancheId(), and ShmemAllocRaw().