Skip to content

Commit eaab2b7

Browse files
committed
add post-initialize function to pools and providers
Split between initialize and post-initialize function is necessary for properly handling CTL defaults.
1 parent d291734 commit eaab2b7

17 files changed

+291
-77
lines changed

.github/workflows/reusable_compatibility.yml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,16 @@ jobs:
9999
UMF_LOG: level:warning;flush:debug;output:stderr;pid:no
100100
LD_LIBRARY_PATH: ${{github.workspace}}/latest_version/build/lib/
101101
run: |
102-
ctest --verbose -E test_memoryProvider
102+
ctest --verbose -E "test_memoryProvider|test_disjoint_pool"
103+
104+
- name: Run disabled tests individually with latest UMF libs (warnings enabled)
105+
working-directory: ${{github.workspace}}/tag_version/build
106+
env:
107+
UMF_LOG: level:warning;flush:debug;output:stderr;pid:no
108+
LD_LIBRARY_PATH: ${{github.workspace}}/latest_version/build/lib/
109+
run: |
103110
test/test_memoryProvider --gtest_filter="-*Trace"
111+
test/test_disjoint_pool --gtest_filter="-test.internals"
104112
105113
# Browse all folders in the examples directory, build them using the
106114
# latest UMF version, and run them, excluding those in the exclude list.
@@ -225,8 +233,10 @@ jobs:
225233
env:
226234
UMF_LOG: level:warning;flush:debug;output:stderr;pid:no
227235
run: |
236+
$env:UMF_LOG="level:warning;flush:debug;output:stderr;pid:no"
228237
cp ${{github.workspace}}/latest_version/build/bin/Debug/umf.dll ${{github.workspace}}/tag_version/build/bin/Debug/umf.dll
229-
ctest -C Debug --verbose -E test_memoryProvider
238+
ctest -C Debug --verbose -E "test_memoryProvider|test_disjoint_pool"
239+
230240
231241
# Browse all folders in the examples directory, build them using the
232242
# latest UMF version, and run them, excluding those in the exclude list.
@@ -368,8 +378,16 @@ jobs:
368378
UMF_LOG: level:warning;flush:debug;output:stderr;pid:no
369379
LD_LIBRARY_PATH: ${{github.workspace}}/latest_version/build/lib/
370380
run: |
371-
ctest --verbose -E test_memoryProvider
381+
ctest --verbose -E "test_memoryProvider|test_disjoint_pool"
382+
383+
- name: Run disabled tests individually with latest UMF libs (warnings enabled)
384+
working-directory: ${{github.workspace}}/tag_version/build
385+
env:
386+
UMF_LOG: level:warning;flush:debug;output:stderr;pid:no
387+
LD_LIBRARY_PATH: ${{github.workspace}}/latest_version/build/lib/
388+
run: |
372389
test/test_memoryProvider --gtest_filter="-*Trace"
390+
test/test_disjoint_pool --gtest_filter="-test.internals"
373391
374392
# Browse all folders in the examples directory, build them using the
375393
# latest UMF version, and run them, excluding those in the exclude list.

