PostgreSQL Source Code git master
Data Structures | Typedefs | Enumerations | Functions | Variables
dsm_registry.c File Reference
#include "postgres.h"
#include "funcapi.h"
#include "lib/dshash.h"
#include "storage/dsm_registry.h"
#include "storage/lwlock.h"
#include "storage/shmem.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
Include dependency graph for dsm_registry.c:

Go to the source code of this file.

Data Structures

 
struct   NamedDSMState
 
struct   NamedDSAState
 
struct   NamedDSHState
 
struct   DSMRegistryEntry
 

Typedefs

 
typedef struct NamedDSMState  NamedDSMState
 
typedef struct NamedDSAState  NamedDSAState
 
typedef struct NamedDSHState  NamedDSHState
 
typedef enum DSMREntryType  DSMREntryType
 
 

Enumerations

 

Functions

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

Variables

 
static const char *const  DSMREntryTypeNames []
 
static const dshash_parameters  dsh_params
 
 
 

Typedef Documentation

DSMRegistryCtxStruct

DSMRegistryEntry

DSMREntryType

NamedDSAState

typedef struct NamedDSAState NamedDSAState

NamedDSHState

typedef struct NamedDSHState NamedDSHState

NamedDSMState

typedef struct NamedDSMState NamedDSMState

Enumeration Type Documentation

DSMREntryType

Enumerator
DSMR_ENTRY_TYPE_DSM 
DSMR_ENTRY_TYPE_DSA 
DSMR_ENTRY_TYPE_DSH 

Definition at line 78 of file dsm_registry.c.

79{
DSMREntryType
Definition: dsm_registry.c:79
@ DSMR_ENTRY_TYPE_DSM
Definition: dsm_registry.c:80
@ DSMR_ENTRY_TYPE_DSA
Definition: dsm_registry.c:81
@ DSMR_ENTRY_TYPE_DSH
Definition: dsm_registry.c:82

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:387
dsa_handle dsah
Definition: dsm_registry.c:53
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:810

References MAXALIGN.

Referenced by CalculateShmemSize(), and DSMRegistryShmemInit().

GetNamedDSA()

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

Definition at line 272 of file dsm_registry.c.

273{
274 DSMRegistryEntry *entry;
275 MemoryContext oldcontext;
276 dsa_area *ret;
277
278 Assert(found);
279
280 if (!name || *name == '0円')
282 (errmsg("DSA name cannot be empty")));
283
284 if (strlen(name) >= offsetof(DSMRegistryEntry, type))
286 (errmsg("DSA name too long")));
287
288 /* Be sure any local memory allocated by DSM/DSA routines is persistent. */
290
291 /* Connect to the registry. */
293
295 if (!(*found))
296 {
297 NamedDSAState *state = &entry->dsa;
298
299 entry->type = DSMR_ENTRY_TYPE_DSA;
300
301 /* Initialize the LWLock tranche for the DSA. */
302 state->tranche = LWLockNewTrancheId(name);
303
304 /* Initialize the DSA. */
305 ret = dsa_create(state->tranche);
306 dsa_pin(ret);
307 dsa_pin_mapping(ret);
308
309 /* Store handle for other backends to use. */
310 state->handle = dsa_get_handle(ret);
311 }
312 else if (entry->type != DSMR_ENTRY_TYPE_DSA)
314 (errmsg("requested DSA does not match type of existing entry")));
315 else
316 {
317 NamedDSAState *state = &entry->dsa;
318
319 if (dsa_is_attached(state->handle))
321 (errmsg("requested DSA already attached to current process")));
322
323 /* Attach to existing DSA. */
324 ret = dsa_attach(state->handle);
325 dsa_pin_mapping(ret);
326 }
327
329 MemoryContextSwitchTo(oldcontext);
330
331 return ret;
332}
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:558
void * dshash_find_or_insert(dshash_table *hash_table, const void *key, bool *found)
Definition: dshash.c:433
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:1071
#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_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().

