Skip to content

Commit 7f19b8a

Browse files
authored
Merge pull request #163 from igchor/handle_checks
Add checks for pool and provider handles
2 parents 04ca601 + 3bee857 commit 7f19b8a

File tree

8 files changed

+171
-46
lines changed

8 files changed

+171
-46
lines changed

src/critnib/critnib.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
#include <stddef.h>
5959

6060
#include "critnib.h"
61+
#include "utils_common.h"
6162
#include "utils_concurrency.h"
6263

6364
/*

src/memory_pool.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
#include "memory_pool_internal.h"
11+
#include "utils_common.h"
1112

1213
#include <umf/memory_pool.h>
1314
#include <umf/memory_pool_ops.h>
@@ -30,30 +31,37 @@ umf_result_t umfPoolCreate(const umf_memory_pool_ops_t *ops,
3031
}
3132

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

3638
void *umfPoolAlignedMalloc(umf_memory_pool_handle_t hPool, size_t size,
3739
size_t alignment) {
40+
UMF_CHECK((hPool != NULL), NULL);
3841
return hPool->ops.aligned_malloc(hPool->pool_priv, size, alignment);
3942
}
4043

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

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

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

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

5764
umf_result_t umfPoolGetLastAllocationError(umf_memory_pool_handle_t hPool) {
65+
UMF_CHECK((hPool != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
5866
return hPool->ops.get_last_allocation_error(hPool->pool_priv);
5967
}

src/memory_provider.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
*/
99

1010
#include "memory_provider_internal.h"
11+
#include "utils_common.h"
12+
1113
#include <umf/memory_provider.h>
1214

