PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
dsa.h
Go to the documentation of this file.
1/*-------------------------------------------------------------------------
2 *
3 * dsa.h
4 * Dynamic shared memory areas.
5 *
6 * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
8 *
9 * IDENTIFICATION
10 * src/include/utils/dsa.h
11 *
12 *-------------------------------------------------------------------------
13 */
14#ifndef DSA_H
15#define DSA_H
16
17#include "port/atomics.h"
18#include "storage/dsm.h"
19
20/* The opaque type used for an area. */
21struct dsa_area;
22typedef struct dsa_area dsa_area;
23
24/*
25 * If this system only uses a 32-bit value for size_t, then use the 32-bit
26 * implementation of DSA. This limits the amount of DSA that can be created
27 * to something significantly less than the entire 4GB address space because
28 * the DSA pointer must encode both a segment identifier and an offset, but
29 * that shouldn't be a significant limitation in practice.
30 *
31 * If this system doesn't support atomic operations on 64-bit values, then
32 * we fall back to 32-bit dsa_pointer for lack of other options.
33 *
34 * For testing purposes, USE_SMALL_DSA_POINTER can be defined to force the use
35 * of 32-bit dsa_pointer even on systems capable of supporting a 64-bit
36 * dsa_pointer.
37 */
38#if SIZEOF_SIZE_T == 4 || !defined(PG_HAVE_ATOMIC_U64_SUPPORT) || \
39 defined(USE_SMALL_DSA_POINTER)
40#define SIZEOF_DSA_POINTER 4
41#else
42#define SIZEOF_DSA_POINTER 8
43#endif
44
45/*
46 * The type of 'relative pointers' to memory allocated by a dynamic shared
47 * area. dsa_pointer values can be shared with other processes, but must be
48 * converted to backend-local pointers before they can be dereferenced. See
49 * dsa_get_address. Also, an atomic version and appropriately sized atomic
50 * operations.
51 */
52#if SIZEOF_DSA_POINTER == 4
53typedef uint32 dsa_pointer;
55#define dsa_pointer_atomic_init pg_atomic_init_u32
56#define dsa_pointer_atomic_read pg_atomic_read_u32
57#define dsa_pointer_atomic_write pg_atomic_write_u32
58#define dsa_pointer_atomic_fetch_add pg_atomic_fetch_add_u32
59#define dsa_pointer_atomic_compare_exchange pg_atomic_compare_exchange_u32
60#define DSA_POINTER_FORMAT "%08x"
61#else
64#define dsa_pointer_atomic_init pg_atomic_init_u64
65#define dsa_pointer_atomic_read pg_atomic_read_u64
66#define dsa_pointer_atomic_write pg_atomic_write_u64
67#define dsa_pointer_atomic_fetch_add pg_atomic_fetch_add_u64
68#define dsa_pointer_atomic_compare_exchange pg_atomic_compare_exchange_u64
69#define DSA_POINTER_FORMAT "%016" PRIx64
70#endif
71
72/* Flags for dsa_allocate_extended. */
73#define DSA_ALLOC_HUGE 0x01 /* allow huge allocation (> 1 GB) */
74#define DSA_ALLOC_NO_OOM 0x02 /* no failure if out-of-memory */
75#define DSA_ALLOC_ZERO 0x04 /* zero allocated memory */
76
77/* A sentinel value for dsa_pointer used to indicate failure to allocate. */
78#define InvalidDsaPointer ((dsa_pointer) 0)
79
80/*
81 * The number of bits used to represent the offset part of a dsa_pointer.
82 * This controls the maximum size of a segment, the maximum possible
83 * allocation size and also the maximum number of segments per area.
84 */
85#if SIZEOF_DSA_POINTER == 4
86#define DSA_OFFSET_WIDTH 27 /* 32 segments of size up to 128MB */
87#else
88#define DSA_OFFSET_WIDTH 40 /* 1024 segments of size up to 1TB */
89#endif
90
91/*
92 * The default size of the initial DSM segment that backs a dsa_area created
93 * by dsa_create. After creating some number of segments of the initial size
94 * we'll double this size, and so on. Larger segments may be created if
95 * necessary to satisfy large requests.
96 */
97#define DSA_DEFAULT_INIT_SEGMENT_SIZE ((size_t) (1 * 1024 * 1024))
98
99/* The minimum size of a DSM segment. */
100#define DSA_MIN_SEGMENT_SIZE ((size_t) (256 * 1024L))
101
102/* The maximum size of a DSM segment. */
103#define DSA_MAX_SEGMENT_SIZE ((size_t) 1 << DSA_OFFSET_WIDTH)
104
105/* Check if a dsa_pointer value is valid. */
106#define DsaPointerIsValid(x) ((x) != InvalidDsaPointer)
107
108/* Allocate uninitialized memory with error on out-of-memory. */
109#define dsa_allocate(area, size) \
110 dsa_allocate_extended(area, size, 0)
111
112/* Allocate zero-initialized memory with error on out-of-memory. */
113#define dsa_allocate0(area, size) \
114 dsa_allocate_extended(area, size, DSA_ALLOC_ZERO)
115
116/* Create dsa_area with default segment sizes */
117#define dsa_create(tranch_id) \
118 dsa_create_ext(tranch_id, DSA_DEFAULT_INIT_SEGMENT_SIZE, \
119 DSA_MAX_SEGMENT_SIZE)
120
121/* Create dsa_area with default segment sizes in an existing share memory space */
122#define dsa_create_in_place(place, size, tranch_id, segment) \
123 dsa_create_in_place_ext(place, size, tranch_id, segment, \
124 DSA_DEFAULT_INIT_SEGMENT_SIZE, \
125 DSA_MAX_SEGMENT_SIZE)
126
127/*
128 * The type used for dsa_area handles. dsa_handle values can be shared with
129 * other processes, so that they can attach to them. This provides a way to
130 * share allocated storage with other processes.
131 *
132 * The handle for a dsa_area is currently implemented as the dsm_handle
133 * for the first DSM segment backing this dynamic storage area, but client
134 * code shouldn't assume that is true.
135 */
137
138/* Sentinel value to use for invalid dsa_handles. */
139#define DSA_HANDLE_INVALID ((dsa_handle) DSM_HANDLE_INVALID)
140
141extern dsa_area *dsa_create_ext(int tranche_id, size_t init_segment_size,
142 size_t max_segment_size);
143extern dsa_area *dsa_create_in_place_ext(void *place, size_t size,
144 int tranche_id, dsm_segment *segment,
145 size_t init_segment_size,
146 size_t max_segment_size);
147extern dsa_area *dsa_attach(dsa_handle handle);
148extern dsa_area *dsa_attach_in_place(void *place, dsm_segment *segment);
149extern void dsa_release_in_place(void *place);
152extern void dsa_pin_mapping(dsa_area *area);
153extern void dsa_detach(dsa_area *area);
154extern void dsa_pin(dsa_area *area);
155extern void dsa_unpin(dsa_area *area);
156extern void dsa_set_size_limit(dsa_area *area, size_t limit);
157extern size_t dsa_minimum_size(void);
159extern dsa_pointer dsa_allocate_extended(dsa_area *area, size_t size, int flags);
160extern void dsa_free(dsa_area *area, dsa_pointer dp);
161extern void *dsa_get_address(dsa_area *area, dsa_pointer dp);
162extern size_t dsa_get_total_size(dsa_area *area);
163extern void dsa_trim(dsa_area *area);
164extern void dsa_dump(dsa_area *area);
165
166#endif /* DSA_H */
uint64_t uint64
Definition: c.h:486
uint32_t uint32
Definition: c.h:485
uint64 dsa_pointer
Definition: dsa.h:62
dsa_area * dsa_attach(dsa_handle handle)
Definition: dsa.c:510
void dsa_trim(dsa_area *area)
Definition: dsa.c:1043
dsa_area * dsa_create_in_place_ext(void *place, size_t size, int tranche_id, dsm_segment *segment, size_t init_segment_size, size_t max_segment_size)
Definition: dsa.c:471
dsa_area * dsa_attach_in_place(void *place, dsm_segment *segment)
Definition: dsa.c:545
void * dsa_get_address(dsa_area *area, dsa_pointer dp)
Definition: dsa.c:942
dsa_pointer dsa_allocate_extended(dsa_area *area, size_t size, int flags)
Definition: dsa.c:671
size_t dsa_get_total_size(dsa_area *area)
Definition: dsa.c:1027
void dsa_on_shmem_exit_release_in_place(int, Datum)
Definition: dsa.c:590
dsm_handle dsa_handle
Definition: dsa.h:136
dsa_area * dsa_create_ext(int tranche_id, size_t init_segment_size, size_t max_segment_size)
Definition: dsa.c:421
void dsa_release_in_place(void *place)
Definition: dsa.c:605
void dsa_set_size_limit(dsa_area *area, size_t limit)
Definition: dsa.c:1018
pg_atomic_uint64 dsa_pointer_atomic
Definition: dsa.h:63
void dsa_unpin(dsa_area *area)
Definition: dsa.c:994
void dsa_pin_mapping(dsa_area *area)
Definition: dsa.c:635
void dsa_dump(dsa_area *area)
Definition: dsa.c:1088
void dsa_on_dsm_detach_release_in_place(dsm_segment *, Datum)
Definition: dsa.c:576
dsa_handle dsa_get_handle(dsa_area *area)
Definition: dsa.c:498
void dsa_detach(dsa_area *area)
Definition: dsa.c:1952
void dsa_free(dsa_area *area, dsa_pointer dp)
Definition: dsa.c:826
size_t dsa_minimum_size(void)
Definition: dsa.c:1196
void dsa_pin(dsa_area *area)
Definition: dsa.c:975
uint32 dsm_handle
Definition: dsm_impl.h:55
uintptr_t Datum
Definition: postgres.h:64
static pg_noinline void Size size
Definition: slab.c:607
Definition: dsa.c:348