Skip to content

Commit 2c1e6cb

Browse files
committed
Add init/teardown functions: umfInit() and umfTearDown()
- umfInit() increments the usage reference counter and initializes the global state of libumf if the usage reference counter was equal 0. Returns 0 on success or -1 on failure. It must be called just after dlopen() and it is not required in other scenarios. - umfTearDown() decrements the usage reference counter and destroys the global state of libumf if the usage reference counter is equal 0. It must be called just before dlclose() and it is not required in other scenarios. Fixes: #514 Signed-off-by: Lukasz Dorau <[email protected]>
1 parent 3419aa2 commit 2c1e6cb

12 files changed

+80
-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: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,6 @@ static void umf_ba_create_global(void) {
6767

6868
size_t smallestSize = BASE_ALLOC.ac_sizes[0];
6969
BASE_ALLOC.smallest_ac_size_log2 = log2Utils(smallestSize);
70-
71-
#if defined(_WIN32) && !defined(UMF_SHARED_LIBRARY)
72-
atexit(umf_ba_destroy_global);
73-
#endif
7470
}
7571

7672
// 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: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,6 @@ static void umfMemspaceHighestBandwidthInit(void) {
9595
ret);
9696
assert(ret == UMF_RESULT_ERROR_NOT_SUPPORTED);
9797
}
98-
99-
#if defined(_WIN32) && !defined(UMF_SHARED_LIBRARY)
100-
atexit(umfMemspaceHighestBandwidthDestroy);
101-
#endif
10298
}
10399

104100
umf_memspace_handle_t umfMemspaceHighestBandwidthGet(void) {

src/memspaces/memspace_highest_capacity.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,6 @@ static void umfMemspaceHighestCapacityInit(void) {
6767
umfMemspaceHighestCapacityCreate(&UMF_MEMSPACE_HIGHEST_CAPACITY);
6868
assert(ret == UMF_RESULT_SUCCESS);
6969
(void)ret;
70-
71-
#if defined(_WIN32) && !defined(UMF_SHARED_LIBRARY)
72-
atexit(umfMemspaceHostAllDestroy);
73-
#endif
7470
}
7571

7672
umf_memspace_handle_t umfMemspaceHighestCapacityGet(void) {

src/topology.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,6 @@ static void umfCreateTopology(void) {
3939
hwloc_topology_destroy(topology);
4040
topology = NULL;
4141
}
42-
43-
#if defined(_WIN32) && !defined(UMF_SHARED_LIBRARY)
44-
atexit(umfDestroyTopology);
45-
#endif
4642
}
4743

4844
hwloc_topology_t umfGetTopology(void) {

0 commit comments

Comments
 (0)