Skip to content

make ops structure flat #1265

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions include/umf/memory_pool_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,11 @@ typedef struct umf_memory_pool_ops_t {
///
umf_result_t (*get_last_allocation_error)(void *pool);

///
/// Following functions, with ext prefix, are optional and memory pool implementation
/// can keep them NULL.
///

///
/// @brief Control operation for the memory pool.
/// The function is used to perform various control operations
Expand All @@ -135,16 +140,17 @@ typedef struct umf_memory_pool_ops_t {
/// @param operationType type of the operation to be performed.
/// @param name name associated with the operation.
/// @param arg argument for the operation.
/// @param size size of the argument [optional - check path requirements]
/// @param size size of the argument [optional - check name requirements]
/// @param queryType type of the query to be performed.
///
/// @return umf_result_t result of the control operation.
///
umf_result_t (*ctl)(void *pool, int operationType, const char *name,
void *arg, size_t size, umf_ctl_query_type_t queryType);
umf_result_t (*ext_ctl)(void *hPool, int operationType, const char *name,
void *arg, size_t size,
umf_ctl_query_type_t queryType);

///
/// @brief Retrieves the name of the memory pool [optional]
/// @brief Retrieves the name of the memory pool
/// @param pool valid pointer to the memory pool or NULL value
/// \details
/// * Implementations *must* return a literal null-terminated string.
Expand All @@ -153,7 +159,7 @@ typedef struct umf_memory_pool_ops_t {
/// otherwise the pool's name is returned.
/// @return A constant character string representing the pool's name.
///
const char *(*get_name)(void *pool);
const char *(*ext_get_name)(void *pool);
} umf_memory_pool_ops_t;

#ifdef __cplusplus
Expand Down
253 changes: 127 additions & 126 deletions include/umf/memory_provider_ops.h

Large diffs are not rendered by default.

33 changes: 18 additions & 15 deletions src/memory_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ static int CTL_SUBTREE_HANDLER(by_handle_pool)(void *ctx,
umf_ctl_query_type_t queryType) {
(void)indexes, (void)source;
umf_memory_pool_handle_t hPool = (umf_memory_pool_handle_t)ctx;
hPool->ops.ctl(hPool->pool_priv, /*unused*/ 0, extra_name, arg, size,
queryType);

hPool->ops.ext_ctl(hPool->pool_priv, /*unused*/ 0, extra_name, arg, size,
queryType);
return 0;
}

Expand Down Expand Up @@ -89,6 +90,7 @@ static int CTL_SUBTREE_HANDLER(default)(void *ctx,
}

utils_mutex_unlock(&ctl_mtx);

return 0;
}

Expand Down Expand Up @@ -118,18 +120,19 @@ static umf_result_t umfPoolCreateInternal(const umf_memory_pool_ops_t *ops,
}

umf_result_t ret = UMF_RESULT_SUCCESS;
umf_memory_pool_handle_t pool =
umf_ba_global_alloc(sizeof(umf_memory_pool_t));
if (!pool) {
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
}

if (ops->version != UMF_POOL_OPS_VERSION_CURRENT) {
LOG_WARN("Memory Pool ops version \"%d\" is different than the current "
"version \"%d\"",
ops->version, UMF_POOL_OPS_VERSION_CURRENT);
}

umf_memory_pool_handle_t pool =
umf_ba_global_alloc(sizeof(umf_memory_pool_t));
if (!pool) {
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY;
}

if (!(flags & UMF_POOL_CREATE_FLAG_DISABLE_TRACKING)) {
// Wrap provider with memory tracking provider.
ret = umfTrackingMemoryProviderCreate(provider, pool, &pool->provider);
Expand All @@ -146,8 +149,8 @@ static umf_result_t umfPoolCreateInternal(const umf_memory_pool_ops_t *ops,
pool->ops = *ops;
pool->tag = NULL;

if (NULL == pool->ops.ctl) {
pool->ops.ctl = umfDefaultCtlPoolHandle;
if (NULL == pool->ops.ext_ctl) {
pool->ops.ext_ctl = umfDefaultCtlPoolHandle;
}

if (NULL == utils_mutex_init(&pool->lock)) {
Expand All @@ -164,10 +167,10 @@ static umf_result_t umfPoolCreateInternal(const umf_memory_pool_ops_t *ops,
// Set default property "name" to pool if exists
for (int i = 0; i < UMF_DEFAULT_SIZE; i++) {
if (CTL_DEFAULT_ENTRIES[i][0] != '\0' &&
strstr(CTL_DEFAULT_ENTRIES[i], ops->get_name(NULL))) {
ops->ctl(pool->pool_priv, CTL_QUERY_PROGRAMMATIC,
CTL_DEFAULT_ENTRIES[i], CTL_DEFAULT_VALUES[i],
UMF_DEFAULT_LEN, CTL_QUERY_WRITE);
strstr(CTL_DEFAULT_ENTRIES[i], ops->ext_get_name(NULL))) {
ops->ext_ctl(pool->pool_priv, CTL_QUERY_PROGRAMMATIC,
CTL_DEFAULT_ENTRIES[i], CTL_DEFAULT_VALUES[i],
UMF_DEFAULT_LEN, CTL_QUERY_WRITE);
}
}

Expand Down Expand Up @@ -246,10 +249,10 @@ umf_result_t umfPoolGetMemoryProvider(umf_memory_pool_handle_t hPool,

const char *umfPoolGetName(umf_memory_pool_handle_t pool) {
UMF_CHECK((pool != NULL), NULL);
if (pool->ops.get_name == NULL) {
if (pool->ops.ext_get_name == NULL) {
return NULL;
}
return pool->ops.get_name(pool->pool_priv);
return pool->ops.ext_get_name(pool->pool_priv);
}

umf_result_t umfPoolCreate(const umf_memory_pool_ops_t *ops,
Expand Down
119 changes: 65 additions & 54 deletions src/memory_provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ static int CTL_SUBTREE_HANDLER(by_handle_provider)(
umf_ctl_query_type_t queryType) {
(void)indexes, (void)source;
umf_memory_provider_handle_t hProvider = (umf_memory_provider_handle_t)ctx;
hProvider->ops.ctl(hProvider->provider_priv, /*unused*/ 0, extra_name, arg,
size, queryType);
hProvider->ops.ext_ctl(hProvider->provider_priv, /*unused*/ 0, extra_name,
arg, size, queryType);
return 0;
}

Expand Down Expand Up @@ -122,67 +122,78 @@ static umf_result_t umfDefaultCtlHandle(void *provider, int operationType,
}

void assignOpsExtDefaults(umf_memory_provider_ops_t *ops) {
if (!ops->ext.purge_lazy) {
ops->ext.purge_lazy = umfDefaultPurgeLazy;
if (!ops->ext_purge_lazy) {
ops->ext_purge_lazy = umfDefaultPurgeLazy;
}
if (!ops->ext.purge_force) {
ops->ext.purge_force = umfDefaultPurgeForce;
if (!ops->ext_purge_force) {
ops->ext_purge_force = umfDefaultPurgeForce;
}
if (!ops->ext.allocation_split) {
ops->ext.allocation_split = umfDefaultAllocationSplit;
if (!ops->ext_allocation_split) {
ops->ext_allocation_split = umfDefaultAllocationSplit;
}
if (!ops->ext.allocation_merge) {
ops->ext.allocation_merge = umfDefaultAllocationMerge;
if (!ops->ext_allocation_merge) {
ops->ext_allocation_merge = umfDefaultAllocationMerge;
}
}

void assignOpsIpcDefaults(umf_memory_provider_ops_t *ops) {
if (!ops->ipc.get_ipc_handle_size) {
ops->ipc.get_ipc_handle_size = umfDefaultGetIPCHandleSize;
if (!ops->ext_get_ipc_handle_size) {
ops->ext_get_ipc_handle_size = umfDefaultGetIPCHandleSize;
}
if (!ops->ipc.get_ipc_handle) {
ops->ipc.get_ipc_handle = umfDefaultGetIPCHandle;
if (!ops->ext_get_ipc_handle) {
ops->ext_get_ipc_handle = umfDefaultGetIPCHandle;
}
if (!ops->ipc.put_ipc_handle) {
ops->ipc.put_ipc_handle = umfDefaultPutIPCHandle;
if (!ops->ext_put_ipc_handle) {
ops->ext_put_ipc_handle = umfDefaultPutIPCHandle;
}
if (!ops->ipc.open_ipc_handle) {
ops->ipc.open_ipc_handle = umfDefaultOpenIPCHandle;
if (!ops->ext_open_ipc_handle) {
ops->ext_open_ipc_handle = umfDefaultOpenIPCHandle;
}
if (!ops->ipc.close_ipc_handle) {
ops->ipc.close_ipc_handle = umfDefaultCloseIPCHandle;
if (!ops->ext_close_ipc_handle) {
ops->ext_close_ipc_handle = umfDefaultCloseIPCHandle;
}
if (!ops->ctl) {
ops->ctl = umfDefaultCtlHandle;
if (!ops->ext_ctl) {
ops->ext_ctl = umfDefaultCtlHandle;
}
}

static bool validateOpsMandatory(const umf_memory_provider_ops_t *ops) {
// Mandatory ops should be non-NULL
return ops->alloc && ops->free && ops->get_recommended_page_size &&
ops->get_min_page_size && ops->initialize && ops->finalize &&
ops->get_last_native_error && ops->get_name;
}
#define CHECK_OP(ops, fn) \
if (!(ops)->fn) { \
LOG_ERR("missing function pointer: %s\n", #fn); \
return false; \
}

static bool validateOpsExt(const umf_memory_provider_ext_ops_t *ext) {
// split and merge functions should be both NULL or both non-NULL
return (ext->allocation_split && ext->allocation_merge) ||
(!ext->allocation_split && !ext->allocation_merge);
}
static bool validateOps(const umf_memory_provider_ops_t *ops) {
// Validate mandatory operations one by one
CHECK_OP(ops, alloc);
CHECK_OP(ops, free);
CHECK_OP(ops, get_recommended_page_size);
CHECK_OP(ops, get_min_page_size);
CHECK_OP(ops, initialize);
CHECK_OP(ops, finalize);
CHECK_OP(ops, get_last_native_error);
CHECK_OP(ops, get_name);

if ((ops->ext_allocation_split == NULL) !=
(ops->ext_allocation_merge == NULL)) {
LOG_ERR("ext_allocation_split and ext_allocation_merge must be "
"both set or both NULL\n");
return false;
}

static bool validateOpsIpc(const umf_memory_provider_ipc_ops_t *ipc) {
// valid if all ops->ipc.* are non-NULL or all are NULL
return (ipc->get_ipc_handle_size && ipc->get_ipc_handle &&
ipc->put_ipc_handle && ipc->open_ipc_handle &&
ipc->close_ipc_handle) ||
(!ipc->get_ipc_handle_size && !ipc->get_ipc_handle &&
!ipc->put_ipc_handle && !ipc->open_ipc_handle &&
!ipc->close_ipc_handle);
}
bool ipcAllSet = ops->ext_get_ipc_handle_size && ops->ext_get_ipc_handle &&
ops->ext_put_ipc_handle && ops->ext_open_ipc_handle &&
ops->ext_close_ipc_handle;
bool ipcAllNull = !ops->ext_get_ipc_handle_size &&
!ops->ext_get_ipc_handle && !ops->ext_put_ipc_handle &&
!ops->ext_open_ipc_handle && !ops->ext_close_ipc_handle;
if (!ipcAllSet && !ipcAllNull) {
LOG_ERR("IPC function pointers must be either all set or all "
"NULL\n");
return false;
}

static bool validateOps(const umf_memory_provider_ops_t *ops) {
return validateOpsMandatory(ops) && validateOpsExt(&(ops->ext)) &&
validateOpsIpc(&(ops->ipc));
return true;
}

umf_result_t umfMemoryProviderCreate(const umf_memory_provider_ops_t *ops,
Expand Down Expand Up @@ -302,7 +313,7 @@ umf_result_t umfMemoryProviderPurgeLazy(umf_memory_provider_handle_t hProvider,
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
UMF_CHECK((ptr != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
umf_result_t res =
hProvider->ops.ext.purge_lazy(hProvider->provider_priv, ptr, size);
hProvider->ops.ext_purge_lazy(hProvider->provider_priv, ptr, size);
checkErrorAndSetLastProvider(res, hProvider);
return res;
}
Expand All @@ -312,7 +323,7 @@ umf_result_t umfMemoryProviderPurgeForce(umf_memory_provider_handle_t hProvider,
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
UMF_CHECK((ptr != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
umf_result_t res =
hProvider->ops.ext.purge_force(hProvider->provider_priv, ptr, size);
hProvider->ops.ext_purge_force(hProvider->provider_priv, ptr, size);
checkErrorAndSetLastProvider(res, hProvider);
return res;
}
Expand All @@ -331,7 +342,7 @@ umfMemoryProviderAllocationSplit(umf_memory_provider_handle_t hProvider,
UMF_RESULT_ERROR_INVALID_ARGUMENT);
UMF_CHECK((firstSize < totalSize), UMF_RESULT_ERROR_INVALID_ARGUMENT);

umf_result_t res = hProvider->ops.ext.allocation_split(
umf_result_t res = hProvider->ops.ext_allocation_split(
hProvider->provider_priv, ptr, totalSize, firstSize);
checkErrorAndSetLastProvider(res, hProvider);
return res;
Expand All @@ -349,7 +360,7 @@ umfMemoryProviderAllocationMerge(umf_memory_provider_handle_t hProvider,
UMF_CHECK(((uintptr_t)highPtr - (uintptr_t)lowPtr < totalSize),
UMF_RESULT_ERROR_INVALID_ARGUMENT);

umf_result_t res = hProvider->ops.ext.allocation_merge(
umf_result_t res = hProvider->ops.ext_allocation_merge(
hProvider->provider_priv, lowPtr, highPtr, totalSize);
checkErrorAndSetLastProvider(res, hProvider);
return res;
Expand All @@ -360,7 +371,7 @@ umfMemoryProviderGetIPCHandleSize(umf_memory_provider_handle_t hProvider,
size_t *size) {
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
UMF_CHECK((size != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
return hProvider->ops.ipc.get_ipc_handle_size(hProvider->provider_priv,
return hProvider->ops.ext_get_ipc_handle_size(hProvider->provider_priv,
size);
}

Expand All @@ -371,7 +382,7 @@ umfMemoryProviderGetIPCHandle(umf_memory_provider_handle_t hProvider,
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
UMF_CHECK((ptr != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
UMF_CHECK((providerIpcData != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
return hProvider->ops.ipc.get_ipc_handle(hProvider->provider_priv, ptr,
return hProvider->ops.ext_get_ipc_handle(hProvider->provider_priv, ptr,
size, providerIpcData);
}

Expand All @@ -380,7 +391,7 @@ umfMemoryProviderPutIPCHandle(umf_memory_provider_handle_t hProvider,
void *providerIpcData) {
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
UMF_CHECK((providerIpcData != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
return hProvider->ops.ipc.put_ipc_handle(hProvider->provider_priv,
return hProvider->ops.ext_put_ipc_handle(hProvider->provider_priv,
providerIpcData);
}

Expand All @@ -390,7 +401,7 @@ umfMemoryProviderOpenIPCHandle(umf_memory_provider_handle_t hProvider,
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
UMF_CHECK((providerIpcData != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
UMF_CHECK((ptr != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
return hProvider->ops.ipc.open_ipc_handle(hProvider->provider_priv,
return hProvider->ops.ext_open_ipc_handle(hProvider->provider_priv,
providerIpcData, ptr);
}

Expand All @@ -399,6 +410,6 @@ umfMemoryProviderCloseIPCHandle(umf_memory_provider_handle_t hProvider,
void *ptr, size_t size) {
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
UMF_CHECK((ptr != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
return hProvider->ops.ipc.close_ipc_handle(hProvider->provider_priv, ptr,
return hProvider->ops.ext_close_ipc_handle(hProvider->provider_priv, ptr,
size);
}
4 changes: 2 additions & 2 deletions src/pool/pool_disjoint.c
Original file line number Diff line number Diff line change
Expand Up @@ -1033,8 +1033,8 @@ static umf_memory_pool_ops_t UMF_DISJOINT_POOL_OPS = {
.malloc_usable_size = disjoint_pool_malloc_usable_size,
.free = disjoint_pool_free,
.get_last_allocation_error = disjoint_pool_get_last_allocation_error,
.get_name = disjoint_pool_get_name,
.ctl = disjoint_pool_ctl,
.ext_get_name = disjoint_pool_get_name,
.ext_ctl = disjoint_pool_ctl,
};

const umf_memory_pool_ops_t *umfDisjointPoolOps(void) {
Expand Down
4 changes: 2 additions & 2 deletions src/pool/pool_scalable.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,8 +437,8 @@ static umf_memory_pool_ops_t UMF_SCALABLE_POOL_OPS = {
.malloc_usable_size = tbb_malloc_usable_size,
.free = tbb_free,
.get_last_allocation_error = tbb_get_last_allocation_error,
.ctl = pool_ctl,
.get_name = scalable_get_name,
.ext_ctl = pool_ctl,
.ext_get_name = scalable_get_name,
};

const umf_memory_pool_ops_t *umfScalablePoolOps(void) {
Expand Down
18 changes: 9 additions & 9 deletions src/provider/provider_cuda.c
Original file line number Diff line number Diff line change
Expand Up @@ -688,16 +688,16 @@ static umf_memory_provider_ops_t UMF_CUDA_MEMORY_PROVIDER_OPS = {
.get_name = cu_memory_provider_get_name,
// TODO
/*
.ext.purge_lazy = cu_memory_provider_purge_lazy,
.ext.purge_force = cu_memory_provider_purge_force,
.ext.allocation_merge = cu_memory_provider_allocation_merge,
.ext.allocation_split = cu_memory_provider_allocation_split,
.ext_purge_lazy = cu_memory_provider_purge_lazy,
.ext_purge_force = cu_memory_provider_purge_force,
.ext_allocation_merge = cu_memory_provider_allocation_merge,
.ext_allocation_split = cu_memory_provider_allocation_split,
*/
.ipc.get_ipc_handle_size = cu_memory_provider_get_ipc_handle_size,
.ipc.get_ipc_handle = cu_memory_provider_get_ipc_handle,
.ipc.put_ipc_handle = cu_memory_provider_put_ipc_handle,
.ipc.open_ipc_handle = cu_memory_provider_open_ipc_handle,
.ipc.close_ipc_handle = cu_memory_provider_close_ipc_handle,
.ext_get_ipc_handle_size = cu_memory_provider_get_ipc_handle_size,
.ext_get_ipc_handle = cu_memory_provider_get_ipc_handle,
.ext_put_ipc_handle = cu_memory_provider_put_ipc_handle,
.ext_open_ipc_handle = cu_memory_provider_open_ipc_handle,
.ext_close_ipc_handle = cu_memory_provider_close_ipc_handle,
};

const umf_memory_provider_ops_t *umfCUDAMemoryProviderOps(void) {
Expand Down
Loading
Loading