include/umf/memory_pool_ops.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ typedef struct umf_memory_pool_ops_t {
3636

3737
///
3838
/// @brief Initializes memory pool.
39+
/// /details
40+
/// * The memory pool implementation *must* allocate the memory pool structure
41+
/// and return it by the \p pool parameter.
3942
/// @param provider memory provider that will be used for coarse-grain allocations.
4043
/// @param params pool-specific params, or NULL for defaults
4144
/// @param pool [out] returns pointer to the pool
@@ -190,7 +193,26 @@ typedef struct umf_memory_pool_ops_t {
190193
/// @return UMF_RESULT_SUCCESS on success or appropriate error code on
191194
/// failure.
192195
///
196+
193197
umf_result_t (*ext_trim_memory)(void *pool, size_t minBytesToKeep);
198+
///
199+
/// @brief Post-initializes and set up memory pool.
200+
/// Post-construction hook for memory pools, enabling advanced or deferred setup that cannot
201+
/// be done in the initial allocation phase (e.g. setting defaults from CTL).
202+
///
203+
/// \details
204+
/// * This function *must* be implemented if the pool/provider supports CTL that overrides defaults.
205+
/// * This function *must* free any resources allocated in the function.
206+
/// * This function *must* be called after the memory pool has been allocated in initialize function
207+
/// and is used to perform any additional setup required by the memory pool.
208+
/// * This function *may* be used to set up any additional resources required by the memory pool.
209+
/// * This function *may* be used to set up default values for the memory pool parameters set up by CTL.
210+
///
211+
/// @param pool pointer to the pool
212+
/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure
213+
///
214+
umf_result_t (*ext_post_initialize)(void *pool);
215+
194216
} umf_memory_pool_ops_t;
195217

196218
#ifdef __cplusplus

include/umf/memory_provider_ops.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ extern "C" {
2121
/// @brief Version of the Memory Provider ops structure.
2222
/// NOTE: This is equal to the latest UMF version, in which the ops structure
2323
/// has been modified.
24-
#define UMF_PROVIDER_OPS_VERSION_CURRENT UMF_MAKE_VERSION(1, 0)
24+
#define UMF_PROVIDER_OPS_VERSION_CURRENT UMF_MAKE_VERSION(1, 1)
2525

2626
///
2727
/// @brief This structure comprises function pointers used by corresponding
@@ -288,6 +288,18 @@ typedef struct umf_memory_provider_ops_t {
288288
const char *name, void *arg, size_t size,
289289
umf_ctl_query_type_t queryType, va_list args);
290290

291+
// The following operations were added in ops version 1.1
292+
293+
///
294+
/// @brief Post-initializes memory provider.
295+
/// Post-construction hook for memory pools, enabling advanced or deferred setup that cannot
296+
/// be done in the initial allocation phase (e.g. setting defaults from CTL).
297+
///
298+
/// @param provider pointer to the provider
299+
/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
300+
///
301+
umf_result_t (*ext_post_initialize)(void *provider);
302+
291303
} umf_memory_provider_ops_t;
292304

293305
#ifdef __cplusplus

src/memory_pool.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,11 @@ static umf_result_t umfDefaultTrimMemory(void *provider,
463463
return UMF_RESULT_ERROR_NOT_SUPPORTED;
464464
}
465465

466+
static umf_result_t umfDefaultExtPostInitialize(void *pool) {
467+
(void)pool;
468+
return UMF_RESULT_SUCCESS;
469+
}
470+
466471
// logical sum (OR) of all umf_pool_create_flags_t flags
467472
static const umf_pool_create_flags_t UMF_POOL_CREATE_FLAG_ALL =
468473
UMF_POOL_CREATE_FLAG_OWN_PROVIDER | UMF_POOL_CREATE_FLAG_DISABLE_TRACKING;
@@ -495,7 +500,6 @@ static umf_result_t umfPoolCreateInternal(const umf_memory_pool_ops_t *ops,
495500
}
496501

497502
umf_result_t ret = UMF_RESULT_SUCCESS;
498-
499503
umf_memory_pool_ops_t compatible_ops;
500504
if (ops->version != UMF_POOL_OPS_VERSION_CURRENT) {
501505
LOG_WARN("Memory Pool ops version \"%d\" is different than the current "
@@ -504,8 +508,8 @@ static umf_result_t umfPoolCreateInternal(const umf_memory_pool_ops_t *ops,
504508

505509
// Create a new ops compatible structure with the current version
506510
memset(&compatible_ops, 0, sizeof(compatible_ops));
507-
if (UMF_MINOR_VERSION(ops->version) == 0) {
508-
LOG_INFO("Detected 1.0 version of Memory Pool ops, "
511+
if (ops->version < UMF_MAKE_VERSION(1, 1)) {
512+
LOG_INFO("Detected 1.0 version or below of Memory Pool ops, "
509513
"upgrading to current version");
510514
memcpy(&compatible_ops, ops,
511515
offsetof(umf_memory_pool_ops_t, ext_trim_memory));
@@ -547,13 +551,17 @@ static umf_result_t umfPoolCreateInternal(const umf_memory_pool_ops_t *ops,
547551
pool->ops.ext_trim_memory = umfDefaultTrimMemory;
548552
}
549553

554+
if (NULL == pool->ops.ext_post_initialize) {
555+
pool->ops.ext_post_initialize = umfDefaultExtPostInitialize;
556+
}
557+
550558
if (NULL == utils_mutex_init(&pool->lock)) {
551559
LOG_ERR("Failed to initialize mutex for pool");
552560
ret = UMF_RESULT_ERROR_UNKNOWN;
553561
goto err_lock_init;
554562
}
555563

556-
ret = ops->initialize(pool->provider, params, &pool->pool_priv);
564+
ret = pool->ops.initialize(pool->provider, params, &pool->pool_priv);
557565
if (ret != UMF_RESULT_SUCCESS) {
558566
goto err_pool_init;
559567
}
@@ -579,6 +587,12 @@ static umf_result_t umfPoolCreateInternal(const umf_memory_pool_ops_t *ops,
579587
}
580588
}
581589

590+
ret = pool->ops.ext_post_initialize(pool->pool_priv);
591+
if (ret != UMF_RESULT_SUCCESS) {
592+
LOG_ERR("Failed to post-initialize pool");
593+
goto err_pool_init;
594+
}
595+
582596
*hPool = pool;
583597
pools_by_name_add(pool);
584598

src/memory_provider.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <stdbool.h>
1212
#include <stdio.h>
1313
#include <stdlib.h>
14+
#include <string.h>
1415

1516
#include <umf/base.h>
1617
#include <umf/memory_provider.h>
@@ -120,6 +121,11 @@ static umf_result_t umfDefaultCloseIPCHandle(void *provider, void *ptr,
120121
return UMF_RESULT_ERROR_NOT_SUPPORTED;
121122
}
122123

124+
static umf_result_t umfDefaultPostInitialize(void *provider) {
125+
(void)provider;
126+
return UMF_RESULT_ERROR_NOT_SUPPORTED;
127+
}
128+
123129
static umf_result_t
124130
umfDefaultCtlHandle(void *provider, umf_ctl_query_source_t operationType,
125131
const char *name, void *arg, size_t size,
@@ -154,6 +160,10 @@ void assignOpsExtDefaults(umf_memory_provider_ops_t *ops) {
154160
if (!ops->ext_ctl) {
155161
ops->ext_ctl = umfDefaultCtlHandle;
156162
}
163+
164+
if (!ops->ext_post_initialize) {
165+
ops->ext_post_initialize = umfDefaultPostInitialize;
166+
}
157167
}
158168

159169
void assignOpsIpcDefaults(umf_memory_provider_ops_t *ops) {
@@ -225,10 +235,24 @@ umf_result_t umfMemoryProviderCreate(const umf_memory_provider_ops_t *ops,
225235
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
226236
}
227237

238+
umf_memory_provider_ops_t compatible_ops;
228239
if (ops->version != UMF_PROVIDER_OPS_VERSION_CURRENT) {
229240
LOG_WARN("Memory Provider ops version \"%d\" is different than the "
230241
"current version \"%d\"",
231242
ops->version, UMF_PROVIDER_OPS_VERSION_CURRENT);
243+
memset(&compatible_ops, 0, sizeof(compatible_ops));
244+
if (UMF_MINOR_VERSION(ops->version) == 0) {
245+
LOG_INFO("Detected 1.0 version of Memory Pool ops, "
246+
"upgrading to current version");
247+
memcpy(&compatible_ops, ops,
248+
offsetof(umf_memory_provider_ops_t, ext_post_initialize));
249+
} else {
250+
LOG_ERR("Memory Provider ops unknown version, which \"%d\" is not "
251+
"supported",
252+
ops->version);
253+
return UMF_RESULT_ERROR_NOT_SUPPORTED;
254+
}
255+
ops = &compatible_ops;
232256
}
233257

234258
umf_memory_provider_handle_t provider =
@@ -251,6 +275,14 @@ umf_result_t umfMemoryProviderCreate(const umf_memory_provider_ops_t *ops,
251275

252276
provider->provider_priv = provider_priv;
253277

278+
ret = provider->ops.ext_post_initialize(provider_priv);
279+
if (ret != UMF_RESULT_SUCCESS && ret != UMF_RESULT_ERROR_NOT_SUPPORTED) {
280+
LOG_ERR("Failed to post-initialize provider");
281+
provider->ops.finalize(provider_priv);
282+
umf_ba_global_free(provider);
283+
return ret;
284+
}
285+
254286
*hProvider = provider;
255287

256288
const char *provider_name = NULL;

src/pool/pool_disjoint.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,14 @@ umf_result_t disjoint_pool_initialize(umf_memory_provider_handle_t provider,
758758
disjoint_pool->provider = provider;
759759
disjoint_pool->params = *dp_params;
760760

761+
*ppPool = (void *)disjoint_pool;
762+
763+
return UMF_RESULT_SUCCESS;
764+
}
765+
766+
umf_result_t disjoint_pool_post_initialize(void *ppPool) {
767+
disjoint_pool_t *disjoint_pool = (disjoint_pool_t *)ppPool;
768+
761769
disjoint_pool->known_slabs = critnib_new(free_slab, NULL);
762770
if (disjoint_pool->known_slabs == NULL) {
763771
goto err_free_disjoint_pool;
@@ -816,13 +824,11 @@ umf_result_t disjoint_pool_initialize(umf_memory_provider_handle_t provider,
816824
}
817825

818826
umf_result_t ret = umfMemoryProviderGetMinPageSize(
819-
provider, NULL, &disjoint_pool->provider_min_page_size);
827+
disjoint_pool->provider, NULL, &disjoint_pool->provider_min_page_size);
820828
if (ret != UMF_RESULT_SUCCESS) {
821829
disjoint_pool->provider_min_page_size = 0;
822830
}
823831

824-
*ppPool = (void *)disjoint_pool;
825-
826832
return UMF_RESULT_SUCCESS;
827833

828834
err_free_buckets:
@@ -841,7 +847,6 @@ umf_result_t disjoint_pool_initialize(umf_memory_provider_handle_t provider,
841847

842848
err_free_disjoint_pool:
843849
umf_ba_global_free(disjoint_pool);
844-
845850
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
846851
}
847852

@@ -1188,7 +1193,7 @@ static umf_memory_pool_ops_t UMF_DISJOINT_POOL_OPS = {
11881193
.get_name = disjoint_pool_get_name,
11891194
.ext_ctl = disjoint_pool_ctl,
11901195
.ext_trim_memory = disjoint_pool_trim_memory,
1191-
};
1196+
.ext_post_initialize = disjoint_pool_post_initialize};
11921197

11931198
const umf_memory_pool_ops_t *umfDisjointPoolOps(void) {
11941199
return &UMF_DISJOINT_POOL_OPS;

0 commit comments

Comments
 (0)