PostgreSQL Source Code git master
dsm_registry.h File Reference
#include "lib/dshash.h"
Include dependency graph for dsm_registry.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

void * GetNamedDSMSegment (const char *name, size_t size, void(*init_callback)(void *ptr, void *arg), bool *found, void *arg)
 
dsa_areaGetNamedDSA (const char *name, bool *found)
 
dshash_tableGetNamedDSHash (const char *name, const dshash_parameters *params, bool *found)
 
Size DSMRegistryShmemSize (void)
 
void DSMRegistryShmemInit (void)
 

Function Documentation

◆ DSMRegistryShmemInit()

void DSMRegistryShmemInit ( void  )

Definition at line 123 of file dsm_registry.c.

124{
125 bool found;
126
128 ShmemInitStruct("DSM Registry Data",
130 &found);
131
132 if (!found)
133 {
136 }
137}
#define DSA_HANDLE_INVALID
Definition: dsa.h:139
#define DSHASH_HANDLE_INVALID
Definition: dshash.h:27
static DSMRegistryCtxStruct * DSMRegistryCtx
Definition: dsm_registry.c:57
Size DSMRegistryShmemSize(void)
Definition: dsm_registry.c:117
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:389
dshash_table_handle dshh
Definition: dsm_registry.c:54

References DSA_HANDLE_INVALID, DSMRegistryCtxStruct::dsah, DSHASH_HANDLE_INVALID, DSMRegistryCtxStruct::dshh, DSMRegistryCtx, DSMRegistryShmemSize(), and ShmemInitStruct().

Referenced by CreateOrAttachShmemStructs().

◆ DSMRegistryShmemSize()

Size DSMRegistryShmemSize ( void  )

Definition at line 117 of file dsm_registry.c.

118{
119 return MAXALIGN(sizeof(DSMRegistryCtxStruct));
120}
#define MAXALIGN(LEN)
Definition: c.h:832

References MAXALIGN.

Referenced by CalculateShmemSize(), and DSMRegistryShmemInit().

◆ GetNamedDSA()

dsa_area * GetNamedDSA ( const char *  name,
bool *  found 
)

Definition at line 276 of file dsm_registry.c.

277{
278 DSMRegistryEntry *entry;
279 MemoryContext oldcontext;
280 dsa_area *ret;
282
283 Assert(found);
284
285 if (!name || *name == '\0')
287 (errmsg("DSA name cannot be empty")));
288
289 if (strlen(name) >= offsetof(DSMRegistryEntry, type))
291 (errmsg("DSA name too long")));
292
293 /* Be sure any local memory allocated by DSM/DSA routines is persistent. */
295
296 /* Connect to the registry. */
298
300 state = &entry->dsa;
301 if (!(*found))
302 {
303 entry->type = DSMR_ENTRY_TYPE_DSA;
304 state->handle = DSA_HANDLE_INVALID;
305 state->tranche = -1;
306 }
307 else if (entry->type != DSMR_ENTRY_TYPE_DSA)
309 (errmsg("requested DSA does not match type of existing entry")));
310
311 if (state->tranche == -1)
312 {
313 *found = false;
314
315 /* Initialize the LWLock tranche for the DSA. */
316 state->tranche = LWLockNewTrancheId(name);
317 }
318
319 if (state->handle == DSA_HANDLE_INVALID)
320 {
321 *found = false;
322
323 /* Initialize the DSA. */
324 ret = dsa_create(state->tranche);
325 dsa_pin(ret);
326 dsa_pin_mapping(ret);
327
328 /* Store handle for other backends to use. */
329 state->handle = dsa_get_handle(ret);
330 }
331 else if (dsa_is_attached(state->handle))
333 (errmsg("requested DSA already attached to current process")));
334 else
335 {
336 /* Attach to existing DSA. */
337 ret = dsa_attach(state->handle);
338 dsa_pin_mapping(ret);
339 }
340
342 MemoryContextSwitchTo(oldcontext);
343
344 return ret;
345}
dsa_area * dsa_attach(dsa_handle handle)
Definition: dsa.c:510
void dsa_pin_mapping(dsa_area *area)
Definition: dsa.c:650
dsa_handle dsa_get_handle(dsa_area *area)
Definition: dsa.c:498
bool dsa_is_attached(dsa_handle handle)
Definition: dsa.c:540
void dsa_pin(dsa_area *area)
Definition: dsa.c:990
#define dsa_create(tranche_id)
Definition: dsa.h:117
void dshash_release_lock(dshash_table *hash_table, void *entry)
Definition: dshash.c:560
void * dshash_find_or_insert(dshash_table *hash_table, const void *key, bool *found)
Definition: dshash.c:435
@ DSMR_ENTRY_TYPE_DSA
Definition: dsm_registry.c:81
static void init_dsm_registry(void)
Definition: dsm_registry.c:145
static dshash_table * dsm_registry_table
Definition: dsm_registry.c:114
int errmsg(const char *fmt,...)
Definition: elog.c:1080
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:150
Assert(PointerIsAligned(start, uint64))
int LWLockNewTrancheId(const char *name)
Definition: lwlock.c:596
MemoryContext TopMemoryContext
Definition: mcxt.c:166
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
NamedDSAState dsa
Definition: dsm_registry.c:99
DSMREntryType type
Definition: dsm_registry.c:95
Definition: dsa.c:348
Definition: regguts.h:323
const char * type
const char * name

