Skip to content

Commit a5f6195

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 856058d commit a5f6195

17 files changed

+259
-42
lines changed

.github/workflows/reusable_compatibility.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ jobs:
9898
run: >
9999
UMF_LOG="level:warning;flush:debug;output:stderr;pid:no"
100100
LD_LIBRARY_PATH=${{github.workspace}}/latest_version/build/lib/
101-
ctest --verbose
101+
ctest --verbose -E test_disjoint_pool
102102
103103
# Browse all folders in the examples directory, build them using the
104104
# latest UMF version, and run them, excluding those in the exclude list.
@@ -223,7 +223,7 @@ jobs:
223223
run: |
224224
$env:UMF_LOG="level:warning;flush:debug;output:stderr;pid:no"
225225
cp ${{github.workspace}}/latest_version/build/bin/Debug/umf.dll ${{github.workspace}}/tag_version/build/bin/Debug/umf.dll
226-
ctest -C Debug --verbose
226+
ctest -C Debug --verbose -E test_disjoint_pool
227227
228228
# Browse all folders in the examples directory, build them using the
229229
# latest UMF version, and run them, excluding those in the exclude list.
@@ -364,7 +364,7 @@ jobs:
364364
run: >
365365
UMF_LOG="level:warning;flush:debug;output:stderr;pid:no"
366366
LD_LIBRARY_PATH=${{github.workspace}}/latest_version/build/lib/
367-
ctest --verbose
367+
ctest --verbose -E test_disjoint_pool
368368
369369
# Browse all folders in the examples directory, build them using the
370370
# latest UMF version, and run them, excluding those in the exclude list.

include/umf/memory_pool_ops.h

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ extern "C" {
2222
/// @brief Version of the Memory Pool ops structure.
2323
/// NOTE: This is equal to the latest UMF version, in which the ops structure
2424
/// has been modified.
25-
#define UMF_POOL_OPS_VERSION_CURRENT UMF_MAKE_VERSION(1, 0)
25+
#define UMF_POOL_OPS_VERSION_CURRENT UMF_MAKE_VERSION(1, 1)
2626

2727
///
2828
/// @brief This structure comprises function pointers used by corresponding umfPool*
@@ -36,6 +36,10 @@ typedef struct umf_memory_pool_ops_t {
3636

3737
///
3838
/// @brief Initializes memory pool.
39+
/// /details
40+
/// * This function *must* be called before any other memory pool operation.
41+
/// * The memory pool implementation *must* allocate the memory pool structure
42+
/// and return it by the \p pool parameter.
3943
/// @param provider memory provider that will be used for coarse-grain allocations.
4044
/// @param params pool-specific params, or NULL for defaults
4145
/// @param pool [out] returns pointer to the pool
@@ -166,6 +170,24 @@ typedef struct umf_memory_pool_ops_t {
166170
const char *name, void *arg, size_t size,
167171
umf_ctl_query_type_t queryType, va_list args);
168172

173+
///
174+
/// @brief Post-initializes and set up memory pool.
175+
///
176+
/// \details
177+
/// * This function *must* be called before any other memory pool operation.
178+
/// * This function *must* be called after the memory pool has been allocated in initialize function
179+
/// and is used to perform any additional setup required by the memory pool.
180+
/// * This function *may* be used to set up any additional resources required by the memory pool.
181+
/// * This function *may* be used to set up default values for the memory pool parameters set up by CTL.
182+
///
183+
/// @param provider memory provider that will be used for coarse-grain allocations
184+
/// @param params pool-specific params, or NULL for defaults
185+
/// @param pool returns pointer to the pool
186+
/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure
187+
///
188+
umf_result_t (*ext_post_initialize)(umf_memory_provider_handle_t provider,
189+
const void *params, void *pool);
190+
169191
} umf_memory_pool_ops_t;
170192

171193
#ifdef __cplusplus

include/umf/memory_provider_ops.h

Lines changed: 9 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
@@ -278,6 +278,14 @@ typedef struct umf_memory_provider_ops_t {
278278
const char *name, void *arg, size_t size,
279279
umf_ctl_query_type_t queryType, va_list args);
280280

281+
///
282+
/// @brief Post-initializes memory provider.
283+
/// @param params provider-specific params, or NULL for defaults
284+
/// @param provider pointer to the provider
285+
/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure.
286+
///
287+
umf_result_t (*ext_post_initialize)(const void *params, void *provider);
288+
281289
} umf_memory_provider_ops_t;
282290

