PostgreSQL Source Code git master
Loading...
Searching...
No Matches
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

voidGetNamedDSMSegment (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)
 

Function Documentation

◆ GetNamedDSA()

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

Definition at line 279 of file dsm_registry.c.

280{
281 DSMRegistryEntry *entry;
282 MemoryContext oldcontext;
283 dsa_area *ret;
285
286 Assert(found);
287
288 if (!name || *name == '\0')
290 (errmsg("DSA name cannot be empty")));
291
294 (errmsg("DSA name too long")));
295
296 /* Be sure any local memory allocated by DSM/DSA routines is persistent. */
298
299 /* Connect to the registry. */
301
303 state = &entry->dsa;
304 if (!(*found))
305 {
306 entry->type = DSMR_ENTRY_TYPE_DSA;
307 state->handle = DSA_HANDLE_INVALID;
308 state->tranche = -1;
309 }
310 else if (entry->type != DSMR_ENTRY_TYPE_DSA)
312 (errmsg("requested DSA does not match type of existing entry")));
313
314 if (state->tranche == -1)
315 {
316 *found = false;
317
318 /* Initialize the LWLock tranche for the DSA. */
319 state->tranche = LWLockNewTrancheId(name);
320 }
321
322 if (state->handle == DSA_HANDLE_INVALID)
323 {
324 *found = false;
325
326 /* Initialize the DSA. */
327 ret = dsa_create(state->tranche);
328 dsa_pin(ret);
329 dsa_pin_mapping(ret);
330
331 /* Store handle for other backends to use. */
332 state->handle = dsa_get_handle(ret);
333 }
334 else if (dsa_is_attached(state->handle))
336 (errmsg("requested DSA already attached to current process")));
337 else
338 {
339 /* Attach to existing DSA. */
340 ret = dsa_attach(state->handle);
341 dsa_pin_mapping(ret);
342 }
343
345 MemoryContextSwitchTo(oldcontext);
346
347 return ret;
348}
#define Assert(condition)
Definition c.h:943
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
#define DSA_HANDLE_INVALID
Definition dsa.h:139
void dshash_release_lock(dshash_table *hash_table, void *entry)
Definition dshash.c:579
#define dshash_find_or_insert(hash_table, key, found)
Definition dshash.h:109
@ DSMR_ENTRY_TYPE_DSA
static void init_dsm_registry(void)
static dshash_table * dsm_registry_table
#define ERROR
Definition elog.h:40
#define ereport(elevel,...)
Definition elog.h:152
int LWLockNewTrancheId(const char *name)
Definition lwlock.c:562
MemoryContext TopMemoryContext
Definition mcxt.c:166
static char * errmsg
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
static int fb(int x)
NamedDSAState dsa
DSMREntryType type
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, fb(), 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 
)
extern

Definition at line 360 of file dsm_registry.c.

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

References Assert, dsa_attach(), dsa_create, dsa_get_handle(), DSA_HANDLE_INVALID, dsa_is_attached(), dsa_pin(), dsa_pin_mapping(), DSMRegistryEntry::dsh, 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, fb(), init_dsm_registry(), LWLockNewTrancheId(), memcpy(), MemoryContextSwitchTo(), name, TopMemoryContext, 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 
)
extern

Definition at line 190 of file dsm_registry.c.

193{
194 DSMRegistryEntry *entry;
195 MemoryContext oldcontext;
196 void *ret;
198 dsm_segment *seg;
199
200 Assert(found);
201
202 if (!name || *name == '\0')
204 (errmsg("DSM segment name cannot be empty")));
205
208 (errmsg("DSM segment name too long")));
209
210 if (size == 0)
212 (errmsg("DSM segment size must be nonzero")));
213
214 /* Be sure any local memory allocated by DSM/DSA routines is persistent. */
216
217 /* Connect to the registry. */
219
221 state = &entry->dsm;
222 if (!(*found))
223 {
224 entry->type = DSMR_ENTRY_TYPE_DSM;
225 state->handle = DSM_HANDLE_INVALID;
226 state->size = size;
227 }
228 else if (entry->type != DSMR_ENTRY_TYPE_DSM)
230 (errmsg("requested DSM segment does not match type of existing entry")));
231 else if (state->size != size)
233 (errmsg("requested DSM segment size does not match size of existing segment")));
234
235 if (state->handle == DSM_HANDLE_INVALID)
236 {
237 *found = false;
238
239 /* Initialize the segment. */
240 seg = dsm_create(size, 0);
241
242 if (init_callback)
243 (*init_callback) (dsm_segment_address(seg), arg);
244
245 dsm_pin_segment(seg);
246 dsm_pin_mapping(seg);
247 state->handle = dsm_segment_handle(seg);
248 }
249 else
250 {
251 /* If the existing segment is not already attached, attach it now. */
252 seg = dsm_find_mapping(state->handle);
253 if (seg == NULL)
254 {
255 seg = dsm_attach(state->handle);
256 if (seg == NULL)
257 elog(ERROR, "could not map dynamic shared memory segment");
258
259 dsm_pin_mapping(seg);
260 }
261 }
262
263 ret = dsm_segment_address(seg);
265 MemoryContextSwitchTo(oldcontext);
266
267 return ret;
268}
dsm_handle dsm_segment_handle(dsm_segment *seg)
Definition dsm.c:1131
void dsm_pin_mapping(dsm_segment *seg)
Definition dsm.c:923
void dsm_pin_segment(dsm_segment *seg)
Definition dsm.c:963
void * dsm_segment_address(dsm_segment *seg)
Definition dsm.c:1103
dsm_segment * dsm_create(Size size, int flags)
Definition dsm.c:524
dsm_segment * dsm_attach(dsm_handle h)
Definition dsm.c:673
dsm_segment * dsm_find_mapping(dsm_handle handle)
Definition dsm.c:1084
#define DSM_HANDLE_INVALID
Definition dsm_impl.h:58
@ DSMR_ENTRY_TYPE_DSM
Datum arg
Definition elog.c:1322
#define elog(elevel,...)
Definition elog.h:228
NamedDSMState dsm

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, fb(), init_dsm_registry(), MemoryContextSwitchTo(), name, TopMemoryContext, DSMRegistryEntry::type, and type.

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