=== Applying patches on top of PostgreSQL commit ID 972c14fb9134fdfd76ea6ebcf98a55a945bbc988 === /etc/rc.d/jail: WARNING: Per-jail configuration via jail_* variables is obsolete. Please consider migrating to /etc/jail.conf. Wed Apr 15 07:07:27 UTC 2026 On branch cf/5914 nothing to commit, working tree clean === using 'git am' to apply patch ./v1-0001-Document-DSM-registry.patch === Applying: Document DSM registry Using index info to reconstruct a base tree... M doc/src/sgml/xfunc.sgml Falling back to patching base and 3-way merge... Auto-merging doc/src/sgml/xfunc.sgml CONFLICT (content): Merge conflict in doc/src/sgml/xfunc.sgml error: Failed to merge in the changes. hint: Use 'git am --show-current-patch=diff' to see the failed patch Patch failed at 0001 Document DSM registry When you have resolved this problem, run "git am --continue". If you prefer to skip this patch, run "git am --skip" instead. To restore the original branch and stop patching, run "git am --abort". === using patch(1) to apply patch ./v1-0001-Document-DSM-registry.patch === patching file doc/src/sgml/xfunc.sgml Hunk #1 FAILED at 3685. Hunk #2 FAILED at 3705. 2 out of 2 hunks FAILED -- saving rejects to file doc/src/sgml/xfunc.sgml.rej Removing doc/src/sgml/xfunc.sgml.rej === using 'git apply' to apply patch ./v1-0001-Document-DSM-registry.patch === Applied patch to 'doc/src/sgml/xfunc.sgml' with conflicts. U doc/src/sgml/xfunc.sgml diff --cc doc/src/sgml/xfunc.sgml index 086e6231998,e94f472e225..00000000000 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@@ -3716,62 -3685,64 +3716,117 @@@ my_shmem_init(void *arg ++<<<<<<< ours + Requesting Shared Memory After Startup with <function>ShmemRequestStruct</function> + + + The ShmemRequestStruct() can also be called after + system startup, which is useful to allow small allocations in add-in + libraries that are not specified in + shared_preload_libraries. + However, after startup the allocation can fail if there is not enough + shared memory available. The system reserves some memory for allocations + after startup, but that reservation is small. + + + By default, RegisterShmemCallbacks() fails with an + error if called after system startup. To use it after startup, you must + set the SHMEM_CALLBACKS_ALLOW_AFTER_STARTUP flag in + the argument ShmemCallbacks struct to + acknowledge the risk. + + + When RegisterShmemCallbacks() is called after + startup, it will immediately call the appropriate callbacks, depending + on whether the requested memory areas were already initialized by + another backend. The callbacks will be called while holding an internal + lock, which prevents concurrent two backends from initializing the + memory area concurrently. + + + + + Allocating Dynamic Shared Memory After Startup + + + There is another, more flexible method of reserving shared memory that + can be done after server startup. To do so, each backend that will + use the shared memory should obtain a pointer to it by calling: + +void *GetNamedDSMSegment(const char *name, size_t size, + void (*init_callback) (void *ptr, void *arg), + bool *found, void *arg) + ++======= + DSM Registry + + + Another, more flexible way to reserve shared memory after server startup + (and outside a shmem_request_hook) is to use the dynamic shared memory (DSM) registry. + The registry maps library-defined string keys to DSM handles. + It supports creating named DSM segments with GetNamedDSMSegment, + named dynamic shared memory areas (DSAs) with GetNamedDSA, + and named hash tables backed by a DSA with GetNamedDSHash. + + + + Unlike shared memory reserved at server startup, there is no need to + acquire AddinShmemInitLock or otherwise take action + to avoid race conditions when reserving shared memory with these functions. + They ensure that only one backend allocates and initializes the memory structure and that all other + backends receive an appropriate pointer to the fully allocated and initialized segment, area or hash table. + + + + Consider for example this function to allocate a named DSM segment. + + void *GetNamedDSMSegment(const char *name, size_t size, + void (*init_callback) (void *ptr), + bool *found) + ++>>>>>>> theirs If a dynamic shared memory segment with the given name does not yet exist, this function will allocate it and initialize it with the provided init_callback callback function. If the segment has already been allocated and initialized by another backend, this function simply attaches the existing dynamic shared memory segment to the current - backend. + backend. In the former case, GetNamedDSMSegment + passes the void *arg argument to the + init_callback. This is particularly useful for + reusing an initialization callback function for multiple DSM segments. + The same logic applies to the other functions offered by the registry. + ++<<<<<<< ours + GetNamedDSMSegment ensures that only + one backend allocates and initializes the segment and that all other + backends receive a pointer to the fully allocated and initialized + segment. ++======= + To allocate a named DSA, one can use + + dsa_area *GetNamedDSA(const char *name, bool *found) + + + Νote that this should be called at most once for a given DSA in each backend. + + + + To allocate a named hash table backed by shared memory, one can use + + dshash_table *GetNamedDSHash(const char *name, const dshash_parameters *params, bool *found) + + + Also note that this should be called at most once for a given table in each backend. + + + + To monitor the allocations of the DSM registry + the pg_dsm_registry_allocations system view + documented in can be used. ++>>>>>>> theirs