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

Go to the source code of this file.

Typedefs

typedef struct PGShmemHeader PGShmemHeader
 

Enumerations

enum  ShmemRequestKind { SHMEM_KIND_STRUCT = 0 , SHMEM_KIND_HASH , SHMEM_KIND_SLRU }
 

Functions

void ShmemCallRequestCallbacks (void)
 
void InitShmemAllocator (PGShmemHeader *seghdr)
 
void ResetShmemAllocator (void)
 
void ShmemRequestInternal (ShmemStructOpts *options, ShmemRequestKind kind)
 
size_t ShmemGetRequestedSize (void)
 
void ShmemInitRequested (void)
 
PGDLLIMPORT Size pg_get_shmem_pagesize (void)
 
HTABshmem_hash_create (void *location, size_t size, bool found, const char *name, int64 nelems, HASHCTL *infoP, int hash_flags)
 
void shmem_hash_init (void *location, ShmemStructOpts *base_options)
 
void shmem_hash_attach (void *location, ShmemStructOpts *base_options)
 

Typedef Documentation

◆ PGShmemHeader

Definition at line 28 of file shmem_internal.h.

Enumeration Type Documentation

◆ ShmemRequestKind

Enumerator
SHMEM_KIND_STRUCT 
SHMEM_KIND_HASH 
SHMEM_KIND_SLRU 

Definition at line 20 of file shmem_internal.h.

21{
22 SHMEM_KIND_STRUCT = 0, /* plain, contiguous area of memory */
23 SHMEM_KIND_HASH, /* a hash table */
24 SHMEM_KIND_SLRU, /* SLRU buffers and control structures */
ShmemRequestKind
@ SHMEM_KIND_SLRU
@ SHMEM_KIND_HASH
@ SHMEM_KIND_STRUCT

Function Documentation

◆ InitShmemAllocator()

void InitShmemAllocator ( PGShmemHeader seghdr)
extern

Definition at line 638 of file shmem.c.

639{
640 Size offset;
642 HASHCTL info;
643 int hash_flags;
644
645#ifndef EXEC_BACKEND
647#endif
648 Assert(seghdr != NULL);
649
651 {
653 }
654 else
655 {
658 }
659
660 /*
661 * We assume the pointer and offset are MAXALIGN. Not a hard requirement,
662 * but it's true today and keeps the math below simpler.
663 */
664 Assert(seghdr == (void *) MAXALIGN(seghdr));
665 Assert(seghdr->content_offset == MAXALIGN(seghdr->content_offset));
666
667 /*
668 * Allocations after this point should go through ShmemAlloc, which
669 * expects to allocate everything on cache line boundaries. Make sure the
670 * first allocation begins on a cache line boundary.
671 */
672 offset = CACHELINEALIGN(seghdr->content_offset + sizeof(ShmemAllocatorData));
673 if (offset > seghdr->totalsize)
676 errmsg("out of shared memory (%zu bytes requested)",
677 offset)));
678
679 /*
680 * In postmaster or stand-alone backend, initialize the shared memory
681 * allocator so that we can allocate shared memory for ShmemIndex using
682 * ShmemAlloc(). In a regular backend just set up the pointers required
683 * by ShmemAlloc().
684 */
685 ShmemAllocator = (ShmemAllocatorData *) ((char *) seghdr + seghdr->content_offset);
687 {
689 ShmemAllocator->free_offset = offset;
691 }
692
695 ShmemEnd = (char *) ShmemBase + seghdr->totalsize;
696
697 /*
698 * Create (or attach to) the shared memory index of shmem areas.
699 *
700 * This is the same initialization as ShmemInitHash() does, but we cannot
701 * use ShmemInitHash() here because it relies on ShmemIndex being already
702 * initialized.
703 */
705
707 info.entrysize = sizeof(ShmemIndexEnt);
708 hash_flags = HASH_ELEM | HASH_STRINGS | HASH_FIXED_SIZE;
709
711 {
714 }
718 "ShmemIndex", hash_nelems,
719 &info, hash_flags);
721
722 /*
723 * Add an entry for ShmemIndex itself into ShmemIndex, so that it's
724 * visible in the pg_shmem_allocations view
725 */
727 {
728 bool found;
730 hash_search(ShmemIndex, "ShmemIndex", HASH_ENTER, &found);
731
732 Assert(!found);
734 result->allocated_size = ShmemAllocator->index_size;
735 result->location = ShmemAllocator->index;
736 }
737}
#define CACHELINEALIGN(LEN)
Definition c.h:899
#define MAXALIGN(LEN)
Definition c.h:896
#define Assert(condition)
Definition c.h:943
int64_t int64
Definition c.h:621
size_t Size
Definition c.h:689
uint32 result
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition dynahash.c:889
Size hash_estimate_size(int64 num_entries, Size entrysize)
Definition dynahash.c:763
int errcode(int sqlerrcode)
Definition elog.c:875
#define ERROR
Definition elog.h:40
#define ereport(elevel,...)
Definition elog.h:152
bool IsUnderPostmaster
Definition globals.c:122
#define HASH_STRINGS
Definition hsearch.h:91
@ HASH_ENTER
Definition hsearch.h:109
#define HASH_ELEM
Definition hsearch.h:90
#define HASH_FIXED_SIZE
Definition hsearch.h:100
void LWLockInitialize(LWLock *lock, int tranche_id)
Definition lwlock.c:670
static char * errmsg
static int list_length(const List *l)
Definition pg_list.h:152
static int fb(int x)
static void * ShmemBase
Definition shmem.c:244
static void * ShmemEnd
Definition shmem.c:245
void * ShmemAlloc(Size size)
Definition shmem.c:764
static PGShmemHeader * ShmemSegHdr
Definition shmem.c:243
shmem_request_state
Definition shmem.c:186
@ SRS_INITIALIZING
Definition shmem.c:201
@ SRS_INITIAL
Definition shmem.c:188
@ SRS_REQUESTING
Definition shmem.c:195
static HTAB * ShmemIndex
Definition shmem.c:253
static List * pending_shmem_requests
Definition shmem.c:170
#define SHMEM_INDEX_ADDITIONAL_SIZE
Definition shmem.c:263
static ShmemAllocatorData * ShmemAllocator
Definition shmem.c:247
#define SHMEM_INDEX_KEYSIZE
Definition shmem.c:256
HTAB * shmem_hash_create(void *location, size_t size, bool found, const char *name, int64 nelems, HASHCTL *infoP, int hash_flags)
Definition shmem_hash.c:149
static void SpinLockInit(volatile slock_t *lock)
Definition spin.h:50
Size keysize
Definition hsearch.h:69
Size entrysize
Definition hsearch.h:70
Size totalsize
Definition pg_shmem.h:34
HASHHDR * index
Definition shmem.c:232
LWLock index_lock
Definition shmem.c:234
slock_t shmem_lock
Definition shmem.c:230
size_t index_size
Definition shmem.c:233

