Skip to content

Commit 2e740f6

Browse files
authored
Merge pull request #806 from ldorau/Add_parameter_to_destroy_upstream_memory_provider_in_finalize
Add parameter to destroy upstream_memory_provider in finalize()
2 parents 7ed8787 + 7a210f0 commit 2e740f6

File tree

3 files changed

+61
-4
lines changed

3 files changed

+61
-4
lines changed

include/umf/providers/provider_coarse.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ typedef struct coarse_memory_provider_params_t {
6969
/// the init_buffer is always used instead
7070
/// (regardless of the value of this parameter).
7171
bool immediate_init_from_upstream;
72+
73+
/// Destroy upstream_memory_provider in finalize().
74+
bool destroy_upstream_memory_provider;
7275
} coarse_memory_provider_params_t;
7376

7477
/// @brief Coarse Memory Provider stats (TODO move to CTL)

src/provider/provider_coarse.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@
3131
typedef struct coarse_memory_provider_t {
3232
umf_memory_provider_handle_t upstream_memory_provider;
3333

34+
// destroy upstream_memory_provider in finalize()
35+
bool destroy_upstream_memory_provider;
36+
3437
// memory allocation strategy
3538
coarse_memory_provider_strategy_t allocation_strategy;
3639

@@ -898,6 +901,13 @@ static umf_result_t coarse_memory_provider_initialize(void *params,
898901
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
899902
}
900903

904+
if (coarse_params->destroy_upstream_memory_provider &&
905+
!coarse_params->upstream_memory_provider) {
906+
LOG_ERR("destroy_upstream_memory_provider is true, but an upstream "
907+
"provider is not provided");
908+
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
909+
}
910+
901911
coarse_memory_provider_t *coarse_provider =
902912
umf_ba_global_alloc(sizeof(*coarse_provider));
903913
if (!coarse_provider) {
@@ -909,6 +919,8 @@ static umf_result_t coarse_memory_provider_initialize(void *params,
909919

910920
coarse_provider->upstream_memory_provider =
911921
coarse_params->upstream_memory_provider;
922+
coarse_provider->destroy_upstream_memory_provider =
923+
coarse_params->destroy_upstream_memory_provider;
912924
coarse_provider->allocation_strategy = coarse_params->allocation_strategy;
913925
coarse_provider->init_buffer = coarse_params->init_buffer;
914926

@@ -1081,6 +1093,11 @@ static void coarse_memory_provider_finalize(void *provider) {
10811093

10821094
umf_ba_global_free(coarse_provider->name);
10831095

1096+
if (coarse_provider->destroy_upstream_memory_provider &&
1097+
coarse_provider->upstream_memory_provider) {
1098+
umfMemoryProviderDestroy(coarse_provider->upstream_memory_provider);
1099+
}
1100+
10841101
umf_ba_global_free(coarse_provider);
10851102
}
10861103

test/disjointCoarseMallocPool.cpp

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ TEST_F(test, disjointCoarseMallocPool_name_upstream) {
5959
sizeof(coarse_memory_provider_params));
6060
coarse_memory_provider_params.upstream_memory_provider =
6161
malloc_memory_provider;
62+
coarse_memory_provider_params.destroy_upstream_memory_provider = true;
6263
coarse_memory_provider_params.immediate_init_from_upstream = true;
6364
coarse_memory_provider_params.init_buffer = nullptr;
6465
coarse_memory_provider_params.init_buffer_size = init_buffer_size;
@@ -75,7 +76,9 @@ TEST_F(test, disjointCoarseMallocPool_name_upstream) {
7576
0);
7677

7778
umfMemoryProviderDestroy(coarse_memory_provider);
78-
umfMemoryProviderDestroy(malloc_memory_provider);
79+
// malloc_memory_provider has already been destroyed
80+
// by umfMemoryProviderDestroy(coarse_memory_provider), because:
81+
// coarse_memory_provider_params.destroy_upstream_memory_provider = true;
7982
}
8083

8184
TEST_F(test, disjointCoarseMallocPool_name_no_upstream) {
@@ -129,6 +132,7 @@ TEST_P(CoarseWithMemoryStrategyTest, disjointCoarseMallocPool_basic) {
129132
coarse_memory_provider_params.allocation_strategy = allocation_strategy;
130133
coarse_memory_provider_params.upstream_memory_provider =
131134
malloc_memory_provider;
135+
coarse_memory_provider_params.destroy_upstream_memory_provider = true;
132136
coarse_memory_provider_params.immediate_init_from_upstream = true;
133137
coarse_memory_provider_params.init_buffer = nullptr;
134138
coarse_memory_provider_params.init_buffer_size = init_buffer_size;
@@ -150,7 +154,7 @@ TEST_P(CoarseWithMemoryStrategyTest, disjointCoarseMallocPool_basic) {
150154
umf_memory_pool_handle_t pool;
151155
umf_result = umfPoolCreate(umfDisjointPoolOps(), coarse_memory_provider,
152156
&disjoint_memory_pool_params,
153-
UMF_POOL_CREATE_FLAG_NONE, &pool);
157+
UMF_POOL_CREATE_FLAG_OWN_PROVIDER, &pool);
154158
ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS);
155159
ASSERT_NE(pool, nullptr);
156160

@@ -282,8 +286,10 @@ TEST_P(CoarseWithMemoryStrategyTest, disjointCoarseMallocPool_basic) {
282286
ASSERT_EQ(GetStats(prov).alloc_size, init_buffer_size);
283287

284288
umfPoolDestroy(pool);
285-
umfMemoryProviderDestroy(coarse_memory_provider);
286-
umfMemoryProviderDestroy(malloc_memory_provider);
289+
// Both coarse_memory_provider and malloc_memory_provider
290+
// have already been destroyed by umfPoolDestroy(), because:
291+
// UMF_POOL_CREATE_FLAG_OWN_PROVIDER was set in umfPoolCreate() and
292+
// coarse_memory_provider_params.destroy_upstream_memory_provider = true;
287293
}
288294

289295
TEST_P(CoarseWithMemoryStrategyTest, disjointCoarseMallocPool_simple1) {
@@ -760,6 +766,37 @@ TEST_P(CoarseWithMemoryStrategyTest, disjointCoarseMallocPool_wrong_params_4) {
760766
umfMemoryProviderDestroy(malloc_memory_provider);
761767
}
762768

769+
// wrong parameters: destroy_upstream_memory_provider is true, but an upstream provider is not provided
770+
TEST_P(CoarseWithMemoryStrategyTest, disjointCoarseMallocPool_wrong_params_5) {
771+
umf_result_t umf_result;
772+
773+
const size_t init_buffer_size = 20 * MB;
774+
775+
// Preallocate some memory
776+
std::unique_ptr<char[]> buffer(new char[init_buffer_size]);
777+
void *buf = buffer.get();
778+
ASSERT_NE(buf, nullptr);
779+
memset(buf, 0, init_buffer_size);
780+
781+
coarse_memory_provider_params_t coarse_memory_provider_params;
782+
// make sure there are no undefined members - prevent a UB
783+
memset(&coarse_memory_provider_params, 0,
784+
sizeof(coarse_memory_provider_params));
785+
coarse_memory_provider_params.allocation_strategy = allocation_strategy;
786+
coarse_memory_provider_params.upstream_memory_provider = nullptr;
787+
coarse_memory_provider_params.destroy_upstream_memory_provider = true;
788+
coarse_memory_provider_params.immediate_init_from_upstream = false;
789+
coarse_memory_provider_params.init_buffer = buf;
790+
coarse_memory_provider_params.init_buffer_size = init_buffer_size;
791+
792+
umf_memory_provider_handle_t coarse_memory_provider = nullptr;
793+
umf_result = umfMemoryProviderCreate(umfCoarseMemoryProviderOps(),
794+
&coarse_memory_provider_params,
795+
&coarse_memory_provider);
796+
ASSERT_EQ(umf_result, UMF_RESULT_ERROR_INVALID_ARGUMENT);
797+
ASSERT_EQ(coarse_memory_provider, nullptr);
798+
}
799+
763800
TEST_P(CoarseWithMemoryStrategyTest, disjointCoarseMallocPool_split_merge) {
764801
umf_memory_provider_handle_t malloc_memory_provider;
765802
umf_result_t umf_result;

0 commit comments

Comments
 (0)