Skip to content

Commit 3fa7cb3

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

File tree

2 files changed

+237
-0
lines changed

2 files changed

+237
-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: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
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(void) {
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+
(*umfInit)();
81+
82+
load_symbol(h_umf, "umfMemoryProviderCreateFromMemspace",
83+
(void **)&umfMemoryProviderCreateFromMemspace);
84+
if (umfMemoryProviderCreateFromMemspace == NULL) {
85+
goto err_dlclose;
86+
}
87+
88+
load_symbol(h_umf, "umfMemoryProviderDestroy",
89+
(void **)&umfMemoryProviderDestroy);
90+
if (umfMemoryProviderDestroy == NULL) {
91+
goto err_dlclose;
92+
}
93+
94+
load_symbol(h_umf, "umfPoolCreate", (void **)&umfPoolCreate);
95+
if (umfPoolCreate == NULL) {
96+
goto err_dlclose;
97+
}
98+
99+
load_symbol(h_umf, "umfPoolDestroy", (void **)&umfPoolDestroy);
100+
if (umfPoolDestroy == NULL) {
101+
goto err_dlclose;
102+
}
103+
104+
load_symbol(h_umf, "umfPoolMalloc", (void **)&umf_alloc);
105+
if (umf_alloc == NULL) {
106+
goto err_dlclose;
107+
}
108+
109+
load_symbol(h_umf, "umfPoolFree", (void **)&umf_free);
110+
if (umf_free == NULL) {
111+
goto err_dlclose;
112+
}
113+
114+
load_symbol(h_umf, "umfScalablePoolOps", (void **)&umfScalablePoolOps);
115+
if (umfScalablePoolOps == NULL) {
116+
goto err_dlclose;
117+
}
118+
119+
load_symbol(h_umf, "umfMemspaceHostAllGet",
120+
(void **)&umfMemspaceHostAllGet);
121+
if (umfMemspaceHostAllGet == NULL) {
122+
goto err_dlclose;
123+
}
124+
125+
memspaceHostAll = (*umfMemspaceHostAllGet)();
126+
if (memspaceHostAll == NULL) {
127+
fprintf(stderr, "umf_load: memspaceHostAll NOT found\n");
128+
goto err_dlclose;
129+
}
130+
fprintf(stderr, "umf_load: got memspace: memspaceHostAll\n");
131+
132+
ret = (*umfMemoryProviderCreateFromMemspace)(memspaceHostAll, NULL,
133+
&umf_provider_default);
134+
if (ret || umf_provider_default == NULL) {
135+
fprintf(stderr, "umf_load: error creating the default provider: %i\n",
136+
ret);
137+
goto err_dlclose;
138+
}
139+
fprintf(stderr, "umf_load: the default provider created from memspace\n");
140+
141+
umf_default = NULL;
142+
ret = (*umfPoolCreate)((*umfScalablePoolOps)(), umf_provider_default, NULL,
143+
0, &umf_pool_default);
144+
if (ret || umf_pool_default == NULL) {
145+
fprintf(stderr, "umf_load: error creating the default pool: %i\n", ret);
146+
goto err_destroy_provider;
147+
}
148+
fprintf(stderr,
149+
"umf_load: the default pool created from the All Nodes provider\n");
150+
151+
umf_default = umf_pool_default; // umf pool using the default memspace
152+
153+
fprintf(stderr, "umf_load: umf initialized\n");
154+
155+
return 0;
156+
157+
err_destroy_provider:
158+
(*umfMemoryProviderDestroy)(umf_provider_default);
159+
err_dlclose:
160+
dlclose(h_umf);
161+
162+
return -1;
163+
}
164+
165+
static void umf_unload(void) {
166+
umf_default = NULL;
167+
168+
fprintf(stderr, "umf_unload: finalizing UMF ...\n");
169+
170+
(*umfPoolDestroy)(umf_pool_default);
171+
fprintf(stderr, "umf_unload: the default umf memory pool destroyed\n");
172+
173+
(*umfMemoryProviderDestroy)(umf_provider_default);
174+
fprintf(stderr, "umf_unload: the default umf memory provider destroyed\n");
175+
176+
// deinitialize libumf (decrement the reference counter of users)
177+
fprintf(stderr, "umf_unload: calling umfTearDown() ...\n");
178+
(*umfTearDown)();
179+
180+
fprintf(stderr, "umf_unload: closing umf library ...\n");
181+
dlclose(h_umf);
182+
fprintf(stderr, "umf_unload: umf library closed\n");
183+
}
184+
185+
static int run_test(int wrong_dtor_order) {
186+
187+
if (wrong_dtor_order) {
188+
fprintf(stderr, "\n\n*** Running test with INCORRECT order of "
189+
"destructors ***\n\n\n");
190+
} else {
191+
fprintf(
192+
stderr,
193+
"\n\n*** Running test with CORRECT order of destructors ***\n\n\n");
194+
}
195+
196+
if (umf_load()) {
197+
return -1;
198+
}
199+
200+
assert(umf_default);
201+
void *ptr = (*umf_alloc)(umf_default, SIZE_ALLOC);
202+
(*umf_free)(umf_default, ptr);
203+
204+
// simulate incorrect order of destructors (an additional, unwanted destructor call)
205+
if (wrong_dtor_order) {
206+
fprintf(stderr,
207+
"*** Simulating incorrect order of destructors !!! ***\n");
208+
(*umfTearDown)();
209+
}
210+
211+
umf_unload();
212+
213+
return 0;
214+
}
215+
216+
int main(void) {
217+
if (run_test(0)) { // correct order of destructors
218+
return -1;
219+
}
220+
221+
if (run_test(1)) { // incorrect order of destructors
222+
return -1;
223+
}
224+
225+
return 0;
226+
}

0 commit comments

Comments
 (0)