GetNamedDSHash()

dshash_table * GetNamedDSHash ( const char *  name,
const dshash_parametersparams,
bool *  found 
)

Definition at line 344 of file dsm_registry.c.

345{
346 DSMRegistryEntry *entry;
347 MemoryContext oldcontext;
348 dshash_table *ret;
349
350 Assert(params);
351 Assert(found);
352
353 if (!name || *name == '0円')
355 (errmsg("DSHash name cannot be empty")));
356
357 if (strlen(name) >= offsetof(DSMRegistryEntry, type))
359 (errmsg("DSHash name too long")));
360
361 /* Be sure any local memory allocated by DSM/DSA routines is persistent. */
363
364 /* Connect to the registry. */
366
368 if (!(*found))
369 {
370 NamedDSHState *dsh_state = &entry->dsh;
371 dshash_parameters params_copy;
372 dsa_area *dsa;
373
374 entry->type = DSMR_ENTRY_TYPE_DSH;
375
376 /* Initialize the LWLock tranche for the hash table. */
377 dsh_state->tranche = LWLockNewTrancheId(name);
378
379 /* Initialize the DSA for the hash table. */
380 dsa = dsa_create(dsh_state->tranche);
381 dsa_pin(dsa);
382 dsa_pin_mapping(dsa);
383
384 /* Initialize the dshash table. */
385 memcpy(&params_copy, params, sizeof(dshash_parameters));
386 params_copy.tranche_id = dsh_state->tranche;
387 ret = dshash_create(dsa, &params_copy, NULL);
388
389 /* Store handles for other backends to use. */
390 dsh_state->dsa_handle = dsa_get_handle(dsa);
392 }
393 else if (entry->type != DSMR_ENTRY_TYPE_DSH)
395 (errmsg("requested DSHash does not match type of existing entry")));
396 else
397 {
398 NamedDSHState *dsh_state = &entry->dsh;
399 dsa_area *dsa;
400
401 /* XXX: Should we verify params matches what table was created with? */
402
403 if (dsa_is_attached(dsh_state->dsa_handle))
405 (errmsg("requested DSHash already attached to current process")));
406
407 /* Attach to existing DSA for the hash table. */
408 dsa = dsa_attach(dsh_state->dsa_handle);
409 dsa_pin_mapping(dsa);
410
411 /* Attach to existing dshash table. */
412 ret = dshash_attach(dsa, params, dsh_state->dsh_handle, NULL);
413 }
414
416 MemoryContextSwitchTo(oldcontext);
417
418 return ret;
419}
dshash_table_handle dshash_get_hash_table_handle(dshash_table *hash_table)
Definition: dshash.c:367
dshash_table * dshash_attach(dsa_area *area, const dshash_parameters *params, dshash_table_handle handle, void *arg)
Definition: dshash.c:270
dshash_table * dshash_create(dsa_area *area, const dshash_parameters *params, void *arg)
Definition: dshash.c:206
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
int tranche_id
Definition: dshash.h:61

References Assert(), dsa_attach(), dsa_create, dsa_get_handle(), NamedDSHState::dsa_handle, 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_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)  init_callback,
bool *  found 
)

Definition at line 185 of file dsm_registry.c.