References Assert(), DSMRegistryEntry::dsa, dsa_attach(), dsa_create, dsa_get_handle(), DSA_HANDLE_INVALID, dsa_is_attached(), dsa_pin(), dsa_pin_mapping(), dshash_find_or_insert(), dshash_release_lock(), dsm_registry_table, DSMR_ENTRY_TYPE_DSA, ereport, errmsg(), ERROR, init_dsm_registry(), LWLockNewTrancheId(), MemoryContextSwitchTo(), name, TopMemoryContext, DSMRegistryEntry::type, and type.

Referenced by tdr_attach_shmem(), test_custom_stats_var_create(), test_custom_stats_var_from_serialized_data(), test_custom_stats_var_report(), and test_custom_stats_var_to_serialized_data().

◆ GetNamedDSHash()

dshash_table * GetNamedDSHash ( const char *  name,
const dshash_parameters params,
bool *  found 
)

Definition at line 357 of file dsm_registry.c.

358{
359 DSMRegistryEntry *entry;
360 MemoryContext oldcontext;
361 dshash_table *ret;
362 NamedDSHState *dsh_state;
363
364 Assert(params);
365 Assert(found);
366
367 if (!name || *name == '\0')
369 (errmsg("DSHash name cannot be empty")));
370
371 if (strlen(name) >= offsetof(DSMRegistryEntry, type))
373 (errmsg("DSHash name too long")));
374
375 /* Be sure any local memory allocated by DSM/DSA routines is persistent. */
377
378 /* Connect to the registry. */
380
382 dsh_state = &entry->dsh;
383 if (!(*found))
384 {
385 entry->type = DSMR_ENTRY_TYPE_DSH;
386 dsh_state->dsa_handle = DSA_HANDLE_INVALID;
388 dsh_state->tranche = -1;
389 }
390 else if (entry->type != DSMR_ENTRY_TYPE_DSH)
392 (errmsg("requested DSHash does not match type of existing entry")));
393
394 if (dsh_state->tranche == -1)
395 {
396 *found = false;
397
398 /* Initialize the LWLock tranche for the hash table. */
399 dsh_state->tranche = LWLockNewTrancheId(name);
400 }
401
402 if (dsh_state->dsa_handle == DSA_HANDLE_INVALID)
403 {
404 dshash_parameters params_copy;
405 dsa_area *dsa;
406
407 *found = false;
408
409 /* Initialize the DSA for the hash table. */
410 dsa = dsa_create(dsh_state->tranche);
411
412 /* Initialize the dshash table. */
413 memcpy(&params_copy, params, sizeof(dshash_parameters));
414 params_copy.tranche_id = dsh_state->tranche;
415 ret = dshash_create(dsa, &params_copy, NULL);
416
417 dsa_pin(dsa);
418 dsa_pin_mapping(dsa);
419
420 /* Store handles for other backends to use. */
421 dsh_state->dsa_handle = dsa_get_handle(dsa);
423 }
424 else if (dsa_is_attached(dsh_state->dsa_handle))
426 (errmsg("requested DSHash already attached to current process")));
427 else
428 {
429 dsa_area *dsa;
430
431 /* XXX: Should we verify params matches what table was created with? */
432
433 /* Attach to existing DSA for the hash table. */
434 dsa = dsa_attach(dsh_state->dsa_handle);
435 dsa_pin_mapping(dsa);
436
437 /* Attach to existing dshash table. */
438 ret = dshash_attach(dsa, params, dsh_state->dsh_handle, NULL);
439 }
440
442 MemoryContextSwitchTo(oldcontext);
443
444 return ret;
445}
dshash_table_handle dshash_get_hash_table_handle(dshash_table *hash_table)
Definition: dshash.c:369
dshash_table * dshash_attach(dsa_area *area, const dshash_parameters *params, dshash_table_handle handle, void *arg)
Definition: dshash.c:272
dshash_table * dshash_create(dsa_area *area, const dshash_parameters *params, void *arg)
Definition: dshash.c:208
@ DSMR_ENTRY_TYPE_DSH
Definition: dsm_registry.c:82
NamedDSHState dsh
Definition: dsm_registry.c:100
dsa_handle dsa_handle
Definition: dsm_registry.c:73
dshash_table_handle dsh_handle
Definition: dsm_registry.c:74

