Skip to content

Commit 17a9f28

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. - umfTearDown() decrements the usage reference counter and destroys the global state of libumf if the usage reference counter is equal 0. Fixes: #514 Signed-off-by: Lukasz Dorau <[email protected]>
1 parent ff3dd93 commit 17a9f28

12 files changed

+84
-72
lines changed

include/umf.h

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

18+
// Increment the usage reference counter and initialize the global state of libumf
19+
// if the usage reference counter was equal 0.
20+
// Returns 0 on success or -1 on failure.
21+
int umfInit(void);
22+
23+
// Decrement the usage reference counter and destroy the global state of libumf
24+
// if the usage reference counter is equal 0.
25+
void umfTearDown(void);
26+
1827
#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
@@ -62,10 +62,6 @@ static void umf_ba_create_global(void) {
6262

6363
size_t smallestSize = BASE_ALLOC.ac_sizes[0];
6464
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
6965
}
7066

7167
// 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: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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+
// Increment the usage reference counter and initialize the global state of libumf
23+
// if the usage reference counter was equal 0.
24+
// Returns 0 on success or -1 on failure.
25+
int umfInit(void) {
26+
if (util_fetch_and_add64(&umfRefCount, 1) == 0) {
27+
util_log_init();
28+
TRACKER = umfMemoryTrackerCreate();
29+
}
30+
31+
return (TRACKER) ? 0 : -1;
32+
}
33+
34+
// Decrement the usage reference counter and destroy the global state of libumf
35+
// if the usage reference counter is equal 0.
36+
void umfTearDown(void) {
37+
if (util_fetch_and_add64(&umfRefCount, -1) == 1) {
38+
#ifndef _WIN32
39+
umfMemspaceHostAllDestroy();
40+
umfMemspaceHighestCapacityDestroy();
41+
umfMemspaceHighestBandwidthDestroy();
42+
#endif
43+
umfDestroyTopology();
44+
45+
// make sure TRACKER is not used after being destroyed
46+
umf_memory_tracker_handle_t t = TRACKER;
47+
TRACKER = NULL;
48+
umfMemoryTrackerDestroy(t);
49+
50+
umf_ba_destroy_global();
51+
}
52+
}

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: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,49 +7,39 @@
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+
int ret = 0;
18+
if (fdwReason == DLL_PROCESS_ATTACH) {
19+
ret = umfInit();
20+
} else if (fdwReason == DLL_PROCESS_DETACH) {
21+
umfTearDown();
3522
}
36-
return TRUE;
23+
return (ret == 0) ? TRUE : FALSE;
3724
}
3825

3926
void libumfInit(void) {
4027
// do nothing, additional initialization not needed
4128
}
42-
#else
29+
30+
#else /* STATIC LIBRARY */
31+
4332
INIT_ONCE init_once_flag = INIT_ONCE_STATIC_INIT;
4433

4534
BOOL CALLBACK initOnceCb(PINIT_ONCE InitOnce, PVOID Parameter,
4635
PVOID *lpContext) {
47-
umfCreate();
48-
atexit(umfDestroy);
49-
return TRACKER ? TRUE : FALSE;
36+
int ret = umfInit();
37+
atexit(umfTearDown);
38+
return (ret == 0) ? TRUE : FALSE;
5039
}
5140

5241
void libumfInit(void) {
5342
InitOnceExecuteOnce(&init_once_flag, initOnceCb, NULL, NULL);
5443
}
44+
5545
#endif

src/memspaces/memspace_highest_bandwidth.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,6 @@ static void umfMemspaceHighestBandwidthInit(void) {
9090
ret);
9191
assert(ret == UMF_RESULT_ERROR_NOT_SUPPORTED);
9292
}
93-
94-
#if defined(_WIN32) && !defined(UMF_SHARED_LIBRARY)
95-
atexit(umfMemspaceHighestBandwidthDestroy);
96-
#endif
9793
}
9894

9995
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
@@ -62,10 +62,6 @@ static void umfMemspaceHighestCapacityInit(void) {
6262
umfMemspaceHighestCapacityCreate(&UMF_MEMSPACE_HIGHEST_CAPACITY);
6363
assert(ret == UMF_RESULT_SUCCESS);
6464
(void)ret;
65-
66-
#if defined(_WIN32) && !defined(UMF_SHARED_LIBRARY)
67-
atexit(umfMemspaceHostAllDestroy);
68-
#endif
6965
}
7066

7167
umf_memspace_handle_t umfMemspaceHighestCapacityGet(void) {

src/topology.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,6 @@ static void umfCreateTopology(void) {
3434
hwloc_topology_destroy(topology);
3535
topology = NULL;
3636
}
37-
38-
#if defined(_WIN32) && !defined(UMF_SHARED_LIBRARY)
39-
atexit(umfDestroyTopology);
40-
#endif
4137
}
4238

4339
hwloc_topology_t umfGetTopology(void) {

0 commit comments

Comments
 (0)