Skip to content

Add checks for pool and provider handles #163

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/critnib/critnib.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#include <stddef.h>

#include "critnib.h"
#include "utils_common.h"
#include "utils_concurrency.h"

/*
Expand Down
8 changes: 8 additions & 0 deletions src/memory_pool.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*/

#include "memory_pool_internal.h"
#include "utils_common.h"

#include <umf/memory_pool.h>
#include <umf/memory_pool_ops.h>
Expand Down Expand Up @@ -47,30 +48,37 @@ umf_result_t umfPoolCreateEx(const umf_memory_pool_ops_t *pool_ops,
}

void *umfPoolMalloc(umf_memory_pool_handle_t hPool, size_t size) {
UMF_CHECK((hPool != NULL), NULL);
return hPool->ops.malloc(hPool->pool_priv, size);
}

void *umfPoolAlignedMalloc(umf_memory_pool_handle_t hPool, size_t size,
size_t alignment) {
UMF_CHECK((hPool != NULL), NULL);
return hPool->ops.aligned_malloc(hPool->pool_priv, size, alignment);
}

void *umfPoolCalloc(umf_memory_pool_handle_t hPool, size_t num, size_t size) {
UMF_CHECK((hPool != NULL), NULL);
return hPool->ops.calloc(hPool->pool_priv, num, size);
}

void *umfPoolRealloc(umf_memory_pool_handle_t hPool, void *ptr, size_t size) {
UMF_CHECK((hPool != NULL), NULL);
return hPool->ops.realloc(hPool->pool_priv, ptr, size);
}

size_t umfPoolMallocUsableSize(umf_memory_pool_handle_t hPool, void *ptr) {
UMF_CHECK((hPool != NULL), 0);
return hPool->ops.malloc_usable_size(hPool->pool_priv, ptr);
}