References Assert(), dsa_attach(), dsa_create, dsa_get_handle(), NamedDSHState::dsa_handle, DSA_HANDLE_INVALID, dsa_is_attached(), dsa_pin(), dsa_pin_mapping(), DSMRegistryEntry::dsh, NamedDSHState::dsh_handle, dshash_attach(), dshash_create(), dshash_find_or_insert(), dshash_get_hash_table_handle(), DSHASH_HANDLE_INVALID, dshash_release_lock(), dsm_registry_table, DSMR_ENTRY_TYPE_DSH, ereport, errmsg(), ERROR, init_dsm_registry(), LWLockNewTrancheId(), MemoryContextSwitchTo(), name, TopMemoryContext, NamedDSHState::tranche, dshash_parameters::tranche_id, DSMRegistryEntry::type, and type.

Referenced by tdr_attach_shmem().

◆ GetNamedDSMSegment()

void * GetNamedDSMSegment ( const char *  name,
size_t  size,
void(*)(void *ptr, void *arg init_callback,
bool *  found,
void *  arg 
)

Definition at line 187 of file dsm_registry.c.

190{
191 DSMRegistryEntry *entry;
192 MemoryContext oldcontext;
193 void *ret;
195 dsm_segment *seg;
196
197 Assert(found);
198
199 if (!name || *name == '\0')
201 (errmsg("DSM segment name cannot be empty")));
202
203 if (strlen(name) >= offsetof(DSMRegistryEntry, type))
205 (errmsg("DSM segment name too long")));
206
207 if (size == 0)
209 (errmsg("DSM segment size must be nonzero")));
210
211 /* Be sure any local memory allocated by DSM/DSA routines is persistent. */
213
214 /* Connect to the registry. */
216
218 state = &entry->dsm;
219 if (!(*found))
220 {
221 entry->type = DSMR_ENTRY_TYPE_DSM;
222 state->handle = DSM_HANDLE_INVALID;
223 state->size = size;
224 }
225 else if (entry->type != DSMR_ENTRY_TYPE_DSM)
227 (errmsg("requested DSM segment does not match type of existing entry")));
228 else if (state->size != size)
230 (errmsg("requested DSM segment size does not match size of existing segment")));
231
232 if (state->handle == DSM_HANDLE_INVALID)
233 {
234 *found = false;
235
236 /* Initialize the segment. */
237 seg = dsm_create(size, 0);
238
239 if (init_callback)
240 (*init_callback) (dsm_segment_address(seg), arg);
241
242 dsm_pin_segment(seg);
243 dsm_pin_mapping(seg);
244 state->handle = dsm_segment_handle(seg);
245 }
246 else
247 {
248 /* If the existing segment is not already attached, attach it now. */
249 seg = dsm_find_mapping(state->handle);
250 if (seg == NULL)
251 {
252 seg = dsm_attach(state->handle);
253 if (seg == NULL)
254 elog(ERROR, "could not map dynamic shared memory segment");
255
256 dsm_pin_mapping(seg);
257 }
258 }
259
260 ret = dsm_segment_address(seg);
262 MemoryContextSwitchTo(oldcontext);
263
264 return ret;
265}
dsm_handle dsm_segment_handle(dsm_segment *seg)
Definition: dsm.c:1123
void dsm_pin_mapping(dsm_segment *seg)
Definition: dsm.c:915
void dsm_pin_segment(dsm_segment *seg)
Definition: dsm.c:955
void * dsm_segment_address(dsm_segment *seg)
Definition: dsm.c:1095
dsm_segment * dsm_create(Size size, int flags)
Definition: dsm.c:516
dsm_segment * dsm_attach(dsm_handle h)
Definition: dsm.c:665
dsm_segment * dsm_find_mapping(dsm_handle handle)
Definition: dsm.c:1076
#define DSM_HANDLE_INVALID
Definition: dsm_impl.h:58
@ DSMR_ENTRY_TYPE_DSM
Definition: dsm_registry.c:80
#define elog(elevel,...)
Definition: elog.h:226
void * arg
NamedDSMState dsm
Definition: dsm_registry.c:98

References arg, Assert(), dshash_find_or_insert(), dshash_release_lock(), DSMRegistryEntry::dsm, dsm_attach(), dsm_create(), dsm_find_mapping(), DSM_HANDLE_INVALID, dsm_pin_mapping(), dsm_pin_segment(), dsm_registry_table, dsm_segment_address(), dsm_segment_handle(), DSMR_ENTRY_TYPE_DSM, elog, ereport, errmsg(), ERROR, init_dsm_registry(), MemoryContextSwitchTo(), name, TopMemoryContext, DSMRegistryEntry::type, and type.

Referenced by apw_init_shmem(), injection_init_shmem(), tdr_attach_shmem(), test_dsa_basic(), and test_dsa_resowners().