Skip to content

Commit 40d5329

Browse files
authored
Merge pull request #530 from ldorau/Add_init_teardown_functions_umfInit_and_umfTearDown
Add init/teardown functions: umfInit() and umfTearDown()
2 parents 32543b1 + a562f8e commit 40d5329

16 files changed

+363
-71
lines changed

include/umf.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,17 @@
1515
#include <umf/mempolicy.h>
1616
#include <umf/memspace.h>
1717

18+
///
19+
/// @brief Increment the usage reference counter and initialize the global state of libumf
20+
/// if the usage reference counter was equal to 0.
21+
/// It must be called just after dlopen() and it is not required in other scenarios.
22+
/// @return 0 on success or -1 on failure.
23+
int umfInit(void);
24+
25+
///
26+
/// @brief Decrement the usage reference counter and destroy the global state of libumf
27+
/// if the usage reference counter is equal to 0.
28+
/// It must be called just before dlclose() and it is not required in other scenarios.
29+
void umfTearDown(void);
30+
1831
#endif /* UMF_UNIFIED_MEMORY_FRAMEWORK_H */

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ set(BA_SOURCES
5353

5454
set(UMF_SOURCES
5555
${BA_SOURCES}
56+
libumf.c
5657
ipc.c
5758
memory_pool.c
5859
memory_provider.c

src/base_alloc/base_alloc_global.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <assert.h>
1111
#include <stdio.h>
1212
#include <stdlib.h>
13+
#include <string.h>
1314

1415
#include "base_alloc.h"
1516
#include "base_alloc_global.h"
@@ -45,6 +46,10 @@ void umf_ba_destroy_global(void) {
4546
BASE_ALLOC.ac[i] = NULL;
4647
}
4748
}
49+
50+
// portable version of "ba_is_initialized = UTIL_ONCE_FLAG_INIT;"
51+
static UTIL_ONCE_FLAG is_initialized = UTIL_ONCE_FLAG_INIT;
52+
memcpy(&ba_is_initialized, &is_initialized, sizeof(ba_is_initialized));
4853
}
4954