References Assert, CACHELINEALIGN, HASHCTL::entrysize, ereport, errcode(), errmsg, ERROR, fb(), ShmemAllocatorData::free_offset, HASH_ELEM, HASH_ENTER, hash_estimate_size(), HASH_FIXED_SIZE, hash_search(), HASH_STRINGS, ShmemAllocatorData::index, ShmemAllocatorData::index_lock, ShmemAllocatorData::index_size, IsUnderPostmaster, HASHCTL::keysize, list_length(), LWLockInitialize(), MAXALIGN, pending_shmem_requests, result, shmem_hash_create(), SHMEM_INDEX_ADDITIONAL_SIZE, SHMEM_INDEX_KEYSIZE, ShmemAllocatorData::shmem_lock, ShmemAlloc(), ShmemAllocator, ShmemBase, ShmemEnd, ShmemIndex, ShmemSegHdr, SpinLockInit(), SRS_INITIAL, SRS_INITIALIZING, SRS_REQUESTING, and PGShmemHeader::totalsize.

Referenced by CreateSharedMemoryAndSemaphores().

◆ pg_get_shmem_pagesize()

PGDLLIMPORT Size pg_get_shmem_pagesize ( void  )
extern

Definition at line 1304 of file shmem.c.

1305{
1307#ifdef WIN32
1309
1311 os_page_size = sysinfo.dwPageSize;
1312#else
1314#endif
1315
1318
1321
1322 return os_page_size;
1323}
int huge_pages_status
Definition guc_tables.c:610
@ 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:480

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

Referenced by pg_buffercache_os_pages_internal(), and pg_get_shmem_allocations_numa().

◆ ResetShmemAllocator()

void ResetShmemAllocator ( void  )
extern

Definition at line 743 of file shmem.c.

744{
747
749
750 /*
751 * Note that we don't clear the registered callbacks. We will need to
752 * call them again as we restart
753 */
754}
#define NIL
Definition pg_list.h:68

References Assert, IsUnderPostmaster, NIL, pending_shmem_requests, and SRS_INITIAL.

Referenced by PostmasterStateMachine().

◆ shmem_hash_attach()

void shmem_hash_attach ( void location,
ShmemStructOpts base_options 
)
extern

