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

638{
639 Size offset;
641 HASHCTL info;
642 int hash_flags;
643
644#ifndef EXEC_BACKEND
646#endif
647 Assert(seghdr != NULL);
648
650 {
652 }
653 else
654 {
657 }
658
659 /*
660 * We assume the pointer and offset are MAXALIGN. Not a hard requirement,
661 * but it's true today and keeps the math below simpler.
662 */
663 Assert(seghdr == (void *) MAXALIGN(seghdr));
664 Assert(seghdr->content_offset == MAXALIGN(seghdr->content_offset));
665
666 /*
667 * Allocations after this point should go through ShmemAlloc, which
668 * expects to allocate everything on cache line boundaries. Make sure the
669 * first allocation begins on a cache line boundary.
670 */
671 offset = CACHELINEALIGN(seghdr->content_offset + sizeof(ShmemAllocatorData));
672 if (offset > seghdr->totalsize)
675 errmsg("out of shared memory (%zu bytes requested)",
676 offset)));
677
678 /*
679 * In postmaster or stand-alone backend, initialize the shared memory
680 * allocator so that we can allocate shared memory for ShmemIndex using
681 * ShmemAlloc(). In a regular backend just set up the pointers required
682 * by ShmemAlloc().
683 */
684 ShmemAllocator = (ShmemAllocatorData *) ((char *) seghdr + seghdr->content_offset);
686 {
688 ShmemAllocator->free_offset = offset;
690 }
691
694 ShmemEnd = (char *) ShmemBase + seghdr->totalsize;
695
696 /*
697 * Create (or attach to) the shared memory index of shmem areas.
698 *
699 * This is the same initialization as ShmemInitHash() does, but we cannot
700 * use ShmemInitHash() here because it relies on ShmemIndex being already
701 * initialized.
702 */
704
706 info.entrysize = sizeof(ShmemIndexEnt);
707 hash_flags = HASH_ELEM | HASH_STRINGS | HASH_FIXED_SIZE;
708
710 {
713 }
717 "ShmemIndex", hash_nelems,
718 &info, hash_flags);
720
721 /*
722 * Add an entry for ShmemIndex itself into ShmemIndex, so that it's
723 * visible in the pg_shmem_allocations view
724 */
726 {
727 bool found;
729 hash_search(ShmemIndex, "ShmemIndex", HASH_ENTER, &found);
730
731 Assert(!found);
733 result->allocated_size = ShmemAllocator->index_size;
734 result->location = ShmemAllocator->index;
735 }
736}
#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:243
static void * ShmemEnd
Definition shmem.c:244
void * ShmemAlloc(Size size)
Definition shmem.c:763
static PGShmemHeader * ShmemSegHdr
Definition shmem.c:242
shmem_request_state
Definition shmem.c:185
@ SRS_INITIALIZING
Definition shmem.c:200
@ SRS_INITIAL
Definition shmem.c:187
@ SRS_REQUESTING
Definition shmem.c:194
static HTAB * ShmemIndex
Definition shmem.c:252
static List * pending_shmem_requests
Definition shmem.c:169
#define SHMEM_INDEX_ADDITIONAL_SIZE
Definition shmem.c:262
static ShmemAllocatorData * ShmemAllocator
Definition shmem.c:246
#define SHMEM_INDEX_KEYSIZE
Definition shmem.c:255
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:231
LWLock index_lock
Definition shmem.c:233
slock_t shmem_lock
Definition shmem.c:229
size_t index_size
Definition shmem.c:232

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

1274{
1276#ifdef WIN32
1278
1280 os_page_size = sysinfo.dwPageSize;
1281#else
1283#endif
1284
1287
1290
1291 return os_page_size;
1292}
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 742 of file shmem.c.

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

979{
980 ListCell *lc;
981
984
986 {
987 const ShmemCallbacks *callbacks = (const ShmemCallbacks *) lfirst(lc);
988
989 if (callbacks->request_fn)
990 callbacks->request_fn(callbacks->opaque_arg);
991 }
992}
#define lfirst(lc)
Definition pg_list.h:172
static List * registered_shmem_callbacks
Definition shmem.c:157
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
Size add_size(Size s1, Size s2)
Definition mcxt.c:1733
#define PG_CACHE_LINE_SIZE
#define foreach_ptr(type, var, lst)
Definition pg_list.h:501

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 pfree(request->options);
439 }
442
443 /*
444 * Call the subsystem-specific init callbacks to finish initialization of
445 * all the areas.
446 */
448 {
449 if (callbacks->init_fn)
450 callbacks->init_fn(callbacks->opaque_arg);
451 }
452
454}
void list_free_deep(List *list)
Definition list.c:1560
void pfree(void *pointer)
Definition mcxt.c:1619
static void InitShmemIndexEntry(ShmemRequest *request)
Definition shmem.c:511
@ SRS_DONE
Definition shmem.c:212

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 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:228
List * lappend(List *list, void *datum)
Definition list.c:339
void * palloc(Size size)
Definition mcxt.c:1390
#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().