187{
188 DSMRegistryEntry *entry;
189 MemoryContext oldcontext;
190 void *ret;
191
192 Assert(found);
193
194 if (!name || *name == '0円')
196 (errmsg("DSM segment name cannot be empty")));
197
198 if (strlen(name) >= offsetof(DSMRegistryEntry, type))
200 (errmsg("DSM segment name too long")));
201
202 if (size == 0)
204 (errmsg("DSM segment size must be nonzero")));
205
206 /* Be sure any local memory allocated by DSM/DSA routines is persistent. */
208
209 /* Connect to the registry. */
211
213 if (!(*found))
214 {
215 NamedDSMState *state = &entry->dsm;
216 dsm_segment *seg;
217
218 entry->type = DSMR_ENTRY_TYPE_DSM;
219
220 /* Initialize the segment. */
221 seg = dsm_create(size, 0);
222
223 dsm_pin_segment(seg);
224 dsm_pin_mapping(seg);
225 state->handle = dsm_segment_handle(seg);
226 state->size = size;
227 ret = dsm_segment_address(seg);
228
229 if (init_callback)
230 (*init_callback) (ret);
231 }
232 else if (entry->type != DSMR_ENTRY_TYPE_DSM)
234 (errmsg("requested DSM segment does not match type of existing entry")));
235 else if (entry->dsm.size != size)
237 (errmsg("requested DSM segment size does not match size of existing segment")));
238 else
239 {
240 NamedDSMState *state = &entry->dsm;
241 dsm_segment *seg;
242
243 /* If the existing segment is not already attached, attach it now. */
244 seg = dsm_find_mapping(state->handle);
245 if (seg == NULL)
246 {
247 seg = dsm_attach(state->handle);
248 if (seg == NULL)
249 elog(ERROR, "could not map dynamic shared memory segment");
250
251 dsm_pin_mapping(seg);
252 }
253
254 ret = dsm_segment_address(seg);
255 }
256
258 MemoryContextSwitchTo(oldcontext);
259
260 return ret;
261}
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 elog(elevel,...)
Definition: elog.h:226
NamedDSMState dsm
Definition: dsm_registry.c:98
size_t size
Definition: dsm_registry.c:62
Definition: dsm.c:67

References Assert(), dshash_find_or_insert(), dshash_release_lock(), DSMRegistryEntry::dsm, dsm_attach(), dsm_create(), dsm_find_mapping(), 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, NamedDSMState::size, TopMemoryContext, DSMRegistryEntry::type, and type.

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

init_dsm_registry()

static void init_dsm_registry ( void  )
static

Definition at line 145 of file dsm_registry.c.

146{
147 /* Quick exit if we already did this. */
149 return;
150
151 /* Otherwise, use a lock to ensure only one process creates the table. */
152 LWLockAcquire(DSMRegistryLock, LW_EXCLUSIVE);
153
155 {
156 /* Initialize dynamic shared hash table for registry. */
157 dsm_registry_dsa = dsa_create(LWTRANCHE_DSM_REGISTRY_DSA);
161
162 /* Store handles in shared memory for other backends to use. */
165 }
166 else
167 {
168 /* Attach to existing dynamic shared hash table. */
172 DSMRegistryCtx->dshh, NULL);
173 }
174
175 LWLockRelease(DSMRegistryLock);
176}
static dsa_area * dsm_registry_dsa
Definition: dsm_registry.c:113
static const dshash_parameters dsh_params
Definition: dsm_registry.c:104
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1174
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1894
@ LW_EXCLUSIVE
Definition: lwlock.h:112

References dsa_attach(), dsa_create, dsa_get_handle(), dsa_pin(), dsa_pin_mapping(), DSMRegistryCtxStruct::dsah, dsh_params, dshash_attach(), dshash_create(), dshash_get_hash_table_handle(), DSHASH_HANDLE_INVALID, DSMRegistryCtxStruct::dshh, dsm_registry_dsa, dsm_registry_table, DSMRegistryCtx, LW_EXCLUSIVE, LWLockAcquire(), and LWLockRelease().

Referenced by GetNamedDSA(), GetNamedDSHash(), GetNamedDSMSegment(), and pg_get_dsm_registry_allocations().

pg_get_dsm_registry_allocations()

Datum pg_get_dsm_registry_allocations ( PG_FUNCTION_ARGS  )

Definition at line 422 of file dsm_registry.c.

