59
59
#include "utils/memutils.h"
60
60
#include "utils/resowner.h"
61
61
62
- /*
63
- * The size of the initial DSM segment that backs a dsa_area created by
64
- * dsa_create. After creating some number of segments of this size we'll
65
- * double this size, and so on. Larger segments may be created if necessary
66
- * to satisfy large requests.
67
- */
68
- #define DSA_INITIAL_SEGMENT_SIZE ((size_t) (1 * 1024 * 1024))
69
-
70
62
/*
71
63
* How many segments to create before we double the segment size. If this is
72
64
* low, then there is likely to be a lot of wasted space in the largest
76
68
*/
77
69
#define DSA_NUM_SEGMENTS_AT_EACH_SIZE 2
78
70
79
- /*
80
- * The number of bits used to represent the offset part of a dsa_pointer.
81
- * This controls the maximum size of a segment, the maximum possible
82
- * allocation size and also the maximum number of segments per area.
83
- */
84
- #if SIZEOF_DSA_POINTER == 4
85
- #define DSA_OFFSET_WIDTH 27 /* 32 segments of size up to 128MB */
86
- #else
87
- #define DSA_OFFSET_WIDTH 40 /* 1024 segments of size up to 1TB */
88
- #endif
89
-
90
71
/*
91
72
* The maximum number of DSM segments that an area can own, determined by
92
73
* the number of bits remaining (but capped at 1024).
97
78
/* The bitmask for extracting the offset from a dsa_pointer. */
98
79
#define DSA_OFFSET_BITMASK (((dsa_pointer) 1 << DSA_OFFSET_WIDTH) - 1)
99
80
100
- /* The maximum size of a DSM segment. */
101
- #define DSA_MAX_SEGMENT_SIZE ((size_t) 1 << DSA_OFFSET_WIDTH)
102
-
103
81
/* Number of pages (see FPM_PAGE_SIZE) per regular superblock. */
104
82
#define DSA_PAGES_PER_SUPERBLOCK 16
105
83
@@ -318,6 +296,10 @@ typedef struct
318
296
dsa_segment_index segment_bins [DSA_NUM_SEGMENT_BINS ];
319
297
/* The object pools for each size class. */
320
298
dsa_area_pool pools [DSA_NUM_SIZE_CLASSES ];
299
+ /* initial allocation segment size */
300
+ size_t init_segment_size ;
301
+ /* maximum allocation segment size */
302
+ size_t max_segment_size ;
321
303
/* The total size of all active segments. */
322
304
size_t total_segment_size ;
323
305
/* The maximum total size of backing storage we are allowed. */
@@ -417,7 +399,9 @@ static dsa_segment_map *make_new_segment(dsa_area *area, size_t requested_pages)
417
399
static dsa_area * create_internal (void * place , size_t size ,
418
400
int tranche_id ,
419
401
dsm_handle control_handle ,
420
- dsm_segment * control_segment );
402
+ dsm_segment * control_segment ,
403
+ size_t init_segment_size ,
404
+ size_t max_segment_size );
421
405
static dsa_area * attach_internal (void * place , dsm_segment * segment ,
422
406
dsa_handle handle );
423
407
static void check_for_freed_segments (dsa_area * area );
@@ -434,7 +418,7 @@ static void rebin_segment(dsa_area *area, dsa_segment_map *segment_map);
434
418
* we require the caller to provide one.
435
419
*/
436
420
dsa_area *
437
- dsa_create (int tranche_id )
421
+ dsa_create_ext (int tranche_id , size_t init_segment_size , size_t max_segment_size )
438
422
{
439
423
dsm_segment * segment ;
440
424
dsa_area * area ;
@@ -443,7 +427,7 @@ dsa_create(int tranche_id)
443
427
* Create the DSM segment that will hold the shared control object and the
444
428
* first segment of usable space.
445
429
*/
446
- segment = dsm_create (DSA_INITIAL_SEGMENT_SIZE , 0 );
430
+ segment = dsm_create (init_segment_size , 0 );
447
431
448
432
/*
449
433
* All segments backing this area are pinned, so that DSA can explicitly
@@ -455,9 +439,10 @@ dsa_create(int tranche_id)
455
439
456
440
/* Create a new DSA area with the control object in this segment. */
457
441
area = create_internal (dsm_segment_address (segment ),
458
- DSA_INITIAL_SEGMENT_SIZE ,
442
+ init_segment_size ,
459
443
tranche_id ,
460
- dsm_segment_handle (segment ), segment );
444
+ dsm_segment_handle (segment ), segment ,
445
+ init_segment_size , max_segment_size );
461
446
462
447
/* Clean up when the control segment detaches. */
463
448
on_dsm_detach (segment , & dsa_on_dsm_detach_release_in_place ,
@@ -483,13 +468,15 @@ dsa_create(int tranche_id)
483
468
* See dsa_create() for a note about the tranche arguments.
484
469
*/
485
470
dsa_area *
486
- dsa_create_in_place (void * place , size_t size ,
487
- int tranche_id , dsm_segment * segment )
471
+ dsa_create_in_place_ext (void * place , size_t size ,
472
+ int tranche_id , dsm_segment * segment ,
473
+ size_t init_segment_size , size_t max_segment_size )
488
474
{
489
475
dsa_area * area ;
490
476
491
477
area = create_internal (place , size , tranche_id ,
492
- DSM_HANDLE_INVALID , NULL );
478
+ DSM_HANDLE_INVALID , NULL ,
479
+ init_segment_size , max_segment_size );
493
480
494
481
/*
495
482
* Clean up when the control segment detaches, if a containing DSM segment
@@ -1231,7 +1218,8 @@ static dsa_area *
1231
1218
create_internal (void * place , size_t size ,
1232
1219
int tranche_id ,
1233
1220
dsm_handle control_handle ,
1234
- dsm_segment * control_segment )
1221
+ dsm_segment * control_segment ,
1222
+ size_t init_segment_size , size_t max_segment_size )
1235
1223
{
1236
1224
dsa_area_control * control ;
1237
1225
dsa_area * area ;
@@ -1241,6 +1229,11 @@ create_internal(void *place, size_t size,
1241
1229
size_t metadata_bytes ;
1242
1230
int i ;
1243
1231
1232
+ /* Check the initial and maximum block sizes */
1233
+ Assert (init_segment_size >= DSA_MIN_SEGMENT_SIZE );
1234
+ Assert (max_segment_size >= init_segment_size );
1235
+ Assert (max_segment_size <= DSA_MAX_SEGMENT_SIZE );
1236
+
1244
1237
/* Sanity check on the space we have to work in. */
1245
1238
if (size < dsa_minimum_size ())
1246
1239
elog (ERROR , "dsa_area space must be at least %zu, but %zu provided" ,
@@ -1270,8 +1263,10 @@ create_internal(void *place, size_t size,
1270
1263
control -> segment_header .prev = DSA_SEGMENT_INDEX_NONE ;
1271
1264
control -> segment_header .usable_pages = usable_pages ;
1272
1265
control -> segment_header .freed = false;
1273
- control -> segment_header .size = DSA_INITIAL_SEGMENT_SIZE ;
1266
+ control -> segment_header .size = size ;
1274
1267
control -> handle = control_handle ;
1268
+ control -> init_segment_size = init_segment_size ;
1269
+ control -> max_segment_size = max_segment_size ;
1275
1270
control -> max_total_segment_size = (size_t ) -1 ;
1276
1271
control -> total_segment_size = size ;
1277
1272
control -> segment_handles [0 ] = control_handle ;
@@ -2127,9 +2122,9 @@ make_new_segment(dsa_area *area, size_t requested_pages)
2127
2122
* move to huge pages in the future. Then we work back to the number of
2128
2123
* pages we can fit.
2129
2124
*/
2130
- total_size = DSA_INITIAL_SEGMENT_SIZE *
2125
+ total_size = area -> control -> init_segment_size *
2131
2126
((size_t ) 1 << (new_index / DSA_NUM_SEGMENTS_AT_EACH_SIZE ));
2132
- total_size = Min (total_size , DSA_MAX_SEGMENT_SIZE );
2127
+ total_size = Min (total_size , area -> control -> max_segment_size );
2133
2128
total_size = Min (total_size ,
2134
2129
area -> control -> max_total_segment_size -
2135
2130
area -> control -> total_segment_size );
0 commit comments