diff options
author | Masahiko Sawada <msawada@postgresql.org> | 2024-03-27 11:43:29 +0900 |
---|---|---|
committer | Masahiko Sawada <msawada@postgresql.org> | 2024-03-27 11:43:29 +0900 |
commit | bb952c8c8b13279eca039499249cb5dc60991603 (patch) | |
tree | ba7cc3ced86501cb0da23a66b9170ffae19dcf6c /src/include/utils/dsa.h | |
parent | 1f42337be535243e665f85916ce21b2d85d9f2b3 (diff) |
Allow specifying initial and maximum segment sizes for DSA.
Previously, the DSA segment size always started with 1MB and grew up
to DSA_MAX_SEGMENT_SIZE. It was inconvenient in certain scenarios,
such as when the caller desired a soft constraint on the total DSA
segment size, limiting it to less than 1MB.
This commit introduces the capability to specify the initial and
maximum DSA segment sizes when creating a DSA area, providing more
flexibility and control over memory usage.
Reviewed-by: John Naylor, Tomas Vondra
Discussion: https://postgr.es/m/CAD21AoAYGGC1ePjVX0H%2Bpp9rH%3D9vuPK19nNOiu12NprdV5TVJA%40mail.gmail.com
Diffstat (limited to 'src/include/utils/dsa.h')
-rw-r--r-- | src/include/utils/dsa.h | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/src/include/utils/dsa.h b/src/include/utils/dsa.h index fe9cbebbec1..8dff964bf33 100644 --- a/src/include/utils/dsa.h +++ b/src/include/utils/dsa.h @@ -77,6 +77,31 @@ typedef pg_atomic_uint64 dsa_pointer_atomic; /* A sentinel value for dsa_pointer used to indicate failure to allocate. */ #define InvalidDsaPointer ((dsa_pointer) 0) +/* + * The number of bits used to represent the offset part of a dsa_pointer. + * This controls the maximum size of a segment, the maximum possible + * allocation size and also the maximum number of segments per area. + */ +#if SIZEOF_DSA_POINTER == 4 +#define DSA_OFFSET_WIDTH 27 /* 32 segments of size up to 128MB */ +#else +#define DSA_OFFSET_WIDTH 40 /* 1024 segments of size up to 1TB */ +#endif + +/* + * The default size of the initial DSM segment that backs a dsa_area created + * by dsa_create. After creating some number of segments of the initial size + * we'll double this size, and so on. Larger segments may be created if + * necessary to satisfy large requests. + */ +#define DSA_DEFAULT_INIT_SEGMENT_SIZE ((size_t) (1 * 1024 * 1024)) + +/* The minimum size of a DSM segment. */ +#define DSA_MIN_SEGMENT_SIZE ((size_t) (256 * 1024L)) + +/* The maximum size of a DSM segment. */ +#define DSA_MAX_SEGMENT_SIZE ((size_t) 1 << DSA_OFFSET_WIDTH) + /* Check if a dsa_pointer value is valid. */ #define DsaPointerIsValid(x) ((x) != InvalidDsaPointer) @@ -88,6 +113,17 @@ typedef pg_atomic_uint64 dsa_pointer_atomic; #define dsa_allocate0(area, size) \ dsa_allocate_extended(area, size, DSA_ALLOC_ZERO) +/* Create dsa_area with default segment sizes */ +#define dsa_create(tranch_id) \ + dsa_create_ext(tranch_id, DSA_DEFAULT_INIT_SEGMENT_SIZE, \ + DSA_MAX_SEGMENT_SIZE) + +/* Create dsa_area with default segment sizes in an existing share memory space */ +#define dsa_create_in_place(place, size, tranch_id, segment) \ + dsa_create_in_place_ext(place, size, tranch_id, segment, \ + DSA_DEFAULT_INIT_SEGMENT_SIZE, \ + DSA_MAX_SEGMENT_SIZE) + /* * The type used for dsa_area handles. dsa_handle values can be shared with * other processes, so that they can attach to them. This provides a way to @@ -102,10 +138,12 @@ typedef dsm_handle dsa_handle; /* Sentinel value to use for invalid dsa_handles. */ #define DSA_HANDLE_INVALID ((dsa_handle) DSM_HANDLE_INVALID) - -extern dsa_area *dsa_create(int tranche_id); -extern dsa_area *dsa_create_in_place(void *place, size_t size, - int tranche_id, dsm_segment *segment); +extern dsa_area *dsa_create_ext(int tranche_id, size_t init_segment_size, + size_t max_segment_size); +extern 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); extern dsa_area *dsa_attach(dsa_handle handle); extern dsa_area *dsa_attach_in_place(void *place, dsm_segment *segment); extern void dsa_release_in_place(void *place); |