48 #define PG_DYNSHMEM_CONTROL_MAGIC 0x9a503d32 50 #define PG_DYNSHMEM_FIXED_SLOTS 64 51 #define PG_DYNSHMEM_SLOTS_PER_BACKEND 5 53 #define INVALID_CONTROL_SLOT ((uint32) -1) 151 void *dsm_control_address = NULL;
169 elog(
DEBUG2,
"dynamic shared memory system will support %u segments",
181 Assert(dsm_control_address == NULL);
191 dsm_control = dsm_control_address;
194 "created dynamic shared memory control segment %u (%zu bytes)",
212 void *mapped_address = NULL;
213 void *junk_mapped_address = NULL;
214 void *impl_private = NULL;
215 void *junk_impl_private = NULL;
216 Size mapped_size = 0;
217 Size junk_mapped_size = 0;
229 &mapped_address, &mapped_size,
DEBUG1))
240 &mapped_address, &mapped_size,
LOG);
248 nitems = old_control->
nitems;
249 for (i = 0; i < nitems; ++
i)
265 elog(
DEBUG2,
"cleaning up orphaned dynamic shared memory with ID %u (reference count %u)",
270 &junk_mapped_address, &junk_mapped_size,
LOG);
275 "cleaning up dynamic shared memory control segment with ID %u",
278 &mapped_address, &mapped_size,
LOG);
312 if (unlink(
buf) != 0)
315 errmsg(
"could not remove file \"%s\": %m",
buf)));
334 void *dsm_control_address;
335 void *junk_mapped_address = NULL;
336 void *junk_impl_private = NULL;
337 Size junk_mapped_size = 0;
347 nitems = dsm_control->
nitems;
351 (
errmsg(
"dynamic shared memory control segment is corrupt")));
356 for (i = 0; i < nitems; ++
i)
369 elog(
DEBUG2,
"cleaning up orphaned dynamic shared memory with ID %u",
374 &junk_mapped_address, &junk_mapped_size,
LOG);
379 "cleaning up dynamic shared memory control segment with ID %u",
385 dsm_control = dsm_control_address;
399 void *control_address = NULL;
406 dsm_control = control_address;
414 (
errcode(ERRCODE_INTERNAL_ERROR),
415 errmsg(
"dynamic shared memory control segment is not valid")));
462 size_t first_page = 0;
493 size_t first_page = 0;
495 bool using_main_dsm_region =
false;
510 if (dsm_main_space_fpm)
523 using_main_dsm_region =
true;
528 if (!using_main_dsm_region)
534 if (dsm_main_space_fpm)
550 nitems = dsm_control->
nitems;
551 for (i = 0; i < nitems; ++
i)
555 if (using_main_dsm_region)
575 if (nitems >= dsm_control->
maxitems)
577 if (using_main_dsm_region)
580 if (!using_main_dsm_region)
591 (
errcode(ERRCODE_INSUFFICIENT_RESOURCES),
592 errmsg(
"too many dynamic shared memory segments")));
596 if (using_main_dsm_region)
658 elog(
ERROR,
"can't attach the same segment more than once");
667 nitems = dsm_control->
nitems;
668 for (i = 0; i < nitems; ++
i)
753 if (control_address != NULL)
819 refcnt = --dsm_control->
item[control_slot].
refcnt;
928 elog(
ERROR,
"cannot pin a segment that is already pinned");
951 bool destroy =
false;
956 for (i = 0; i < dsm_control->
nitems; ++
i)
976 elog(
ERROR,
"cannot unpin unknown segment handle");
978 elog(
ERROR,
"cannot unpin a segment that is not pinned");
990 if (--dsm_control->
item[control_slot].
refcnt == 1)
992 dsm_control->
item[control_slot].
pinned =
false;
1000 void *junk_impl_private = NULL;
1001 void *junk_mapped_address = NULL;
1002 Size junk_mapped_size = 0;
1016 &junk_mapped_address, &junk_mapped_size,
WARNING))
1234 handle |= slot << 1;
static void * dsm_control_impl_private
void dsm_postmaster_startup(PGShmemHeader *shim)
void ResourceOwnerRememberDSM(ResourceOwner owner, dsm_segment *seg)
dsm_segment * dsm_find_mapping(dsm_handle h)
void dsm_impl_unpin_segment(dsm_handle handle, void **impl_private)
void reset_on_dsm_detach(void)
void dsm_shmem_init(void)
static void * dsm_main_space_begin
#define PG_DYNSHMEM_SLOTS_PER_BACKEND
#define PG_DYNSHMEM_FIXED_SLOTS
static void dlist_push_head(dlist_head *head, dlist_node *node)
void dsm_cleanup_using_control_segment(dsm_handle old_control_handle)
#define PointerGetDatum(X)
#define dlist_foreach(iter, lhead)
ResourceOwner CurrentResourceOwner
struct dsm_control_header dsm_control_header
dsm_segment * dsm_attach(dsm_handle h)
static dsm_handle dsm_control_handle
static void slist_push_head(slist_head *head, slist_node *node)
#define FLEXIBLE_ARRAY_MEMBER
dsm_handle dsm_segment_handle(dsm_segment *seg)
int errcode(int sqlerrcode)
static int pg_leftmost_one_pos32(uint32 word)
static void dsm_backend_startup(void)
static dlist_head dsm_segment_list
static dsm_handle make_main_region_dsm_handle(int slot)
void on_dsm_detach(dsm_segment *seg, on_dsm_detach_callback function, Datum arg)
static uint64 dsm_control_bytes_needed(uint32 nitems)
void FreePageManagerPut(FreePageManager *fpm, Size first_page, Size npages)
#define slist_foreach_modify(iter, lhead)
void LWLockRelease(LWLock *lock)
void dsm_pin_segment(dsm_segment *seg)
#define DSM_HANDLE_INVALID
bool FreePageManagerGet(FreePageManager *fpm, Size npages, Size *first_page)
#define dlist_container(type, membername, ptr)
void pfree(void *pointer)
static void slist_init(slist_head *head)
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
on_dsm_detach_callback function
void dsm_pin_mapping(dsm_segment *seg)
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
size_t dsm_estimate_size(void)
#define DSM_CREATE_NULL_IF_MAXSEGMENTS
void ResourceOwnerEnlargeDSMs(ResourceOwner owner)
static bool is_main_region_dsm_handle(dsm_handle handle)
int errcode_for_file_access(void)
static void dsm_postmaster_shutdown(int code, Datum arg)
int dynamic_shared_memory_type
DIR * AllocateDir(const char *dirname)
void dsm_unpin_segment(dsm_handle handle)
static void dlist_delete(dlist_node *node)
static bool dsm_control_segment_sane(dsm_control_header *control, Size mapped_size)
MemoryContext TopMemoryContext
void dsm_backend_shutdown(void)
static slist_node * slist_pop_head_node(slist_head *head)
static bool slist_is_empty(slist_head *head)
#define DLIST_STATIC_INIT(name)
#define dlist_head_element(type, membername, lhead)
#define slist_container(type, membername, ptr)
void FreePageManagerInitialize(FreePageManager *fpm, char *base)
dsm_segment * dsm_create(Size size, int flags)
static void dsm_cleanup_for_mmap(void)
void dsm_unpin_mapping(dsm_segment *seg)
#define ereport(elevel,...)
static dsm_control_header * dsm_control
void * dsm_segment_address(dsm_segment *seg)
#define Assert(condition)
struct dirent * ReadDir(DIR *dir, const char *dirname)
static bool dlist_is_empty(dlist_head *head)
void ResourceOwnerForgetDSM(ResourceOwner owner, dsm_segment *seg)
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
void dsm_detach_all(void)
#define DatumGetPointer(X)
static dsm_segment * dsm_create_descriptor(void)
static bool dsm_init_done
void dsm_impl_pin_segment(dsm_handle handle, void *impl_private, void **impl_private_pm_handle)
void dsm_detach(dsm_segment *seg)
int errmsg(const char *fmt,...)
struct dsm_control_item dsm_control_item
static Size dsm_control_mapped_size
void * MemoryContextAlloc(MemoryContext context, Size size)
struct dsm_segment_detach_callback dsm_segment_detach_callback
#define PG_DYNSHMEM_MMAP_FILE_PREFIX
void * impl_private_pm_handle
static void slist_delete_current(slist_mutable_iter *iter)
#define INVALID_CONTROL_SLOT
void(* on_dsm_detach_callback)(dsm_segment *, Datum arg)
bool dsm_impl_op(dsm_op op, dsm_handle handle, Size request_size, void **impl_private, void **mapped_address, Size *mapped_size, int elevel)
void cancel_on_dsm_detach(dsm_segment *seg, on_dsm_detach_callback function, Datum arg)
Size dsm_segment_map_length(dsm_segment *seg)
#define PG_DYNSHMEM_CONTROL_MAGIC
int min_dynamic_shared_memory
#define offsetof(type, field)