Skip to content

Commit 711f56c

Browse files
committed
make umfInit threadsafe
1 parent a2a0919 commit 711f56c

File tree

1 file changed

+37
-22
lines changed

1 file changed

+37
-22
lines changed

src/libumf.c

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "provider_level_zero_internal.h"
2020
#include "provider_tracking.h"
2121
#include "utils_common.h"
22+
#include "utils_concurrency.h"
2223
#include "utils_log.h"
2324
#if !defined(UMF_NO_HWLOC)
2425
#include "topology.h"
@@ -34,36 +35,49 @@ static umf_ctl_node_t CTL_NODE(umf)[] = {CTL_CHILD(provider), CTL_CHILD(pool),
3435
void initialize_global_ctl(void) { CTL_REGISTER_MODULE(NULL, umf); }
3536

3637
umf_result_t umfInit(void) {
37-
if (utils_fetch_and_add_u64(&umfRefCount, 1) == 0) {
38-
utils_log_init();
39-
umf_result_t umf_result = umfMemoryTrackerCreate(&TRACKER);
40-
if (umf_result != UMF_RESULT_SUCCESS) {
41-
LOG_ERR("Failed to create memory tracker");
42-
return umf_result;
38+
uint64_t refCount;
39+
uint64_t one = 1;
40+
do {
41+
utils_atomic_load_acquire_u64(&umfRefCount, &refCount);
42+
if (refCount == 0 &&
43+
utils_compare_exchange_u64(&umfRefCount, &refCount, &one)) {
44+
utils_log_init();
45+
umf_result_t umf_result = umfMemoryTrackerCreate(&TRACKER);
46+
if (!TRACKER) {
47+
LOG_ERR("Failed to create memory tracker");
48+
utils_atomic_decrement_size_t(&umfRefCount);
49+
return umf_result;
50+
}
51+
52+
LOG_DEBUG("UMF tracker created");
53+
54+
umf_result = umfIpcCacheGlobalInit();
55+
if (umf_result != UMF_RESULT_SUCCESS) {
56+
LOG_ERR("Failed to initialize IPC cache");
57+
umfMemoryTrackerDestroy(TRACKER);
58+
utils_atomic_decrement_size_t(&umfRefCount);
59+
return umf_result;
60+
}
61+
62+
LOG_DEBUG("UMF IPC cache initialized");
63+
initialize_global_ctl();
64+
65+
} else {
66+
do {
67+
utils_atomic_load_acquire_u64(&umfRefCount, &refCount);
68+
} while (refCount == 1);
4369
}
70+
utils_atomic_increment_u64(&umfRefCount);
4471

45-
LOG_DEBUG("UMF tracker created");
72+
} while (refCount < 2);
4673

47-
umf_result = umfIpcCacheGlobalInit();
48-
if (umf_result != UMF_RESULT_SUCCESS) {
49-
LOG_ERR("Failed to initialize IPC cache");
50-
umfMemoryTrackerDestroy(TRACKER);
51-
return umf_result;
52-
}
53-
54-
LOG_DEBUG("UMF IPC cache initialized");
55-
initialize_global_ctl();
56-
}
57-
58-
if (TRACKER) {
59-
LOG_DEBUG("UMF library initialized");
60-
}
74+
LOG_DEBUG("UMF library initialized");
6175

6276
return UMF_RESULT_SUCCESS;
6377
}
6478

6579
umf_result_t umfTearDown(void) {
66-
if (utils_fetch_and_sub_u64(&umfRefCount, 1) == 1) {
80+
if (utils_fetch_and_sub_u64(&umfRefCount, 1) == 2) {
6781
#if !defined(_WIN32) && !defined(UMF_NO_HWLOC)
6882
umfMemspaceHostAllDestroy();
6983
umfMemspaceHighestCapacityDestroy();
@@ -95,6 +109,7 @@ umf_result_t umfTearDown(void) {
95109
fini_cu_global_state();
96110
fini_tbb_global_state();
97111
LOG_DEBUG("UMF library finalized");
112+
utils_atomic_decrement_u64(&umfRefCount);
98113
}
99114
return UMF_RESULT_SUCCESS;
100115
}

0 commit comments

Comments
 (0)