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 635 of file shmem.c.

636{
637 Size offset;
639 HASHCTL info;
640 int hash_flags;
641
642#ifndef EXEC_BACKEND
644#endif
645 Assert(seghdr != NULL);
646
648 {
650 }
651 else
652 {
655 }
656
657 /*
658 * We assume the pointer and offset are MAXALIGN. Not a hard requirement,
659 * but it's true today and keeps the math below simpler.
660 */
661 Assert(seghdr == (void *) MAXALIGN(seghdr));
662 Assert(seghdr->content_offset == MAXALIGN(seghdr->content_offset));
663
664 /*
665 * Allocations after this point should go through ShmemAlloc, which
666 * expects to allocate everything on cache line boundaries. Make sure the
667 * first allocation begins on a cache line boundary.
668 */
669 offset = CACHELINEALIGN(seghdr->content_offset + sizeof(ShmemAllocatorData));
670 if (offset > seghdr->totalsize)
673 errmsg("out of shared memory (%zu bytes requested)",
674 offset)));
675
676 /*
677 * In postmaster or stand-alone backend, initialize the shared memory
678 * allocator so that we can allocate shared memory for ShmemIndex using
679 * ShmemAlloc(). In a regular backend just set up the pointers required
680 * by ShmemAlloc().
681 */
682 ShmemAllocator = (ShmemAllocatorData *) ((char *) seghdr + seghdr->content_offset);
684 {
686 ShmemAllocator->free_offset = offset;
688 }
689
692 ShmemEnd = (char *) ShmemBase + seghdr->totalsize;
693
694 /*
695 * Create (or attach to) the shared memory index of shmem areas.
696 *
697 * This is the same initialization as ShmemInitHash() does, but we cannot
698 * use ShmemInitHash() here because it relies on ShmemIndex being already
699 * initialized.
700 */
702
704 info.entrysize = sizeof(ShmemIndexEnt);
705 hash_flags = HASH_ELEM | HASH_STRINGS | HASH_FIXED_SIZE;
706
708 {
711 }
715 "ShmemIndex", hash_nelems,
716 &info, hash_flags);
718
719 /*
720 * Add an entry for ShmemIndex itself into ShmemIndex, so that it's
721 * visible in the pg_shmem_allocations view
722 */
724 {
725 bool found;
727 hash_search(ShmemIndex, "ShmemIndex", HASH_ENTER, &found);
728
729 Assert(!found);
731 result->allocated_size = ShmemAllocator->index_size;
732 result->location = ShmemAllocator->index;
733 }
734}
#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:874
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:151
bool IsUnderPostmaster
Definition globals.c:120
#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:761
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 1299 of file shmem.c.

1300{
1302#ifdef WIN32
1304
1306 os_page_size = sysinfo.dwPageSize;
1307#else
1309#endif
1310
1313
1316
1317 return os_page_size;
1318}
int huge_pages_status
Definition guc_tables.c:600
@ 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 740 of file shmem.c.

741{
744
746
747 /*
748 * Note that we don't clear the registered callbacks. We will need to
749 * call them again as we restart
750 */
751}
#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 974 of file shmem.c.

975{
976 ListCell *lc;
977
980
982 {
983 const ShmemCallbacks *callbacks = (const ShmemCallbacks *) lfirst(lc);
984
985 if (callbacks->request_fn)
986 callbacks->request_fn(callbacks->opaque_arg);
987 }
988}
#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 391 of file shmem.c.

392{
393 size_t size;
394
395 /* memory needed for the ShmemIndex */
397 sizeof(ShmemIndexEnt));
398 size = CACHELINEALIGN(size);
399
400 /* memory needed for all the requested areas */
402 {
403 size_t alignment = request->options->alignment;
404
405 /* pad the start address for alignment like ShmemAllocRaw() does */
406 if (alignment < PG_CACHE_LINE_SIZE)
407 alignment = PG_CACHE_LINE_SIZE;
408 size = TYPEALIGN(alignment, size);
409
410 size = add_size(size, request->options->size);
411 }
412
413 return size;
414}
#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:1043

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 424 of file shmem.c.

425{
426 /* should be called only by the postmaster or a standalone backend */
429
430 /*
431 * Initialize the ShmemIndex entries and perform basic initialization of
432 * all the requested memory areas. There are no concurrent processes yet,
433 * so no need for locking.
434 */
436 {
438 }
441
442 /*
443 * Call the subsystem-specific init callbacks to finish initialization of
444 * all the areas.
445 */
447 {
448 if (callbacks->init_fn)
449 callbacks->init_fn(callbacks->opaque_arg);
450 }
451
453}
void list_free_deep(List *list)
Definition list.c:1560
static void InitShmemIndexEntry(ShmemRequest *request)
Definition shmem.c:509
@ SRS_DONE
Definition shmem.c:213

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

Referenced by CreateSharedMemoryAndSemaphores().

◆ ShmemRequestInternal()

void ShmemRequestInternal ( ShmemStructOpts options,
ShmemRequestKind  kind 
)
extern

Definition at line 336 of file shmem.c.

337{
339
340 /* Check the options */
341 if (options->name == NULL)
342 elog(ERROR, "shared memory request is missing 'name' option");
343
345 {
346 if (options->size <= 0 && options->size != SHMEM_ATTACH_UNKNOWN_SIZE)
347 elog(ERROR, "invalid size %zd for shared memory request for \"%s\"",
348 options->size, options->name);
349 }
350 else
351 {
353 elog(ERROR, "SHMEM_ATTACH_UNKNOWN_SIZE cannot be used during startup");
354 if (options->size <= 0)
355 elog(ERROR, "invalid size %zd for shared memory request for \"%s\"",
356 options->size, options->name);
357 }
358
359 if (options->alignment != 0 && pg_nextpower2_size_t(options->alignment) != options->alignment)
360 elog(ERROR, "invalid alignment %zu for shared memory request for \"%s\"",
361 options->alignment, options->name);
362
363 /* Check that we're in the right state */
365 elog(ERROR, "ShmemRequestStruct can only be called from a shmem_request callback");
366
367 /* Check that it's not already registered in this process */
369 {
370 if (strcmp(existing->options->name, options->name) == 0)
372 (errmsg("shared memory struct \"%s\" is already registered",
373 options->name)));
374 }
375
376 /* Request looks valid, remember it */
377 request = palloc(sizeof(ShmemRequest));
378 request->options = options;
379 request->kind = kind;
381}
#define elog(elevel,...)
Definition elog.h:227
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().