50 #define PG_DYNSHMEM_CONTROL_MAGIC 0x9a503d32
52 #define PG_DYNSHMEM_FIXED_SLOTS 64
53 #define PG_DYNSHMEM_SLOTS_PER_BACKEND 5
55 #define INVALID_CONTROL_SLOT ((uint32) -1)
151 .
name =
"dynamic shared memory segment",
179 void *dsm_control_address = NULL;
197 elog(
DEBUG2,
"dynamic shared memory system will support %u segments",
208 Assert(dsm_control_address == NULL);
222 "created dynamic shared memory control segment %u (%zu bytes)",
240 void *mapped_address = NULL;
241 void *junk_mapped_address = NULL;
242 void *impl_private = NULL;
243 void *junk_impl_private = NULL;
244 Size mapped_size = 0;
245 Size junk_mapped_size = 0;
257 &mapped_address, &mapped_size,
DEBUG1))
268 &mapped_address, &mapped_size,
LOG);
293 elog(
DEBUG2,
"cleaning up orphaned dynamic shared memory with ID %u (reference count %u)",
298 &junk_mapped_address, &junk_mapped_size,
LOG);
303 "cleaning up dynamic shared memory control segment with ID %u",
306 &mapped_address, &mapped_size,
LOG);
340 if (unlink(
buf) != 0)
343 errmsg(
"could not remove file \"%s\": %m",
buf)));
362 void *dsm_control_address;
363 void *junk_mapped_address = NULL;
364 void *junk_impl_private = NULL;
365 Size junk_mapped_size = 0;
379 (
errmsg(
"dynamic shared memory control segment is corrupt")));
397 elog(
DEBUG2,
"cleaning up orphaned dynamic shared memory with ID %u",
402 &junk_mapped_address, &junk_mapped_size,
LOG);
407 "cleaning up dynamic shared memory control segment with ID %u",
428 void *control_address = NULL;
443 (
errcode(ERRCODE_INTERNAL_ERROR),
444 errmsg(
"dynamic shared memory control segment is not valid")));
491 size_t first_page = 0;
522 size_t first_page = 0;
524 bool using_main_dsm_region =
false;
543 if (dsm_main_space_fpm)
556 using_main_dsm_region =
true;
561 if (!using_main_dsm_region)
567 if (dsm_main_space_fpm)
589 if (using_main_dsm_region)
611 if (using_main_dsm_region)
614 if (!using_main_dsm_region)
625 (
errcode(ERRCODE_INSUFFICIENT_RESOURCES),
626 errmsg(
"too many dynamic shared memory segments")));
630 if (using_main_dsm_region)
692 elog(
ERROR,
"can't attach the same segment more than once");
787 if (control_address != NULL)
967 elog(
ERROR,
"cannot pin a segment that is already pinned");
991 bool destroy =
false;
1016 elog(
ERROR,
"cannot unpin unknown segment handle");
1018 elog(
ERROR,
"cannot unpin a segment that is not pinned");
1041 void *junk_impl_private = NULL;
1042 void *junk_mapped_address = NULL;
1043 Size junk_mapped_size = 0;
1057 &junk_mapped_address, &junk_mapped_size,
WARNING))
1084 if (seg->
handle == handle)
1275 handle |= slot << 1;
1301 return psprintf(
"dynamic shared memory segment %u",
#define Assert(condition)
#define FLEXIBLE_ARRAY_MEMBER
static void PGresult * res
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 char * ResOwnerPrintDSM(Datum res)
static void dsm_postmaster_shutdown(int code, Datum arg)
void dsm_unpin_segment(dsm_handle handle)
void dsm_pin_segment(dsm_segment *seg)
static void ResourceOwnerForgetDSM(ResourceOwner owner, dsm_segment *seg)
void dsm_detach_all(void)
static void ResourceOwnerRememberDSM(ResourceOwner owner, dsm_segment *seg)
static dsm_handle make_main_region_dsm_handle(int slot)
static const ResourceOwnerDesc dsm_resowner_desc
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)
static void ResOwnerReleaseDSM(Datum res)
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)
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)
char * psprintf(const char *fmt,...)
ResourceOwner CurrentResourceOwner
void ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
void ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)
void ResourceOwnerEnlarge(ResourceOwner owner)
@ RESOURCE_RELEASE_BEFORE_LOCKS
#define RELEASE_PRIO_DSMS
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
static pg_noinline void Size size
void * impl_private_pm_handle
on_dsm_detach_callback function