diff --git a/.github/workflows/pr_push.yml b/.github/workflows/pr_push.yml index c1b8eac874..fbdc8c56d3 100644 --- a/.github/workflows/pr_push.yml +++ b/.github/workflows/pr_push.yml @@ -94,11 +94,11 @@ jobs: contents: read security-events: write uses: ./.github/workflows/reusable_trivy.yml - Compatibility: - needs: [Build] - uses: ./.github/workflows/reusable_compatibility.yml - strategy: - matrix: - tag: ["v0.12.0-dev3"] - with: - tag: ${{matrix.tag}} +# Compatibility: +# needs: [Build] +# uses: ./.github/workflows/reusable_compatibility.yml +# strategy: +# matrix: +# tag: ["v0.12.0-dev3"] +# with: +# tag: ${{matrix.tag}} diff --git a/examples/basic/basic.c b/examples/basic/basic.c index 41e48c6f64..e58be45389 100644 --- a/examples/basic/basic.c +++ b/examples/basic/basic.c @@ -96,7 +96,12 @@ int main(void) { printf("%s %p\n", ptr, (void *)ptr); // Retrieve a memory pool from a pointer, available with memory tracking - umf_memory_pool_handle_t check_pool = umfPoolByPtr(ptr); + umf_memory_pool_handle_t check_pool; + res = umfPoolByPtr(ptr, &check_pool); + if (res != UMF_RESULT_SUCCESS) { + printf("Failed to retrieve a memory pool for the pointer!\n"); + goto memory_pool_destroy; + } printf("Memory at %p has been allocated from the pool at %p\n", (void *)ptr, (void *)check_pool); diff --git a/examples/custom_file_provider/custom_file_provider.c b/examples/custom_file_provider/custom_file_provider.c index dbf1bb0922..1ba934a589 100644 --- a/examples/custom_file_provider/custom_file_provider.c +++ b/examples/custom_file_provider/custom_file_provider.c @@ -201,18 +201,25 @@ static umf_result_t file_free(void *provider, void *ptr, size_t size) { } // Function to get the name of the file provider -static const char *file_get_name(void *provider) { +static umf_result_t file_get_name(void *provider, const char **name) { (void)provider; // Unused parameter - return "File Provider"; + if (!name) { + fprintf(stderr, "Name is NULL\n"); + return UMF_RESULT_ERROR_INVALID_ARGUMENT; + } + *name = "File Provider"; + return UMF_RESULT_SUCCESS; } // Function to get the last native error of the file provider // This function is needed only if the provider returns UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC -static void file_get_last_native_error(void *provider, const char **ppMessage, - int32_t *pError) { +static umf_result_t file_get_last_native_error(void *provider, + const char **ppMessage, + int32_t *pError) { (void)provider; // Unused parameter *ppMessage = ""; *pError = 0; + return UMF_RESULT_SUCCESS; } // Function to get the recommended page size of the file provider @@ -319,7 +326,12 @@ int main(void) { printf("%s %p\n", ptr, (void *)ptr); // Retrieve a memory pool from a pointer, available with memory tracking - umf_memory_pool_handle_t check_pool = umfPoolByPtr(ptr); + umf_memory_pool_handle_t check_pool; + res = umfPoolByPtr(ptr, &check_pool); + if (res != UMF_RESULT_SUCCESS) { + fprintf(stderr, "Failed to retrieve a memory pool for the pointer!\n"); + goto memory_pool_destroy; + } printf("Memory at %p has been allocated from the pool at %p\n", (void *)ptr, (void *)check_pool); diff --git a/include/umf.h b/include/umf.h index 57bebef8a9..6c23bb16e9 100644 --- a/include/umf.h +++ b/include/umf.h @@ -10,6 +10,7 @@ #ifndef UMF_UNIFIED_MEMORY_FRAMEWORK_H #define UMF_UNIFIED_MEMORY_FRAMEWORK_H 1 +#include #include #include #include @@ -23,17 +24,19 @@ extern "C" { /// @brief Increment the usage reference counter and initialize the global state of libumf /// if the usage reference counter was equal to 0. /// It must be called just after dlopen() and it is not required in other scenarios. -/// @return 0 on success or -1 on failure. -int umfInit(void); +/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. +umf_result_t umfInit(void); /// /// @brief Decrement the usage reference counter and destroy the global state of libumf /// if the usage reference counter is equal to 0. /// It must be called just before dlclose() and it is not required in other scenarios. -void umfTearDown(void); +/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. +umf_result_t umfTearDown(void); /// /// @brief Get the current version of the UMF headers defined by UMF_VERSION_CURRENT. +/// @return The current version of the UMF headers. int umfGetCurrentVersion(void); #ifdef __cplusplus diff --git a/include/umf/ipc.h b/include/umf/ipc.h index ab47b09713..9484a827dc 100644 --- a/include/umf/ipc.h +++ b/include/umf/ipc.h @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2023-2024 Intel Corporation + * Copyright (C) 2023-2025 Intel Corporation * * Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception diff --git a/include/umf/memory_pool.h b/include/umf/memory_pool.h index c9b02214ee..ea30dfe007 100644 --- a/include/umf/memory_pool.h +++ b/include/umf/memory_pool.h @@ -10,6 +10,8 @@ #ifndef UMF_MEMORY_POOL_H #define UMF_MEMORY_POOL_H 1 +#include + #include #include #include @@ -105,9 +107,11 @@ void *umfPoolRealloc(umf_memory_pool_handle_t hPool, void *ptr, size_t size); /// @brief Obtains size of block of memory allocated from the \p hPool for a given \p ptr /// @param hPool specified memory hPool /// @param ptr pointer to the allocated memory -/// @return size of the memory block allocated from the \p hPool +/// @param size [out] pointer to a variable that will receive the size of the memory block +/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. /// -size_t umfPoolMallocUsableSize(umf_memory_pool_handle_t hPool, const void *ptr); +umf_result_t umfPoolMallocUsableSize(umf_memory_pool_handle_t hPool, + const void *ptr, size_t *size); /// /// @brief Frees the memory space of the specified \p hPool pointed by \p ptr @@ -152,14 +156,16 @@ umf_result_t umfPoolGetLastAllocationError(umf_memory_pool_handle_t hPool); /// @brief Retrieve memory pool associated with a given ptr. Only memory allocated /// with the usage of a memory provider is being tracked. /// @param ptr pointer to memory belonging to a memory pool -/// @return Handle to a memory pool that contains ptr or NULL if pointer does not belong to any UMF pool. +/// @param pool [out] handle to the memory pool that contains ptr +/// @return UMF_RESULT_SUCCESS on success +/// UMF_RESULT_ERROR_INVALID_ARGUMENT if pool is NULL, or ptr do not belongs to any pool. /// -umf_memory_pool_handle_t umfPoolByPtr(const void *ptr); +umf_result_t umfPoolByPtr(const void *ptr, umf_memory_pool_handle_t *pool); /// /// @brief Retrieve memory provider associated with a given pool. /// @param hPool specified memory pool -/// @param hProvider [out] memory providers handle. +/// @param hProvider [out] memory providers handle /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. /// UMF_RESULT_ERROR_INVALID_ARGUMENT if hProvider is NULL /// @@ -169,10 +175,10 @@ umf_result_t umfPoolGetMemoryProvider(umf_memory_pool_handle_t hPool, /// /// @brief Retrieve name of a given memory \p pool. /// @param pool handle to the memory pool -/// @return pointer to a string containing the name of the \p pool -/// or NULL if the pool doesn't support retrieving its name. +/// @param name [out] pointer to a string containing the name of the \p pool +/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. /// -const char *umfPoolGetName(umf_memory_pool_handle_t pool); +umf_result_t umfPoolGetName(umf_memory_pool_handle_t pool, const char **name); /// /// @brief Set a custom tag on the memory pool that can be later retrieved using umfPoolGetTag. diff --git a/include/umf/memory_pool_ops.h b/include/umf/memory_pool_ops.h index 7b03ec8d2d..42fd168030 100644 --- a/include/umf/memory_pool_ops.h +++ b/include/umf/memory_pool_ops.h @@ -93,9 +93,11 @@ typedef struct umf_memory_pool_ops_t { /// @brief Obtains size of block of memory allocated from the \p pool for a given \p ptr /// @param pool pointer to the memory pool /// @param ptr pointer to the allocated memory - /// @return size of the memory block allocated from the \p pool + /// @param size [out] size of the memory block allocated from the \p pool + /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. /// - size_t (*malloc_usable_size)(void *pool, const void *ptr); + umf_result_t (*malloc_usable_size)(void *pool, const void *ptr, + size_t *size); /// /// @brief Frees the memory space of the specified \p pool pointed by \p ptr @@ -105,7 +107,7 @@ typedef struct umf_memory_pool_ops_t { /// Whether any status other than UMF_RESULT_SUCCESS can be returned /// depends on the memory provider used by the \p pool. /// - umf_result_t (*free)(void *pool, void *); + umf_result_t (*free)(void *pool, void *ptr); /// /// @brief Retrieve \p umf_result_t representing the error of the last failed allocation @@ -153,14 +155,15 @@ typedef struct umf_memory_pool_ops_t { /// /// @brief Retrieves the name of the memory pool /// @param pool valid pointer to the memory pool or NULL value + /// @param name [out] pointer to a constant character string that will be set to the pool's name /// \details /// * Implementations *must* return a literal null-terminated string. /// /// * Implementations *must* return default pool name when NULL is provided, /// otherwise the pool's name is returned. - /// @return A constant character string representing the pool's name. + /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. /// - const char *(*ext_get_name)(void *pool); + umf_result_t (*ext_get_name)(void *pool, const char **name); } umf_memory_pool_ops_t; #ifdef __cplusplus diff --git a/include/umf/memory_provider.h b/include/umf/memory_provider.h index b9fbb28c9f..b98b893468 100644 --- a/include/umf/memory_provider.h +++ b/include/umf/memory_provider.h @@ -24,7 +24,7 @@ typedef enum umf_memory_visibility_t { } umf_memory_visibility_t; /// @brief Protection of the memory allocations -typedef enum umf_mem_protection_flags_t { +typedef enum umf_mem_protection_flag_t { UMF_PROTECTION_NONE = (1 << 0), ///< Memory allocations can not be accessed UMF_PROTECTION_READ = (1 << 1), ///< Memory allocations can be read. UMF_PROTECTION_WRITE = (1 << 2), ///< Memory allocations can be written. @@ -32,7 +32,7 @@ typedef enum umf_mem_protection_flags_t { /// @cond UMF_PROTECTION_MAX // must be the last one /// @endcond -} umf_mem_protection_flags_t; +} umf_mem_protection_flag_t; /// @brief A struct containing memory provider specific set of functions typedef struct umf_memory_provider_t *umf_memory_provider_handle_t; @@ -100,10 +100,11 @@ umf_result_t umfMemoryProviderFree(umf_memory_provider_handle_t hProvider, /// @param ppMessage [out] pointer to a string containing provider specific /// result in string representation /// @param pError [out] pointer to an integer where the adapter specific error code will be stored +/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. /// -void umfMemoryProviderGetLastNativeError(umf_memory_provider_handle_t hProvider, - const char **ppMessage, - int32_t *pError); +umf_result_t +umfMemoryProviderGetLastNativeError(umf_memory_provider_handle_t hProvider, + const char **ppMessage, int32_t *pError); /// /// @brief Retrieve recommended page size for a given allocation size. @@ -217,21 +218,24 @@ umfMemoryProviderCloseIPCHandle(umf_memory_provider_handle_t hProvider, /// /// @brief Retrieve name of a given memory \p hProvider. /// @param hProvider handle to the memory provider -/// @return pointer to a string containing the name of the \p hProvider -/// -const char *umfMemoryProviderGetName(umf_memory_provider_handle_t hProvider); +/// @param name [out] pointer to the provider name string +/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure +umf_result_t umfMemoryProviderGetName(umf_memory_provider_handle_t hProvider, + const char **name); /// /// @brief Retrieve handle to the last memory provider that returned status other /// than UMF_RESULT_SUCCESS on the calling thread. +/// @param provider [out] pointer to the handle to the last failed memory provider /// /// \details Handle to the memory provider is stored in the thread local /// storage. The handle is updated every time a memory provider /// returns status other than UMF_RESULT_SUCCESS. /// -/// @return Handle to the memory provider +/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. /// -umf_memory_provider_handle_t umfGetLastFailedMemoryProvider(void); +umf_result_t +umfGetLastFailedMemoryProvider(umf_memory_provider_handle_t *provider); /// /// @brief Splits a coarse grain allocation into 2 adjacent allocations that diff --git a/include/umf/memory_provider_ops.h b/include/umf/memory_provider_ops.h index 8f383235cd..90741e9c28 100644 --- a/include/umf/memory_provider_ops.h +++ b/include/umf/memory_provider_ops.h @@ -90,9 +90,11 @@ typedef struct umf_memory_provider_ops_t { /// @param ppMessage [out] pointer to a string containing provider specific /// result in string representation /// @param pError [out] pointer to an integer where the adapter specific error code will be stored + /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. /// - void (*get_last_native_error)(void *provider, const char **ppMessage, - int32_t *pError); + umf_result_t (*get_last_native_error)(void *provider, + const char **ppMessage, + int32_t *pError); /// /// @brief Retrieve recommended page size for a given allocation size. @@ -118,9 +120,10 @@ typedef struct umf_memory_provider_ops_t { /// /// @brief Retrieve name of a given memory \p provider. /// @param provider pointer to the memory provider - /// @return pointer to a string containing the name of the \p provider + /// @param name [out] pointer to a string containing the name of the \p provider + /// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. /// - const char *(*get_name)(void *provider); + umf_result_t (*get_name)(void *provider, const char **name); /// /// Following functions, with ext prefix, are optional and memory provider implementation diff --git a/include/umf/pools/pool_disjoint.h b/include/umf/pools/pool_disjoint.h index 9f467d9a6e..e475d1e809 100644 --- a/include/umf/pools/pool_disjoint.h +++ b/include/umf/pools/pool_disjoint.h @@ -29,9 +29,10 @@ typedef struct umf_disjoint_pool_params_t *umf_disjoint_pool_params_handle_t; /// @brief Create a pool limits struct. /// @param MaxSize specifies hard limit for memory allocated from a provider. -/// @return handle to the created shared limits struct. -umf_disjoint_pool_shared_limits_handle_t -umfDisjointPoolSharedLimitsCreate(size_t MaxSize); +/// @param hSharedLimits [out] handle to the newly created shared limits struct. +/// @return UMF_RESULT_SUCCESS on success or appropriate error code on failure. +umf_result_t umfDisjointPoolSharedLimitsCreate( + size_t MaxSize, umf_disjoint_pool_shared_limits_handle_t *hSharedLimits); /// @brief Destroy previously created pool limits struct. /// @param hSharedLimits handle to the shared limits struct. diff --git a/src/libumf.c b/src/libumf.c index 60030fed6e..f96a764bc7 100644 --- a/src/libumf.c +++ b/src/libumf.c @@ -33,21 +33,22 @@ static umf_ctl_node_t CTL_NODE(umf)[] = {CTL_CHILD(provider), CTL_CHILD(pool), void initialize_global_ctl(void) { CTL_REGISTER_MODULE(NULL, umf); } -int umfInit(void) { +umf_result_t umfInit(void) { if (utils_fetch_and_add_u64(&umfRefCount, 1) == 0) { utils_log_init(); - TRACKER = umfMemoryTrackerCreate(); - if (!TRACKER) { + umf_result_t umf_result = umfMemoryTrackerCreate(&TRACKER); + if (umf_result != UMF_RESULT_SUCCESS) { LOG_ERR("Failed to create memory tracker"); - return -1; + return umf_result; } LOG_DEBUG("UMF tracker created"); - umf_result_t umf_result = umfIpcCacheGlobalInit(); + umf_result = umfIpcCacheGlobalInit(); if (umf_result != UMF_RESULT_SUCCESS) { LOG_ERR("Failed to initialize IPC cache"); - return -1; + umfMemoryTrackerDestroy(TRACKER); + return umf_result; } LOG_DEBUG("UMF IPC cache initialized"); @@ -58,10 +59,10 @@ int umfInit(void) { LOG_DEBUG("UMF library initialized"); } - return 0; + return UMF_RESULT_SUCCESS; } -void umfTearDown(void) { +umf_result_t umfTearDown(void) { if (utils_fetch_and_sub_u64(&umfRefCount, 1) == 1) { #if !defined(_WIN32) && !defined(UMF_NO_HWLOC) umfMemspaceHostAllDestroy(); @@ -95,6 +96,7 @@ void umfTearDown(void) { fini_tbb_global_state(); LOG_DEBUG("UMF library finalized"); } + return UMF_RESULT_SUCCESS; } int umfGetCurrentVersion(void) { return UMF_VERSION_CURRENT; } diff --git a/src/libumf_linux.c b/src/libumf_linux.c index 8832952ead..0bb8a1d4e1 100644 --- a/src/libumf_linux.c +++ b/src/libumf_linux.c @@ -1,6 +1,6 @@ /* * - * 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 @@ -11,7 +11,7 @@ void __attribute__((constructor)) umfCreate(void) { (void)umfInit(); } -void __attribute__((destructor)) umfDestroy(void) { umfTearDown(); } +void __attribute__((destructor)) umfDestroy(void) { (void)umfTearDown(); } void libumfInit(void) { // do nothing, additional initialization not needed diff --git a/src/libumf_windows.c b/src/libumf_windows.c index 1531a7b8b1..d1815dc915 100644 --- a/src/libumf_windows.c +++ b/src/libumf_windows.c @@ -1,6 +1,6 @@ /* * - * 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 @@ -20,7 +20,7 @@ BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { if (fdwReason == DLL_PROCESS_ATTACH) { (void)umfInit(); } else if (fdwReason == DLL_PROCESS_DETACH) { - umfTearDown(); + (void)umfTearDown(); } return TRUE; } @@ -39,9 +39,9 @@ BOOL CALLBACK initOnceCb(PINIT_ONCE InitOnce, PVOID Parameter, (void)Parameter; // unused (void)lpContext; // unused - int ret = umfInit(); + umf_result_t ret = umfInit(); atexit(umfTearDown); - return (ret == 0) ? TRUE : FALSE; + return (ret == UMF_RESULT_SUCCESS) ? TRUE : FALSE; } void libumfInit(void) { diff --git a/src/memory_pool.c b/src/memory_pool.c index bef783427a..9791cef936 100644 --- a/src/memory_pool.c +++ b/src/memory_pool.c @@ -209,8 +209,20 @@ 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->ext_get_name(NULL))) { + const char *pname = NULL; + if (ops->ext_get_name) { + ret = ops->ext_get_name(NULL, &pname); + if (ret != UMF_RESULT_SUCCESS) { + LOG_ERR("Failed to get pool name"); + goto err_pool_init; + } + } else { + LOG_INFO("Pool name getter is not implemented, CTL defaults " + "settings are not supported for this pool"); + break; + } + if (CTL_DEFAULT_ENTRIES[i][0] != '\0' && pname && + strstr(CTL_DEFAULT_ENTRIES[i], pname)) { ops->ext_ctl(pool->pool_priv, CTL_QUERY_PROGRAMMATIC, CTL_DEFAULT_ENTRIES[i], CTL_DEFAULT_VALUES[i], UMF_DEFAULT_LEN, CTL_QUERY_WRITE); @@ -268,24 +280,26 @@ umf_result_t umfPoolDestroy(umf_memory_pool_handle_t hPool) { } umf_result_t umfFree(void *ptr) { - umf_memory_pool_handle_t hPool = umfPoolByPtr(ptr); - if (hPool) { + umf_memory_pool_handle_t hPool = NULL; + umf_result_t ret = umfPoolByPtr(ptr, &hPool); + if (ret == UMF_RESULT_SUCCESS) { LOG_DEBUG("calling umfPoolFree(pool=%p, ptr=%p) ...", (void *)hPool, ptr); return umfPoolFree(hPool, ptr); } - return UMF_RESULT_SUCCESS; + return ret; } -umf_memory_pool_handle_t umfPoolByPtr(const void *ptr) { - return umfMemoryTrackerGetPool(ptr); +umf_result_t umfPoolByPtr(const void *ptr, umf_memory_pool_handle_t *pool) { + UMF_CHECK((pool != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT); + *pool = umfMemoryTrackerGetPool(ptr); + return *pool ? UMF_RESULT_SUCCESS : UMF_RESULT_ERROR_INVALID_ARGUMENT; } umf_result_t umfPoolGetMemoryProvider(umf_memory_pool_handle_t hPool, umf_memory_provider_handle_t *hProvider) { - if (!hProvider) { - return UMF_RESULT_ERROR_INVALID_ARGUMENT; - } + UMF_CHECK((hPool != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT); + UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT); if (hPool->flags & UMF_POOL_CREATE_FLAG_DISABLE_TRACKING) { *hProvider = hPool->provider; @@ -297,12 +311,14 @@ umf_result_t umfPoolGetMemoryProvider(umf_memory_pool_handle_t hPool, return UMF_RESULT_SUCCESS; } -const char *umfPoolGetName(umf_memory_pool_handle_t pool) { - UMF_CHECK((pool != NULL), NULL); +umf_result_t umfPoolGetName(umf_memory_pool_handle_t pool, const char **name) { + UMF_CHECK((pool != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT); + UMF_CHECK((name != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT); if (pool->ops.ext_get_name == NULL) { - return NULL; + *name = NULL; + return UMF_RESULT_ERROR_NOT_SUPPORTED; } - return pool->ops.ext_get_name(pool->pool_priv); + return pool->ops.ext_get_name(pool->pool_priv, name); } umf_result_t umfPoolCreate(const umf_memory_pool_ops_t *ops, @@ -366,10 +382,10 @@ void *umfPoolRealloc(umf_memory_pool_handle_t hPool, void *ptr, size_t size) { return ret; } -size_t umfPoolMallocUsableSize(umf_memory_pool_handle_t hPool, - const void *ptr) { - UMF_CHECK((hPool != NULL), 0); - return hPool->ops.malloc_usable_size(hPool->pool_priv, ptr); +umf_result_t umfPoolMallocUsableSize(umf_memory_pool_handle_t hPool, + const void *ptr, size_t *size) { + UMF_CHECK((hPool != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT); + return hPool->ops.malloc_usable_size(hPool->pool_priv, ptr, size); } umf_result_t umfPoolFree(umf_memory_pool_handle_t hPool, void *ptr) { diff --git a/src/memory_provider.c b/src/memory_provider.c index 995fab6420..74aefddef3 100644 --- a/src/memory_provider.c +++ b/src/memory_provider.c @@ -275,12 +275,14 @@ umf_result_t umfMemoryProviderFree(umf_memory_provider_handle_t hProvider, return res; } -void umfMemoryProviderGetLastNativeError(umf_memory_provider_handle_t hProvider, - const char **ppMessage, - int32_t *pError) { - ASSERT(hProvider != NULL); - hProvider->ops.get_last_native_error(hProvider->provider_priv, ppMessage, - pError); +umf_result_t +umfMemoryProviderGetLastNativeError(umf_memory_provider_handle_t hProvider, + const char **ppMessage, int32_t *pError) { + UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT); + UMF_CHECK((ppMessage != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT); + UMF_CHECK((pError != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT); + return hProvider->ops.get_last_native_error(hProvider->provider_priv, + ppMessage, pError); } void *umfMemoryProviderGetPriv(umf_memory_provider_handle_t hProvider) { @@ -310,9 +312,11 @@ umfMemoryProviderGetMinPageSize(umf_memory_provider_handle_t hProvider, return res; } -const char *umfMemoryProviderGetName(umf_memory_provider_handle_t hProvider) { - UMF_CHECK((hProvider != NULL), NULL); - return hProvider->ops.get_name(hProvider->provider_priv); +umf_result_t umfMemoryProviderGetName(umf_memory_provider_handle_t hProvider, + const char **name) { + UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT); + UMF_CHECK((name != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT); + return hProvider->ops.get_name(hProvider->provider_priv, name); } umf_result_t umfMemoryProviderPurgeLazy(umf_memory_provider_handle_t hProvider, @@ -335,8 +339,11 @@ umf_result_t umfMemoryProviderPurgeForce(umf_memory_provider_handle_t hProvider, return res; } -umf_memory_provider_handle_t umfGetLastFailedMemoryProvider(void) { - return *umfGetLastFailedMemoryProviderPtr(); +umf_result_t +umfGetLastFailedMemoryProvider(umf_memory_provider_handle_t *provider) { + UMF_CHECK((provider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT); + *provider = *umfGetLastFailedMemoryProviderPtr(); + return UMF_RESULT_SUCCESS; } umf_result_t diff --git a/src/pool/pool_disjoint.c b/src/pool/pool_disjoint.c index 0104c0bb70..702a30f91a 100644 --- a/src/pool/pool_disjoint.c +++ b/src/pool/pool_disjoint.c @@ -688,9 +688,9 @@ umf_result_t disjoint_pool_initialize(umf_memory_provider_handle_t provider, // Calculate the exponent for min_bucket_size used for finding buckets. disjoint_pool->min_bucket_size_exp = (size_t)utils_msb64(Size1); - disjoint_pool->default_shared_limits = - umfDisjointPoolSharedLimitsCreate(SIZE_MAX); - if (disjoint_pool->default_shared_limits == NULL) { + if (umfDisjointPoolSharedLimitsCreate( + SIZE_MAX, &disjoint_pool->default_shared_limits) != + UMF_RESULT_SUCCESS) { goto err_free_known_slabs; } @@ -874,10 +874,15 @@ static void *get_unaligned_ptr(size_t chunk_idx, slab_t *slab) { return (void *)((uintptr_t)slab->mem_ptr + chunk_idx * slab->bucket->size); } -size_t disjoint_pool_malloc_usable_size(void *pool, const void *ptr) { +umf_result_t disjoint_pool_malloc_usable_size(void *pool, const void *ptr, + size_t *size) { disjoint_pool_t *disjoint_pool = (disjoint_pool_t *)pool; + if (!size || !disjoint_pool) { + return UMF_RESULT_ERROR_INVALID_ARGUMENT; + } if (ptr == NULL) { - return 0; + *size = 0; + return UMF_RESULT_SUCCESS; } // check if given pointer is allocated inside any Disjoint Pool slab @@ -893,10 +898,12 @@ size_t disjoint_pool_malloc_usable_size(void *pool, const void *ptr) { umf_alloc_info_t allocInfo = {NULL, 0, NULL}; umf_result_t ret = umfMemoryTrackerGetAllocInfo(ptr, &allocInfo); if (ret != UMF_RESULT_SUCCESS) { - return 0; + *size = 0; + return ret; } - return allocInfo.baseSize; + *size = allocInfo.baseSize; + return UMF_RESULT_SUCCESS; } // Get the unaligned pointer @@ -906,12 +913,12 @@ size_t disjoint_pool_malloc_usable_size(void *pool, const void *ptr) { ptrdiff_t diff = (ptrdiff_t)ptr - (ptrdiff_t)unaligned_ptr; - size_t size = slab->bucket->size - diff; + *size = slab->bucket->size - diff; assert(ref_slab); critnib_release(disjoint_pool->known_slabs, ref_slab); - return size; + return UMF_RESULT_SUCCESS; } umf_result_t disjoint_pool_free(void *pool, void *ptr) { @@ -1025,12 +1032,17 @@ umf_result_t disjoint_pool_finalize(void *pool) { return ret; } -const char *disjoint_pool_get_name(void *pool) { +static umf_result_t disjoint_pool_get_name(void *pool, const char **name) { + if (!name) { + return UMF_RESULT_ERROR_INVALID_ARGUMENT; + } disjoint_pool_t *hPool = (disjoint_pool_t *)pool; if (pool == NULL) { - return DEFAULT_NAME; + *name = DEFAULT_NAME; + return UMF_RESULT_SUCCESS; } - return hPool->params.name; + *name = hPool->params.name; + return UMF_RESULT_SUCCESS; } static umf_memory_pool_ops_t UMF_DISJOINT_POOL_OPS = { @@ -1052,16 +1064,21 @@ const umf_memory_pool_ops_t *umfDisjointPoolOps(void) { return &UMF_DISJOINT_POOL_OPS; } -umf_disjoint_pool_shared_limits_t * -umfDisjointPoolSharedLimitsCreate(size_t max_size) { +umf_result_t umfDisjointPoolSharedLimitsCreate( + size_t max_size, umf_disjoint_pool_shared_limits_t **hSharedLimits) { + if (!hSharedLimits) { + return UMF_RESULT_ERROR_INVALID_ARGUMENT; + } + umf_disjoint_pool_shared_limits_t *ptr = umf_ba_global_alloc(sizeof(*ptr)); if (ptr == NULL) { LOG_ERR("cannot allocate memory for disjoint pool shared limits"); - return NULL; + return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY; } ptr->max_size = max_size; ptr->total_size = 0; - return ptr; + *hSharedLimits = ptr; + return UMF_RESULT_SUCCESS; } umf_result_t diff --git a/src/pool/pool_jemalloc.c b/src/pool/pool_jemalloc.c index 8d6a2daf20..60a6e6e970 100644 --- a/src/pool/pool_jemalloc.c +++ b/src/pool/pool_jemalloc.c @@ -540,11 +540,16 @@ static umf_result_t op_finalize(void *pool) { return ret; } -static size_t op_malloc_usable_size(void *pool, const void *ptr) { +static umf_result_t op_malloc_usable_size(void *pool, const void *ptr, + size_t *size) { (void)pool; // not used + if (!size) { + return UMF_RESULT_ERROR_INVALID_ARGUMENT; + } // Remove the 'const' qualifier because the je_malloc_usable_size // function requires a non-const pointer. - return je_malloc_usable_size((void *)ptr); + *size = je_malloc_usable_size((void *)ptr); + return UMF_RESULT_SUCCESS; } static umf_result_t op_get_last_allocation_error(void *pool) { diff --git a/src/pool/pool_proxy.c b/src/pool/pool_proxy.c index 208b46d4c5..d8376155e8 100644 --- a/src/pool/pool_proxy.c +++ b/src/pool/pool_proxy.c @@ -110,14 +110,19 @@ static umf_result_t proxy_free(void *pool, void *ptr) { return umfMemoryProviderFree(hPool->hProvider, ptr, size); } -static size_t proxy_malloc_usable_size(void *pool, const void *ptr) { +static umf_result_t proxy_malloc_usable_size(void *pool, const void *ptr, + size_t *size) { assert(pool); (void)pool; (void)ptr; + if (!size) { + return UMF_RESULT_ERROR_INVALID_ARGUMENT; + } TLS_last_allocation_error = UMF_RESULT_ERROR_NOT_SUPPORTED; - return 0; + *size = 0; + return UMF_RESULT_ERROR_NOT_SUPPORTED; } static umf_result_t proxy_get_last_allocation_error(void *pool) { diff --git a/src/pool/pool_scalable.c b/src/pool/pool_scalable.c index fa63351c22..8c17e76ae9 100644 --- a/src/pool/pool_scalable.c +++ b/src/pool/pool_scalable.c @@ -405,10 +405,15 @@ static umf_result_t tbb_free(void *pool, void *ptr) { return UMF_RESULT_ERROR_UNKNOWN; } -static size_t tbb_malloc_usable_size(void *pool, const void *ptr) { +static umf_result_t tbb_malloc_usable_size(void *pool, const void *ptr, + size_t *size) { tbb_memory_pool_t *pool_data = (tbb_memory_pool_t *)pool; + if (!size) { + return UMF_RESULT_ERROR_INVALID_ARGUMENT; + } // Remove the 'const' qualifier because the TBB pool_msize function requires a non-const pointer. - return tbb_callbacks.pool_msize(pool_data->tbb_pool, (void *)ptr); + *size = tbb_callbacks.pool_msize(pool_data->tbb_pool, (void *)ptr); + return UMF_RESULT_SUCCESS; } static umf_result_t tbb_get_last_allocation_error(void *pool) { @@ -426,9 +431,10 @@ static umf_result_t pool_ctl(void *hPool, int operationType, const char *name, CTL_QUERY_PROGRAMMATIC, name, query_type, arg, size); } -static const char *scalable_get_name(void *pool) { +static umf_result_t scalable_get_name(void *pool, const char **name) { (void)pool; // unused - return "scalable"; + *name = "scalable"; + return UMF_RESULT_SUCCESS; } static umf_memory_pool_ops_t UMF_SCALABLE_POOL_OPS = { diff --git a/src/provider/provider_cuda.c b/src/provider/provider_cuda.c index 29083d4534..d024ae0ea4 100644 --- a/src/provider/provider_cuda.c +++ b/src/provider/provider_cuda.c @@ -507,17 +507,18 @@ static umf_result_t cu_memory_provider_free(void *provider, void *ptr, return cu2umf_result(cu_result); } -static void cu_memory_provider_get_last_native_error(void *provider, - const char **ppMessage, - int32_t *pError) { +static umf_result_t +cu_memory_provider_get_last_native_error(void *provider, const char **ppMessage, + int32_t *pError) { (void)provider; if (ppMessage == NULL || pError == NULL) { ASSERT(0); - return; + return UMF_RESULT_ERROR_INVALID_ARGUMENT; } CUresult result; + umf_result_t ret = UMF_RESULT_SUCCESS; size_t buf_size = 0; const char *error_name = NULL; const char *error_string = NULL; @@ -535,6 +536,7 @@ static void cu_memory_provider_get_last_native_error(void *provider, strncpy(TLS_last_native_error.msg_buff, "cuGetErrorName() failed", TLS_MSG_BUF_LEN - 1); TLS_last_native_error.msg_buff[TLS_MSG_BUF_LEN - 1] = '\0'; + ret = cu2umf_result(result); } buf_size = strlen(TLS_last_native_error.msg_buff); @@ -553,10 +555,12 @@ static void cu_memory_provider_get_last_native_error(void *provider, } else { strncat(TLS_last_native_error.msg_buff, "cuGetErrorString() failed", TLS_MSG_BUF_LEN - buf_size - 1); + ret = cu2umf_result(result); } *pError = TLS_last_native_error.native_error; *ppMessage = TLS_last_native_error.msg_buff; + return ret; } static umf_result_t cu_memory_provider_get_min_page_size(void *provider, @@ -595,9 +599,11 @@ cu_memory_provider_get_recommended_page_size(void *provider, size_t size, return cu2umf_result(cu_result); } -static const char *cu_memory_provider_get_name(void *provider) { +static umf_result_t cu_memory_provider_get_name(void *provider, + const char **name) { (void)provider; - return "CUDA"; + *name = "CUDA"; + return UMF_RESULT_SUCCESS; } static umf_result_t cu_memory_provider_get_ipc_handle_size(void *provider, diff --git a/src/provider/provider_devdax_memory.c b/src/provider/provider_devdax_memory.c index fdd8ad9b99..617082524b 100644 --- a/src/provider/provider_devdax_memory.c +++ b/src/provider/provider_devdax_memory.c @@ -287,19 +287,19 @@ static umf_result_t devdax_alloc(void *provider, size_t size, size_t alignment, return coarse_alloc(devdax_provider->coarse, size, alignment, resultPtr); } -static void devdax_get_last_native_error(void *provider, const char **ppMessage, - int32_t *pError) { +static umf_result_t devdax_get_last_native_error(void *provider, + const char **ppMessage, + int32_t *pError) { (void)provider; // unused if (ppMessage == NULL || pError == NULL) { - assert(0); - return; + return UMF_RESULT_ERROR_INVALID_ARGUMENT; } *pError = TLS_last_native_error.native_error; if (TLS_last_native_error.errno_value == 0) { *ppMessage = Native_error_str[*pError - UMF_DEVDAX_RESULT_SUCCESS]; - return; + return UMF_RESULT_SUCCESS; } const char *msg; @@ -320,6 +320,7 @@ static void devdax_get_last_native_error(void *provider, const char **ppMessage, TLS_last_native_error.msg_buff + pos, TLS_MSG_BUF_LEN - pos); *ppMessage = TLS_last_native_error.msg_buff; + return UMF_RESULT_SUCCESS; } static umf_result_t devdax_get_recommended_page_size(void *provider, @@ -362,9 +363,10 @@ static umf_result_t devdax_purge_force(void *provider, void *ptr, size_t size) { return UMF_RESULT_SUCCESS; } -static const char *devdax_get_name(void *provider) { +static umf_result_t devdax_get_name(void *provider, const char **name) { (void)provider; // unused - return "DEVDAX"; + *name = "DEVDAX"; + return UMF_RESULT_SUCCESS; } static umf_result_t devdax_allocation_split(void *provider, void *ptr, diff --git a/src/provider/provider_file_memory.c b/src/provider/provider_file_memory.c index b4ff44f8a0..0c4b28613e 100644 --- a/src/provider/provider_file_memory.c +++ b/src/provider/provider_file_memory.c @@ -554,19 +554,19 @@ static umf_result_t file_alloc_cb(void *provider, size_t size, size_t alignment, return UMF_RESULT_SUCCESS; } -static void file_get_last_native_error(void *provider, const char **ppMessage, - int32_t *pError) { +static umf_result_t file_get_last_native_error(void *provider, + const char **ppMessage, + int32_t *pError) { (void)provider; // unused if (ppMessage == NULL || pError == NULL) { - assert(0); - return; + return UMF_RESULT_ERROR_INVALID_ARGUMENT; } *pError = TLS_last_native_error.native_error; if (TLS_last_native_error.errno_value == 0) { *ppMessage = Native_error_str[*pError - UMF_FILE_RESULT_SUCCESS]; - return; + return UMF_RESULT_SUCCESS; } const char *msg; @@ -587,6 +587,7 @@ static void file_get_last_native_error(void *provider, const char **ppMessage, TLS_last_native_error.msg_buff + pos, TLS_MSG_BUF_LEN - pos); *ppMessage = TLS_last_native_error.msg_buff; + return UMF_RESULT_SUCCESS; } static umf_result_t file_get_recommended_page_size(void *provider, size_t size, @@ -630,9 +631,10 @@ static umf_result_t file_purge_force(void *provider, void *ptr, size_t size) { return UMF_RESULT_SUCCESS; } -static const char *file_get_name(void *provider) { +static umf_result_t file_get_name(void *provider, const char **name) { (void)provider; // unused - return "FILE"; + *name = "FILE"; + return UMF_RESULT_SUCCESS; } static umf_result_t file_allocation_split(void *provider, void *ptr, diff --git a/src/provider/provider_fixed_memory.c b/src/provider/provider_fixed_memory.c index c300449463..bb63db46ac 100644 --- a/src/provider/provider_fixed_memory.c +++ b/src/provider/provider_fixed_memory.c @@ -175,19 +175,20 @@ static umf_result_t fixed_alloc(void *provider, size_t size, size_t alignment, return ret; } -static void fixed_get_last_native_error(void *provider, const char **ppMessage, - int32_t *pError) { +static umf_result_t fixed_get_last_native_error(void *provider, + const char **ppMessage, + int32_t *pError) { (void)provider; // unused if (ppMessage == NULL || pError == NULL) { assert(0); - return; + return UMF_RESULT_ERROR_INVALID_ARGUMENT; } *pError = TLS_last_native_error.native_error; if (TLS_last_native_error.errno_value == 0) { *ppMessage = Native_error_str[*pError - UMF_FIXED_RESULT_SUCCESS]; - return; + return UMF_RESULT_SUCCESS; } const char *msg; @@ -208,6 +209,7 @@ static void fixed_get_last_native_error(void *provider, const char **ppMessage, TLS_last_native_error.msg_buff + pos, TLS_MSG_BUF_LEN - pos); *ppMessage = TLS_last_native_error.msg_buff; + return UMF_RESULT_SUCCESS; } static umf_result_t fixed_get_recommended_page_size(void *provider, size_t size, @@ -247,9 +249,10 @@ static umf_result_t fixed_purge_force(void *provider, void *ptr, size_t size) { return UMF_RESULT_SUCCESS; } -static const char *fixed_get_name(void *provider) { +static umf_result_t fixed_get_name(void *provider, const char **name) { (void)provider; // unused - return "FIXED"; + *name = "FIXED"; + return UMF_RESULT_SUCCESS; } static umf_result_t fixed_allocation_split(void *provider, void *ptr, diff --git a/src/provider/provider_level_zero.c b/src/provider/provider_level_zero.c index ca91ac2a08..ba071a45e1 100644 --- a/src/provider/provider_level_zero.c +++ b/src/provider/provider_level_zero.c @@ -582,17 +582,18 @@ static umf_result_t ze_memory_provider_initialize(const void *params, return UMF_RESULT_SUCCESS; } -static void ze_memory_provider_get_last_native_error(void *provider, - const char **ppMessage, - int32_t *pError) { +static umf_result_t +ze_memory_provider_get_last_native_error(void *provider, const char **ppMessage, + int32_t *pError) { (void)provider; if (ppMessage == NULL || pError == NULL) { - ASSERT(0); - return; + return UMF_RESULT_ERROR_INVALID_ARGUMENT; } *pError = TLS_last_native_error; + + return UMF_RESULT_ERROR_NOT_SUPPORTED; // TODO: see #1385 } static umf_result_t ze_memory_provider_get_min_page_size(void *provider, @@ -645,9 +646,11 @@ ze_memory_provider_get_recommended_page_size(void *provider, size_t size, return ze_memory_provider_get_min_page_size(provider, NULL, pageSize); } -static const char *ze_memory_provider_get_name(void *provider) { +static umf_result_t ze_memory_provider_get_name(void *provider, + const char **name) { (void)provider; - return "LEVEL_ZERO"; + *name = "LEVEL_ZERO"; + return UMF_RESULT_SUCCESS; } static umf_result_t ze_memory_provider_allocation_merge(void *hProvider, diff --git a/src/provider/provider_os_memory.c b/src/provider/provider_os_memory.c index 8ebdaa38ec..1790c91af0 100644 --- a/src/provider/provider_os_memory.c +++ b/src/provider/provider_os_memory.c @@ -1150,19 +1150,19 @@ static umf_result_t os_free(void *provider, void *ptr, size_t size) { return UMF_RESULT_SUCCESS; } -static void os_get_last_native_error(void *provider, const char **ppMessage, - int32_t *pError) { +static umf_result_t os_get_last_native_error(void *provider, + const char **ppMessage, + int32_t *pError) { (void)provider; // unused if (ppMessage == NULL || pError == NULL) { - assert(0); - return; + return UMF_RESULT_SUCCESS; } *pError = TLS_last_native_error.native_error; if (TLS_last_native_error.errno_value == 0) { *ppMessage = Native_error_str[*pError - UMF_OS_RESULT_SUCCESS]; - return; + return UMF_RESULT_SUCCESS; } const char *msg; @@ -1183,6 +1183,7 @@ static void os_get_last_native_error(void *provider, const char **ppMessage, TLS_last_native_error.msg_buff + pos, TLS_MSG_BUF_LEN - pos); *ppMessage = TLS_last_native_error.msg_buff; + return UMF_RESULT_SUCCESS; } static umf_result_t os_get_recommended_page_size(void *provider, size_t size, @@ -1229,9 +1230,10 @@ static umf_result_t os_purge_force(void *provider, void *ptr, size_t size) { return UMF_RESULT_SUCCESS; } -static const char *os_get_name(void *provider) { +static umf_result_t os_get_name(void *provider, const char **name) { (void)provider; // unused - return "OS"; + *name = "OS"; + return UMF_RESULT_SUCCESS; } // This function is supposed to be thread-safe, so it should NOT be called concurrently diff --git a/src/provider/provider_tracking.c b/src/provider/provider_tracking.c index 252316ea60..386eef0ba3 100644 --- a/src/provider/provider_tracking.c +++ b/src/provider/provider_tracking.c @@ -1000,11 +1000,11 @@ static umf_result_t trackingFinalize(void *provider) { return UMF_RESULT_SUCCESS; } -static void trackingGetLastError(void *provider, const char **msg, - int32_t *pError) { +static umf_result_t trackingGetLastError(void *provider, const char **msg, + int32_t *pError) { umf_tracking_memory_provider_t *p = (umf_tracking_memory_provider_t *)provider; - umfMemoryProviderGetLastNativeError(p->hUpstream, msg, pError); + return umfMemoryProviderGetLastNativeError(p->hUpstream, msg, pError); } static umf_result_t trackingGetRecommendedPageSize(void *provider, size_t size, @@ -1034,10 +1034,10 @@ static umf_result_t trackingPurgeForce(void *provider, void *ptr, size_t size) { return umfMemoryProviderPurgeForce(p->hUpstream, ptr, size); } -static const char *trackingName(void *provider) { +static umf_result_t trackingName(void *provider, const char **name) { umf_tracking_memory_provider_t *p = (umf_tracking_memory_provider_t *)provider; - return umfMemoryProviderGetName(p->hUpstream); + return umfMemoryProviderGetName(p->hUpstream, name); } static umf_result_t trackingGetIpcHandleSize(void *provider, size_t *size) { @@ -1378,18 +1378,20 @@ static void free_ipc_segment(void *ipc_info_allocator, void *ptr) { } } -umf_memory_tracker_handle_t umfMemoryTrackerCreate(void) { +umf_result_t umfMemoryTrackerCreate(umf_memory_tracker_handle_t *handle_out) { umf_memory_tracker_handle_t handle = umf_ba_global_alloc(sizeof(struct umf_memory_tracker_t)); if (!handle) { - return NULL; + return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY; } - + umf_result_t ret = UMF_RESULT_SUCCESS; memset(handle, 0, sizeof(struct umf_memory_tracker_t)); umf_ba_pool_t *alloc_info_allocator = umf_ba_create(sizeof(struct tracker_alloc_info_t)); + if (!alloc_info_allocator) { + ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY; goto err_free_handle; } @@ -1397,6 +1399,7 @@ umf_memory_tracker_handle_t umfMemoryTrackerCreate(void) { void *mutex_ptr = utils_mutex_init(&handle->splitMergeMutex); if (!mutex_ptr) { + ret = UMF_RESULT_ERROR_UNKNOWN; goto err_destroy_alloc_info_allocator; } @@ -1405,6 +1408,7 @@ umf_memory_tracker_handle_t umfMemoryTrackerCreate(void) { handle->alloc_segments_map[i] = critnib_new(free_leaf, alloc_info_allocator); if (!handle->alloc_segments_map[i]) { + ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY; goto err_destroy_alloc_segments_map; } } @@ -1412,19 +1416,21 @@ umf_memory_tracker_handle_t umfMemoryTrackerCreate(void) { handle->ipc_info_allocator = umf_ba_create(sizeof(struct tracker_ipc_info_t)); if (!handle->ipc_info_allocator) { + ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY; goto err_destroy_alloc_segments_map; } handle->ipc_segments_map = critnib_new(free_ipc_segment, handle->ipc_info_allocator); if (!handle->ipc_segments_map) { + ret = UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY; goto err_destroy_ipc_info_allocator; } LOG_DEBUG("tracker created, handle=%p, alloc_segments_map=%p", (void *)handle, (void *)handle->alloc_segments_map); - - return handle; + *handle_out = handle; + return ret; err_destroy_ipc_info_allocator: umf_ba_destroy(handle->ipc_info_allocator); @@ -1439,7 +1445,7 @@ umf_memory_tracker_handle_t umfMemoryTrackerCreate(void) { umf_ba_destroy(alloc_info_allocator); err_free_handle: umf_ba_global_free(handle); - return NULL; + return ret; } void umfMemoryTrackerDestroy(umf_memory_tracker_handle_t handle) { diff --git a/src/provider/provider_tracking.h b/src/provider/provider_tracking.h index 842449be5c..d7ee06c1bb 100644 --- a/src/provider/provider_tracking.h +++ b/src/provider/provider_tracking.h @@ -31,7 +31,7 @@ typedef struct umf_memory_tracker_t *umf_memory_tracker_handle_t; extern umf_memory_tracker_handle_t TRACKER; -umf_memory_tracker_handle_t umfMemoryTrackerCreate(void); +umf_result_t umfMemoryTrackerCreate(umf_memory_tracker_handle_t *handle); void umfMemoryTrackerDestroy(umf_memory_tracker_handle_t handle); umf_memory_pool_handle_t umfMemoryTrackerGetPool(const void *ptr); diff --git a/src/proxy_lib/proxy_lib.c b/src/proxy_lib/proxy_lib.c index ccb60f8aba..690cdb63fa 100644 --- a/src/proxy_lib/proxy_lib.c +++ b/src/proxy_lib/proxy_lib.c @@ -391,8 +391,10 @@ void free(void *ptr) { if (ba_leak_free(ptr) == 0) { return; } + umf_memory_pool_handle_t pool; - if (Proxy_pool && (umfPoolByPtr(ptr) == Proxy_pool)) { + if (Proxy_pool && (umfPoolByPtr(ptr, &pool) == UMF_RESULT_SUCCESS && + pool == Proxy_pool)) { if (umfPoolFree(Proxy_pool, ptr) != UMF_RESULT_SUCCESS) { LOG_ERR("umfPoolFree() failed"); } @@ -425,8 +427,10 @@ void *realloc(void *ptr, size_t size) { if (leak_pool_contains_pointer) { return ba_leak_realloc(ptr, size, leak_pool_contains_pointer); } + umf_memory_pool_handle_t pool; - if (Proxy_pool && (umfPoolByPtr(ptr) == Proxy_pool)) { + if (Proxy_pool && (umfPoolByPtr(ptr, &pool) == UMF_RESULT_SUCCESS && + pool == Proxy_pool)) { was_called_from_umfPool = 1; void *new_ptr = umfPoolRealloc(Proxy_pool, ptr, size); was_called_from_umfPool = 0; @@ -474,10 +478,13 @@ size_t malloc_usable_size(void *ptr) { if (ba_leak_pool_contains_pointer(ptr)) { return 0; // unsupported in case of the ba_leak allocator } + umf_memory_pool_handle_t pool; - if (Proxy_pool && (umfPoolByPtr(ptr) == Proxy_pool)) { + if (Proxy_pool && (umfPoolByPtr(ptr, &pool) == UMF_RESULT_SUCCESS && + pool == Proxy_pool)) { was_called_from_umfPool = 1; - size_t size = umfPoolMallocUsableSize(Proxy_pool, ptr); + size_t size = 0; + umfPoolMallocUsableSize(Proxy_pool, ptr, &size); was_called_from_umfPool = 0; return size; } diff --git a/test/c_api/disjoint_pool.c b/test/c_api/disjoint_pool.c index 9058351603..932e14c38c 100644 --- a/test/c_api/disjoint_pool.c +++ b/test/c_api/disjoint_pool.c @@ -36,8 +36,9 @@ void test_disjoint_pool_shared_limits(void) { retp = umfDisjointPoolParamsCreate(¶ms); UT_ASSERTeq(retp, UMF_RESULT_SUCCESS); - umf_disjoint_pool_shared_limits_handle_t limits = - umfDisjointPoolSharedLimitsCreate(1024); + umf_disjoint_pool_shared_limits_handle_t limits; + retp = umfDisjointPoolSharedLimitsCreate(1024, &limits); + UT_ASSERTeq(retp, UMF_RESULT_SUCCESS); UT_ASSERTne(limits, NULL); retp = umfDisjointPoolParamsSetSharedLimits(params, limits); diff --git a/test/c_api/multi_pool.c b/test/c_api/multi_pool.c index bbd8383124..d9f3144d2a 100644 --- a/test/c_api/multi_pool.c +++ b/test/c_api/multi_pool.c @@ -1,4 +1,4 @@ -// Copyright (C) 2023-2024 Intel Corporation +// Copyright (C) 2023-2025 Intel Corporation // Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception @@ -87,7 +87,10 @@ int main(void) { } for (int i = 0; i < 4; i++) { - UT_ASSERTeq(umfPoolByPtr(ptrs[i]), pools[i]); + umf_memory_pool_handle_t pool = NULL; + ret = umfPoolByPtr(ptrs[i], &pool); + UT_ASSERTeq(ret, UMF_RESULT_SUCCESS); + UT_ASSERTeq(pool, pools[i]); } for (int i = 0; i < 4; i++) { diff --git a/test/common/pool.hpp b/test/common/pool.hpp index d9873810a1..6f1077a15e 100644 --- a/test/common/pool.hpp +++ b/test/common/pool.hpp @@ -112,7 +112,12 @@ typedef struct pool_base_t { void *calloc(size_t, size_t) noexcept { return nullptr; } void *realloc(void *, size_t) noexcept { return nullptr; } void *aligned_malloc(size_t, size_t) noexcept { return nullptr; } - size_t malloc_usable_size(const void *) noexcept { return 0; } + umf_result_t malloc_usable_size(const void *, size_t *size) noexcept { + if (size) { + *size = 0; + } + return UMF_RESULT_SUCCESS; + } umf_result_t free(void *) noexcept { return UMF_RESULT_SUCCESS; } umf_result_t get_last_allocation_error() noexcept { return UMF_RESULT_SUCCESS; @@ -138,14 +143,17 @@ struct malloc_pool : public pool_base_t { return ::aligned_alloc(alignment, size); #endif } - size_t malloc_usable_size(const void *ptr) noexcept { + umf_result_t malloc_usable_size(const void *ptr, size_t *size) noexcept { + if (size) { #ifdef _WIN32 - return _msize((void *)ptr); + *size = _msize((void *)ptr); #elif __APPLE__ - return ::malloc_size((void *)ptr); + *size = ::malloc_size((void *)ptr); #else - return ::malloc_usable_size((void *)ptr); + *size = ::malloc_usable_size((void *)ptr); #endif + } + return UMF_RESULT_SUCCESS; } umf_result_t free(void *ptr) noexcept { ::free(ptr); diff --git a/test/common/pool_null.c b/test/common/pool_null.c index a44f3c4ab1..4073fe6598 100644 --- a/test/common/pool_null.c +++ b/test/common/pool_null.c @@ -49,10 +49,14 @@ static void *nullAlignedMalloc(void *pool, size_t size, size_t alignment) { return NULL; } -static size_t nullMallocUsableSize(void *pool, const void *ptr) { +static umf_result_t nullMallocUsableSize(void *pool, const void *ptr, + size_t *size) { (void)ptr; (void)pool; - return 0; + if (size) { + *size = 0; + } + return UMF_RESULT_SUCCESS; } static umf_result_t nullFree(void *pool, void *ptr) { diff --git a/test/common/pool_trace.c b/test/common/pool_trace.c index e4479548f6..719a57fb4c 100644 --- a/test/common/pool_trace.c +++ b/test/common/pool_trace.c @@ -69,12 +69,13 @@ static void *traceAlignedMalloc(void *pool, size_t size, size_t alignment) { alignment); } -static size_t traceMallocUsableSize(void *pool, const void *ptr) { +static umf_result_t traceMallocUsableSize(void *pool, const void *ptr, + size_t *size) { trace_pool_t *trace_pool = (trace_pool_t *)pool; trace_pool->params.trace_handler(trace_pool->params.trace_context, "malloc_usable_size"); - return umfPoolMallocUsableSize(trace_pool->params.hUpstreamPool, ptr); + return umfPoolMallocUsableSize(trace_pool->params.hUpstreamPool, ptr, size); } static umf_result_t traceFree(void *pool, void *ptr) { diff --git a/test/common/provider.hpp b/test/common/provider.hpp index a393a77c67..6d42c59f23 100644 --- a/test/common/provider.hpp +++ b/test/common/provider.hpp @@ -42,7 +42,9 @@ typedef struct provider_base_t { [[maybe_unused]] size_t size) noexcept { return UMF_RESULT_ERROR_UNKNOWN; } - void get_last_native_error(const char **, int32_t *) noexcept {} + umf_result_t get_last_native_error(const char **, int32_t *) noexcept { + return UMF_RESULT_ERROR_UNKNOWN; + } umf_result_t get_recommended_page_size([[maybe_unused]] size_t size, [[maybe_unused]] size_t *pageSize) noexcept { @@ -52,7 +54,10 @@ typedef struct provider_base_t { [[maybe_unused]] size_t *pageSize) noexcept { return UMF_RESULT_ERROR_UNKNOWN; } - const char *get_name() noexcept { return "base"; } + umf_result_t get_name(const char **name) noexcept { + *name = "base"; + return UMF_RESULT_SUCCESS; + } umf_result_t ext_purge_lazy([[maybe_unused]] void *ptr, [[maybe_unused]] size_t size) noexcept { return UMF_RESULT_ERROR_UNKNOWN; @@ -125,7 +130,10 @@ struct provider_ba_global : public provider_base_t { umf_ba_global_free(ptr); return UMF_RESULT_SUCCESS; } - const char *get_name() noexcept { return "umf_ba_global"; } + umf_result_t get_name(const char **name) noexcept { + *name = "umf_ba_global"; + return UMF_RESULT_SUCCESS; + } }; umf_memory_provider_ops_t BA_GLOBAL_PROVIDER_OPS = @@ -150,7 +158,10 @@ struct provider_mock_out_of_mem : public provider_base_t { umf_result_t free(void *ptr, size_t size) noexcept { return helper_prov.free(ptr, size); } - const char *get_name() noexcept { return "mock_out_of_mem"; } + umf_result_t get_name(const char **name) noexcept { + *name = "mock_out_of_mem"; + return UMF_RESULT_SUCCESS; + } }; const umf_memory_provider_ops_t MOCK_OUT_OF_MEM_PROVIDER_OPS = diff --git a/test/common/provider_null.c b/test/common/provider_null.c index 8c1602be7e..380cba47d3 100644 --- a/test/common/provider_null.c +++ b/test/common/provider_null.c @@ -35,11 +35,12 @@ static umf_result_t nullFree(void *provider, void *ptr, size_t size) { return UMF_RESULT_SUCCESS; } -static void nullGetLastError(void *provider, const char **ppMsg, - int32_t *pError) { +static umf_result_t nullGetLastError(void *provider, const char **ppMsg, + int32_t *pError) { (void)provider; (void)ppMsg; (void)pError; + return UMF_RESULT_SUCCESS; } static umf_result_t nullGetRecommendedPageSize(void *provider, size_t size, @@ -58,9 +59,10 @@ static umf_result_t nullGetPageSize(void *provider, const void *ptr, return UMF_RESULT_SUCCESS; } -static const char *nullName(void *provider) { +static umf_result_t nullName(void *provider, const char **name) { (void)provider; - return "null"; + *name = "null"; + return UMF_RESULT_SUCCESS; } static umf_result_t nullPurgeLazy(void *provider, void *ptr, size_t size) { diff --git a/test/common/provider_trace.c b/test/common/provider_trace.c index 6be80c0de3..adb8083369 100644 --- a/test/common/provider_trace.c +++ b/test/common/provider_trace.c @@ -60,8 +60,8 @@ static umf_result_t traceFree(void *provider, void *ptr, size_t size) { return umfMemoryProviderFree(traceProvider->hUpstreamProvider, ptr, size); } -static void traceGetLastError(void *provider, const char **ppMsg, - int32_t *pError) { +static umf_result_t traceGetLastError(void *provider, const char **ppMsg, + int32_t *pError) { umf_provider_trace_params_t *traceProvider = (umf_provider_trace_params_t *)provider; @@ -69,6 +69,7 @@ static void traceGetLastError(void *provider, const char **ppMsg, "get_last_native_error"); umfMemoryProviderGetLastNativeError(traceProvider->hUpstreamProvider, ppMsg, pError); + return UMF_RESULT_SUCCESS; } static umf_result_t traceGetRecommendedPageSize(void *provider, size_t size, @@ -93,12 +94,12 @@ static umf_result_t traceGetPageSize(void *provider, const void *ptr, ptr, pageSize); } -static const char *traceName(void *provider) { +static umf_result_t traceName(void *provider, const char **name) { umf_provider_trace_params_t *traceProvider = (umf_provider_trace_params_t *)provider; traceProvider->trace_handler(traceProvider->trace_context, "name"); - return umfMemoryProviderGetName(traceProvider->hUpstreamProvider); + return umfMemoryProviderGetName(traceProvider->hUpstreamProvider, name); } static umf_result_t tracePurgeLazy(void *provider, void *ptr, size_t size) { diff --git a/test/ipcAPI.cpp b/test/ipcAPI.cpp index 15e995acdc..bd3f412da4 100644 --- a/test/ipcAPI.cpp +++ b/test/ipcAPI.cpp @@ -47,7 +47,10 @@ struct provider_mock_ipc : public umf_test::provider_base_t { return ret; } - const char *get_name() noexcept { return "mock_ipc"; } + umf_result_t get_name(const char **name) noexcept { + *name = "mock_ipc"; + return UMF_RESULT_SUCCESS; + } umf_result_t ext_get_ipc_handle_size(size_t *size) noexcept { *size = sizeof(provider_ipc_data_t); diff --git a/test/memoryPoolAPI.cpp b/test/memoryPoolAPI.cpp index 8df9735a25..235db02fcd 100644 --- a/test/memoryPoolAPI.cpp +++ b/test/memoryPoolAPI.cpp @@ -77,7 +77,9 @@ TEST_P(umfPoolWithCreateFlagsTest, memoryPoolTrace) { ASSERT_EQ(providerCalls["alloc"], 1UL); ASSERT_EQ(providerCalls.size(), ++provider_call_count); - umfPoolMallocUsableSize(tracingPool.get(), nullptr); + size_t tmpSize; + umfPoolMallocUsableSize(tracingPool.get(), nullptr, &tmpSize); + // we ignore return value of poolMallocUsabeSize(), as it might be not supported ASSERT_EQ(poolCalls["malloc_usable_size"], 1UL); ASSERT_EQ(poolCalls.size(), ++pool_call_count); @@ -166,13 +168,17 @@ TEST_F(test, BasicPoolByPtrTest) { char *ptr = (char *)umfPoolMalloc(expected_pool, SIZE); ASSERT_NE(ptr, nullptr); - auto ret_pool = umfPoolByPtr(ptr); + umf_memory_pool_handle_t ret_pool = nullptr; + ret = umfPoolByPtr(ptr, &ret_pool); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); EXPECT_EQ(ret_pool, expected_pool); - ret_pool = umfPoolByPtr(ptr + SIZE); + ret = umfPoolByPtr(ptr + SIZE, &ret_pool); + ASSERT_NE(ret, UMF_RESULT_SUCCESS); EXPECT_EQ(ret_pool, nullptr); - ret_pool = umfPoolByPtr(ptr + SIZE - 1); + ret = umfPoolByPtr(ptr + SIZE - 1, &ret_pool); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); EXPECT_EQ(ret_pool, expected_pool); ret = umfFree(ptr); @@ -415,8 +421,8 @@ TEST_F(test, getLastFailedMemoryProvider) { static umf_result_t allocResult = UMF_RESULT_SUCCESS; struct memory_provider : public umf_test::provider_base_t { - umf_result_t initialize(const char *inName) { - name = inName; + umf_result_t initialize(const char *name) { + provider_name = name; return UMF_RESULT_SUCCESS; } @@ -435,9 +441,12 @@ TEST_F(test, getLastFailedMemoryProvider) { return UMF_RESULT_SUCCESS; } - const char *get_name() noexcept { return this->name; } + umf_result_t get_name(const char **name) noexcept { + *name = this->provider_name; + return UMF_RESULT_SUCCESS; + } - const char *name; + const char *provider_name; }; umf_memory_provider_ops_t provider_ops = umf_test::providerMakeCOps(); @@ -459,25 +468,32 @@ TEST_F(test, getLastFailedMemoryProvider) { allocResult = UMF_RESULT_ERROR_UNKNOWN; ptr = umfPoolMalloc(pool.get(), allocSize); ASSERT_EQ(ptr, nullptr); - ASSERT_EQ(std::string_view( - umfMemoryProviderGetName(umfGetLastFailedMemoryProvider())), - "provider1"); + umf_memory_provider_handle_t lastProv = nullptr; + umf_result_t ret = umfGetLastFailedMemoryProvider(&lastProv); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); + const char *lastName = nullptr; + ret = umfMemoryProviderGetName(lastProv, &lastName); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); + ASSERT_EQ(std::string_view(lastName), "provider1"); - auto ret = - umfMemoryProviderAlloc(providerUnique2.get(), allocSize, 0, &ptr); + ret = umfMemoryProviderAlloc(providerUnique2.get(), allocSize, 0, &ptr); ASSERT_NE(ret, UMF_RESULT_SUCCESS); ASSERT_EQ(ptr, nullptr); - ASSERT_EQ(std::string_view( - umfMemoryProviderGetName(umfGetLastFailedMemoryProvider())), - "provider2"); + ret = umfGetLastFailedMemoryProvider(&lastProv); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); + ret = umfMemoryProviderGetName(lastProv, &lastName); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); + ASSERT_EQ(std::string_view(lastName), "provider2"); // successful provider should not be returned by umfGetLastFailedMemoryProvider allocResult = UMF_RESULT_SUCCESS; ptr = umfPoolMalloc(pool.get(), allocSize); ASSERT_NE(ptr, nullptr); - ASSERT_EQ(std::string_view( - umfMemoryProviderGetName(umfGetLastFailedMemoryProvider())), - "provider2"); + ret = umfGetLastFailedMemoryProvider(&lastProv); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); + ret = umfMemoryProviderGetName(lastProv, &lastName); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); + ASSERT_EQ(std::string_view(lastName), "provider2"); umfPoolFree(pool.get(), ptr); // error in another thread should not impact umfGetLastFailedMemoryProvider on this thread @@ -485,15 +501,21 @@ TEST_F(test, getLastFailedMemoryProvider) { std::thread t([&, hPool = pool.get()] { ptr = umfPoolMalloc(hPool, allocSize); ASSERT_EQ(ptr, nullptr); - ASSERT_EQ(std::string_view(umfMemoryProviderGetName( - umfGetLastFailedMemoryProvider())), - "provider1"); + umf_memory_provider_handle_t prov = nullptr; + umf_result_t ret = umfGetLastFailedMemoryProvider(&prov); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); + const char *name = nullptr; + ret = umfMemoryProviderGetName(prov, &name); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); + ASSERT_EQ(std::string_view(name), "provider1"); }); t.join(); - ASSERT_EQ(std::string_view( - umfMemoryProviderGetName(umfGetLastFailedMemoryProvider())), - "provider2"); + ret = umfGetLastFailedMemoryProvider(&lastProv); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); + ret = umfMemoryProviderGetName(lastProv, &lastName); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); + ASSERT_EQ(std::string_view(lastName), "provider2"); } // This fixture can be instantiated with any function that accepts void diff --git a/test/memoryProviderAPI.cpp b/test/memoryProviderAPI.cpp index e35fc5282d..33e298dc6e 100644 --- a/test/memoryProviderAPI.cpp +++ b/test/memoryProviderAPI.cpp @@ -7,6 +7,7 @@ #include "provider_null.h" #include "test_helpers.h" +#include #include #include #include @@ -38,8 +39,11 @@ TEST_F(test, memoryProviderTrace) { ASSERT_EQ(calls["free"], 1UL); ASSERT_EQ(calls.size(), ++call_count); - umfMemoryProviderGetLastNativeError(tracingProvider.get(), nullptr, - nullptr); + const char *buffer; + int err; + ret = umfMemoryProviderGetLastNativeError(tracingProvider.get(), &buffer, + &err); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); ASSERT_EQ(calls["get_last_native_error"], 1UL); ASSERT_EQ(calls.size(), ++call_count); @@ -56,7 +60,10 @@ TEST_F(test, memoryProviderTrace) { ASSERT_EQ(calls["get_min_page_size"], 1UL); ASSERT_EQ(calls.size(), ++call_count); - const char *pName = umfMemoryProviderGetName(tracingProvider.get()); + const char *pName = nullptr; + ret = umfMemoryProviderGetName(tracingProvider.get(), &pName); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); + ASSERT_NE(pName, nullptr); ASSERT_EQ(calls["name"], 1UL); ASSERT_EQ(calls.size(), ++call_count); ASSERT_EQ(std::string(pName), std::string("null")); diff --git a/test/poolFixtures.hpp b/test/poolFixtures.hpp index 23f519eccd..c9c98568a0 100644 --- a/test/poolFixtures.hpp +++ b/test/poolFixtures.hpp @@ -468,11 +468,15 @@ TEST_P(umfMultiPoolTest, memoryTracking) { } for (auto [ptr, size, expectedPool] : ptrs) { - auto pool = umfPoolByPtr(ptr); + umf_memory_pool_handle_t pool = nullptr; + auto ret = umfPoolByPtr(ptr, &pool); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); ASSERT_EQ(pool, expectedPool); - pool = umfPoolByPtr(reinterpret_cast( - reinterpret_cast(ptr) + size - 1)); + ret = umfPoolByPtr(reinterpret_cast( + reinterpret_cast(ptr) + size - 1), + &pool); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); ASSERT_EQ(pool, expectedPool); } @@ -526,6 +530,9 @@ TEST_P(umfPoolTest, mallocUsableSize) { << "This test is invalid with AddressSanitizer instrumentation"; } #endif + if (pool_ops == umfProxyPoolOps()) { + GTEST_SKIP() << "Proxy pool does not support umfPoolMallocUsableSize"; + } for (size_t allocSize : {32, 64, 1 << 6, 1 << 10, 1 << 13, 1 << 16, 1 << 19}) { for (size_t alignment : {0, 1 << 6, 1 << 8, 1 << 12}) { @@ -539,7 +546,11 @@ TEST_P(umfPoolTest, mallocUsableSize) { ptr = umfPoolAlignedMalloc(pool.get(), allocSize, alignment); } ASSERT_NE(ptr, nullptr); - size_t result = umfPoolMallocUsableSize(pool.get(), ptr); + size_t result = 0; + umf_result_t ret = + umfPoolMallocUsableSize(pool.get(), ptr, &result); + + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); ASSERT_TRUE(result == 0 || result >= allocSize); // Make sure we can write to this memory diff --git a/test/pools/disjoint_pool.cpp b/test/pools/disjoint_pool.cpp index 7780846ced..e1a91a58e3 100644 --- a/test/pools/disjoint_pool.cpp +++ b/test/pools/disjoint_pool.cpp @@ -218,11 +218,14 @@ TEST_F(test, sharedLimits) { umf_result_t ret = umfDisjointPoolParamsSetSlabMinSize(params, SlabMinSize); EXPECT_EQ(ret, UMF_RESULT_SUCCESS); + umf_disjoint_pool_shared_limits_handle_t hLimits = nullptr; + ret = umfDisjointPoolSharedLimitsCreate(MaxSize, &hLimits); + EXPECT_EQ(ret, UMF_RESULT_SUCCESS); + EXPECT_NE(hLimits, nullptr); auto limits = std::unique_ptr( - umfDisjointPoolSharedLimitsCreate(MaxSize), - &umfDisjointPoolSharedLimitsDestroy); + hLimits, &umfDisjointPoolSharedLimitsDestroy); ret = umfDisjointPoolParamsSetSharedLimits(params, limits.get()); EXPECT_EQ(ret, UMF_RESULT_SUCCESS); @@ -349,7 +352,9 @@ TEST_F(test, disjointPoolName) { res = umfPoolCreate(umfDisjointPoolOps(), provider_handle, params, 0, &pool); EXPECT_EQ(res, UMF_RESULT_SUCCESS); - const char *name = umfPoolGetName(pool); + const char *name = nullptr; + res = umfPoolGetName(pool, &name); + EXPECT_EQ(res, UMF_RESULT_SUCCESS); EXPECT_STREQ(name, "disjoint"); umfPoolDestroy(pool); diff --git a/test/pools/disjoint_pool_ctl.cpp b/test/pools/disjoint_pool_ctl.cpp index e683b9bc0f..fa084b2216 100644 --- a/test/pools/disjoint_pool_ctl.cpp +++ b/test/pools/disjoint_pool_ctl.cpp @@ -109,7 +109,8 @@ TEST_F(test, disjointCtlName) { params); // Check that the default name is correctly set - const char *name = umfPoolGetName(poolWrapper.get()); + const char *name = NULL; + ASSERT_SUCCESS(umfPoolGetName(poolWrapper.get(), &name)); ASSERT_STREQ(name, val); // Clean up @@ -142,7 +143,8 @@ TEST_F(test, disjointCtlChangeNameTwice) { params); // Check that the default name is correctly set - const char *name = umfPoolGetName(poolWrapper.get()); + const char *name = NULL; + ASSERT_SUCCESS(umfPoolGetName(poolWrapper.get(), &name)); ASSERT_STREQ(name, val2); // Clean up diff --git a/test/pools/pool_base_alloc.cpp b/test/pools/pool_base_alloc.cpp index 574803fd3f..e1d69226d8 100644 --- a/test/pools/pool_base_alloc.cpp +++ b/test/pools/pool_base_alloc.cpp @@ -31,8 +31,11 @@ struct base_alloc_pool : public umf_test::pool_base_t { UMF_RESULT_ERROR_NOT_SUPPORTED; return NULL; } - size_t malloc_usable_size(const void *ptr) noexcept { - return umf_ba_global_malloc_usable_size(ptr); + umf_result_t malloc_usable_size(const void *ptr, size_t *size) noexcept { + if (size) { + *size = umf_ba_global_malloc_usable_size(ptr); + } + return UMF_RESULT_SUCCESS; } umf_result_t free(void *ptr) noexcept { umf_ba_global_free(ptr); diff --git a/test/pools/scalable_pool.cpp b/test/pools/scalable_pool.cpp index 5f392da466..b961d4f5ed 100644 --- a/test/pools/scalable_pool.cpp +++ b/test/pools/scalable_pool.cpp @@ -180,7 +180,9 @@ TEST(scalablePoolTest, scalablePoolName) { ret = umfPoolCreate(umfScalablePoolOps(), provider, nullptr, 0, &pool); ASSERT_EQ(ret, UMF_RESULT_SUCCESS); - const char *name = umfPoolGetName(pool); + const char *name = nullptr; + ret = umfPoolGetName(pool, &name); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); EXPECT_STREQ(name, "scalable"); umfPoolDestroy(pool); diff --git a/test/provider_devdax_memory.cpp b/test/provider_devdax_memory.cpp index 41724fd91c..0405bf6780 100644 --- a/test/provider_devdax_memory.cpp +++ b/test/provider_devdax_memory.cpp @@ -108,7 +108,9 @@ static void verify_last_native_error(umf_memory_provider_handle_t provider, int32_t err) { const char *message; int32_t error; - umfMemoryProviderGetLastNativeError(provider, &message, &error); + umf_result_t ret = + umfMemoryProviderGetLastNativeError(provider, &message, &error); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); ASSERT_EQ(error, err); ASSERT_EQ(compare_native_error_str(message, error), 0); } @@ -296,7 +298,9 @@ TEST_P(umfProviderTest, get_recommended_page_size) { } TEST_P(umfProviderTest, get_name) { - const char *name = umfMemoryProviderGetName(provider.get()); + const char *name = nullptr; + umf_result_t ret = umfMemoryProviderGetName(provider.get(), &name); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); ASSERT_STREQ(name, "DEVDAX"); } diff --git a/test/provider_file_memory.cpp b/test/provider_file_memory.cpp index 2445447315..917f30a369 100644 --- a/test/provider_file_memory.cpp +++ b/test/provider_file_memory.cpp @@ -106,7 +106,9 @@ static void verify_last_native_error(umf_memory_provider_handle_t provider, int32_t err) { const char *message; int32_t error; - umfMemoryProviderGetLastNativeError(provider, &message, &error); + umf_result_t ret = + umfMemoryProviderGetLastNativeError(provider, &message, &error); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); ASSERT_EQ(error, err); ASSERT_EQ(compare_native_error_str(message, error), 0); } @@ -361,7 +363,9 @@ TEST_P(FileProviderParamsDefault, get_recommended_page_size) { } TEST_P(FileProviderParamsDefault, get_name) { - const char *name = umfMemoryProviderGetName(provider.get()); + const char *name = nullptr; + umf_result_t ret_get = umfMemoryProviderGetName(provider.get(), &name); + ASSERT_EQ(ret_get, UMF_RESULT_SUCCESS); ASSERT_STREQ(name, "FILE"); } diff --git a/test/provider_fixed_memory.cpp b/test/provider_fixed_memory.cpp index 83727de2b2..f7befa0b6d 100644 --- a/test/provider_fixed_memory.cpp +++ b/test/provider_fixed_memory.cpp @@ -119,7 +119,9 @@ struct FixedProviderTest const char *message; int32_t error; auto provider = this->provider.get(); - umfMemoryProviderGetLastNativeError(provider, &message, &error); + umf_result_t ret = + umfMemoryProviderGetLastNativeError(provider, &message, &error); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); ASSERT_EQ(error, err); ASSERT_EQ(compare_native_error_str(message, error), 0); } @@ -270,7 +272,9 @@ TEST_P(FixedProviderTest, get_recommended_page_size) { } TEST_P(FixedProviderTest, get_name) { - const char *name = umfMemoryProviderGetName(provider.get()); + const char *name = nullptr; + umf_result_t ret = umfMemoryProviderGetName(provider.get(), &name); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); ASSERT_STREQ(name, "FIXED"); } diff --git a/test/provider_os_memory.cpp b/test/provider_os_memory.cpp index 96396c18f2..02a20df2f6 100644 --- a/test/provider_os_memory.cpp +++ b/test/provider_os_memory.cpp @@ -109,7 +109,9 @@ static void verify_last_native_error(umf_memory_provider_handle_t provider, int32_t err) { const char *message; int32_t error; - umfMemoryProviderGetLastNativeError(provider, &message, &error); + umf_result_t ret = + umfMemoryProviderGetLastNativeError(provider, &message, &error); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); ASSERT_EQ(error, err); ASSERT_EQ(compare_native_error_str(message, error), 0); } @@ -326,7 +328,9 @@ TEST_P(umfProviderTest, get_recommended_page_size) { } TEST_P(umfProviderTest, get_name) { - const char *name = umfMemoryProviderGetName(provider.get()); + const char *name = nullptr; + umf_result_t ret = umfMemoryProviderGetName(provider.get(), &name); + ASSERT_EQ(ret, UMF_RESULT_SUCCESS); ASSERT_STREQ(name, "OS"); } diff --git a/test/provider_tracking_fixture_tests.cpp b/test/provider_tracking_fixture_tests.cpp index 8ab7082758..3da861073e 100644 --- a/test/provider_tracking_fixture_tests.cpp +++ b/test/provider_tracking_fixture_tests.cpp @@ -37,7 +37,10 @@ struct provider_from_pool : public umf_test::provider_base_t { umf_result_t free(void *ptr, size_t) noexcept { return umfPoolFree(pool, ptr); } - const char *get_name() noexcept { return "provider_from_pool"; } + umf_result_t get_name(const char **name) noexcept { + *name = "provider_from_pool"; + return UMF_RESULT_SUCCESS; + } virtual ~provider_from_pool() { if (pool) { diff --git a/test/providers/provider_cuda.cpp b/test/providers/provider_cuda.cpp index 00d8e9d8fc..9b0d29f4b5 100644 --- a/test/providers/provider_cuda.cpp +++ b/test/providers/provider_cuda.cpp @@ -268,7 +268,9 @@ TEST_P(umfCUDAProviderTest, getName) { ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS); ASSERT_NE(provider, nullptr); - const char *name = umfMemoryProviderGetName(provider); + const char *name = nullptr; + umf_result = umfMemoryProviderGetName(provider, &name); + ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS); ASSERT_STREQ(name, "CUDA"); umfMemoryProviderDestroy(provider); diff --git a/test/providers/provider_level_zero.cpp b/test/providers/provider_level_zero.cpp index e30500d9de..d6d479a14d 100644 --- a/test/providers/provider_level_zero.cpp +++ b/test/providers/provider_level_zero.cpp @@ -381,7 +381,9 @@ TEST_P(umfLevelZeroProviderTest, getName) { ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS); ASSERT_NE(provider, nullptr); - const char *name = umfMemoryProviderGetName(provider); + const char *name = nullptr; + umf_result = umfMemoryProviderGetName(provider, &name); + ASSERT_EQ(umf_result, UMF_RESULT_SUCCESS); ASSERT_STREQ(name, "LEVEL_ZERO"); umfMemoryProviderDestroy(provider); @@ -400,7 +402,9 @@ TEST_P(umfLevelZeroProviderTest, allocInvalidSize) { ASSERT_EQ(umf_result, UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC); const char *message; int32_t error; - umfMemoryProviderGetLastNativeError(provider, &message, &error); + umf_result = + umfMemoryProviderGetLastNativeError(provider, &message, &error); + ASSERT_EQ(umf_result, UMF_RESULT_ERROR_NOT_SUPPORTED); // TODO: see #1385 ASSERT_EQ(error, ZE_RESULT_ERROR_UNSUPPORTED_SIZE); umfMemoryProviderDestroy(provider); diff --git a/test/test_proxy_lib_size_threshold.cpp b/test/test_proxy_lib_size_threshold.cpp index fac1c516b0..69394e787b 100644 --- a/test/test_proxy_lib_size_threshold.cpp +++ b/test/test_proxy_lib_size_threshold.cpp @@ -1,5 +1,5 @@ /* - * 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 @@ -70,8 +70,13 @@ TEST_F(test, proxyLib_size_threshold_aligned_alloc) { ASSERT_EQ((int)(IS_ALIGNED((uintptr_t)ptr_LT, ALIGN_1024)), 1); ASSERT_EQ((int)(IS_ALIGNED((uintptr_t)ptr_EQ, ALIGN_1024)), 1); - ASSERT_EQ(umfPoolByPtr(ptr_LT), nullptr); - ASSERT_NE(umfPoolByPtr(ptr_EQ), nullptr); + umf_memory_pool_handle_t poolTmp = nullptr; + umf_result_t ret_pool = umfPoolByPtr(ptr_LT, &poolTmp); + ASSERT_NE(ret_pool, UMF_RESULT_SUCCESS); + ASSERT_EQ(poolTmp, nullptr); + ret_pool = umfPoolByPtr(ptr_EQ, &poolTmp); + ASSERT_EQ(ret_pool, UMF_RESULT_SUCCESS); + ASSERT_NE(poolTmp, nullptr); #ifdef _WIN32 _aligned_free(ptr_LT); @@ -89,8 +94,13 @@ TEST_F(test, proxyLib_size_threshold_malloc) { ASSERT_NE(ptr_LT, nullptr); ASSERT_NE(ptr_EQ, nullptr); - ASSERT_EQ(umfPoolByPtr(ptr_LT), nullptr); - ASSERT_NE(umfPoolByPtr(ptr_EQ), nullptr); + umf_memory_pool_handle_t poolTmp = nullptr; + umf_result_t ret_pool = umfPoolByPtr(ptr_LT, &poolTmp); + ASSERT_NE(ret_pool, UMF_RESULT_SUCCESS); + ASSERT_EQ(poolTmp, nullptr); + ret_pool = umfPoolByPtr(ptr_EQ, &poolTmp); + ASSERT_EQ(ret_pool, UMF_RESULT_SUCCESS); + ASSERT_NE(poolTmp, nullptr); ::free(ptr_LT); ::free(ptr_EQ); @@ -103,8 +113,13 @@ TEST_F(test, proxyLib_size_threshold_calloc) { ASSERT_NE(ptr_LT, nullptr); ASSERT_NE(ptr_EQ, nullptr); - ASSERT_EQ(umfPoolByPtr(ptr_LT), nullptr); - ASSERT_NE(umfPoolByPtr(ptr_EQ), nullptr); + umf_memory_pool_handle_t poolTmp = nullptr; + umf_result_t ret_pool = umfPoolByPtr(ptr_LT, &poolTmp); + ASSERT_NE(ret_pool, UMF_RESULT_SUCCESS); + ASSERT_EQ(poolTmp, nullptr); + ret_pool = umfPoolByPtr(ptr_EQ, &poolTmp); + ASSERT_EQ(ret_pool, UMF_RESULT_SUCCESS); + ASSERT_NE(poolTmp, nullptr); ::free(ptr_LT); ::free(ptr_EQ); @@ -123,8 +138,13 @@ TEST_F(test, proxyLib_size_threshold_realloc_up) { ASSERT_NE(ptr_LT_r, nullptr); ASSERT_NE(ptr_EQ_r, nullptr); - ASSERT_EQ(umfPoolByPtr(ptr_LT_r), nullptr); - ASSERT_NE(umfPoolByPtr(ptr_EQ_r), nullptr); + umf_memory_pool_handle_t poolTmp = nullptr; + umf_result_t ret_pool = umfPoolByPtr(ptr_LT_r, &poolTmp); + ASSERT_NE(ret_pool, UMF_RESULT_SUCCESS); + ASSERT_EQ(poolTmp, nullptr); + ret_pool = umfPoolByPtr(ptr_EQ_r, &poolTmp); + ASSERT_EQ(ret_pool, UMF_RESULT_SUCCESS); + ASSERT_NE(poolTmp, nullptr); ::free(ptr_LT_r); ::free(ptr_EQ_r); @@ -143,8 +163,13 @@ TEST_F(test, proxyLib_size_threshold_realloc_down) { ASSERT_NE(ptr_LT_r, nullptr); ASSERT_NE(ptr_EQ_r, nullptr); - ASSERT_EQ(umfPoolByPtr(ptr_LT_r), nullptr); - ASSERT_NE(umfPoolByPtr(ptr_EQ_r), nullptr); + umf_memory_pool_handle_t poolTmp = nullptr; + umf_result_t ret_pool = umfPoolByPtr(ptr_LT_r, &poolTmp); + ASSERT_NE(ret_pool, UMF_RESULT_SUCCESS); + ASSERT_EQ(poolTmp, nullptr); + ret_pool = umfPoolByPtr(ptr_EQ_r, &poolTmp); + ASSERT_EQ(ret_pool, UMF_RESULT_SUCCESS); + ASSERT_NE(poolTmp, nullptr); ::free(ptr_LT_r); ::free(ptr_EQ_r); diff --git a/test/utils/cpp_helpers.hpp b/test/utils/cpp_helpers.hpp index ae18d7b1b2..8594a6aa07 100644 --- a/test/utils/cpp_helpers.hpp +++ b/test/utils/cpp_helpers.hpp @@ -76,7 +76,7 @@ template umf_memory_pool_ops_t poolOpsBase() { UMF_ASSIGN_OP(ops, T, calloc, ((void *)nullptr)); UMF_ASSIGN_OP(ops, T, aligned_malloc, ((void *)nullptr)); UMF_ASSIGN_OP(ops, T, realloc, ((void *)nullptr)); - UMF_ASSIGN_OP(ops, T, malloc_usable_size, ((size_t)0)); + UMF_ASSIGN_OP(ops, T, malloc_usable_size, UMF_RESULT_SUCCESS); UMF_ASSIGN_OP(ops, T, free, UMF_RESULT_SUCCESS); UMF_ASSIGN_OP(ops, T, get_last_allocation_error, UMF_RESULT_ERROR_UNKNOWN); return ops; @@ -91,10 +91,10 @@ template constexpr umf_memory_provider_ops_t providerOpsBase() { }; UMF_ASSIGN_OP(ops, T, alloc, UMF_RESULT_ERROR_UNKNOWN); UMF_ASSIGN_OP(ops, T, free, UMF_RESULT_ERROR_UNKNOWN); - UMF_ASSIGN_OP_NORETURN(ops, T, get_last_native_error); + UMF_ASSIGN_OP(ops, T, get_last_native_error, UMF_RESULT_ERROR_UNKNOWN); 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, T, get_name, 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);