Skip to content

Commit 249c364

Browse files
committed
implement malloc_usable_size and enable pool tests for disjoint
1 parent 7e68cc8 commit 249c364

File tree

5 files changed

+131
-82
lines changed

5 files changed

+131
-82
lines changed

src/pool/pool_disjoint.c

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -752,8 +752,10 @@ void *disjoint_pool_aligned_malloc(void *pool, size_t size, size_t alignment) {
752752
}
753753

754754
void *aligned_ptr = (void *)ALIGN_UP_SAFE((size_t)ptr, alignment);
755-
VALGRIND_DO_MEMPOOL_ALLOC(disjoint_pool, aligned_ptr, size);
756-
utils_annotate_memory_undefined(aligned_ptr, size);
755+
size_t diff = (ptrdiff_t)aligned_ptr - (ptrdiff_t)ptr;
756+
size_t real_size = bucket->size - diff;
757+
VALGRIND_DO_MEMPOOL_ALLOC(disjoint_pool, aligned_ptr, real_size);
758+
utils_annotate_memory_undefined(aligned_ptr, real_size);
757759

758760
utils_mutex_unlock(&bucket->bucket_lock);
759761

@@ -767,11 +769,34 @@ void *disjoint_pool_aligned_malloc(void *pool, size_t size, size_t alignment) {
767769
}
768770

769771
size_t disjoint_pool_malloc_usable_size(void *pool, void *ptr) {
770-
(void)pool;
771-
(void)ptr;
772+
disjoint_pool_t *disjoint_pool = (disjoint_pool_t *)pool;
773+
if (ptr == NULL) {
774+
return 0;
775+
}
772776

773-
// Not supported
774-
return 0;
777+
// check if given pointer is allocated inside any Disjoint Pool slab
778+
slab_t *slab =
779+
(slab_t *)critnib_find_le(disjoint_pool->known_slabs, (uintptr_t)ptr);
780+
if (slab == NULL || ptr >= slab_get_end(slab)) {
781+
// memory comes directly from the provider
782+
umf_alloc_info_t allocInfo = {NULL, 0, NULL};
783+
umf_result_t ret = umfMemoryTrackerGetAllocInfo(ptr, &allocInfo);
784+
if (ret != UMF_RESULT_SUCCESS) {
785+
return 0;
786+
}
787+
788+
return allocInfo.baseSize;
789+
}
790+
// Get the unaligned pointer
791+
// NOTE: the base pointer slab->mem_ptr needn't to be aligned to bucket size
792+
size_t chunk_idx =
793+
(((uintptr_t)ptr - (uintptr_t)slab->mem_ptr) / slab->bucket->size);
794+
void *unaligned_ptr =
795+
(void *)((uintptr_t)slab->mem_ptr + chunk_idx * slab->bucket->size);
796+
797+
ptrdiff_t diff = (ptrdiff_t)ptr - (ptrdiff_t)unaligned_ptr;
798+
799+
return slab->bucket->size - diff;
775800
}
776801

