49 #define PG_DYNSHMEM_CONTROL_MAGIC 0x9a503d32
51 #define PG_DYNSHMEM_FIXED_SLOTS 64
52 #define PG_DYNSHMEM_SLOTS_PER_BACKEND 5
54 #define INVALID_CONTROL_SLOT ((uint32) -1)
152 void *dsm_control_address = NULL;
170 elog(
DEBUG2,
"dynamic shared memory system will support %u segments",
181 Assert(dsm_control_address == NULL);
195 "created dynamic shared memory control segment %u (%zu bytes)",
213 void *mapped_address = NULL;
214 void *junk_mapped_address = NULL;
215 void *impl_private = NULL;
216 void *junk_impl_private = NULL;
217 Size mapped_size = 0;
218 Size junk_mapped_size = 0;
230 &mapped_address, &mapped_size,
DEBUG1))
241 &mapped_address, &mapped_size,
LOG);
266 elog(
DEBUG2,
"cleaning up orphaned dynamic shared memory with ID %u (reference count %u)",
271 &junk_mapped_address, &junk_mapped_size,
LOG);
276 "cleaning up dynamic shared memory control segment with ID %u",
279 &mapped_address, &mapped_size,
LOG);
313 if (unlink(
buf) != 0)
316 errmsg(
"could not remove file \"%s\": %m",
buf)));
335 void *dsm_control_address;
336 void *junk_mapped_address = NULL;
337 void *junk_impl_private = NULL;
338 Size junk_mapped_size = 0;
352 (
errmsg(
"dynamic shared memory control segment is corrupt")));
370 elog(
DEBUG2,
"cleaning up orphaned dynamic shared memory with ID %u",
375 &junk_mapped_address, &junk_mapped_size,
LOG);
380 "cleaning up dynamic shared memory control segment with ID %u",
401 void *control_address = NULL;
416 (
errcode(ERRCODE_INTERNAL_ERROR),
417 errmsg(
"dynamic shared memory control segment is not valid")));
464 size_t first_page = 0;
495 size_t first_page = 0;
497 bool using_main_dsm_region =
false;
516 if (dsm_main_space_fpm)
529 using_main_dsm_region =
true;
534 if (!using_main_dsm_region)
540 if (dsm_main_space_fpm)
562 if (using_main_dsm_region)
584 if (using_main_dsm_region)
587 if (!using_main_dsm_region)
598 (
errcode(ERRCODE_INSUFFICIENT_RESOURCES),
599 errmsg(
"too many dynamic shared memory segments")));
603 if (using_main_dsm_region)
665 elog(
ERROR,
"can't attach the same segment more than once");
760 if (control_address != NULL)
940 elog(
ERROR,
"cannot pin a segment that is already pinned");
963 bool destroy =
false;
988 elog(
ERROR,
"cannot unpin unknown segment handle");
990 elog(
ERROR,
"cannot unpin a segment that is not pinned");
1012 void *junk_impl_private = NULL;
1013 void *junk_mapped_address = NULL;
1014 Size junk_mapped_size = 0;
1028 &junk_mapped_address, &junk_mapped_size,
WARNING))
1055 if (seg->
handle == handle)
1246 handle |= slot << 1;
#define FLEXIBLE_ARRAY_MEMBER
elog(ERROR, "%s: %s", p2, msg)
dsm_handle dsm_segment_handle(dsm_segment *seg)
size_t dsm_estimate_size(void)
static void dsm_backend_startup(void)
void * dsm_segment_address(dsm_segment *seg)
static void * dsm_main_space_begin
void dsm_detach(dsm_segment *seg)
void on_dsm_detach(dsm_segment *seg, on_dsm_detach_callback function, Datum arg)
dsm_segment * dsm_attach(dsm_handle h)
dsm_segment * dsm_create(Size size, int flags)
static dsm_handle dsm_control_handle
void dsm_pin_mapping(dsm_segment *seg)
static dlist_head dsm_segment_list
static void dsm_postmaster_shutdown(int code, Datum arg)
void dsm_unpin_segment(dsm_handle handle)
void dsm_pin_segment(dsm_segment *seg)
void dsm_detach_all(void)
static dsm_handle make_main_region_dsm_handle(int slot)
static bool dsm_init_done
void dsm_cleanup_using_control_segment(dsm_handle old_control_handle)
void dsm_postmaster_startup(PGShmemHeader *shim)
#define PG_DYNSHMEM_CONTROL_MAGIC
static dsm_control_header * dsm_control
static Size dsm_control_mapped_size
static dsm_segment * dsm_create_descriptor(void)
static uint64 dsm_control_bytes_needed(uint32 nitems)
void dsm_shmem_init(void)
#define PG_DYNSHMEM_SLOTS_PER_BACKEND
struct dsm_control_item dsm_control_item
#define PG_DYNSHMEM_FIXED_SLOTS
void dsm_backend_shutdown(void)
struct dsm_segment_detach_callback dsm_segment_detach_callback
void cancel_on_dsm_detach(dsm_segment *seg, on_dsm_detach_callback function, Datum arg)
void reset_on_dsm_detach(void)
dsm_segment * dsm_find_mapping(dsm_handle handle)
static void dsm_cleanup_for_mmap(void)
Size dsm_segment_map_length(dsm_segment *seg)
void dsm_unpin_mapping(dsm_segment *seg)
struct dsm_control_header dsm_control_header
static bool dsm_control_segment_sane(dsm_control_header *control, Size mapped_size)
#define INVALID_CONTROL_SLOT
static void * dsm_control_impl_private
static bool is_main_region_dsm_handle(dsm_handle handle)
#define DSM_CREATE_NULL_IF_MAXSEGMENTS
void(* on_dsm_detach_callback)(dsm_segment *, Datum arg)
void dsm_impl_pin_segment(dsm_handle handle, void *impl_private, void **impl_private_pm_handle)
int min_dynamic_shared_memory
void dsm_impl_unpin_segment(dsm_handle handle, void **impl_private)
bool dsm_impl_op(dsm_op op, dsm_handle handle, Size request_size, void **impl_private, void **mapped_address, Size *mapped_size, int elevel)
int dynamic_shared_memory_type
#define PG_DYNSHMEM_MMAP_FILE_PREFIX
#define DSM_HANDLE_INVALID
int errcode_for_file_access(void)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
struct dirent * ReadDir(DIR *dir, const char *dirname)
DIR * AllocateDir(const char *dirname)
bool FreePageManagerGet(FreePageManager *fpm, Size npages, Size *first_page)
void FreePageManagerPut(FreePageManager *fpm, Size first_page, Size npages)
void FreePageManagerInitialize(FreePageManager *fpm, char *base)
bool IsPostmasterEnvironment
static void slist_delete_current(slist_mutable_iter *iter)
#define dlist_foreach(iter, lhead)
#define dlist_head_element(type, membername, lhead)
static void dlist_delete(dlist_node *node)
#define slist_foreach_modify(iter, lhead)
static void slist_init(slist_head *head)
static bool slist_is_empty(const slist_head *head)
static void dlist_push_head(dlist_head *head, dlist_node *node)
static bool dlist_is_empty(const dlist_head *head)
static void slist_push_head(slist_head *head, slist_node *node)
#define slist_container(type, membername, ptr)
#define DLIST_STATIC_INIT(name)
#define dlist_container(type, membername, ptr)
static slist_node * slist_pop_head_node(slist_head *head)
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Assert(fmt[strlen(fmt) - 1] !='\n')
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
void LWLockRelease(LWLock *lock)
void pfree(void *pointer)
MemoryContext TopMemoryContext
void * MemoryContextAlloc(MemoryContext context, Size size)
#define RESUME_INTERRUPTS()
#define HOLD_INTERRUPTS()
static int pg_leftmost_one_pos32(uint32 word)
uint32 pg_prng_uint32(pg_prng_state *state)
pg_prng_state pg_global_prng_state
static Datum PointerGetDatum(const void *X)
static Pointer DatumGetPointer(Datum X)
void ResourceOwnerForgetDSM(ResourceOwner owner, dsm_segment *seg)
ResourceOwner CurrentResourceOwner
void ResourceOwnerRememberDSM(ResourceOwner owner, dsm_segment *seg)
void ResourceOwnerEnlargeDSMs(ResourceOwner owner)
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
void * impl_private_pm_handle
on_dsm_detach_callback function