diff --git a/include/umf/memory_pool_ops.h b/include/umf/memory_pool_ops.h index 1c9772268..d77e970f5 100644 --- a/include/umf/memory_pool_ops.h +++ b/include/umf/memory_pool_ops.h @@ -28,6 +28,9 @@ extern "C" { /// pointers. /// typedef struct umf_memory_pool_ops_t { + /// Size of this structure. + /// Should be initialized with sizeof(umf_memory_pool_ops_t) in the current umf version + size_t size; /// Version of the ops structure. /// Should be initialized using UMF_POOL_OPS_VERSION_CURRENT. uint32_t version; @@ -126,6 +129,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 @@ -139,8 +147,12 @@ typedef struct umf_memory_pool_ops_t { /// /// @return umf_result_t result of the control operation. /// - umf_result_t (*ctl)(void *hPool, int operationType, const char *name, - void *arg, umf_ctl_query_type_t queryType); + umf_result_t (*ext_ctl)(void *hPool, int operationType, const char *name, + void *arg, umf_ctl_query_type_t queryType); + + /// Reserved for future use + /// Note: When copying this structure, use its provided size field rather than using sizeof. + char reserved[]; } umf_memory_pool_ops_t; #ifdef __cplusplus diff --git a/include/umf/memory_provider_ops.h b/include/umf/memory_provider_ops.h index a531c10ba..8784a7e4b 100644 --- a/include/umf/memory_provider_ops.h +++ b/include/umf/memory_provider_ops.h @@ -21,131 +21,16 @@ extern "C" { /// has been modified. #define UMF_PROVIDER_OPS_VERSION_CURRENT UMF_MAKE_VERSION(0, 12) -/// -/// @brief This structure comprises optional function pointers used -/// by corresponding umfMemoryProvider* calls. A memory provider implementation -/// can keep them NULL. -/// -typedef struct umf_memory_provider_ext_ops_t { - /// - /// @brief Discard physical pages within the virtual memory mapping associated at the given addr - /// and \p size. This call is asynchronous and may delay purging the pages indefinitely. - /// @param provider pointer to the memory provider - /// @param ptr beginning of the virtual memory range - /// @param size size of the virtual memory range - /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. - /// UMF_RESULT_ERROR_INVALID_ALIGNMENT if ptr or size is not page-aligned. - /// UMF_RESULT_ERROR_NOT_SUPPORTED if operation is not supported by this provider. - /// - umf_result_t (*purge_lazy)(void *provider, void *ptr, size_t size); - - /// - /// @brief Discard physical pages within the virtual memory mapping associated at the given addr and \p size. - /// This call is synchronous and if it succeeds, pages are guaranteed to be zero-filled on the next access. - /// @param provider pointer to the memory provider - /// @param ptr beginning of the virtual memory range - /// @param size size of the virtual memory range - /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure - /// UMF_RESULT_ERROR_INVALID_ALIGNMENT if ptr or size is not page-aligned. - /// UMF_RESULT_ERROR_NOT_SUPPORTED if operation is not supported by this provider. - /// - umf_result_t (*purge_force)(void *provider, void *ptr, size_t size); - - /// - /// @brief Merges two coarse grain allocations into a single allocation that - /// can be managed (freed) as a whole. - /// allocation_split and allocation_merge should be both set or both NULL. - /// allocation_merge should NOT be called concurrently with allocation_split() - /// with the same pointer. - /// @param hProvider handle to the memory provider - /// @param lowPtr pointer to the first allocation - /// @param highPtr pointer to the second allocation (should be > lowPtr) - /// @param totalSize size of a new merged allocation. Should be equal - /// to the sum of sizes of allocations beginning at lowPtr and highPtr - /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure - /// - umf_result_t (*allocation_merge)(void *hProvider, void *lowPtr, - void *highPtr, size_t totalSize); - - /// - /// @brief Splits a coarse grain allocation into 2 adjacent allocations that - /// can be managed (freed) separately. - /// allocation_split and allocation_merge should be both set or both NULL. - /// allocation_split should NOT be called concurrently with allocation_merge() - /// with the same pointer. - /// @param hProvider handle to the memory provider - /// @param ptr pointer to the beginning of the allocation - /// @param totalSize total size of the allocation to be split - /// @param firstSize size of the first new allocation, second allocation - // has a size equal to totalSize - firstSize - /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure - /// - umf_result_t (*allocation_split)(void *hProvider, void *ptr, - size_t totalSize, size_t firstSize); -} umf_memory_provider_ext_ops_t; - -/// -/// @brief This structure comprises optional IPC API. The API allows sharing of -/// memory objects across different processes. A memory provider implementation can keep them NULL. -/// -typedef struct umf_memory_provider_ipc_ops_t { - /// - /// @brief Retrieve the size of opaque data structure required to store IPC data. - /// @param provider pointer to the memory provider. - /// @param size [out] pointer to the size. - /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. - /// UMF_RESULT_ERROR_NOT_SUPPORTED if IPC functionality is not supported by this provider. - umf_result_t (*get_ipc_handle_size)(void *provider, size_t *size); - - /// - /// @brief Retrieve an IPC memory handle for the specified allocation. - /// @param provider pointer to the memory provider. - /// @param ptr beginning of the virtual memory range. - /// @param size size of the memory address range. - /// @param providerIpcData [out] pointer to the preallocated opaque data structure to store IPC handle. - /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. - /// UMF_RESULT_ERROR_INVALID_ARGUMENT if ptr was not allocated by this provider. - /// UMF_RESULT_ERROR_NOT_SUPPORTED if IPC functionality is not supported by this provider. - umf_result_t (*get_ipc_handle)(void *provider, const void *ptr, size_t size, - void *providerIpcData); - - /// - /// @brief Release IPC handle retrieved with get_ipc_handle function. - /// @param provider pointer to the memory provider. - /// @param providerIpcData pointer to the IPC opaque data structure. - /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. - /// UMF_RESULT_ERROR_INVALID_ARGUMENT if providerIpcData was not created by this provider. - /// UMF_RESULT_ERROR_NOT_SUPPORTED if IPC functionality is not supported by this provider. - umf_result_t (*put_ipc_handle)(void *provider, void *providerIpcData); - - /// - /// @brief Open IPC handle. - /// @param provider pointer to the memory provider. - /// @param providerIpcData pointer to the IPC opaque data structure. - /// @param ptr [out] pointer to the memory to be used in the current process. - /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. - /// UMF_RESULT_ERROR_INVALID_ARGUMENT if providerIpcData cannot be handled by the provider. - /// UMF_RESULT_ERROR_NOT_SUPPORTED if IPC functionality is not supported by this provider. - umf_result_t (*open_ipc_handle)(void *provider, void *providerIpcData, - void **ptr); - - /// - /// @brief Closes an IPC memory handle. - /// @param provider pointer to the memory provider. - /// @param ptr pointer to the memory retrieved with open_ipc_handle function. - /// @param size size of the memory address range. - /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. - /// UMF_RESULT_ERROR_INVALID_ARGUMENT if invalid \p ptr is passed. - /// UMF_RESULT_ERROR_NOT_SUPPORTED if IPC functionality is not supported by this provider. - umf_result_t (*close_ipc_handle)(void *provider, void *ptr, size_t size); -} umf_memory_provider_ipc_ops_t; - /// /// @brief This structure comprises function pointers used by corresponding /// umfMemoryProvider* calls. Each memory provider implementation should /// initialize all function pointers. /// typedef struct umf_memory_provider_ops_t { + /// Size of this structure. + /// Should be initialized with sizeof(umf_memory_provider_ops_t) in the current umf version + size_t size; + /// Version of the ops structure. /// Should be initialized using UMF_PROVIDER_OPS_VERSION_CURRENT. uint32_t version; @@ -241,14 +126,133 @@ typedef struct umf_memory_provider_ops_t { const char *(*get_name)(void *provider); /// - /// @brief Optional ops + /// Following functions, with ext prefix, are optional and memory provider implementation + /// can keep them NULL. + /// + + /// + /// @brief Discard physical pages within the virtual memory mapping associated at the given addr + /// and \p size. This call is asynchronous and may delay purging the pages indefinitely. + /// @param provider pointer to the memory provider + /// @param ptr beginning of the virtual memory range + /// @param size size of the virtual memory range + /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. + /// UMF_RESULT_ERROR_INVALID_ALIGNMENT if ptr or size is not page-aligned. + /// UMF_RESULT_ERROR_NOT_SUPPORTED if operation is not supported by this provider. + /// + umf_result_t (*ext_purge_lazy)(void *provider, void *ptr, size_t size); + + /// + /// @brief Discard physical pages within the virtual memory mapping associated at the given addr and \p size. + /// This call is synchronous and if it succeeds, pages are guaranteed to be zero-filled on the next access. + /// @param provider pointer to the memory provider + /// @param ptr beginning of the virtual memory range + /// @param size size of the virtual memory range + /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure + /// UMF_RESULT_ERROR_INVALID_ALIGNMENT if ptr or size is not page-aligned. + /// UMF_RESULT_ERROR_NOT_SUPPORTED if operation is not supported by this provider. /// - umf_memory_provider_ext_ops_t ext; + umf_result_t (*ext_purge_force)(void *provider, void *ptr, size_t size); /// - /// @brief Optional IPC ops. The API allows sharing of memory objects across different processes. + /// @brief Merges two coarse grain allocations into a single allocation that + /// can be managed (freed) as a whole. + /// allocation_split and allocation_merge should be both set or both NULL. + /// allocation_merge should NOT be called concurrently with allocation_split() + /// with the same pointer. + /// @param hProvider handle to the memory provider + /// @param lowPtr pointer to the first allocation + /// @param highPtr pointer to the second allocation (should be > lowPtr) + /// @param totalSize size of a new merged allocation. Should be equal + /// to the sum of sizes of allocations beginning at lowPtr and highPtr + /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure + /// + umf_result_t (*ext_allocation_merge)(void *hProvider, void *lowPtr, + void *highPtr, size_t totalSize); + /// - umf_memory_provider_ipc_ops_t ipc; + /// @brief Splits a coarse grain allocation into 2 adjacent allocations that + /// can be managed (freed) separately. + /// allocation_split and allocation_merge should be both set or both NULL. + /// allocation_split should NOT be called concurrently with allocation_merge() + /// with the same pointer. + /// @param hProvider handle to the memory provider + /// @param ptr pointer to the beginning of the allocation + /// @param totalSize total size of the allocation to be split + /// @param firstSize size of the first new allocation, second allocation + // has a size equal to totalSize - firstSize + /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure + /// + umf_result_t (*ext_allocation_split)(void *hProvider, void *ptr, + size_t totalSize, size_t firstSize); + /// @brief Retrieve the size of opaque data structure required to store IPC data. + /// \details + /// * If provider supports IPC, all following functions pointers: + /// ext_get_ipc_handle_size, ext_get_ipc_handle, ext_put_ipc_handle, ext_open_ipc_handle, ext_close_ipc_handle, + /// must either be all set or all NULL. + /// @param provider pointer to the memory provider. + /// @param size [out] pointer to the size. + /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. + /// UMF_RESULT_ERROR_NOT_SUPPORTED if IPC functionality is not supported by this provider. + umf_result_t (*ext_get_ipc_handle_size)(void *provider, size_t *size); + + /// + /// @brief Retrieve an IPC memory handle for the specified allocation. + /// \details + /// * If provider supports IPC, all following functions pointers: + /// ext_get_ipc_handle_size, ext_get_ipc_handle, ext_put_ipc_handle, ext_open_ipc_handle, ext_close_ipc_handle, + /// must either be all set or all NULL. + /// @param provider pointer to the memory provider. + /// @param ptr beginning of the virtual memory range. + /// @param size size of the memory address range. + /// @param providerIpcData [out] pointer to the preallocated opaque data structure to store IPC handle. + /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. + /// UMF_RESULT_ERROR_INVALID_ARGUMENT if ptr was not allocated by this provider. + /// UMF_RESULT_ERROR_NOT_SUPPORTED if IPC functionality is not supported by this provider. + umf_result_t (*ext_get_ipc_handle)(void *provider, const void *ptr, + size_t size, void *providerIpcData); + + /// + /// @brief Release IPC handle retrieved with get_ipc_handle function. + /// \details + /// * If provider supports IPC, all following functions pointers: + /// ext_get_ipc_handle_size, ext_get_ipc_handle, ext_put_ipc_handle, ext_open_ipc_handle, ext_close_ipc_handle, + /// must either be all set or all NULL. + /// @param provider pointer to the memory provider. + /// @param providerIpcData pointer to the IPC opaque data structure. + /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. + /// UMF_RESULT_ERROR_INVALID_ARGUMENT if providerIpcData was not created by this provider. + /// UMF_RESULT_ERROR_NOT_SUPPORTED if IPC functionality is not supported by this provider. + umf_result_t (*ext_put_ipc_handle)(void *provider, void *providerIpcData); + + /// + /// @brief Open IPC handle. + /// \details + /// * If provider supports IPC, all following functions pointers: + /// ext_get_ipc_handle_size, ext_get_ipc_handle, ext_put_ipc_handle, ext_open_ipc_handle, ext_close_ipc_handle, + /// must either be all set or all NULL. + /// @param provider pointer to the memory provider. + /// @param providerIpcData pointer to the IPC opaque data structure. + /// @param ptr [out] pointer to the memory to be used in the current process. + /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. + /// UMF_RESULT_ERROR_INVALID_ARGUMENT if providerIpcData cannot be handled by the provider. + /// UMF_RESULT_ERROR_NOT_SUPPORTED if IPC functionality is not supported by this provider. + umf_result_t (*ext_open_ipc_handle)(void *provider, void *providerIpcData, + void **ptr); + /// + /// @brief Closes an IPC memory handle. + /// \details + /// * If provider supports IPC, all following functions pointers: + /// ext_get_ipc_handle_size, ext_get_ipc_handle, ext_put_ipc_handle, ext_open_ipc_handle, ext_close_ipc_handle, + /// must either be all set or all NULL. + /// @param provider pointer to the memory provider. + /// @param ptr pointer to the memory retrieved with open_ipc_handle function. + /// @param size size of the memory address range. + /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. + /// UMF_RESULT_ERROR_INVALID_ARGUMENT if invalid \p ptr is passed. + /// UMF_RESULT_ERROR_NOT_SUPPORTED if IPC functionality is not supported by this provider. + umf_result_t (*ext_close_ipc_handle)(void *provider, void *ptr, + size_t size); /// /// @brief Control operation for the memory provider. @@ -263,9 +267,13 @@ typedef struct umf_memory_provider_ops_t { /// /// @return umf_result_t result of the control operation. /// - umf_result_t (*ctl)(void *hProvider, int operationType, const char *name, - void *arg, umf_ctl_query_type_t queryType); + umf_result_t (*ext_ctl)(void *hProvider, int operationType, + const char *name, void *arg, + umf_ctl_query_type_t queryType); + /// Reserved for future use + /// Note: When copying this structure, use its provided size field rather than using sizeof. + char reserved[]; } umf_memory_provider_ops_t; #ifdef __cplusplus diff --git a/src/memory_pool.c b/src/memory_pool.c index 985600d2a..c7d601436 100644 --- a/src/memory_pool.c +++ b/src/memory_pool.c @@ -30,7 +30,7 @@ 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, /*unused*/ 0, extra_name, arg, queryType); + hPool->ops.ext_ctl(hPool, /*unused*/ 0, extra_name, arg, queryType); return 0; } @@ -58,11 +58,6 @@ 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 " @@ -70,6 +65,24 @@ static umf_result_t umfPoolCreateInternal(const umf_memory_pool_ops_t *ops, ops->version, UMF_POOL_OPS_VERSION_CURRENT); } + if (ops->size == 0) { + LOG_ERR("Memory Pool ops size is not set"); + return UMF_RESULT_ERROR_INVALID_ARGUMENT; + } + + if (ops->size > sizeof(umf_memory_pool_ops_t)) { + LOG_ERR("Memory Pool ops size \"%zu\" is greater than the current " + "size \"%zu\"", + ops->size, sizeof(umf_memory_pool_ops_t)); + return UMF_RESULT_ERROR_INVALID_ARGUMENT; + } + + 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); @@ -84,8 +97,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)) { diff --git a/src/memory_provider.c b/src/memory_provider.c index 627ad23ac..2a4878d34 100644 --- a/src/memory_provider.c +++ b/src/memory_provider.c @@ -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, - queryType); + hProvider->ops.ext_ctl(hProvider->provider_priv, /*unused*/ 0, extra_name, + arg, queryType); return 0; } @@ -120,67 +120,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("Error: 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("Error: 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("Error: 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, @@ -197,6 +208,18 @@ umf_result_t umfMemoryProviderCreate(const umf_memory_provider_ops_t *ops, ops->version, UMF_PROVIDER_OPS_VERSION_CURRENT); } + if (ops->size == 0) { + LOG_ERR("Memory Provider ops size is zero"); + return UMF_RESULT_ERROR_INVALID_ARGUMENT; + } + + if (ops->size > sizeof(umf_memory_provider_ops_t)) { + LOG_ERR("Memory Provider ops size \"%zu\" is greater than the " + "current size \"%zu\"", + ops->size, sizeof(umf_memory_provider_ops_t)); + return UMF_RESULT_ERROR_INVALID_ARGUMENT; + } + umf_memory_provider_handle_t provider = umf_ba_global_alloc(sizeof(umf_memory_provider_t)); if (!provider) { @@ -300,7 +323,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; } @@ -310,7 +333,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; } @@ -329,7 +352,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; @@ -347,7 +370,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; @@ -358,7 +381,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); } @@ -369,7 +392,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); } @@ -378,7 +401,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); } @@ -388,7 +411,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); } @@ -397,6 +420,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); } diff --git a/src/pool/pool_disjoint.c b/src/pool/pool_disjoint.c index 8ce9f70dd..8f3a7a0a8 100644 --- a/src/pool/pool_disjoint.c +++ b/src/pool/pool_disjoint.c @@ -929,6 +929,7 @@ void disjoint_pool_finalize(void *pool) { } static umf_memory_pool_ops_t UMF_DISJOINT_POOL_OPS = { + .size = sizeof(umf_memory_provider_ops_t), .version = UMF_VERSION_CURRENT, .initialize = disjoint_pool_initialize, .finalize = disjoint_pool_finalize, diff --git a/src/pool/pool_jemalloc.c b/src/pool/pool_jemalloc.c index bed78ce26..ed27bce87 100644 --- a/src/pool/pool_jemalloc.c +++ b/src/pool/pool_jemalloc.c @@ -527,6 +527,7 @@ static umf_result_t op_get_last_allocation_error(void *pool) { } static umf_memory_pool_ops_t UMF_JEMALLOC_POOL_OPS = { + .size = sizeof(umf_memory_provider_ops_t), .version = UMF_POOL_OPS_VERSION_CURRENT, .initialize = op_initialize, .finalize = op_finalize, diff --git a/src/pool/pool_proxy.c b/src/pool/pool_proxy.c index 91ae098ca..9800e90ff 100644 --- a/src/pool/pool_proxy.c +++ b/src/pool/pool_proxy.c @@ -123,6 +123,7 @@ static umf_result_t proxy_get_last_allocation_error(void *pool) { } static umf_memory_pool_ops_t UMF_PROXY_POOL_OPS = { + .size = sizeof(umf_memory_pool_ops_t), .version = UMF_POOL_OPS_VERSION_CURRENT, .initialize = proxy_pool_initialize, .finalize = proxy_pool_finalize, diff --git a/src/pool/pool_scalable.c b/src/pool/pool_scalable.c index ea0260659..8979de64e 100644 --- a/src/pool/pool_scalable.c +++ b/src/pool/pool_scalable.c @@ -444,6 +444,7 @@ static umf_result_t pool_ctl(void *hPool, int operationType, const char *name, } static umf_memory_pool_ops_t UMF_SCALABLE_POOL_OPS = { + .size = sizeof(umf_memory_provider_ops_t), .version = UMF_POOL_OPS_VERSION_CURRENT, .initialize = tbb_pool_initialize, .finalize = tbb_pool_finalize, @@ -454,7 +455,7 @@ 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}; + .ext_ctl = pool_ctl}; const umf_memory_pool_ops_t *umfScalablePoolOps(void) { return &UMF_SCALABLE_POOL_OPS; diff --git a/src/provider/provider_cuda.c b/src/provider/provider_cuda.c index f3e0658a5..98ad48645 100644 --- a/src/provider/provider_cuda.c +++ b/src/provider/provider_cuda.c @@ -732,6 +732,7 @@ cu_memory_provider_close_ipc_handle(void *provider, void *ptr, size_t size) { } static umf_memory_provider_ops_t UMF_CUDA_MEMORY_PROVIDER_OPS = { + .size = sizeof(umf_memory_provider_ops_t), .version = UMF_PROVIDER_OPS_VERSION_CURRENT, .initialize = cu_memory_provider_initialize, .finalize = cu_memory_provider_finalize, @@ -743,16 +744,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) { diff --git a/src/provider/provider_devdax_memory.c b/src/provider/provider_devdax_memory.c index 50e60cdb7..5c806334d 100644 --- a/src/provider/provider_devdax_memory.c +++ b/src/provider/provider_devdax_memory.c @@ -529,6 +529,7 @@ static umf_result_t devdax_free(void *provider, void *ptr, size_t size) { } static umf_memory_provider_ops_t UMF_DEVDAX_MEMORY_PROVIDER_OPS = { + .size = sizeof(umf_memory_provider_ops_t), .version = UMF_PROVIDER_OPS_VERSION_CURRENT, .initialize = devdax_initialize, .finalize = devdax_finalize, @@ -538,15 +539,15 @@ static umf_memory_provider_ops_t UMF_DEVDAX_MEMORY_PROVIDER_OPS = { .get_recommended_page_size = devdax_get_recommended_page_size, .get_min_page_size = devdax_get_min_page_size, .get_name = devdax_get_name, - .ext.purge_lazy = devdax_purge_lazy, - .ext.purge_force = devdax_purge_force, - .ext.allocation_merge = devdax_allocation_merge, - .ext.allocation_split = devdax_allocation_split, - .ipc.get_ipc_handle_size = devdax_get_ipc_handle_size, - .ipc.get_ipc_handle = devdax_get_ipc_handle, - .ipc.put_ipc_handle = devdax_put_ipc_handle, - .ipc.open_ipc_handle = devdax_open_ipc_handle, - .ipc.close_ipc_handle = devdax_close_ipc_handle}; + .ext_purge_lazy = devdax_purge_lazy, + .ext_purge_force = devdax_purge_force, + .ext_allocation_merge = devdax_allocation_merge, + .ext_allocation_split = devdax_allocation_split, + .ext_get_ipc_handle_size = devdax_get_ipc_handle_size, + .ext_get_ipc_handle = devdax_get_ipc_handle, + .ext_put_ipc_handle = devdax_put_ipc_handle, + .ext_open_ipc_handle = devdax_open_ipc_handle, + .ext_close_ipc_handle = devdax_close_ipc_handle}; const umf_memory_provider_ops_t *umfDevDaxMemoryProviderOps(void) { return &UMF_DEVDAX_MEMORY_PROVIDER_OPS; diff --git a/src/provider/provider_file_memory.c b/src/provider/provider_file_memory.c index 7754078d9..6e397af08 100644 --- a/src/provider/provider_file_memory.c +++ b/src/provider/provider_file_memory.c @@ -854,6 +854,7 @@ static umf_result_t file_free(void *provider, void *ptr, size_t size) { } static umf_memory_provider_ops_t UMF_FILE_MEMORY_PROVIDER_OPS = { + .size = sizeof(umf_memory_provider_ops_t), .version = UMF_PROVIDER_OPS_VERSION_CURRENT, .initialize = file_initialize, .finalize = file_finalize, @@ -863,15 +864,15 @@ static umf_memory_provider_ops_t UMF_FILE_MEMORY_PROVIDER_OPS = { .get_recommended_page_size = file_get_recommended_page_size, .get_min_page_size = file_get_min_page_size, .get_name = file_get_name, - .ext.purge_lazy = file_purge_lazy, - .ext.purge_force = file_purge_force, - .ext.allocation_merge = file_allocation_merge, - .ext.allocation_split = file_allocation_split, - .ipc.get_ipc_handle_size = file_get_ipc_handle_size, - .ipc.get_ipc_handle = file_get_ipc_handle, - .ipc.put_ipc_handle = file_put_ipc_handle, - .ipc.open_ipc_handle = file_open_ipc_handle, - .ipc.close_ipc_handle = file_close_ipc_handle}; + .ext_purge_lazy = file_purge_lazy, + .ext_purge_force = file_purge_force, + .ext_allocation_merge = file_allocation_merge, + .ext_allocation_split = file_allocation_split, + .ext_get_ipc_handle_size = file_get_ipc_handle_size, + .ext_get_ipc_handle = file_get_ipc_handle, + .ext_put_ipc_handle = file_put_ipc_handle, + .ext_open_ipc_handle = file_open_ipc_handle, + .ext_close_ipc_handle = file_close_ipc_handle}; const umf_memory_provider_ops_t *umfFileMemoryProviderOps(void) { return &UMF_FILE_MEMORY_PROVIDER_OPS; diff --git a/src/provider/provider_fixed_memory.c b/src/provider/provider_fixed_memory.c index 1ce937313..6b7db7496 100644 --- a/src/provider/provider_fixed_memory.c +++ b/src/provider/provider_fixed_memory.c @@ -288,6 +288,7 @@ static umf_result_t fixed_ctl(void *provider, int operationType, } static umf_memory_provider_ops_t UMF_FIXED_MEMORY_PROVIDER_OPS = { + .size = sizeof(umf_memory_provider_ops_t), .version = UMF_PROVIDER_OPS_VERSION_CURRENT, .initialize = fixed_initialize, .finalize = fixed_finalize, @@ -297,16 +298,16 @@ static umf_memory_provider_ops_t UMF_FIXED_MEMORY_PROVIDER_OPS = { .get_recommended_page_size = fixed_get_recommended_page_size, .get_min_page_size = fixed_get_min_page_size, .get_name = fixed_get_name, - .ext.purge_lazy = fixed_purge_lazy, - .ext.purge_force = fixed_purge_force, - .ext.allocation_merge = fixed_allocation_merge, - .ext.allocation_split = fixed_allocation_split, - .ipc.get_ipc_handle_size = NULL, - .ipc.get_ipc_handle = NULL, - .ipc.put_ipc_handle = NULL, - .ipc.open_ipc_handle = NULL, - .ipc.close_ipc_handle = NULL, - .ctl = fixed_ctl}; + .ext_purge_lazy = fixed_purge_lazy, + .ext_purge_force = fixed_purge_force, + .ext_allocation_merge = fixed_allocation_merge, + .ext_allocation_split = fixed_allocation_split, + .ext_get_ipc_handle_size = NULL, + .ext_get_ipc_handle = NULL, + .ext_put_ipc_handle = NULL, + .ext_open_ipc_handle = NULL, + .ext_close_ipc_handle = NULL, + .ext_ctl = fixed_ctl}; const umf_memory_provider_ops_t *umfFixedMemoryProviderOps(void) { return &UMF_FIXED_MEMORY_PROVIDER_OPS; diff --git a/src/provider/provider_level_zero.c b/src/provider/provider_level_zero.c index 623bf7054..09882c5d3 100644 --- a/src/provider/provider_level_zero.c +++ b/src/provider/provider_level_zero.c @@ -843,6 +843,7 @@ ze_memory_provider_close_ipc_handle(void *provider, void *ptr, size_t size) { } static umf_memory_provider_ops_t UMF_LEVEL_ZERO_MEMORY_PROVIDER_OPS = { + .size = sizeof(umf_memory_provider_ops_t), .version = UMF_PROVIDER_OPS_VERSION_CURRENT, .initialize = ze_memory_provider_initialize, .finalize = ze_memory_provider_finalize, @@ -852,15 +853,15 @@ static umf_memory_provider_ops_t UMF_LEVEL_ZERO_MEMORY_PROVIDER_OPS = { .get_recommended_page_size = ze_memory_provider_get_recommended_page_size, .get_min_page_size = ze_memory_provider_get_min_page_size, .get_name = ze_memory_provider_get_name, - .ext.purge_lazy = ze_memory_provider_purge_lazy, - .ext.purge_force = ze_memory_provider_purge_force, - .ext.allocation_merge = ze_memory_provider_allocation_merge, - .ext.allocation_split = ze_memory_provider_allocation_split, - .ipc.get_ipc_handle_size = ze_memory_provider_get_ipc_handle_size, - .ipc.get_ipc_handle = ze_memory_provider_get_ipc_handle, - .ipc.put_ipc_handle = ze_memory_provider_put_ipc_handle, - .ipc.open_ipc_handle = ze_memory_provider_open_ipc_handle, - .ipc.close_ipc_handle = ze_memory_provider_close_ipc_handle, + .ext_purge_lazy = ze_memory_provider_purge_lazy, + .ext_purge_force = ze_memory_provider_purge_force, + .ext_allocation_merge = ze_memory_provider_allocation_merge, + .ext_allocation_split = ze_memory_provider_allocation_split, + .ext_get_ipc_handle_size = ze_memory_provider_get_ipc_handle_size, + .ext_get_ipc_handle = ze_memory_provider_get_ipc_handle, + .ext_put_ipc_handle = ze_memory_provider_put_ipc_handle, + .ext_open_ipc_handle = ze_memory_provider_open_ipc_handle, + .ext_close_ipc_handle = ze_memory_provider_close_ipc_handle, }; const umf_memory_provider_ops_t *umfLevelZeroMemoryProviderOps(void) { diff --git a/src/provider/provider_os_memory.c b/src/provider/provider_os_memory.c index 744293691..c33317205 100644 --- a/src/provider/provider_os_memory.c +++ b/src/provider/provider_os_memory.c @@ -1449,6 +1449,7 @@ static umf_result_t os_ctl(void *hProvider, int operationType, const char *name, } static umf_memory_provider_ops_t UMF_OS_MEMORY_PROVIDER_OPS = { + .size = sizeof(umf_memory_provider_ops_t), .version = UMF_PROVIDER_OPS_VERSION_CURRENT, .initialize = os_initialize, .finalize = os_finalize, @@ -1458,16 +1459,16 @@ static umf_memory_provider_ops_t UMF_OS_MEMORY_PROVIDER_OPS = { .get_recommended_page_size = os_get_recommended_page_size, .get_min_page_size = os_get_min_page_size, .get_name = os_get_name, - .ext.purge_lazy = os_purge_lazy, - .ext.purge_force = os_purge_force, - .ext.allocation_merge = os_allocation_merge, - .ext.allocation_split = os_allocation_split, - .ipc.get_ipc_handle_size = os_get_ipc_handle_size, - .ipc.get_ipc_handle = os_get_ipc_handle, - .ipc.put_ipc_handle = os_put_ipc_handle, - .ipc.open_ipc_handle = os_open_ipc_handle, - .ipc.close_ipc_handle = os_close_ipc_handle, - .ctl = os_ctl, + .ext_purge_lazy = os_purge_lazy, + .ext_purge_force = os_purge_force, + .ext_allocation_merge = os_allocation_merge, + .ext_allocation_split = os_allocation_split, + .ext_get_ipc_handle_size = os_get_ipc_handle_size, + .ext_get_ipc_handle = os_get_ipc_handle, + .ext_put_ipc_handle = os_put_ipc_handle, + .ext_open_ipc_handle = os_open_ipc_handle, + .ext_close_ipc_handle = os_close_ipc_handle, + .ext_ctl = os_ctl, }; const umf_memory_provider_ops_t *umfOsMemoryProviderOps(void) { diff --git a/src/provider/provider_tracking.c b/src/provider/provider_tracking.c index 2636460e6..5cecf02f6 100644 --- a/src/provider/provider_tracking.c +++ b/src/provider/provider_tracking.c @@ -1097,6 +1097,7 @@ static umf_result_t trackingCloseIpcHandle(void *provider, void *ptr, } umf_memory_provider_ops_t UMF_TRACKING_MEMORY_PROVIDER_OPS = { + .size = sizeof(umf_memory_provider_ops_t), .version = UMF_PROVIDER_OPS_VERSION_CURRENT, .initialize = trackingInitialize, .finalize = trackingFinalize, @@ -1106,15 +1107,15 @@ umf_memory_provider_ops_t UMF_TRACKING_MEMORY_PROVIDER_OPS = { .get_min_page_size = trackingGetMinPageSize, .get_recommended_page_size = trackingGetRecommendedPageSize, .get_name = trackingName, - .ext.purge_force = trackingPurgeForce, - .ext.purge_lazy = trackingPurgeLazy, - .ext.allocation_split = trackingAllocationSplit, - .ext.allocation_merge = trackingAllocationMerge, - .ipc.get_ipc_handle_size = trackingGetIpcHandleSize, - .ipc.get_ipc_handle = trackingGetIpcHandle, - .ipc.put_ipc_handle = trackingPutIpcHandle, - .ipc.open_ipc_handle = trackingOpenIpcHandle, - .ipc.close_ipc_handle = trackingCloseIpcHandle}; + .ext_purge_force = trackingPurgeForce, + .ext_purge_lazy = trackingPurgeLazy, + .ext_allocation_split = trackingAllocationSplit, + .ext_allocation_merge = trackingAllocationMerge, + .ext_get_ipc_handle_size = trackingGetIpcHandleSize, + .ext_get_ipc_handle = trackingGetIpcHandle, + .ext_put_ipc_handle = trackingPutIpcHandle, + .ext_open_ipc_handle = trackingOpenIpcHandle, + .ext_close_ipc_handle = trackingCloseIpcHandle}; umf_result_t umfTrackingMemoryProviderCreate( umf_memory_provider_handle_t hUpstream, umf_memory_pool_handle_t hPool, diff --git a/test/common/provider.hpp b/test/common/provider.hpp index d362d5006..a393a77c6 100644 --- a/test/common/provider.hpp +++ b/test/common/provider.hpp @@ -53,45 +53,46 @@ typedef struct provider_base_t { return UMF_RESULT_ERROR_UNKNOWN; } const char *get_name() noexcept { return "base"; } - umf_result_t purge_lazy([[maybe_unused]] void *ptr, - [[maybe_unused]] size_t size) noexcept { + umf_result_t ext_purge_lazy([[maybe_unused]] void *ptr, + [[maybe_unused]] size_t size) noexcept { return UMF_RESULT_ERROR_UNKNOWN; } - umf_result_t purge_force([[maybe_unused]] void *ptr, - [[maybe_unused]] size_t size) noexcept { + umf_result_t ext_purge_force([[maybe_unused]] void *ptr, + [[maybe_unused]] size_t size) noexcept { return UMF_RESULT_ERROR_UNKNOWN; } - umf_result_t allocation_merge([[maybe_unused]] void *lowPtr, - [[maybe_unused]] void *highPtr, - [[maybe_unused]] size_t totalSize) { + umf_result_t ext_allocation_merge([[maybe_unused]] void *lowPtr, + [[maybe_unused]] void *highPtr, + [[maybe_unused]] size_t totalSize) { return UMF_RESULT_ERROR_UNKNOWN; } - umf_result_t allocation_split([[maybe_unused]] void *ptr, - [[maybe_unused]] size_t totalSize, - [[maybe_unused]] size_t firstSize) { + umf_result_t ext_allocation_split([[maybe_unused]] void *ptr, + [[maybe_unused]] size_t totalSize, + [[maybe_unused]] size_t firstSize) { return UMF_RESULT_ERROR_UNKNOWN; } - umf_result_t get_ipc_handle_size([[maybe_unused]] size_t *size) noexcept { + umf_result_t + ext_get_ipc_handle_size([[maybe_unused]] size_t *size) noexcept { return UMF_RESULT_ERROR_UNKNOWN; } umf_result_t - get_ipc_handle([[maybe_unused]] const void *ptr, - [[maybe_unused]] size_t size, - [[maybe_unused]] void *providerIpcData) noexcept { + ext_get_ipc_handle([[maybe_unused]] const void *ptr, + [[maybe_unused]] size_t size, + [[maybe_unused]] void *providerIpcData) noexcept { return UMF_RESULT_ERROR_UNKNOWN; } umf_result_t - put_ipc_handle([[maybe_unused]] void *providerIpcData) noexcept { + ext_put_ipc_handle([[maybe_unused]] void *providerIpcData) noexcept { return UMF_RESULT_ERROR_UNKNOWN; } - umf_result_t open_ipc_handle([[maybe_unused]] void *providerIpcData, - [[maybe_unused]] void **ptr) noexcept { + umf_result_t ext_open_ipc_handle([[maybe_unused]] void *providerIpcData, + [[maybe_unused]] void **ptr) noexcept { return UMF_RESULT_ERROR_UNKNOWN; } - umf_result_t close_ipc_handle([[maybe_unused]] void *ptr, - [[maybe_unused]] size_t size) noexcept { + umf_result_t ext_close_ipc_handle([[maybe_unused]] void *ptr, + [[maybe_unused]] size_t size) noexcept { return UMF_RESULT_ERROR_UNKNOWN; } virtual ~provider_base_t() = default; diff --git a/test/common/provider_null.c b/test/common/provider_null.c index d74c3ffaa..b74c2328c 100644 --- a/test/common/provider_null.c +++ b/test/common/provider_null.c @@ -129,6 +129,7 @@ static umf_result_t nullCloseIpcHandle(void *provider, void *ptr, size_t size) { } umf_memory_provider_ops_t UMF_NULL_PROVIDER_OPS = { + .size = sizeof(umf_memory_provider_ops_t), .version = UMF_PROVIDER_OPS_VERSION_CURRENT, .initialize = nullInitialize, .finalize = nullFinalize, @@ -138,13 +139,13 @@ umf_memory_provider_ops_t UMF_NULL_PROVIDER_OPS = { .get_recommended_page_size = nullGetRecommendedPageSize, .get_min_page_size = nullGetPageSize, .get_name = nullName, - .ext.purge_lazy = nullPurgeLazy, - .ext.purge_force = nullPurgeForce, - .ext.allocation_merge = nullAllocationMerge, - .ext.allocation_split = nullAllocationSplit, - .ipc.get_ipc_handle_size = nullGetIpcHandleSize, - .ipc.get_ipc_handle = nullGetIpcHandle, - .ipc.put_ipc_handle = nullPutIpcHandle, - .ipc.open_ipc_handle = nullOpenIpcHandle, - .ipc.close_ipc_handle = nullCloseIpcHandle, + .ext_purge_lazy = nullPurgeLazy, + .ext_purge_force = nullPurgeForce, + .ext_allocation_merge = nullAllocationMerge, + .ext_allocation_split = nullAllocationSplit, + .ext_get_ipc_handle_size = nullGetIpcHandleSize, + .ext_get_ipc_handle = nullGetIpcHandle, + .ext_put_ipc_handle = nullPutIpcHandle, + .ext_open_ipc_handle = nullOpenIpcHandle, + .ext_close_ipc_handle = nullCloseIpcHandle, }; diff --git a/test/common/provider_trace.c b/test/common/provider_trace.c index b30e92225..6f5e95e0f 100644 --- a/test/common/provider_trace.c +++ b/test/common/provider_trace.c @@ -199,13 +199,13 @@ umf_memory_provider_ops_t UMF_TRACE_PROVIDER_OPS = { .get_recommended_page_size = traceGetRecommendedPageSize, .get_min_page_size = traceGetPageSize, .get_name = traceName, - .ext.purge_lazy = tracePurgeLazy, - .ext.purge_force = tracePurgeForce, - .ext.allocation_merge = traceAllocationMerge, - .ext.allocation_split = traceAllocationSplit, - .ipc.get_ipc_handle_size = traceGetIpcHandleSize, - .ipc.get_ipc_handle = traceGetIpcHandle, - .ipc.put_ipc_handle = tracePutIpcHandle, - .ipc.open_ipc_handle = traceOpenIpcHandle, - .ipc.close_ipc_handle = traceCloseIpcHandle, + .ext_purge_lazy = tracePurgeLazy, + .ext_purge_force = tracePurgeForce, + .ext_allocation_merge = traceAllocationMerge, + .ext_allocation_split = traceAllocationSplit, + .ext_get_ipc_handle_size = traceGetIpcHandleSize, + .ext_get_ipc_handle = traceGetIpcHandle, + .ext_put_ipc_handle = tracePutIpcHandle, + .ext_open_ipc_handle = traceOpenIpcHandle, + .ext_close_ipc_handle = traceCloseIpcHandle, }; diff --git a/test/ipc_negative.cpp b/test/ipc_negative.cpp index 5c4cccf22..7cbeb3668 100644 --- a/test/ipc_negative.cpp +++ b/test/ipc_negative.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2024 Intel Corporation +// Copyright (C) 2024-2025 Intel Corporation // Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception @@ -16,11 +16,11 @@ struct IpcNotSupported : umf_test::test { protected: void SetUp() override { umf_memory_provider_ops_t provider_ops = UMF_NULL_PROVIDER_OPS; - provider_ops.ipc.get_ipc_handle_size = nullptr; - provider_ops.ipc.get_ipc_handle = nullptr; - provider_ops.ipc.open_ipc_handle = nullptr; - provider_ops.ipc.put_ipc_handle = nullptr; - provider_ops.ipc.close_ipc_handle = nullptr; + provider_ops.ext_get_ipc_handle_size = nullptr; + provider_ops.ext_get_ipc_handle = nullptr; + provider_ops.ext_open_ipc_handle = nullptr; + provider_ops.ext_put_ipc_handle = nullptr; + provider_ops.ext_close_ipc_handle = nullptr; umf_result_t ret; ret = umfMemoryProviderCreate(&provider_ops, nullptr, &provider); diff --git a/test/memoryProviderAPI.cpp b/test/memoryProviderAPI.cpp index 6eb1b40e0..0ec6fb633 100644 --- a/test/memoryProviderAPI.cpp +++ b/test/memoryProviderAPI.cpp @@ -91,7 +91,7 @@ TEST_F(test, memoryProviderTrace) { TEST_F(test, memoryProviderOpsNullPurgeLazyField) { umf_memory_provider_ops_t provider_ops = UMF_NULL_PROVIDER_OPS; - provider_ops.ext.purge_lazy = nullptr; + provider_ops.ext_purge_lazy = nullptr; umf_memory_provider_handle_t hProvider; auto ret = umfMemoryProviderCreate(&provider_ops, nullptr, &hProvider); ASSERT_EQ(ret, UMF_RESULT_SUCCESS); @@ -104,7 +104,7 @@ TEST_F(test, memoryProviderOpsNullPurgeLazyField) { TEST_F(test, memoryProviderOpsNullPurgeForceField) { umf_memory_provider_ops_t provider_ops = UMF_NULL_PROVIDER_OPS; - provider_ops.ext.purge_force = nullptr; + provider_ops.ext_purge_force = nullptr; umf_memory_provider_handle_t hProvider; auto ret = umfMemoryProviderCreate(&provider_ops, nullptr, &hProvider); ASSERT_EQ(ret, UMF_RESULT_SUCCESS); @@ -117,8 +117,8 @@ TEST_F(test, memoryProviderOpsNullPurgeForceField) { TEST_F(test, memoryProviderOpsNullAllocationSplitAllocationMergeFields) { umf_memory_provider_ops_t provider_ops = UMF_NULL_PROVIDER_OPS; - provider_ops.ext.allocation_split = nullptr; - provider_ops.ext.allocation_merge = nullptr; + provider_ops.ext_allocation_split = nullptr; + provider_ops.ext_allocation_merge = nullptr; umf_memory_provider_handle_t hProvider; auto ret = umfMemoryProviderCreate(&provider_ops, nullptr, &hProvider); ASSERT_EQ(ret, UMF_RESULT_SUCCESS); @@ -138,11 +138,11 @@ TEST_F(test, memoryProviderOpsNullAllocationSplitAllocationMergeFields) { TEST_F(test, memoryProviderOpsNullAllIPCFields) { umf_memory_provider_ops_t provider_ops = UMF_NULL_PROVIDER_OPS; - provider_ops.ipc.get_ipc_handle_size = nullptr; - provider_ops.ipc.get_ipc_handle = nullptr; - provider_ops.ipc.put_ipc_handle = nullptr; - provider_ops.ipc.open_ipc_handle = nullptr; - provider_ops.ipc.close_ipc_handle = nullptr; + provider_ops.ext_get_ipc_handle_size = nullptr; + provider_ops.ext_get_ipc_handle = nullptr; + provider_ops.ext_put_ipc_handle = nullptr; + provider_ops.ext_open_ipc_handle = nullptr; + provider_ops.ext_close_ipc_handle = nullptr; umf_memory_provider_handle_t hProvider; auto ret = umfMemoryProviderCreate(&provider_ops, nullptr, &hProvider); @@ -233,7 +233,7 @@ TEST_F(test, memoryProviderOpsNullGetNameField) { TEST_F(test, memoryProviderOpsNullAllocationSplitField) { umf_memory_provider_ops_t provider_ops = UMF_NULL_PROVIDER_OPS; - provider_ops.ext.allocation_split = nullptr; + provider_ops.ext_allocation_split = nullptr; umf_memory_provider_handle_t hProvider; auto ret = umfMemoryProviderCreate(&provider_ops, nullptr, &hProvider); ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT); @@ -241,7 +241,7 @@ TEST_F(test, memoryProviderOpsNullAllocationSplitField) { TEST_F(test, memoryProviderOpsNullAllocationMergeField) { umf_memory_provider_ops_t provider_ops = UMF_NULL_PROVIDER_OPS; - provider_ops.ext.allocation_merge = nullptr; + provider_ops.ext_allocation_merge = nullptr; umf_memory_provider_handle_t hProvider; auto ret = umfMemoryProviderCreate(&provider_ops, nullptr, &hProvider); ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT); @@ -249,7 +249,7 @@ TEST_F(test, memoryProviderOpsNullAllocationMergeField) { TEST_F(test, memoryProviderOpsNullGetIpcHandleSize) { umf_memory_provider_ops_t provider_ops = UMF_NULL_PROVIDER_OPS; - provider_ops.ipc.get_ipc_handle_size = nullptr; + provider_ops.ext_get_ipc_handle_size = nullptr; umf_memory_provider_handle_t hProvider; auto ret = umfMemoryProviderCreate(&provider_ops, nullptr, &hProvider); ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT); @@ -257,7 +257,7 @@ TEST_F(test, memoryProviderOpsNullGetIpcHandleSize) { TEST_F(test, memoryProviderOpsNullGetIpcHandle) { umf_memory_provider_ops_t provider_ops = UMF_NULL_PROVIDER_OPS; - provider_ops.ipc.get_ipc_handle = nullptr; + provider_ops.ext_get_ipc_handle = nullptr; umf_memory_provider_handle_t hProvider; auto ret = umfMemoryProviderCreate(&provider_ops, nullptr, &hProvider); ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT); @@ -265,7 +265,7 @@ TEST_F(test, memoryProviderOpsNullGetIpcHandle) { TEST_F(test, memoryProviderOpsNullPutIpcHandle) { umf_memory_provider_ops_t provider_ops = UMF_NULL_PROVIDER_OPS; - provider_ops.ipc.put_ipc_handle = nullptr; + provider_ops.ext_put_ipc_handle = nullptr; umf_memory_provider_handle_t hProvider; auto ret = umfMemoryProviderCreate(&provider_ops, nullptr, &hProvider); ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT); @@ -273,7 +273,7 @@ TEST_F(test, memoryProviderOpsNullPutIpcHandle) { TEST_F(test, memoryProviderOpsNullOpenIpcHandle) { umf_memory_provider_ops_t provider_ops = UMF_NULL_PROVIDER_OPS; - provider_ops.ipc.open_ipc_handle = nullptr; + provider_ops.ext_open_ipc_handle = nullptr; umf_memory_provider_handle_t hProvider; auto ret = umfMemoryProviderCreate(&provider_ops, nullptr, &hProvider); ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT); @@ -281,7 +281,7 @@ TEST_F(test, memoryProviderOpsNullOpenIpcHandle) { TEST_F(test, memoryProviderOpsNullCloseIpcHandle) { umf_memory_provider_ops_t provider_ops = UMF_NULL_PROVIDER_OPS; - provider_ops.ipc.close_ipc_handle = nullptr; + provider_ops.ext_close_ipc_handle = nullptr; umf_memory_provider_handle_t hProvider; auto ret = umfMemoryProviderCreate(&provider_ops, nullptr, &hProvider); ASSERT_EQ(ret, UMF_RESULT_ERROR_INVALID_ARGUMENT); diff --git a/test/utils/cpp_helpers.hpp b/test/utils/cpp_helpers.hpp index e81788ea9..7eebef0bf 100644 --- a/test/utils/cpp_helpers.hpp +++ b/test/utils/cpp_helpers.hpp @@ -67,6 +67,7 @@ umf_result_t initialize(T *obj, ArgsTuple &&args) { template umf_memory_pool_ops_t poolOpsBase() { umf_memory_pool_ops_t ops{}; + ops.size = sizeof(umf_memory_pool_ops_t); ops.version = UMF_POOL_OPS_VERSION_CURRENT; ops.finalize = [](void *obj) { delete reinterpret_cast(obj); }; UMF_ASSIGN_OP(ops, T, malloc, ((void *)nullptr)); @@ -81,6 +82,7 @@ template umf_memory_pool_ops_t poolOpsBase() { template constexpr umf_memory_provider_ops_t providerOpsBase() { umf_memory_provider_ops_t ops{}; + ops.size = sizeof(umf_memory_provider_ops_t); ops.version = UMF_PROVIDER_OPS_VERSION_CURRENT; ops.finalize = [](void *obj) { delete reinterpret_cast(obj); }; UMF_ASSIGN_OP(ops, T, alloc, UMF_RESULT_ERROR_UNKNOWN); @@ -89,15 +91,15 @@ template constexpr umf_memory_provider_ops_t providerOpsBase() { UMF_ASSIGN_OP(ops, T, get_recommended_page_size, UMF_RESULT_ERROR_UNKNOWN); UMF_ASSIGN_OP(ops, T, get_min_page_size, UMF_RESULT_ERROR_UNKNOWN); UMF_ASSIGN_OP(ops, T, get_name, ""); - UMF_ASSIGN_OP(ops.ext, T, purge_lazy, UMF_RESULT_ERROR_UNKNOWN); - UMF_ASSIGN_OP(ops.ext, T, purge_force, UMF_RESULT_ERROR_UNKNOWN); - UMF_ASSIGN_OP(ops.ext, T, allocation_merge, UMF_RESULT_ERROR_UNKNOWN); - UMF_ASSIGN_OP(ops.ext, T, allocation_split, UMF_RESULT_ERROR_UNKNOWN); - UMF_ASSIGN_OP(ops.ipc, T, get_ipc_handle_size, UMF_RESULT_ERROR_UNKNOWN); - UMF_ASSIGN_OP(ops.ipc, T, get_ipc_handle, UMF_RESULT_ERROR_UNKNOWN); - UMF_ASSIGN_OP(ops.ipc, T, put_ipc_handle, UMF_RESULT_ERROR_UNKNOWN); - UMF_ASSIGN_OP(ops.ipc, T, open_ipc_handle, UMF_RESULT_ERROR_UNKNOWN); - UMF_ASSIGN_OP(ops.ipc, T, close_ipc_handle, UMF_RESULT_ERROR_UNKNOWN); + UMF_ASSIGN_OP(ops, T, ext_purge_lazy, UMF_RESULT_ERROR_UNKNOWN); + UMF_ASSIGN_OP(ops, T, ext_purge_force, UMF_RESULT_ERROR_UNKNOWN); + UMF_ASSIGN_OP(ops, T, ext_allocation_merge, UMF_RESULT_ERROR_UNKNOWN); + UMF_ASSIGN_OP(ops, T, ext_allocation_split, UMF_RESULT_ERROR_UNKNOWN); + UMF_ASSIGN_OP(ops, T, ext_get_ipc_handle_size, UMF_RESULT_ERROR_UNKNOWN); + UMF_ASSIGN_OP(ops, T, ext_get_ipc_handle, UMF_RESULT_ERROR_UNKNOWN); + UMF_ASSIGN_OP(ops, T, ext_put_ipc_handle, UMF_RESULT_ERROR_UNKNOWN); + UMF_ASSIGN_OP(ops, T, ext_open_ipc_handle, UMF_RESULT_ERROR_UNKNOWN); + UMF_ASSIGN_OP(ops, T, ext_close_ipc_handle, UMF_RESULT_ERROR_UNKNOWN); return ops; } } // namespace detail