423{
424 ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
425 DSMRegistryEntry *entry;
426 MemoryContext oldcontext;
427 dshash_seq_status status;
428
430
431 /* Be sure any local memory allocated by DSM/DSA routines is persistent. */
434 MemoryContextSwitchTo(oldcontext);
435
436 dshash_seq_init(&status, dsm_registry_table, false);
437 while ((entry = dshash_seq_next(&status)) != NULL)
438 {
439 Datum vals[3];
440 bool nulls[3] = {0};
441
442 vals[0] = CStringGetTextDatum(entry->name);
443 vals[1] = CStringGetTextDatum(DSMREntryTypeNames[entry->type]);
444
445 /*
446 * Since we can't know the size of DSA/dshash entries without first
447 * attaching to them, return NULL for those.
448 */
449 if (entry->type == DSMR_ENTRY_TYPE_DSM)
450 vals[2] = Int64GetDatum(entry->dsm.size);
451 else
452 nulls[2] = true;
453
454 tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, vals, nulls);
455 }
456 dshash_seq_term(&status);
457
458 return (Datum) 0;
459}
#define CStringGetTextDatum(s)
Definition: builtins.h:97
void dshash_seq_init(dshash_seq_status *status, dshash_table *hash_table, bool exclusive)
Definition: dshash.c:638
void dshash_seq_term(dshash_seq_status *status)
Definition: dshash.c:747
void * dshash_seq_next(dshash_seq_status *status)
Definition: dshash.c:657
static const char *const DSMREntryTypeNames[]
Definition: dsm_registry.c:85
void InitMaterializedSRF(FunctionCallInfo fcinfo, bits32 flags)
Definition: funcapi.c:76
#define MAT_SRF_USE_EXPECTED_DESC
Definition: funcapi.h:296
static Datum Int64GetDatum(int64 X)
Definition: postgres.h:403
uint64_t Datum
Definition: postgres.h:70
TupleDesc setDesc
Definition: execnodes.h:364
Tuplestorestate * setResult
Definition: execnodes.h:363
void tuplestore_putvalues(Tuplestorestate *state, TupleDesc tdesc, const Datum *values, const bool *isnull)
Definition: tuplestore.c:784

References CStringGetTextDatum, dshash_seq_init(), dshash_seq_next(), dshash_seq_term(), dsm_registry_table, DSMR_ENTRY_TYPE_DSM, DSMREntryTypeNames, init_dsm_registry(), InitMaterializedSRF(), Int64GetDatum(), MAT_SRF_USE_EXPECTED_DESC, MemoryContextSwitchTo(), ReturnSetInfo::setDesc, ReturnSetInfo::setResult, TopMemoryContext, and tuplestore_putvalues().

Variable Documentation

dsh_params

const dshash_parameters dsh_params
static
Initial value:
= {
offsetof(DSMRegistryEntry, type),
LWTRANCHE_DSM_REGISTRY_HASH
}
void dshash_strcpy(void *dest, const void *src, size_t size, void *arg)
Definition: dshash.c:622
dshash_hash dshash_strhash(const void *v, size_t size, void *arg)
Definition: dshash.c:611
int dshash_strcmp(const void *a, const void *b, size_t size, void *arg)
Definition: dshash.c:599
struct DSMRegistryEntry DSMRegistryEntry

Definition at line 104 of file dsm_registry.c.

Referenced by init_dsm_registry().

dsm_registry_dsa

dsa_area* dsm_registry_dsa
static

Definition at line 113 of file dsm_registry.c.

Referenced by init_dsm_registry().

dsm_registry_table

dshash_table* dsm_registry_table
static

DSMRegistryCtx

DSMRegistryCtxStruct* DSMRegistryCtx
static

Definition at line 57 of file dsm_registry.c.

Referenced by DSMRegistryShmemInit(), and init_dsm_registry().

DSMREntryTypeNames

const char* const DSMREntryTypeNames[]
static
Initial value:
=
{
[DSMR_ENTRY_TYPE_DSM] = "segment",
[DSMR_ENTRY_TYPE_DSA] = "area",
[DSMR_ENTRY_TYPE_DSH] = "hash",
}

Definition at line 85 of file dsm_registry.c.

Referenced by pg_get_dsm_registry_allocations().

AltStyle によって変換されたページ (->オリジナル) /