777802
umf_result_t disjoint_pool_free(void *pool, void *ptr) {

test/common/pool.hpp

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
*
3-
* Copyright (C) 2023-2024 Intel Corporation
3+
* Copyright (C) 2023-2025 Intel Corporation
44
*
55
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
66
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -19,6 +19,7 @@
1919

2020
#include <umf/base.h>
2121
#include <umf/memory_provider.h>
22+
#include <umf/pools/pool_disjoint.h>
2223

2324
#include "base.hpp"
2425
#include "cpp_helpers.hpp"
@@ -150,6 +151,49 @@ struct malloc_pool : public pool_base_t {
150151
umf_memory_pool_ops_t MALLOC_POOL_OPS =
151152
umf::poolMakeCOps<umf_test::malloc_pool, void>();
152153

154+
static constexpr size_t DEFAULT_DISJOINT_SLAB_MIN_SIZE = 4096;
155+
static constexpr size_t DEFAULT_DISJOINT_MAX_POOLABLE_SIZE = 4096;
156+
static constexpr size_t DEFAULT_DISJOINT_CAPACITY = 4;
157+
static constexpr size_t DEFAULT_DISJOINT_MIN_BUCKET_SIZE = 64;
158+
159+
inline void *defaultDisjointPoolConfig() {
160+
umf_disjoint_pool_params_handle_t config = nullptr;
161+
umf_result_t res = umfDisjointPoolParamsCreate(&config);
162+
if (res != UMF_RESULT_SUCCESS) {
163+
throw std::runtime_error("Failed to create pool params");
164+
}
165+
res = umfDisjointPoolParamsSetSlabMinSize(config,
166+
DEFAULT_DISJOINT_SLAB_MIN_SIZE);
167+
if (res != UMF_RESULT_SUCCESS) {
168+
umfDisjointPoolParamsDestroy(config);
169+
throw std::runtime_error("Failed to set slab min size");
170+
}
171+
res = umfDisjointPoolParamsSetMaxPoolableSize(
172+
config, DEFAULT_DISJOINT_MAX_POOLABLE_SIZE);
173+
if (res != UMF_RESULT_SUCCESS) {
174+
umfDisjointPoolParamsDestroy(config);
175+
throw std::runtime_error("Failed to set max poolable size");
176+
}
177+
res = umfDisjointPoolParamsSetCapacity(config, DEFAULT_DISJOINT_CAPACITY);
178+
if (res != UMF_RESULT_SUCCESS) {
179+
umfDisjointPoolParamsDestroy(config);
180+
throw std::runtime_error("Failed to set capacity");
181+
}
182+
res = umfDisjointPoolParamsSetMinBucketSize(
183+
config, DEFAULT_DISJOINT_MIN_BUCKET_SIZE);
184+
if (res != UMF_RESULT_SUCCESS) {
185+
umfDisjointPoolParamsDestroy(config);
186+
throw std::runtime_error("Failed to set min bucket size");
187+
}
188+
189+
return config;
190+
}
191+
192+
inline umf_result_t defaultDisjointPoolConfigDestroy(void *config) {
193+
return umfDisjointPoolParamsDestroy(
194+
static_cast<umf_disjoint_pool_params_handle_t>(config));
195+
}
196+
153197
} // namespace umf_test
154198

155199
#endif /* UMF_TEST_POOL_HPP */

test/memoryPoolAPI.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "test_helpers.h"
1313

1414
#include <umf/memory_provider.h>
15+
#include <umf/pools/pool_disjoint.h>
1516
#include <umf/pools/pool_proxy.h>
1617

1718
#ifdef UMF_PROXY_LIB_ENABLED
@@ -295,12 +296,14 @@ TEST_F(tagTest, SetAndGetInvalidPool) {
295296

296297
INSTANTIATE_TEST_SUITE_P(
297298
mallocPoolTest, umfPoolTest,
298-
::testing::Values(poolCreateExtParams{&MALLOC_POOL_OPS, nullptr, nullptr,
299-
&UMF_NULL_PROVIDER_OPS, nullptr,
300-
nullptr},
301-
poolCreateExtParams{umfProxyPoolOps(), nullptr, nullptr,
302-
&BA_GLOBAL_PROVIDER_OPS, nullptr,
303-
nullptr}));
299+
::testing::Values(
300+
poolCreateExtParams{&MALLOC_POOL_OPS, nullptr, nullptr,
301+
&UMF_NULL_PROVIDER_OPS, nullptr, nullptr},
302+
poolCreateExtParams{umfProxyPoolOps(), nullptr, nullptr,
303+
&BA_GLOBAL_PROVIDER_OPS, nullptr, nullptr},
304+
poolCreateExtParams{umfDisjointPoolOps(), defaultDisjointPoolConfig,
305+
defaultDisjointPoolConfigDestroy,
306+
&BA_GLOBAL_PROVIDER_OPS, nullptr, nullptr}));
304307

305308
INSTANTIATE_TEST_SUITE_P(mallocMultiPoolTest, umfMultiPoolTest,
306309
::testing::Values(poolCreateExtParams{

test/poolFixtures.hpp

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -452,26 +452,45 @@ TEST_P(umfPoolTest, allocMaxSize) {
452452
}
453453

454454
TEST_P(umfPoolTest, mallocUsableSize) {
455+
[[maybe_unused]] auto pool_ops = std::get<0>(this->GetParam());
456+
#ifdef _WIN32
457+
if (pool_ops == &umf_test::MALLOC_POOL_OPS) {
458+
GTEST_SKIP()
459+
<< "Windows Malloc Pool does not support umfPoolAlignedMalloc";
460+
}
461+
#endif
462+
if (!umf_test::isAlignedAllocSupported(pool.get())) {
463+
GTEST_SKIP();
464+
}
455465
#ifdef __SANITIZE_ADDRESS__
456-
// Sanitizer replaces malloc_usable_size implementation with its own
457-
GTEST_SKIP()
458-
<< "This test is invalid with AddressSanitizer instrumentation";
459-
#else
466+
if (pool_ops == &umf_test::MALLOC_POOL_OPS) {
467+
// Sanitizer replaces malloc_usable_size implementation with its own
468+
GTEST_SKIP()
469+
<< "This test is invalid with AddressSanitizer instrumentation";
470+
}
471+
#endif
472+
for (size_t allocSize :
473+
{32, 64, 1 << 6, 1 << 10, 1 << 13, 1 << 16, 1 << 19}) {
474+
for (size_t alignment : {0, 1 << 6, 1 << 8, 1 << 12}) {
475+
if (alignment >= allocSize) {
476+
continue;
477+
}
478+
void *ptr = nullptr;
479+
if (alignment == 0) {
480+
ptr = umfPoolMalloc(pool.get(), allocSize);
481+
} else {
482+
ptr = umfPoolAlignedMalloc(pool.get(), allocSize, alignment);
483+
}
484+
ASSERT_NE(ptr, nullptr);
485+
size_t result = umfPoolMallocUsableSize(pool.get(), ptr);
486+
ASSERT_TRUE(result == 0 || result >= allocSize);
460487

461-
for (size_t allocSize : {32, 48, 1024, 8192}) {
462-
char *ptr = static_cast<char *>(umfPoolMalloc(pool.get(), allocSize));
463-
ASSERT_NE(ptr, nullptr);
464-
size_t result = umfPoolMallocUsableSize(pool.get(), ptr);
465-
ASSERT_TRUE(result == 0 || result >= allocSize);
488+
// Make sure we can write to this memory
489+
memset(ptr, 123, result);
466490

467-
// Make sure we can write to this memory
468-
for (size_t i = 0; i < result; i++) {
469-
ptr[i] = 123;
491+
umfPoolFree(pool.get(), ptr);
470492
}
471-
472-
umfPoolFree(pool.get(), ptr);
473493
}
474-
#endif
475494
}
476495

477496
#endif /* UMF_TEST_POOL_FIXTURES_HPP */

test/pools/disjoint_pool.cpp

Lines changed: 12 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -13,49 +13,6 @@
1313
#include "provider_null.h"
1414
#include "provider_trace.h"
1515

16-
static constexpr size_t DEFAULT_DISJOINT_SLAB_MIN_SIZE = 4096;
17-
static constexpr size_t DEFAULT_DISJOINT_MAX_POOLABLE_SIZE = 4096;
18-
static constexpr size_t DEFAULT_DISJOINT_CAPACITY = 4;
19-
static constexpr size_t DEFAULT_DISJOINT_MIN_BUCKET_SIZE = 64;
20-
21-
void *defaultPoolConfig() {
22-
umf_disjoint_pool_params_handle_t config = nullptr;
23-
umf_result_t res = umfDisjointPoolParamsCreate(&config);
24-
if (res != UMF_RESULT_SUCCESS) {
25-
throw std::runtime_error("Failed to create pool params");
26-
}
27-
res = umfDisjointPoolParamsSetSlabMinSize(config,
28-
DEFAULT_DISJOINT_SLAB_MIN_SIZE);
29-
if (res != UMF_RESULT_SUCCESS) {
30-
umfDisjointPoolParamsDestroy(config);
31-
throw std::runtime_error("Failed to set slab min size");
32-
}
33-
res = umfDisjointPoolParamsSetMaxPoolableSize(
34-
config, DEFAULT_DISJOINT_MAX_POOLABLE_SIZE);
35-
if (res != UMF_RESULT_SUCCESS) {
36-
umfDisjointPoolParamsDestroy(config);
37-
throw std::runtime_error("Failed to set max poolable size");
38-
}
39-
res = umfDisjointPoolParamsSetCapacity(config, DEFAULT_DISJOINT_CAPACITY);
40-
if (res != UMF_RESULT_SUCCESS) {
41-
umfDisjointPoolParamsDestroy(config);
42-
throw std::runtime_error("Failed to set capacity");
43-
}
44-
res = umfDisjointPoolParamsSetMinBucketSize(
45-
config, DEFAULT_DISJOINT_MIN_BUCKET_SIZE);
46-
if (res != UMF_RESULT_SUCCESS) {
47-
umfDisjointPoolParamsDestroy(config);
48-
throw std::runtime_error("Failed to set min bucket size");
49-
}
50-
51-
return config;
52-
}
53-
54-
umf_result_t poolConfigDestroy(void *config) {
55-
return umfDisjointPoolParamsDestroy(
56-
static_cast<umf_disjoint_pool_params_handle_t>(config));
57-
}
58-
5916
using umf_test::test;
6017
using namespace umf_test;
6118

@@ -92,7 +49,7 @@ TEST_F(test, internals) {
9249
provider_handle = providerUnique.get();
9350

9451
umf_disjoint_pool_params_handle_t params =
95-
(umf_disjoint_pool_params_handle_t)defaultPoolConfig();
52+
(umf_disjoint_pool_params_handle_t)defaultDisjointPoolConfig();
9653
// set to maximum tracing
9754
params->pool_trace = 3;
9855
params->max_poolable_size = 1024 * 1024;
@@ -256,7 +213,7 @@ TEST_F(test, sharedLimits) {
256213
static constexpr size_t MaxSize = 4 * SlabMinSize;
257214

258215
umf_disjoint_pool_params_handle_t params =
259-
(umf_disjoint_pool_params_handle_t)defaultPoolConfig();
216+
(umf_disjoint_pool_params_handle_t)defaultDisjointPoolConfig();
260217
umf_result_t ret = umfDisjointPoolParamsSetSlabMinSize(params, SlabMinSize);
261218
EXPECT_EQ(ret, UMF_RESULT_SUCCESS);
262219

@@ -373,22 +330,23 @@ TEST_F(test, disjointPoolInvalidBucketSize) {
373330

374331
INSTANTIATE_TEST_SUITE_P(disjointPoolTests, umfPoolTest,
375332
::testing::Values(poolCreateExtParams{
376-
umfDisjointPoolOps(), defaultPoolConfig,
377-
poolConfigDestroy, &BA_GLOBAL_PROVIDER_OPS,
378-
nullptr, nullptr}));
333+
umfDisjointPoolOps(), defaultDisjointPoolConfig,
334+
defaultDisjointPoolConfigDestroy,
335+
&BA_GLOBAL_PROVIDER_OPS, nullptr, nullptr}));
379336

380337
void *memProviderParams() { return (void *)&DEFAULT_DISJOINT_CAPACITY; }
381338

382339
INSTANTIATE_TEST_SUITE_P(
383340
disjointPoolTests, umfMemTest,
384341
::testing::Values(std::make_tuple(
385-
poolCreateExtParams{umfDisjointPoolOps(), defaultPoolConfig,
386-
poolConfigDestroy, &MOCK_OUT_OF_MEM_PROVIDER_OPS,
387-
memProviderParams, nullptr},
342+
poolCreateExtParams{umfDisjointPoolOps(), defaultDisjointPoolConfig,
343+
defaultDisjointPoolConfigDestroy,
344+
&MOCK_OUT_OF_MEM_PROVIDER_OPS, memProviderParams,
345+
nullptr},
388346
static_cast<int>(DEFAULT_DISJOINT_CAPACITY) / 2)));
389347

390348
INSTANTIATE_TEST_SUITE_P(disjointMultiPoolTests, umfMultiPoolTest,
391349
::testing::Values(poolCreateExtParams{
392-
umfDisjointPoolOps(), defaultPoolConfig,
393-
poolConfigDestroy, &BA_GLOBAL_PROVIDER_OPS,
394-
nullptr, nullptr}));
350+
umfDisjointPoolOps(), defaultDisjointPoolConfig,
351+
defaultDisjointPoolConfigDestroy,
352+
&BA_GLOBAL_PROVIDER_OPS, nullptr, nullptr}));

0 commit comments

Comments
 (0)