283291
#ifdef __cplusplus

src/memory_pool.c

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,14 @@ umfDefaultCtlPoolHandle(void *hPool, umf_ctl_query_source_t operationType,
167167
return UMF_RESULT_ERROR_NOT_SUPPORTED;
168168
}
169169

170+
static umf_result_t umfDefaultExtPostInitialize(umf_memory_provider_handle_t provider,
171+
const void* params, void* pool) {
172+
(void)provider;
173+
(void)params;
174+
(void)pool;
175+
return UMF_RESULT_SUCCESS;
176+
}
177+
170178
// logical sum (OR) of all umf_pool_create_flags_t flags
171179
static const umf_pool_create_flags_t UMF_POOL_CREATE_FLAG_ALL =
172180
UMF_POOL_CREATE_FLAG_OWN_PROVIDER | UMF_POOL_CREATE_FLAG_DISABLE_TRACKING;
@@ -200,11 +208,26 @@ static umf_result_t umfPoolCreateInternal(const umf_memory_pool_ops_t *ops,
200208
}
201209

202210
umf_result_t ret = UMF_RESULT_SUCCESS;
203-
211+
umf_memory_pool_ops_t compatible_ops;
204212
if (ops->version != UMF_POOL_OPS_VERSION_CURRENT) {
205213
LOG_WARN("Memory Pool ops version \"%d\" is different than the current "
206214
"version \"%d\"",
207215
ops->version, UMF_POOL_OPS_VERSION_CURRENT);
216+
217+
// Create a new ops compatible structure with the current version
218+
memset(&compatible_ops, 0, sizeof(compatible_ops));
219+
if (UMF_MINOR_VERSION(ops->version) == 0) {
220+
LOG_INFO("Detected 1.0 version of Memory Pool ops, "
221+
"upgrading to current version");
222+
memcpy(&compatible_ops, ops,
223+
offsetof(umf_memory_pool_ops_t, ext_post_initialize));
224+
} else {
225+
LOG_ERR("Memory Pool ops unknown version, which \"%d\" is not "
226+
"supported",
227+
ops->version);
228+
return UMF_RESULT_ERROR_NOT_SUPPORTED;
229+
}
230+
ops = &compatible_ops;
208231
}
209232

210233
umf_memory_pool_handle_t pool =
@@ -234,13 +257,17 @@ static umf_result_t umfPoolCreateInternal(const umf_memory_pool_ops_t *ops,
234257
pool->ops.ext_ctl = umfDefaultCtlPoolHandle;
235258
}
236259

260+
if (NULL == pool->ops.ext_post_initialize) {
261+
pool->ops.ext_post_initialize = umfDefaultExtPostInitialize;
262+
}
263+
237264
if (NULL == utils_mutex_init(&pool->lock)) {
238265
LOG_ERR("Failed to initialize mutex for pool");
239266
ret = UMF_RESULT_ERROR_UNKNOWN;
240267
goto err_lock_init;
241268
}
242269

243-
ret = ops->initialize(pool->provider, params, &pool->pool_priv);
270+
ret = pool->ops.initialize(pool->provider, params, &pool->pool_priv);
244271
if (ret != UMF_RESULT_SUCCESS) {
245272
goto err_pool_init;
246273
}
@@ -261,7 +288,14 @@ static umf_result_t umfPoolCreateInternal(const umf_memory_pool_ops_t *ops,
261288
}
262289
}
263290

291+
ret = pool->ops.ext_post_initialize(pool->provider, params, pool->pool_priv);
292+
if (ret != UMF_RESULT_SUCCESS) {
293+
LOG_ERR("Failed to post-initialize pool");
294+
goto err_pool_init;
295+
}
296+
264297
*hPool = pool;
298+
265299
LOG_INFO("Memory pool created: %p", (void *)pool);
266300
return UMF_RESULT_SUCCESS;
267301