Definition at line 79 of file shmem_hash.c.

80{
82 int hash_flags = options->hash_flags;
83 HTAB *htab;
84
85 /* attach to it rather than allocate and initialize new space */
86 hash_flags |= HASH_ATTACH;
87 options->hash_info.hctl = location;
88 Assert(options->hash_info.hctl != NULL);
89 htab = shmem_hash_create(location, options->base.size, true,
90 options->name,
91 options->nelems, &options->hash_info, hash_flags);
92
93 if (options->ptr)
94 *options->ptr = htab;
95}
#define HASH_ATTACH
Definition hsearch.h:99

References Assert, fb(), HASH_ATTACH, and shmem_hash_create().

Referenced by AttachShmemIndexEntry().

◆ shmem_hash_create()

HTAB * shmem_hash_create ( void location,
size_t  size,
bool  found,
const char name,
int64  nelems,
HASHCTL infoP,
int  hash_flags 
)
extern

Definition at line 149 of file shmem_hash.c.

151{
153
154 /*
155 * Hash tables allocated in shared memory have a fixed directory and have
156 * all elements allocated upfront. We don't support growing because we'd
157 * need to grow the underlying shmem region with it.
158 *
159 * The shared memory allocator must be specified too.
160 */
161 infoP->alloc = ShmemHashAlloc;
162 infoP->alloc_arg = NULL;
164
165 /*
166 * if it already exists, attach to it rather than allocate and initialize
167 * new space
168 */
169 if (!found)
170 {
171 allocator.next = (char *) location;
172 allocator.end = (char *) location + size;
173 infoP->alloc_arg = &allocator;
174 }
175 else
176 {
177 /* Pass location of hashtable header to hash_create */
178 infoP->hctl = (HASHHDR *) location;
179 hash_flags |= HASH_ATTACH;
180 }
181
182 return hash_create(name, nelems, infoP, hash_flags);
183}
HTAB * hash_create(const char *tabname, int64 nelem, const HASHCTL *info, int flags)
Definition dynahash.c:360
#define HASH_ALLOC
Definition hsearch.h:96
#define HASH_SHARED_MEM
Definition hsearch.h:98
static void * ShmemHashAlloc(Size size, void *alloc_arg)
Definition shmem_hash.c:193
const char * name

References fb(), HASH_ALLOC, HASH_ATTACH, hash_create(), HASH_FIXED_SIZE, HASH_SHARED_MEM, name, shmem_hash_allocator::next, and ShmemHashAlloc().

Referenced by InitShmemAllocator(), shmem_hash_attach(), shmem_hash_init(), and ShmemInitHash().

◆ shmem_hash_init()

void shmem_hash_init ( void location,
ShmemStructOpts base_options 
)
extern

Definition at line 63 of file shmem_hash.c.

64{
66 int hash_flags = options->hash_flags;
67 HTAB *htab;
68
69 options->hash_info.hctl = location;
70 htab = shmem_hash_create(location, options->base.size, false,
71 options->name,
72 options->nelems, &options->hash_info, hash_flags);
73
74 if (options->ptr)
75 *options->ptr = htab;
76}

References fb(), and shmem_hash_create().

Referenced by InitShmemIndexEntry().

◆ ShmemCallRequestCallbacks()

void ShmemCallRequestCallbacks ( void  )
extern

Definition at line 979 of file shmem.c.

980{
981 ListCell *lc;
982
985
987 {
988 const ShmemCallbacks *callbacks = (const ShmemCallbacks *) lfirst(lc);
989
990 if (callbacks->request_fn)
991 callbacks->request_fn(callbacks->opaque_arg);
992 }
993}
#define lfirst(lc)
Definition pg_list.h:172
static List * registered_shmem_callbacks
Definition shmem.c:158
ShmemRequestCallback request_fn
Definition shmem.h:133
void * opaque_arg
Definition shmem.h:153

References Assert, fb(), lfirst, ShmemCallbacks::opaque_arg, registered_shmem_callbacks, ShmemCallbacks::request_fn, SRS_INITIAL, and SRS_REQUESTING.

Referenced by BootstrapModeMain(), PostgresSingleUserMain(), PostmasterMain(), and PostmasterStateMachine().

◆ ShmemGetRequestedSize()

size_t ShmemGetRequestedSize ( void  )
extern

Definition at line 392 of file shmem.c.