5055
static void umf_ba_create_global(void) {
@@ -62,10 +67,6 @@ static void umf_ba_create_global(void) {
6267

6368
size_t smallestSize = BASE_ALLOC.ac_sizes[0];
6469
BASE_ALLOC.smallest_ac_size_log2 = log2Utils(smallestSize);
65-
66-
#if defined(_WIN32) && !defined(UMF_SHARED_LIBRARY)
67-
atexit(umf_ba_destroy_global);
68-
#endif
6970
}
7071

7172
// returns index of the allocation class for a given size

src/base_alloc/base_alloc_linux.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,6 @@
1818
static UTIL_ONCE_FLAG Page_size_is_initialized = UTIL_ONCE_FLAG_INIT;
1919
static size_t Page_size;
2020

21-
// The highest possible priority (101) is used, because the constructor should be called
22-
// as the first one and the destructor as the last one in order to avoid use-after-free.
23-
void __attribute__((constructor(101))) umf_ba_constructor(void) {}
24-
25-
void __attribute__((destructor(101))) umf_ba_destructor(void) {
26-
umf_ba_destroy_global();
27-
}
28-
2921
void *ba_os_alloc(size_t size) {
3022
return mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
3123
-1, 0);

src/libumf.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
*
3+
* Copyright (C) 2024 Intel Corporation
4+
*
5+
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
6+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
*
8+
*/
9+
10+
#include <stddef.h>
11+
12+
#include "base_alloc_global.h"
13+
#include "memspace_internal.h"
14+
#include "provider_tracking.h"
15+
#include "topology.h"
16+
#include "utils_log.h"
17+
18+
umf_memory_tracker_handle_t TRACKER = NULL;
19+
20+
static unsigned long long umfRefCount = 0;
21+
22+
int umfInit(void) {
23+
if (util_fetch_and_add64(&umfRefCount, 1) == 0) {
24+
util_log_init();
25+
TRACKER = umfMemoryTrackerCreate();
26+
}
27+
28+
return (TRACKER) ? 0 : -1;
29+
}
30+
31+
void umfTearDown(void) {
32+
if (util_fetch_and_add64(&umfRefCount, -1) == 1) {
33+
#ifndef _WIN32
34+
umfMemspaceHostAllDestroy();
35+
umfMemspaceHighestCapacityDestroy();
36+
umfMemspaceHighestBandwidthDestroy();
37+
umfDestroyTopology();
38+
#endif
39+
// make sure TRACKER is not used after being destroyed
40+
umf_memory_tracker_handle_t t = TRACKER;
41+
TRACKER = NULL;
42+
umfMemoryTrackerDestroy(t);
43+
44+
umf_ba_destroy_global();
45+
}
46+
}

src/libumf.def.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ VERSION 1.0
1010

1111
EXPORTS
1212
DllMain
13+
umfInit
14+
umfTearDown
1315
umfCloseIPCHandle
1416
umfFree
1517
umfGetIPCHandle

src/libumf.map

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
UMF_1.0 {
66
global:
7+
umfInit;
8+
umfTearDown;
79
umfCloseIPCHandle;
810
umfFree;
911
umfGetIPCHandle;

src/libumf_linux.c

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,11 @@
77
*
88
*/
99

10-
#include <stddef.h>
10+
#include <umf.h>
1111

12-
#include "base_alloc_global.h"
13-
#include "memspace_internal.h"
14-
#include "provider_tracking.h"
15-
#include "topology.h"
16-
#include "utils_log.h"
12+
void __attribute__((constructor)) umfCreate(void) { (void)umfInit(); }
1713

18-
umf_memory_tracker_handle_t TRACKER = NULL;
19-
20-
void __attribute__((constructor)) umfCreate(void) {
21-
util_log_init();
22-
TRACKER = umfMemoryTrackerCreate();
23-
}
24-
25-
void __attribute__((destructor)) umfDestroy(void) {
26-
umf_memory_tracker_handle_t t = TRACKER;
27-
// make sure TRACKER is not used after being destroyed
28-
TRACKER = NULL;
29-
umfMemoryTrackerDestroy(t);
30-
umfMemspaceHostAllDestroy();
31-
umfMemspaceHighestCapacityDestroy();
32-
umfMemspaceHighestBandwidthDestroy();
33-
umfDestroyTopology();
34-
}
14+
void __attribute__((destructor)) umfDestroy(void) { umfTearDown(); }
3515

3616
void libumfInit(void) {
3717
// do nothing, additional initialization not needed

src/libumf_windows.c

Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,49 +7,38 @@
77
*
88
*/
99

10-
#include <stdlib.h>
1110
#include <windows.h>
1211

13-
#include "base_alloc_global.h"
14-
#include "provider_tracking.h"
15-
#include "utils_log.h"
12+
#include <umf.h>
1613

17-
umf_memory_tracker_handle_t TRACKER = NULL;
14+
#if defined(UMF_SHARED_LIBRARY) /* SHARED LIBRARY */
1815

19-
static void umfCreate(void) {
20-
util_log_init();
21-
TRACKER = umfMemoryTrackerCreate();
22-
}
23-
24-
static void umfDestroy(void) {
25-
umfMemoryTrackerDestroy(TRACKER);
26-
umf_ba_destroy_global();
27-
}
28-
29-
#if defined(UMF_SHARED_LIBRARY)
3016
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
31-
if (fdwReason == DLL_PROCESS_DETACH) {
32-
umfDestroy();
33-
} else if (fdwReason == DLL_PROCESS_ATTACH) {
34-
umfCreate();
17+
if (fdwReason == DLL_PROCESS_ATTACH) {
18+
(void)umfInit();
19+
} else if (fdwReason == DLL_PROCESS_DETACH) {
20+
umfTearDown();
3521
}
3622
return TRUE;
3723
}
3824

3925
void libumfInit(void) {
4026
// do nothing, additional initialization not needed
4127
}
42-
#else
28+
29+
#else /* STATIC LIBRARY */
30+
4331
INIT_ONCE init_once_flag = INIT_ONCE_STATIC_INIT;
4432

4533
BOOL CALLBACK initOnceCb(PINIT_ONCE InitOnce, PVOID Parameter,
4634
PVOID *lpContext) {
47-
umfCreate();
48-
atexit(umfDestroy);
49-
return TRACKER ? TRUE : FALSE;
35+
int ret = umfInit();
36+
atexit(umfTearDown);
37+
return (ret == 0) ? TRUE : FALSE;
5038
}
5139

5240
void libumfInit(void) {
5341
InitOnceExecuteOnce(&init_once_flag, initOnceCb, NULL, NULL);
5442
}
43+
5544
#endif

src/memspaces/memspace_highest_bandwidth.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ void umfMemspaceHighestBandwidthDestroy(void) {
7878
if (UMF_MEMSPACE_HIGHEST_BANDWIDTH) {
7979
umfMemspaceDestroy(UMF_MEMSPACE_HIGHEST_BANDWIDTH);
8080
UMF_MEMSPACE_HIGHEST_BANDWIDTH = NULL;
81+
82+
// portable version of "UMF_MEMSPACE_HBW_INITIALIZED = UTIL_ONCE_FLAG_INIT;"
83+
static UTIL_ONCE_FLAG is_initialized = UTIL_ONCE_FLAG_INIT;
84+
memcpy(&UMF_MEMSPACE_HBW_INITIALIZED, &is_initialized,
85+
sizeof(UMF_MEMSPACE_HBW_INITIALIZED));
8186
}
8287
}
8388

@@ -90,10 +95,6 @@ static void umfMemspaceHighestBandwidthInit(void) {
9095
ret);
9196
assert(ret == UMF_RESULT_ERROR_NOT_SUPPORTED);
9297
}
93-
94-
#if defined(_WIN32) && !defined(UMF_SHARED_LIBRARY)
95-
atexit(umfMemspaceHighestBandwidthDestroy);
96-
#endif
9798
}
9899

99100
umf_memspace_handle_t umfMemspaceHighestBandwidthGet(void) {

src/memspaces/memspace_highest_capacity.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ void umfMemspaceHighestCapacityDestroy(void) {
5454
if (UMF_MEMSPACE_HIGHEST_CAPACITY) {
5555
umfMemspaceDestroy(UMF_MEMSPACE_HIGHEST_CAPACITY);
5656
UMF_MEMSPACE_HIGHEST_CAPACITY = NULL;
57+
58+
// portable version of "UMF_MEMSPACE_HIGHEST_CAPACITY_INITIALIZED = UTIL_ONCE_FLAG_INIT;"
59+
static UTIL_ONCE_FLAG is_initialized = UTIL_ONCE_FLAG_INIT;
60+
memcpy(&UMF_MEMSPACE_HIGHEST_CAPACITY_INITIALIZED, &is_initialized,
61+
sizeof(UMF_MEMSPACE_HIGHEST_CAPACITY_INITIALIZED));
5762
}
5863
}
5964

@@ -62,10 +67,6 @@ static void umfMemspaceHighestCapacityInit(void) {
6267
umfMemspaceHighestCapacityCreate(&UMF_MEMSPACE_HIGHEST_CAPACITY);
6368
assert(ret == UMF_RESULT_SUCCESS);
6469
(void)ret;
65-
66-
#if defined(_WIN32) && !defined(UMF_SHARED_LIBRARY)
67-
atexit(umfMemspaceHostAllDestroy);
68-
#endif
6970
}
7071

7172
umf_memspace_handle_t umfMemspaceHighestCapacityGet(void) {

src/memspaces/memspace_host_all.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ void umfMemspaceHostAllDestroy(void) {
7373
if (UMF_MEMSPACE_HOST_ALL) {
7474
umfMemspaceDestroy(UMF_MEMSPACE_HOST_ALL);
7575
UMF_MEMSPACE_HOST_ALL = NULL;
76+
77+
// portable version of "UMF_MEMSPACE_HOST_ALL_INITIALIZED = UTIL_ONCE_FLAG_INIT;"
78+
static UTIL_ONCE_FLAG is_initialized = UTIL_ONCE_FLAG_INIT;
79+
memcpy(&UMF_MEMSPACE_HOST_ALL_INITIALIZED, &is_initialized,
80+
sizeof(UMF_MEMSPACE_HOST_ALL_INITIALIZED));
7681
}
7782
}
7883

src/provider/provider_level_zero.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ void ze_memory_provider_finalize(void *provider) {
124124

125125
util_init_once(&ze_is_initialized, init_ze_global_state);
126126
umf_ba_global_free(provider);
127+
128+
// portable version of "ze_is_initialized = UTIL_ONCE_FLAG_INIT;"
129+
static UTIL_ONCE_FLAG is_initialized = UTIL_ONCE_FLAG_INIT;
130+
memcpy(&ze_is_initialized, &is_initialized, sizeof(ze_is_initialized));
127131
}
128132

129133
static umf_result_t ze_memory_provider_alloc(void *provider, size_t size,

src/topology.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ static UTIL_ONCE_FLAG topology_initialized = UTIL_ONCE_FLAG_INIT;
1919
void umfDestroyTopology(void) {
2020
if (topology) {
2121
hwloc_topology_destroy(topology);
22+
23+
// portable version of "topology_initialized = UTIL_ONCE_FLAG_INIT;"
24+
static UTIL_ONCE_FLAG is_initialized = UTIL_ONCE_FLAG_INIT;
25+
memcpy(&topology_initialized, &is_initialized,
26+
sizeof(topology_initialized));
2227
}
2328
}
2429

@@ -34,10 +39,6 @@ static void umfCreateTopology(void) {
3439
hwloc_topology_destroy(topology);
3540
topology = NULL;
3641
}
37-
38-
#if defined(_WIN32) && !defined(UMF_SHARED_LIBRARY)
39-
atexit(umfDestroyTopology);
40-
#endif
4142
}
4243

4344
hwloc_topology_t umfGetTopology(void) {

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()

0 commit comments

Comments
 (0)