Skip to content

Commit a562f8e

Browse files
committed
Add test for init/teardown functions: umfInit() and umfTearDown()
Signed-off-by: Lukasz Dorau <[email protected]>
1 parent 2c1e6cb commit a562f8e

File tree

2 files changed

+254
-0
lines changed

2 files changed

+254
-0
lines changed

test/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,3 +279,14 @@ else()
279279
message(
280280
STATUS "IPC shared memory test is supported on Linux only - skipping")
281281
endif()
282+
283+
if(LINUX
284+
AND UMF_BUILD_SHARED_LIBRARY
285+
AND UMF_POOL_SCALABLE_ENABLED)
286+
add_umf_test(NAME init_teardown SRCS test_init_teardown.c)
287+
# append LD_LIBRARY_PATH to the libumf
288+
set_property(
289+
TEST umf-init_teardown
290+
PROPERTY ENVIRONMENT_MODIFICATION
291+
"LD_LIBRARY_PATH=path_list_append:${CMAKE_BINARY_DIR}/lib")
292+
endif()

test/test_init_teardown.c

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
/*
2+
* Copyright (C) 2024 Intel Corporation
3+
*
4+
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
5+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
*/
7+
8+
#include <assert.h>
9+
#include <dlfcn.h>
10+
#include <stddef.h>
11+
#include <stdint.h>
12+
#include <stdio.h>
13+
14+
#define SIZE_ALLOC 4096
15+
16+
typedef int (*umfMemoryProviderCreateFromMemspace_t)(void *hMemspace,
17+
void *hPolicy,
18+
void **hPool);
19+
typedef int (*umfPoolCreate_t)(void *ops, void *provider, void *params,
20+
uint32_t flags, void **hPool);
21+
typedef void (*umfDestroy_t)(void *handle);
22+
typedef void (*umfVoidVoid_t)(void);
23+
typedef void *(*umfGetPtr_t)(void);
24+
25+
static umfVoidVoid_t umfTearDown;
26+
static umfDestroy_t umfMemoryProviderDestroy;
27+
static umfDestroy_t umfPoolDestroy;
28+
static const char *umf_lib_name;
29+
static void *h_umf;
30+
static void *umf_provider_default;
31+
static void *umf_pool_default;
32+
static void *umf_default;
33+
34+
// UMF alloc
35+
static void *(*umf_alloc)(void *pool, size_t size);
36+
37+
// UMF free
38+
static void (*umf_free)(void *pool, void *ptr);
39+
40+
static void load_symbol(void *handle, const char *name, void **dest) {
41+
void *symbol = dlsym(handle, name);
42+
if (symbol == NULL) {
43+
fprintf(stderr, "umf_load: symbol %s NOT found\n", name);
44+
*dest = NULL;
45+
return;
46+
}
47+
48+
fprintf(stderr, "umf_load: symbol found: %s\n", name);
49+
50+
*dest = symbol;
51+
}
52+
53+
static int umf_load(int n_init_teardown) {
54+
umfMemoryProviderCreateFromMemspace_t umfMemoryProviderCreateFromMemspace;
55+
umfGetPtr_t umfMemspaceHostAllGet; // the default memspace
56+
umfGetPtr_t umfScalablePoolOps;
57+
umfPoolCreate_t umfPoolCreate;
58+
umfVoidVoid_t umfInit;
59+
void *memspaceHostAll;
60+
int ret;
61+
62+
umf_lib_name = "libumf.so";
63+
h_umf = dlopen(umf_lib_name, RTLD_LAZY);
64+
if (h_umf == NULL) {
65+
fprintf(stderr, "umf_load: UMF library not found (%s)\n", umf_lib_name);
66+
return -1;
67+
}
68+
69+
load_symbol(h_umf, "umfInit", (void **)&umfInit);
70+
if (umfInit == NULL) {
71+
goto err_dlclose;
72+
}
73+
74+
load_symbol(h_umf, "umfTearDown", (void **)&umfTearDown);
75+
if (umfTearDown == NULL) {
76+
goto err_dlclose;
77+
}
78+
79+
// Initialize libumf (increment the reference counter of users).
80+
// Normally this should be done exactly once.
81+
for (int i = 0; i < n_init_teardown; i++) {
82+
(*umfInit)();
83+
}
84+
85+
load_symbol(h_umf, "umfMemoryProviderCreateFromMemspace",
86+
(void **)&umfMemoryProviderCreateFromMemspace);
87+
if (umfMemoryProviderCreateFromMemspace == NULL) {
88+
goto err_dlclose;
89+
}
90+
91+
load_symbol(h_umf, "umfMemoryProviderDestroy",
92+
(void **)&umfMemoryProviderDestroy);
93+
if (umfMemoryProviderDestroy == NULL) {
94+
goto err_dlclose;
95+
}
96+
97+
load_symbol(h_umf, "umfPoolCreate", (void **)&umfPoolCreate);
98+
if (umfPoolCreate == NULL) {
99+
goto err_dlclose;
100+
}
101+
102+
load_symbol(h_umf, "umfPoolDestroy", (void **)&umfPoolDestroy);
103+
if (umfPoolDestroy == NULL) {
104+
goto err_dlclose;
105+
}
106+
107+
load_symbol(h_umf, "umfPoolMalloc", (void **)&umf_alloc);
108+
if (umf_alloc == NULL) {
109+
goto err_dlclose;
110+
}
111+
112+
load_symbol(h_umf, "umfPoolFree", (void **)&umf_free);
113+
if (umf_free == NULL) {
114+
goto err_dlclose;
115+
}
116+
117+
load_symbol(h_umf, "umfScalablePoolOps", (void **)&umfScalablePoolOps);
118+
if (umfScalablePoolOps == NULL) {
119+
goto err_dlclose;
120+
}
121+
122+
load_symbol(h_umf, "umfMemspaceHostAllGet",
123+
(void **)&umfMemspaceHostAllGet);
124+
if (umfMemspaceHostAllGet == NULL) {
125+
goto err_dlclose;
126+
}
127+
128+
memspaceHostAll = (*umfMemspaceHostAllGet)();
129+
if (memspaceHostAll == NULL) {
130+
fprintf(stderr, "umf_load: cannot get the memspaceHostAll memspace\n");
131+
goto err_dlclose;
132+
}
133+
fprintf(stderr, "umf_load: got memspace: memspaceHostAll\n");
134+
135+
ret = (*umfMemoryProviderCreateFromMemspace)(memspaceHostAll, NULL,
136+
&umf_provider_default);
137+
if (ret || umf_provider_default == NULL) {
138+
fprintf(stderr, "umf_load: error creating the default provider: %i\n",
139+
ret);
140+
goto err_dlclose;
141+
}
142+
fprintf(stderr, "umf_load: the default provider created from memspace\n");
143+
144+
umf_default = NULL;
145+
ret = (*umfPoolCreate)((*umfScalablePoolOps)(), umf_provider_default, NULL,
146+
0, &umf_pool_default);
147+
if (ret || umf_pool_default == NULL) {
148+
fprintf(stderr, "umf_load: error creating the default pool: %i\n", ret);
149+
goto err_destroy_provider;
150+
}
151+
fprintf(stderr,
152+
"umf_load: the default pool created from the All Nodes provider\n");
153+
154+
umf_default = umf_pool_default; // umf pool using the default memspace
155+
156+
fprintf(stderr, "umf_load: umf initialized\n");
157+
158+
return 0;
159+
160+
err_destroy_provider:
161+
(*umfMemoryProviderDestroy)(umf_provider_default);
162+
err_dlclose:
163+
dlclose(h_umf);
164+
165+
return -1;
166+
}
167+
168+
static void umf_unload(int n_init_teardown) {
169+
umf_default = NULL;
170+
171+
fprintf(stderr, "umf_unload: finalizing UMF ...\n");
172+
173+
(*umfPoolDestroy)(umf_pool_default);
174+
fprintf(stderr, "umf_unload: the default umf memory pool destroyed\n");
175+
176+
(*umfMemoryProviderDestroy)(umf_provider_default);
177+
fprintf(stderr, "umf_unload: the default umf memory provider destroyed\n");
178+
179+
// Deinitialize libumf (decrement the reference counter of users).
180+
// Normally this should be done exactly once.
181+
for (int i = 0; i < n_init_teardown; i++) {
182+
fprintf(stderr, "umf_unload: calling umfTearDown() ...\n");
183+
(*umfTearDown)();
184+
}
185+
186+
fprintf(stderr, "umf_unload: closing umf library ...\n");
187+
dlclose(h_umf);
188+
fprintf(stderr, "umf_unload: umf library closed\n");
189+
}
190+
191+
static int run_test(int n_init_teardown, int wrong_dtor_order) {
192+
193+
if (wrong_dtor_order) {
194+
fprintf(stderr, "\n\n*** Running test with INCORRECT order of "
195+
"destructors ***\n\n\n");
196+
} else {
197+
fprintf(
198+
stderr,
199+
"\n\n*** Running test with CORRECT order of destructors ***\n\n\n");
200+
}
201+
202+
if (umf_load(n_init_teardown)) {
203+
return -1;
204+
}
205+
206+
assert(umf_default);
207+
void *ptr = (*umf_alloc)(umf_default, SIZE_ALLOC);
208+
(*umf_free)(umf_default, ptr);
209+
210+
// simulate incorrect order of destructors (an additional, unwanted destructor call)
211+
if (wrong_dtor_order) {
212+
fprintf(stderr,
213+
"*** Simulating incorrect order of destructors !!! ***\n");
214+
(*umfTearDown)();
215+
}
216+
217+
umf_unload(n_init_teardown);
218+
219+
return 0;
220+
}
221+
222+
#define CORRECT_ORDER_OF_DESTRUCTORS 0
223+
#define INCORRECT_ORDER_OF_DESTRUCTORS 1
224+
225+
int main(void) {
226+
if (run_test(1, CORRECT_ORDER_OF_DESTRUCTORS)) {
227+
return -1;
228+
}
229+
230+
if (run_test(1, INCORRECT_ORDER_OF_DESTRUCTORS)) {
231+
return -1;
232+
}
233+
234+
if (run_test(10, CORRECT_ORDER_OF_DESTRUCTORS)) {
235+
return -1;
236+
}
237+
238+
if (run_test(10, INCORRECT_ORDER_OF_DESTRUCTORS)) {
239+
return -1;
240+
}
241+
242+
return 0;
243+
}

0 commit comments

Comments
 (0)