393{
394 size_t size;
395
396 /* memory needed for the ShmemIndex */
398 sizeof(ShmemIndexEnt));
399 size = CACHELINEALIGN(size);
400
401 /* memory needed for all the requested areas */
403 {
404 size_t alignment = request->options->alignment;
405
406 /* pad the start address for alignment like ShmemAllocRaw() does */
407 if (alignment < PG_CACHE_LINE_SIZE)
408 alignment = PG_CACHE_LINE_SIZE;
409 size = TYPEALIGN(alignment, size);
410
411 size = add_size(size, request->options->size);
412 }
413
414 return size;
415}
#define TYPEALIGN(ALIGNVAL, LEN)
Definition c.h:889
#define PG_CACHE_LINE_SIZE
#define foreach_ptr(type, var, lst)
Definition pg_list.h:501
Size add_size(Size s1, Size s2)
Definition shmem.c:1048

References add_size(), CACHELINEALIGN, fb(), foreach_ptr, hash_estimate_size(), list_length(), pending_shmem_requests, PG_CACHE_LINE_SIZE, SHMEM_INDEX_ADDITIONAL_SIZE, and TYPEALIGN.

Referenced by CalculateShmemSize().

◆ ShmemInitRequested()

void ShmemInitRequested ( void  )
extern

Definition at line 425 of file shmem.c.

426{
427 /* should be called only by the postmaster or a standalone backend */
430
431 /*
432 * Initialize the ShmemIndex entries and perform basic initialization of
433 * all the requested memory areas. There are no concurrent processes yet,
434 * so no need for locking.
435 */
437 {
439 pfree(request->options);
440 }
443
444 /*
445 * Call the subsystem-specific init callbacks to finish initialization of
446 * all the areas.
447 */
449 {
450 if (callbacks->init_fn)
451 callbacks->init_fn(callbacks->opaque_arg);
452 }
453
455}
void list_free_deep(List *list)
Definition list.c:1560
void pfree(void *pointer)
Definition mcxt.c:1616
static void InitShmemIndexEntry(ShmemRequest *request)
Definition shmem.c:512
@ SRS_DONE
Definition shmem.c:213

References Assert, fb(), foreach_ptr, InitShmemIndexEntry(), IsUnderPostmaster, list_free_deep(), NIL, pending_shmem_requests, pfree(), registered_shmem_callbacks, SRS_DONE, and SRS_INITIALIZING.

Referenced by CreateSharedMemoryAndSemaphores().

◆ ShmemRequestInternal()

void ShmemRequestInternal ( ShmemStructOpts options,
ShmemRequestKind  kind 
)
extern

Definition at line 337 of file shmem.c.

338{
340
341 /* Check the options */
342 if (options->name == NULL)
343 elog(ERROR, "shared memory request is missing 'name' option");
344
346 {
347 if (options->size <= 0 && options->size != SHMEM_ATTACH_UNKNOWN_SIZE)
348 elog(ERROR, "invalid size %zd for shared memory request for \"%s\"",
349 options->size, options->name);
350 }
351 else
352 {
354 elog(ERROR, "SHMEM_ATTACH_UNKNOWN_SIZE cannot be used during startup");
355 if (options->size <= 0)
356 elog(ERROR, "invalid size %zd for shared memory request for \"%s\"",
357 options->size, options->name);
358 }
359
360 if (options->alignment != 0 && pg_nextpower2_size_t(options->alignment) != options->alignment)
361 elog(ERROR, "invalid alignment %zu for shared memory request for \"%s\"",
362 options->alignment, options->name);
363
364 /* Check that we're in the right state */
366 elog(ERROR, "ShmemRequestStruct can only be called from a shmem_request callback");
367
368 /* Check that it's not already registered in this process */
370 {
371 if (strcmp(existing->options->name, options->name) == 0)
373 (errmsg("shared memory struct \"%s\" is already registered",
374 options->name)));
375 }
376
377 /* Request looks valid, remember it */
378 request = palloc(sizeof(ShmemRequest));
379 request->options = options;
380 request->kind = kind;
382}
#define elog(elevel,...)
Definition elog.h:228
List * lappend(List *list, void *datum)
Definition list.c:339
void * palloc(Size size)
Definition mcxt.c:1387
#define pg_nextpower2_size_t
#define SHMEM_ATTACH_UNKNOWN_SIZE
Definition shmem.h:69

References elog, ereport, errmsg, ERROR, fb(), foreach_ptr, IsUnderPostmaster, lappend(), palloc(), pending_shmem_requests, pg_nextpower2_size_t, SHMEM_ATTACH_UNKNOWN_SIZE, and SRS_REQUESTING.

Referenced by ShmemRequestHashWithOpts(), ShmemRequestStructWithOpts(), and SimpleLruRequestWithOpts().