1315
#include <assert.h>
@@ -65,6 +67,7 @@ checkErrorAndSetLastProvider(umf_result_t result,
6567

6668
umf_result_t umfMemoryProviderAlloc(umf_memory_provider_handle_t hProvider,
6769
size_t size, size_t alignment, void **ptr) {
70+
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
6871
umf_result_t res =
6972
hProvider->ops.alloc(hProvider->provider_priv, size, alignment, ptr);
7073
checkErrorAndSetLastProvider(res, hProvider);
@@ -73,6 +76,7 @@ umf_result_t umfMemoryProviderAlloc(umf_memory_provider_handle_t hProvider,
7376

7477
umf_result_t umfMemoryProviderFree(umf_memory_provider_handle_t hProvider,
7578
void *ptr, size_t size) {
79+
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
7680
umf_result_t res = hProvider->ops.free(hProvider->provider_priv, ptr, size);
7781
checkErrorAndSetLastProvider(res, hProvider);
7882
return res;
@@ -81,17 +85,20 @@ umf_result_t umfMemoryProviderFree(umf_memory_provider_handle_t hProvider,
8185
void umfMemoryProviderGetLastNativeError(umf_memory_provider_handle_t hProvider,
8286
const char **ppMessage,
8387
int32_t *pError) {
88+
ASSERT(hProvider != NULL);
8489
hProvider->ops.get_last_native_error(hProvider->provider_priv, ppMessage,
8590
pError);
8691
}
8792

8893
void *umfMemoryProviderGetPriv(umf_memory_provider_handle_t hProvider) {
94+
UMF_CHECK((hProvider != NULL), NULL);
8995
return hProvider->provider_priv;
9096
}
9197

9298
umf_result_t
9399
umfMemoryProviderGetRecommendedPageSize(umf_memory_provider_handle_t hProvider,
94100
size_t size, size_t *pageSize) {
101+
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
95102
umf_result_t res = hProvider->ops.get_recommended_page_size(
96103
hProvider->provider_priv, size, pageSize);
97104
checkErrorAndSetLastProvider(res, hProvider);
@@ -101,6 +108,7 @@ umfMemoryProviderGetRecommendedPageSize(umf_memory_provider_handle_t hProvider,
101108
umf_result_t
102109
umfMemoryProviderGetMinPageSize(umf_memory_provider_handle_t hProvider,
103110
void *ptr, size_t *pageSize) {
111+
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
104112
umf_result_t res = hProvider->ops.get_min_page_size(
105113
hProvider->provider_priv, ptr, pageSize);
106114
checkErrorAndSetLastProvider(res, hProvider);
@@ -109,6 +117,7 @@ umfMemoryProviderGetMinPageSize(umf_memory_provider_handle_t hProvider,
109117

110118
umf_result_t umfMemoryProviderPurgeLazy(umf_memory_provider_handle_t hProvider,
111119
void *ptr, size_t size) {
120+
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
112121
umf_result_t res =
113122
hProvider->ops.purge_lazy(hProvider->provider_priv, ptr, size);
114123
checkErrorAndSetLastProvider(res, hProvider);
@@ -117,13 +126,15 @@ umf_result_t umfMemoryProviderPurgeLazy(umf_memory_provider_handle_t hProvider,
117126

118127
umf_result_t umfMemoryProviderPurgeForce(umf_memory_provider_handle_t hProvider,
119128
void *ptr, size_t size) {
129+
UMF_CHECK((hProvider != NULL), UMF_RESULT_ERROR_INVALID_ARGUMENT);
120130
umf_result_t res =
121131
hProvider->ops.purge_force(hProvider->provider_priv, ptr, size);
122132
checkErrorAndSetLastProvider(res, hProvider);
123133
return res;
124134
}
125135

126136
const char *umfMemoryProviderGetName(umf_memory_provider_handle_t hProvider) {
137+
UMF_CHECK((hProvider != NULL), NULL);
127138
return hProvider->ops.get_name(hProvider->provider_priv);
128139
}
129140

src/utils/utils_common.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
#ifndef UMF_COMMON_H
1111
#define UMF_COMMON_H 1
1212

13+
#include <stdio.h>
14+
#include <stdlib.h>
15+
#include <string.h>
16+
1317
#ifdef __cplusplus
1418
extern "C" {
1519
#endif
@@ -20,6 +24,59 @@ extern "C" {
2024
#define __TLS __thread
2125
#endif
2226

27+
#define Malloc malloc
28+
#define Free free
29+
30+
static inline void *Zalloc(size_t s) {
31+
void *m = Malloc(s);
32+
if (m) {
33+
memset(m, 0, s);
34+
}
35+
return m;
36+
}
37+
38+
#define NOFUNCTION \
39+
do { \
40+
} while (0)
41+
#define VALGRIND_ANNOTATE_NEW_MEMORY(p, s) NOFUNCTION
42+
#define VALGRIND_HG_DRD_DISABLE_CHECKING(p, s) NOFUNCTION
43+
44+
#ifdef NDEBUG
45+
#define ASSERT(x) NOFUNCTION
46+
#define ASSERTne(x, y) ASSERT(x != y)
47+
#else
48+
#define ASSERT(x) \
49+
do { \
50+
if (!(x)) { \
51+
fprintf(stderr, \
52+
"Assertion failed: " #x " at " __FILE__ " line %d.\n", \
53+
__LINE__); \
54+
abort(); \
55+
} \
56+
} while (0)
57+
#define ASSERTne(x, y) \
58+
do { \
59+
long X = (x); \
60+
long Y = (y); \
61+
if (X == Y) { \
62+
fprintf(stderr, \
63+
"Assertion failed: " #x " != " #y \
64+
", both are %ld, at " __FILE__ " line %d.\n", \
65+
X, __LINE__); \
66+
abort(); \
67+
} \
68+
} while (0)
69+
#endif
70+
71+
#define UMF_CHECK(condition, errorStatus) \
72+
do { \
73+
if (!(condition)) { \
74+
fprintf(stderr, "UMF check failed: " #condition " in %s\n", \
75+
__func__); \
76+
return errorStatus; \
77+
} \
78+
} while (0)
79+
2380
#ifdef __cplusplus
2481
}
2582
#endif

src/utils/utils_concurrency.h

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
#define UMF_UTILS_CONCURRENCY_H 1
1212

1313
#include <stdio.h>
14-
#include <stdlib.h>
15-
#include <string.h>
1614
#if defined(_WIN32)
1715
#include <windows.h>
1816
#else
@@ -65,50 +63,6 @@ static __inline unsigned char util_mssb_index(long long value) {
6563
__atomic_add_fetch(object, 1, __ATOMIC_ACQ_REL)
6664
#endif
6765

68-
#define Malloc malloc
69-
#define Free free
70-
71-
static inline void *Zalloc(size_t s) {
72-
void *m = Malloc(s);
73-
if (m) {
74-
memset(m, 0, s);
75-
}
76-
return m;
77-
}
78-
79-
#define NOFUNCTION \
80-
do { \
81-
} while (0)
82-
#define VALGRIND_ANNOTATE_NEW_MEMORY(p, s) NOFUNCTION
83-
#define VALGRIND_HG_DRD_DISABLE_CHECKING(p, s) NOFUNCTION
84-
85-
#ifdef NDEBUG
86-
#define ASSERT(x) NOFUNCTION
87-
#define ASSERTne(x, y) ASSERT(x != y)
88-
#else
89-
#define ASSERT(x) \
90-
do \
91-
if (!(x)) { \
92-
fprintf(stderr, \
93-
"Assertion failed: " #x " at " __FILE__ " line %d.\n", \
94-
__LINE__); \
95-
abort(); \
96-
} \
97-
while (0)
98-
#define ASSERTne(x, y) \
99-
do { \
100-
long X = (x); \
101-
long Y = (y); \
102-
if (X == Y) { \
103-
fprintf(stderr, \
104-
"Assertion failed: " #x " != " #y \
105-
", both are %ld, at " __FILE__ " line %d.\n", \
106-
X, __LINE__); \
107-
abort(); \
108-
} \
109-
} while (0)
110-
#endif
111-
11266
#ifdef __cplusplus
11367
}
11468
#endif

test/common/base.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,22 @@ struct test : ::testing::Test {
3131
void SetUp() override { ::testing::Test::SetUp(); }
3232
void TearDown() override { ::testing::Test::TearDown(); }
3333
};
34+
35+
template <typename T> T generateArg() { return T{}; }
36+
37+
// returns Ret (*f)(void) that calls the original function
38+
// with all arguments created by calling generateArg()
39+
template <typename Ret, typename... Args>
40+
std::function<Ret(void)> withGeneratedArgs(Ret (*f)(Args...)) {
41+
std::tuple<Args...> tuple = {};
42+
auto args = std::apply(
43+
[](auto... x) {
44+
return std::make_tuple(generateArg<decltype(x)>()...);
45+
},
46+
tuple);
47+
return [=]() { return std::apply(f, args); };
48+
}
49+
3450
} // namespace umf_test
3551

3652
#endif /* UMF_TEST_BASE_HPP */

test/memoryPoolAPI.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
44
// This file contains tests for UMF pool API
55

6+
#include "base.hpp"
67
#include "pool.hpp"
78
#include "poolFixtures.hpp"
89
#include "provider.hpp"
@@ -15,7 +16,9 @@
1516
#include <array>
1617
#include <string>
1718
#include <thread>
19+
#include <type_traits>
1820
#include <unordered_map>
21+
#include <variant>
1922

2023
using umf_test::test;
2124
using namespace umf_test;
@@ -372,3 +375,41 @@ TEST_F(test, getLastFailedMemoryProvider) {
372375
umfMemoryProviderGetName(umfGetLastFailedMemoryProvider())),
373376
"provider2");
374377
}
378+
379+
// This fixture can be instantiated with any function that accepts void
380+
// and returns any of the results listed inside the variant type.
381+
struct poolHandleCheck
382+
: umf_test::test,
383+
::testing::WithParamInterface<
384+
std::function<std::variant<void *, umf_result_t, size_t>(void)>> {};
385+
386+
TEST_P(poolHandleCheck, poolHandleCheckAll) {
387+
auto f = GetParam();
388+
auto ret = f();
389+
390+
std::visit(
391+
[&](auto arg) {
392+
using T = decltype(arg);
393+
if constexpr (std::is_same_v<T, umf_result_t>) {
394+
ASSERT_EQ(arg, UMF_RESULT_ERROR_INVALID_ARGUMENT);
395+
} else if constexpr (std::is_same_v<T, size_t>) {
396+
ASSERT_EQ(arg, 0U);
397+
} else {
398+
ASSERT_EQ(arg, nullptr);
399+
}
400+
},
401+
ret);
402+
}
403+
404+
// Run poolHandleCheck for each function listed below. Each function
405+
// will be called with zero-initialized arguments.
406+
INSTANTIATE_TEST_SUITE_P(
407+
poolHandleCheck, poolHandleCheck,
408+
::testing::Values(
409+
umf_test::withGeneratedArgs(umfPoolMalloc),
410+
umf_test::withGeneratedArgs(umfPoolAlignedMalloc),
411+
umf_test::withGeneratedArgs(umfPoolFree),
412+
umf_test::withGeneratedArgs(umfPoolCalloc),
413+
umf_test::withGeneratedArgs(umfPoolRealloc),
414+
umf_test::withGeneratedArgs(umfPoolMallocUsableSize),
415+
umf_test::withGeneratedArgs(umfPoolGetLastAllocationError)));

test/memoryProviderAPI.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
#include <string>
1111
#include <unordered_map>
12+
#include <variant>
1213

1314
using umf_test::test;
1415

@@ -104,3 +105,39 @@ TEST_P(providerInitializeTest, errorPropagation) {
104105
&hProvider);
105106
ASSERT_EQ(ret, this->GetParam());
106107
}
108+
109+
// This fixture can be instantiated with any function that accepts void
110+
// and returns any of the results listed inside the variant type.
111+
struct providerHandleCheck
112+
: umf_test::test,
113+
::testing::WithParamInterface<
114+
std::function<std::variant<const char *, umf_result_t>(void)>> {};
115+
116+
TEST_P(providerHandleCheck, providerHandleCheckAll) {
117+
auto f = GetParam();
118+
auto ret = f();
119+
120+
std::visit(
121+
[&](auto arg) {
122+
using T = decltype(arg);
123+
if constexpr (std::is_same_v<T, umf_result_t>) {
124+
ASSERT_EQ(arg, UMF_RESULT_ERROR_INVALID_ARGUMENT);
125+
} else {
126+
ASSERT_EQ(arg, nullptr);
127+
}
128+
},
129+
ret);
130+
}
131+
132+
// Run poolHandleCheck for each function listed below. Each function
133+
// will be called with zero-initialized arguments.
134+
INSTANTIATE_TEST_SUITE_P(
135+
providerHandleCheck, providerHandleCheck,
136+
::testing::Values(
137+
umf_test::withGeneratedArgs(umfMemoryProviderAlloc),
138+
umf_test::withGeneratedArgs(umfMemoryProviderFree),
139+
umf_test::withGeneratedArgs(umfMemoryProviderGetRecommendedPageSize),
140+
umf_test::withGeneratedArgs(umfMemoryProviderGetMinPageSize),
141+
umf_test::withGeneratedArgs(umfMemoryProviderPurgeLazy),
142+
umf_test::withGeneratedArgs(umfMemoryProviderPurgeForce),
143+
umf_test::withGeneratedArgs(umfMemoryProviderGetName)));

0 commit comments

Comments
 (0)