src/memory_provider.c

Lines changed: 34 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>
@@ -119,6 +120,13 @@ static umf_result_t umfDefaultCloseIPCHandle(void *provider, void *ptr,
119120
return UMF_RESULT_ERROR_NOT_SUPPORTED;
120121
}
121122

123+
static umf_result_t umfDefaultPostInitialize(const void *params,
124+
void *provider) {
125+
(void)params;
126+
(void)provider;
127+
return UMF_RESULT_SUCCESS;
128+
}
129+
122130
static umf_result_t
123131
umfDefaultCtlHandle(void *provider, umf_ctl_query_source_t operationType,
124132
const char *name, void *arg, size_t size,
@@ -153,6 +161,10 @@ void assignOpsExtDefaults(umf_memory_provider_ops_t *ops) {
153161
if (!ops->ext_ctl) {
154162
ops->ext_ctl = umfDefaultCtlHandle;
155163
}
164+
165+
if (!ops->ext_post_initialize) {
166+
ops->ext_post_initialize = umfDefaultPostInitialize;
167+
}
156168
}
157169

158170
void assignOpsIpcDefaults(umf_memory_provider_ops_t *ops) {
@@ -224,10 +236,24 @@ umf_result_t umfMemoryProviderCreate(const umf_memory_provider_ops_t *ops,
224236
return UMF_RESULT_ERROR_INVALID_ARGUMENT;
225237
}
226238

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

233259
umf_memory_provider_handle_t provider =
@@ -250,6 +276,14 @@ umf_result_t umfMemoryProviderCreate(const umf_memory_provider_ops_t *ops,
250276

251277
provider->provider_priv = provider_priv;
252278

279+
ret = provider->ops.ext_post_initialize(params, provider_priv);
280+
if (ret != UMF_RESULT_SUCCESS) {
281+
LOG_ERR("Failed to post-initialize provider");
282+
provider->ops.finalize(provider_priv);
283+
umf_ba_global_free(provider);
284+
return ret;
285+
}
286+
253287
*hProvider = provider;
254288

255289
return UMF_RESULT_SUCCESS;

src/pool/pool_disjoint.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -758,9 +758,21 @@ 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
767+
disjoint_pool_post_initialize(umf_memory_provider_handle_t provider,
768+
const void *params, void *ppPool) {
769+
(void)params;
770+
disjoint_pool_t *disjoint_pool = (disjoint_pool_t *)ppPool;
771+
761772
disjoint_pool->known_slabs = critnib_new(free_slab, NULL);
762773
if (disjoint_pool->known_slabs == NULL) {
763-
goto err_free_disjoint_pool;
774+
umf_ba_global_free(disjoint_pool);
775+
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
764776
}
765777

766778
// Generate buckets sized such as: 64, 96, 128, 192, ..., CutOff.
@@ -821,8 +833,6 @@ umf_result_t disjoint_pool_initialize(umf_memory_provider_handle_t provider,
821833
disjoint_pool->provider_min_page_size = 0;
822834
}
823835

824-
*ppPool = (void *)disjoint_pool;
825-
826836
return UMF_RESULT_SUCCESS;
827837

828838
err_free_buckets:
@@ -838,10 +848,6 @@ umf_result_t disjoint_pool_initialize(umf_memory_provider_handle_t provider,
838848

839849
err_free_known_slabs:
840850
critnib_delete(disjoint_pool->known_slabs);
841-
842-
err_free_disjoint_pool:
843-
umf_ba_global_free(disjoint_pool);
844-
845851
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
846852
}
847853

@@ -1146,7 +1152,7 @@ static umf_memory_pool_ops_t UMF_DISJOINT_POOL_OPS = {
11461152
.get_last_allocation_error = disjoint_pool_get_last_allocation_error,
11471153
.get_name = disjoint_pool_get_name,
11481154
.ext_ctl = disjoint_pool_ctl,
1149-
};
1155+
.ext_post_initialize = disjoint_pool_post_initialize};
11501156

11511157
const umf_memory_pool_ops_t *umfDisjointPoolOps(void) {
11521158
return &UMF_DISJOINT_POOL_OPS;

0 commit comments

Comments
 (0)