Skip to content

Commit 21436f3

Browse files
committed
[disjoint] Set default parameters for disjoint pool
1 parent 7fddd2c commit 21436f3

File tree

4 files changed

+143
-6
lines changed

4 files changed

+143
-6
lines changed

include/umf/pools/pool_disjoint.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ umf_result_t
5252
umfDisjointPoolParamsDestroy(umf_disjoint_pool_params_handle_t hParams);
5353

5454
/// @brief Set minimum allocation size that will be requested from the memory provider.
55+
/// @details Default value for minimum size of slab's is 64KB.
5556
/// @param hParams handle to the parameters of the disjoint pool.
5657
/// @param slabMinSize minimum allocation size.
5758
/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
@@ -60,6 +61,7 @@ umfDisjointPoolParamsSetSlabMinSize(umf_disjoint_pool_params_handle_t hParams,
6061
size_t slabMinSize);
6162

6263
/// @brief Set size limit for allocations that are subject to pooling.
64+
/// @details Default value for maximum poolable size is 2MB.
6365
/// @param hParams handle to the parameters of the disjoint pool.
6466
/// @param maxPoolableSize maximum poolable size.
6567
/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
@@ -68,6 +70,7 @@ umf_result_t umfDisjointPoolParamsSetMaxPoolableSize(
6870

6971
/// @brief Set maximum capacity of each bucket. Each bucket will hold a
7072
/// max of \p maxCapacity unfreed slabs.
73+
/// @details Default value for capacity is 4.
7174
/// @param hParams handle to the parameters of the disjoint pool.
7275
/// @param maxCapacity maximum capacity of each bucket.
7376
/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure.

src/pool/pool_disjoint.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,9 +1085,9 @@ umfDisjointPoolParamsCreate(umf_disjoint_pool_params_handle_t *hParams) {
10851085
}
10861086

10871087
*params = (umf_disjoint_pool_params_t){
1088-
.slab_min_size = 0,
1089-
.max_poolable_size = 0,
1090-
.capacity = 0,
1088+
.slab_min_size = 64 * 1024, // 64K
1089+
.max_poolable_size = 2 * 1024 * 1024, // 2MB
1090+
.capacity = 4,
10911091
.min_bucket_size = UMF_DISJOINT_POOL_MIN_BUCKET_DEFAULT_SIZE,
10921092
.cur_pool_size = 0,
10931093
.pool_trace = 0,

src/pool/pool_disjoint_internal.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,13 @@ typedef struct umf_disjoint_pool_shared_limits_t {
110110

111111
typedef struct umf_disjoint_pool_params_t {
112112
// Minimum allocation size that will be requested from the memory provider.
113-
size_t slab_min_size;
113+
size_t slab_min_size; // Default: 64KB
114114

115115
// Allocations up to this limit will be subject to chunking/pooling
116-
size_t max_poolable_size;
116+
size_t max_poolable_size; // Default: 2MB
117117

118118
// When pooling, each bucket will hold a max of 'capacity' unfreed slabs
119-
size_t capacity;
119+
size_t capacity; // Default: 4
120120

121121
// Holds the minimum bucket size valid for allocation of a memory type.
122122
// This value must be a power of 2.

test/pools/disjoint_pool.cpp

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,140 @@ TEST_F(test, disjointPoolName) {
356356
umfDisjointPoolParamsDestroy(params);
357357
}
358358

359+
TEST_F(test, disjointPoolDefaultParams) {
360+
// Disjoint pool defaults
361+
static constexpr size_t DefaultSlabMinSize = 64 * 1024; // 64K
362+
static constexpr size_t DefaultMaxPoolableSize = 2 * 1024 * 1024; // 2MB
363+
364+
umf_disjoint_pool_params_handle_t params = nullptr;
365+
umf_memory_pool_handle_t pool = nullptr;
366+
umf_memory_provider_handle_t provider_handle = nullptr;
367+
368+
// Create disjoint pool parameters with default settings
369+
umf_result_t res = umfDisjointPoolParamsCreate(&params);
370+
EXPECT_EQ(res, UMF_RESULT_SUCCESS);
371+
372+
int expected_free_counter = 0;
373+
static size_t free_counter = 0;
374+
static size_t last_requested_size = 0;
375+
struct memory_provider : public umf_test::provider_base_t {
376+
umf_result_t alloc(size_t size, size_t alignment, void **ptr) noexcept {
377+
*ptr = umf_ba_global_aligned_alloc(size, alignment);
378+
last_requested_size = size;
379+
return UMF_RESULT_SUCCESS;
380+
}
381+
382+
umf_result_t free(void *ptr, [[maybe_unused]] size_t size) noexcept {
383+
// do the actual free only when we expect the success
384+
umf_ba_global_free(ptr);
385+
free_counter++;
386+
return UMF_RESULT_SUCCESS;
387+
}
388+
};
389+
390+
umf_memory_provider_ops_t provider_ops =
391+
umf_test::providerMakeCOps<memory_provider, void>();
392+
393+
auto providerUnique =
394+
wrapProviderUnique(createProviderChecked(&provider_ops, nullptr));
395+
provider_handle = providerUnique.get();
396+
397+
res = umfDisjointPoolParamsSetTrace(params, 3);
398+
ASSERT_EQ(res, UMF_RESULT_SUCCESS);
399+
400+
umf_result_t ret = umfPoolCreate(umfDisjointPoolOps(), provider_handle,
401+
params, UMF_POOL_CREATE_FLAG_NONE, &pool);
402+
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
403+
404+
// Test allocation and deallocation
405+
// This will use the default disjoint pool parameters
406+
void *ptr = umfPoolMalloc(pool, DefaultSlabMinSize - 1); // Should use pool
407+
ASSERT_NE(ptr, nullptr);
408+
ASSERT_EQ(
409+
last_requested_size,
410+
DefaultSlabMinSize); // First allocated size should be at least the slab min size
411+
ret = umfPoolFree(pool, ptr);
412+
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
413+
ASSERT_EQ(free_counter, expected_free_counter);
414+
415+
// Test allocation and deallocation with a different size
416+
expected_free_counter = 1;
417+
ptr =
418+
umfPoolMalloc(pool, DefaultMaxPoolableSize + 1); // Fallback to provider
419+
ASSERT_EQ(last_requested_size, DefaultMaxPoolableSize + 1);
420+
ASSERT_NE(ptr, nullptr);
421+
ret = umfPoolFree(pool, ptr);
422+
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
423+
ASSERT_EQ(free_counter, expected_free_counter);
424+
425+
// Cleaning up
426+
umfPoolDestroy(pool);
427+
umfDisjointPoolParamsDestroy(params);
428+
expected_free_counter = 2;
429+
ASSERT_EQ(free_counter, expected_free_counter);
430+
}
431+
432+
TEST_F(test, disjointPoolDefaultCapacity) {
433+
// Disjoint pool defaults
434+
static constexpr size_t DefaultSlabMinSize = 64 * 1024; // 64K
435+
static constexpr size_t DefaultCapacity = 4;
436+
437+
static size_t free_counter = 0;
438+
static size_t last_requested_size = 0;
439+
440+
struct memory_provider : public umf_test::provider_base_t {
441+
umf_result_t alloc(size_t size, size_t alignment, void **ptr) noexcept {
442+
*ptr = umf_ba_global_aligned_alloc(size, alignment);
443+
last_requested_size = size;
444+
return UMF_RESULT_SUCCESS;
445+
}
446+
umf_result_t free(void *ptr, [[maybe_unused]] size_t size) noexcept {
447+
// do the actual free only when we expect the success
448+
umf_ba_global_free(ptr);
449+
free_counter++;
450+
return UMF_RESULT_SUCCESS;
451+
}
452+
};
453+
umf_memory_provider_ops_t provider_ops =
454+
umf_test::providerMakeCOps<memory_provider, void>();
455+
auto providerUnique =
456+
wrapProviderUnique(createProviderChecked(&provider_ops, nullptr));
457+
umf_memory_provider_handle_t provider_handle = providerUnique.get();
458+
umf_disjoint_pool_params_handle_t params = nullptr;
459+
umf_result_t ret = umfDisjointPoolParamsCreate(&params);
460+
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
461+
462+
umf_memory_pool_handle_t pool = nullptr;
463+
ret = umfPoolCreate(umfDisjointPoolOps(), provider_handle, params,
464+
UMF_POOL_CREATE_FLAG_NONE, &pool);
465+
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
466+
467+
// Test capacity
468+
void *ptrs[DefaultCapacity + 1];
469+
for (size_t i = 0; i < DefaultCapacity + 1; ++i) {
470+
ptrs[i] =
471+
umfPoolMalloc(pool, DefaultSlabMinSize - 1); // Should use pool
472+
ASSERT_NE(ptrs[i], nullptr);
473+
ASSERT_EQ(last_requested_size, DefaultSlabMinSize);
474+
}
475+
476+
size_t i;
477+
for (i = 0; i < DefaultCapacity + 1; ++i) {
478+
ret = umfPoolFree(pool, ptrs[i]);
479+
ASSERT_EQ(ret, UMF_RESULT_SUCCESS);
480+
}
481+
ASSERT_EQ(
482+
free_counter,
483+
i - DefaultCapacity); // only the last allocation exceeds the capacity
484+
485+
// Cleaning up
486+
umfPoolDestroy(pool);
487+
umfDisjointPoolParamsDestroy(params);
488+
ASSERT_EQ(free_counter,
489+
DefaultCapacity +
490+
1); // +1 for the last allocation that exceeded the capacity
491+
}
492+
359493
INSTANTIATE_TEST_SUITE_P(disjointPoolTests, umfPoolTest,
360494
::testing::Values(poolCreateExtParams{
361495
umfDisjointPoolOps(), defaultDisjointPoolConfig,

0 commit comments

Comments
 (0)