umf_result_t umfPoolFree(umf_memory_pool_handle_t hPool, void *ptr) {
UMF_CHECK((hPool != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
return hPool->ops.free(hPool->pool_priv, ptr);
}

umf_result_t umfPoolGetLastAllocationError(umf_memory_pool_handle_t hPool) {
UMF_CHECK((hPool != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
return hPool->ops.get_last_allocation_error(hPool->pool_priv);
}
11 changes: 11 additions & 0 deletions src/memory_provider.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
*/

#include "memory_provider_internal.h"
#include "utils_common.h"

#include <umf/memory_provider.h>

#include <assert.h>
Expand Down Expand Up @@ -64,6 +66,7 @@ checkErrorAndSetLastProvider(umf_result_t result,

umf_result_t umfMemoryProviderAlloc(umf_memory_provider_handle_t hProvider,
size_t size, size_t alignment, void **ptr) {
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
umf_result_t res =
hProvider->ops.alloc(hProvider->provider_priv, size, alignment, ptr);
checkErrorAndSetLastProvider(res, hProvider);
Expand All @@ -72,6 +75,7 @@ umf_result_t umfMemoryProviderAlloc(umf_memory_provider_handle_t hProvider,

umf_result_t umfMemoryProviderFree(umf_memory_provider_handle_t hProvider,
void *ptr, size_t size) {
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
umf_result_t res = hProvider->ops.free(hProvider->provider_priv, ptr, size);
checkErrorAndSetLastProvider(res, hProvider);
return res;
Expand All @@ -80,17 +84,20 @@ umf_result_t umfMemoryProviderFree(umf_memory_provider_handle_t hProvider,
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);
}

void *umfMemoryProviderGetPriv(umf_memory_provider_handle_t hProvider) {
UMF_CHECK((hProvider != NULL), NULL);
return hProvider->provider_priv;
}

umf_result_t
umfMemoryProviderGetRecommendedPageSize(umf_memory_provider_handle_t hProvider,
size_t size, size_t *pageSize) {
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
umf_result_t res = hProvider->ops.get_recommended_page_size(
hProvider->provider_priv, size, pageSize);
checkErrorAndSetLastProvider(res, hProvider);
Expand All @@ -100,6 +107,7 @@ umfMemoryProviderGetRecommendedPageSize(umf_memory_provider_handle_t hProvider,
umf_result_t
umfMemoryProviderGetMinPageSize(umf_memory_provider_handle_t hProvider,
void *ptr, size_t *pageSize) {
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
umf_result_t res = hProvider->ops.get_min_page_size(
hProvider->provider_priv, ptr, pageSize);
checkErrorAndSetLastProvider(res, hProvider);
Expand All @@ -108,6 +116,7 @@ umfMemoryProviderGetMinPageSize(umf_memory_provider_handle_t hProvider,

umf_result_t umfMemoryProviderPurgeLazy(umf_memory_provider_handle_t hProvider,
void *ptr, size_t size) {
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
umf_result_t res =
hProvider->ops.purge_lazy(hProvider->provider_priv, ptr, size);
checkErrorAndSetLastProvider(res, hProvider);
Expand All @@ -116,13 +125,15 @@ umf_result_t umfMemoryProviderPurgeLazy(umf_memory_provider_handle_t hProvider,

umf_result_t umfMemoryProviderPurgeForce(umf_memory_provider_handle_t hProvider,
void *ptr, size_t size) {
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
umf_result_t res =
hProvider->ops.purge_force(hProvider->provider_priv, ptr, size);
checkErrorAndSetLastProvider(res, 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);
}

Expand Down
57 changes: 57 additions & 0 deletions src/utils/utils_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@
#ifndef UMF_COMMON_H
#define UMF_COMMON_H 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef __cplusplus
extern "C" {
#endif
Expand All @@ -20,6 +24,59 @@ extern "C" {
#define __TLS __thread
#endif

#define Malloc malloc
#define Free free

static inline void *Zalloc(size_t s) {
void *m = Malloc(s);
if (m) {
memset(m, 0, s);
}
return m;
}

#define NOFUNCTION \
do { \
} while (0)
#define VALGRIND_ANNOTATE_NEW_MEMORY(p, s) NOFUNCTION
#define VALGRIND_HG_DRD_DISABLE_CHECKING(p, s) NOFUNCTION

#ifdef NDEBUG
#define ASSERT(x) NOFUNCTION
#define ASSERTne(x, y) ASSERT(x != y)
#else
#define ASSERT(x) \
do { \
if (!(x)) { \
fprintf(stderr, \
"Assertion failed: " #x " at " __FILE__ " line %d.\n", \
__LINE__); \
abort(); \
} \
} while (0)
#define ASSERTne(x, y) \
do { \
long X = (x); \
long Y = (y); \
if (X == Y) { \
fprintf(stderr, \
"Assertion failed: " #x " != " #y \
", both are %ld, at " __FILE__ " line %d.\n", \
X, __LINE__); \
abort(); \
} \
} while (0)
#endif

#define UMF_CHECK(condition, errorStatus) \
do { \
if (!(condition)) { \
fprintf(stderr, "UMF check failed: " #condition " in %s\n", \
__func__); \
return errorStatus; \
} \
} while (0)

#ifdef __cplusplus
}
#endif
Expand Down
46 changes: 0 additions & 46 deletions src/utils/utils_concurrency.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(_WIN32)
#include <windows.h>
#else
Expand Down Expand Up @@ -62,50 +60,6 @@ static __inline unsigned char util_mssb_index(long long value) {
__atomic_add_fetch(object, 1, __ATOMIC_ACQ_REL)
#endif

#define Malloc malloc
#define Free free

static inline void *Zalloc(size_t s) {
void *m = Malloc(s);
if (m) {
memset(m, 0, s);
}
return m;
}

#define NOFUNCTION \
do { \
} while (0)
#define VALGRIND_ANNOTATE_NEW_MEMORY(p, s) NOFUNCTION
#define VALGRIND_HG_DRD_DISABLE_CHECKING(p, s) NOFUNCTION

#ifdef NDEBUG
#define ASSERT(x) NOFUNCTION
#define ASSERTne(x, y) ASSERT(x != y)
#else
#define ASSERT(x) \
do \
if (!(x)) { \
fprintf(stderr, \
"Assertion failed: " #x " at " __FILE__ " line %d.\n", \
__LINE__); \
abort(); \
} \
while (0)
#define ASSERTne(x, y) \
do { \
long X = (x); \
long Y = (y); \
if (X == Y) { \
fprintf(stderr, \
"Assertion failed: " #x " != " #y \
", both are %ld, at " __FILE__ " line %d.\n", \
X, __LINE__); \
abort(); \
} \
} while (0)
#endif

#ifdef __cplusplus
}
#endif
16 changes: 16 additions & 0 deletions test/common/base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ struct test : ::testing::Test {
void SetUp() override { ::testing::Test::SetUp(); }
void TearDown() override { ::testing::Test::TearDown(); }
};

template <typename T> T generateArg() { return T{}; }

// returns Ret (*f)(void) that calls the original function
// with all arguments created by calling generateArg()
template <typename Ret, typename... Args>
std::function<Ret(void)> withGeneratedArgs(Ret (*f)(Args...)) {
std::tuple<Args...> tuple = {};
auto args = std::apply(
[](auto... x) {
return std::make_tuple(generateArg<decltype(x)>()...);
},
tuple);
return [=]() { return std::apply(f, args); };
}

} // namespace umf_test

#endif /* UMF_TEST_BASE_HPP */
41 changes: 41 additions & 0 deletions test/memoryPoolAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
// This file contains tests for UMF pool API

#include "base.hpp"
#include "pool.hpp"
#include "poolFixtures.hpp"
#include "provider.hpp"
Expand All @@ -14,7 +15,9 @@
#include <array>
#include <string>
#include <thread>
#include <type_traits>
#include <unordered_map>
#include <variant>

using umf_test::test;
using namespace umf_test;
Expand Down Expand Up @@ -282,3 +285,41 @@ TEST_F(test, getLastFailedMemoryProvider) {
umfMemoryProviderGetName(umfGetLastFailedMemoryProvider())),
"provider2");
}

// This fixture can be instantiated with any function that accepts void
// and returns any of the results listed inside the variant type.
struct poolHandleCheck
: umf_test::test,
::testing::WithParamInterface<
std::function<std::variant<void *, umf_result_t, size_t>(void)>> {};

TEST_P(poolHandleCheck, poolHandleCheckAll) {
auto f = GetParam();
auto ret = f();

std::visit(
[&](auto arg) {
using T = decltype(arg);
if constexpr (std::is_same_v<T, umf_result_t>) {
ASSERT_EQ(arg, UMF_RESULT_ERROR_INVALID_ARGUMENT);
} else if constexpr (std::is_same_v<T, size_t>) {
ASSERT_EQ(arg, 0U);
} else {
ASSERT_EQ(arg, nullptr);
}
},
ret);
}

// Run poolHandleCheck for each function listed below. Each function
// will be called with zero-initialized arguments.
INSTANTIATE_TEST_SUITE_P(
poolHandleCheck, poolHandleCheck,
::testing::Values(
umf_test::withGeneratedArgs(umfPoolMalloc),
umf_test::withGeneratedArgs(umfPoolAlignedMalloc),
umf_test::withGeneratedArgs(umfPoolFree),
umf_test::withGeneratedArgs(umfPoolCalloc),
umf_test::withGeneratedArgs(umfPoolRealloc),
umf_test::withGeneratedArgs(umfPoolMallocUsableSize),
umf_test::withGeneratedArgs(umfPoolGetLastAllocationError)));
37 changes: 37 additions & 0 deletions test/memoryProviderAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <string>
#include <unordered_map>
#include <variant>

using umf_test::test;

Expand Down Expand Up @@ -104,3 +105,39 @@ TEST_P(providerInitializeTest, errorPropagation) {
&hProvider);
ASSERT_EQ(ret, this->GetParam());
}

// This fixture can be instantiated with any function that accepts void
// and returns any of the results listed inside the variant type.
struct providerHandleCheck
: umf_test::test,
::testing::WithParamInterface<
std::function<std::variant<const char *, umf_result_t>(void)>> {};

TEST_P(providerHandleCheck, providerHandleCheckAll) {
auto f = GetParam();
auto ret = f();

std::visit(
[&](auto arg) {
using T = decltype(arg);
if constexpr (std::is_same_v<T, umf_result_t>) {
ASSERT_EQ(arg, UMF_RESULT_ERROR_INVALID_ARGUMENT);
} else {
ASSERT_EQ(arg, nullptr);
}
},
ret);
}

// Run poolHandleCheck for each function listed below. Each function
// will be called with zero-initialized arguments.
INSTANTIATE_TEST_SUITE_P(
providerHandleCheck, providerHandleCheck,
::testing::Values(
umf_test::withGeneratedArgs(umfMemoryProviderAlloc),
umf_test::withGeneratedArgs(umfMemoryProviderFree),
umf_test::withGeneratedArgs(umfMemoryProviderGetRecommendedPageSize),
umf_test::withGeneratedArgs(umfMemoryProviderGetMinPageSize),
umf_test::withGeneratedArgs(umfMemoryProviderPurgeLazy),
umf_test::withGeneratedArgs(umfMemoryProviderPurgeForce),
umf_test::withGeneratedArgs(umfMemoryProviderGetName)));