20
20
21
21
#include "base_alloc_global.h"
22
22
#include "libumf.h"
23
+ #include "pool_scalable_internal.h"
23
24
#include "utils_common.h"
24
25
#include "utils_concurrency.h"
25
26
#include "utils_load_library.h"
@@ -33,6 +34,7 @@ static __TLS umf_result_t TLS_last_allocation_error;
33
34
static __TLS umf_result_t TLS_last_free_error ;
34
35
35
36
static const size_t DEFAULT_GRANULARITY = 2 * 1024 * 1024 ; // 2MB
37
+
36
38
typedef struct tbb_mem_pool_policy_t {
37
39
raw_alloc_tbb_type pAlloc ;
38
40
raw_free_tbb_type pFree ;
@@ -66,7 +68,6 @@ typedef struct tbb_callbacks_t {
66
68
typedef struct tbb_memory_pool_t {
67
69
umf_memory_provider_handle_t mem_provider ;
68
70
void * tbb_pool ;
69
- tbb_callbacks_t tbb_callbacks ;
70
71
} tbb_memory_pool_t ;
71
72
72
73
typedef enum tbb_enums_t {
@@ -82,6 +83,10 @@ typedef enum tbb_enums_t {
82
83
TBB_POOL_SYMBOLS_MAX // it has to be the last one
83
84
} tbb_enums_t ;
84
85
86
+ static UTIL_ONCE_FLAG tbb_initialized = UTIL_ONCE_FLAG_INIT ;
87
+ int tbb_init_result = 0 ;
88
+ static tbb_callbacks_t tbb_callbacks = {0 };
89
+
85
90
static const char * tbb_symbol [TBB_POOL_SYMBOLS_MAX ] = {
86
91
#ifdef _WIN32
87
92
// symbols copied from oneTBB/src/tbbmalloc/def/win64-tbbmalloc.def
@@ -109,46 +114,60 @@ static const char *tbb_symbol[TBB_POOL_SYMBOLS_MAX] = {
109
114
#endif
110
115
};
111
116
112
- static int init_tbb_callbacks (tbb_callbacks_t * tbb_callbacks ) {
113
- assert (tbb_callbacks );
114
-
117
+ static void init_tbb_callbacks_once (void ) {
115
118
const char * lib_name = tbb_symbol [TBB_LIB_NAME ];
116
- tbb_callbacks -> lib_handle = utils_open_library (lib_name , 0 );
117
- if (!tbb_callbacks -> lib_handle ) {
119
+ tbb_callbacks . lib_handle = utils_open_library (lib_name , 0 );
120
+ if (!tbb_callbacks . lib_handle ) {
118
121
LOG_ERR ("%s required by Scalable Pool not found - install TBB malloc "
119
122
"or make sure it is in the default search paths." ,
120
123
lib_name );
121
- return -1 ;
124
+ tbb_init_result = -1 ;
125
+ return ;
122
126
}
123
-
124
- * (void * * )& tbb_callbacks -> pool_malloc = utils_get_symbol_addr (
125
- tbb_callbacks -> lib_handle , tbb_symbol [TBB_POOL_MALLOC ], lib_name );
126
- * (void * * )& tbb_callbacks -> pool_realloc = utils_get_symbol_addr (
127
- tbb_callbacks -> lib_handle , tbb_symbol [TBB_POOL_REALLOC ], lib_name );
128
- * (void * * )& tbb_callbacks -> pool_aligned_malloc =
129
- utils_get_symbol_addr (tbb_callbacks -> lib_handle ,
127
+ * (void * * )& tbb_callbacks .pool_malloc = utils_get_symbol_addr (
128
+ tbb_callbacks .lib_handle , tbb_symbol [TBB_POOL_MALLOC ], lib_name );
129
+ * (void * * )& tbb_callbacks .pool_realloc = utils_get_symbol_addr (
130
+ tbb_callbacks .lib_handle , tbb_symbol [TBB_POOL_REALLOC ], lib_name );
131
+ * (void * * )& tbb_callbacks .pool_aligned_malloc =
132
+ utils_get_symbol_addr (tbb_callbacks .lib_handle ,
130
133
tbb_symbol [TBB_POOL_ALIGNED_MALLOC ], lib_name );
131
- * (void * * )& tbb_callbacks -> pool_free = utils_get_symbol_addr (
132
- tbb_callbacks -> lib_handle , tbb_symbol [TBB_POOL_FREE ], lib_name );
133
- * (void * * )& tbb_callbacks -> pool_create_v1 = utils_get_symbol_addr (
134
- tbb_callbacks -> lib_handle , tbb_symbol [TBB_POOL_CREATE_V1 ], lib_name );
135
- * (void * * )& tbb_callbacks -> pool_destroy = utils_get_symbol_addr (
136
- tbb_callbacks -> lib_handle , tbb_symbol [TBB_POOL_DESTROY ], lib_name );
137
- * (void * * )& tbb_callbacks -> pool_identify = utils_get_symbol_addr (
138
- tbb_callbacks -> lib_handle , tbb_symbol [TBB_POOL_IDENTIFY ], lib_name );
139
- * (void * * )& tbb_callbacks -> pool_msize = utils_get_symbol_addr (
140
- tbb_callbacks -> lib_handle , tbb_symbol [TBB_POOL_MSIZE ], lib_name );
141
-
142
- if (!tbb_callbacks -> pool_malloc || !tbb_callbacks -> pool_realloc ||
143
- !tbb_callbacks -> pool_aligned_malloc || !tbb_callbacks -> pool_free ||
144
- !tbb_callbacks -> pool_create_v1 || !tbb_callbacks -> pool_destroy ||
145
- !tbb_callbacks -> pool_identify ) {
134
+ * (void * * )& tbb_callbacks . pool_free = utils_get_symbol_addr (
135
+ tbb_callbacks . lib_handle , tbb_symbol [TBB_POOL_FREE ], lib_name );
136
+ * (void * * )& tbb_callbacks . pool_create_v1 = utils_get_symbol_addr (
137
+ tbb_callbacks . lib_handle , tbb_symbol [TBB_POOL_CREATE_V1 ], lib_name );
138
+ * (void * * )& tbb_callbacks . pool_destroy = utils_get_symbol_addr (
139
+ tbb_callbacks . lib_handle , tbb_symbol [TBB_POOL_DESTROY ], lib_name );
140
+ * (void * * )& tbb_callbacks . pool_identify = utils_get_symbol_addr (
141
+ tbb_callbacks . lib_handle , tbb_symbol [TBB_POOL_IDENTIFY ], lib_name );
142
+ * (void * * )& tbb_callbacks . pool_msize = utils_get_symbol_addr (
143
+ tbb_callbacks . lib_handle , tbb_symbol [TBB_POOL_MSIZE ], lib_name );
144
+
145
+ if (!tbb_callbacks . pool_malloc || !tbb_callbacks . pool_realloc ||
146
+ !tbb_callbacks . pool_aligned_malloc || !tbb_callbacks . pool_free ||
147
+ !tbb_callbacks . pool_create_v1 || !tbb_callbacks . pool_destroy ||
148
+ !tbb_callbacks . pool_identify ) {
146
149
LOG_FATAL ("Could not find all TBB symbols in %s" , lib_name );
147
- utils_close_library (tbb_callbacks -> lib_handle );
148
- return -1 ;
150
+ if (utils_close_library (tbb_callbacks .lib_handle )) {
151
+ LOG_ERR ("Could not close %s library" , lib_name );
152
+ }
153
+ tbb_init_result = -1 ;
149
154
}
155
+ }
156
+
157
+ static int init_tbb_callbacks (void ) {
158
+ utils_init_once (& tbb_initialized , init_tbb_callbacks_once );
159
+ return tbb_init_result ;
160
+ }
150
161
151
- return 0 ;
162
+ void fini_tbb_global_state (void ) {
163
+ if (tbb_callbacks .lib_handle ) {
164
+ if (!utils_close_library (tbb_callbacks .lib_handle )) {
165
+ tbb_callbacks .lib_handle = NULL ;
166
+ LOG_DEBUG ("TBB library closed" );
167
+ } else {
168
+ LOG_DEBUG ("TBB library cannot be unloaded" );
169
+ }
170
+ }
152
171
}
153
172
154
173
static void * tbb_raw_alloc_wrapper (intptr_t pool_id , size_t * raw_bytes ) {
@@ -264,15 +283,15 @@ static umf_result_t tbb_pool_initialize(umf_memory_provider_handle_t provider,
264
283
return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY ;
265
284
}
266
285
267
- int ret = init_tbb_callbacks (& pool_data -> tbb_callbacks );
286
+ int ret = init_tbb_callbacks ();
268
287
if (ret != 0 ) {
269
288
LOG_FATAL ("loading TBB symbols failed" );
270
289
return UMF_RESULT_ERROR_UNKNOWN ;
271
290
}
272
291
273
292
pool_data -> mem_provider = provider ;
274
- ret = pool_data -> tbb_callbacks .pool_create_v1 ((intptr_t )pool_data , & policy ,
275
- & (pool_data -> tbb_pool ));
293
+ ret = tbb_callbacks .pool_create_v1 ((intptr_t )pool_data , & policy ,
294
+ & (pool_data -> tbb_pool ));
276
295
if (ret != 0 /* TBBMALLOC_OK */ ) {
277
296
return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC ;
278
297
}
@@ -284,15 +303,14 @@ static umf_result_t tbb_pool_initialize(umf_memory_provider_handle_t provider,
284
303
285
304
static void tbb_pool_finalize (void * pool ) {
286
305
tbb_memory_pool_t * pool_data = (tbb_memory_pool_t * )pool ;
287
- pool_data -> tbb_callbacks .pool_destroy (pool_data -> tbb_pool );
288
- utils_close_library (pool_data -> tbb_callbacks .lib_handle );
306
+ tbb_callbacks .pool_destroy (pool_data -> tbb_pool );
289
307
umf_ba_global_free (pool_data );
290
308
}
291
309
292
310
static void * tbb_malloc (void * pool , size_t size ) {
293
311
tbb_memory_pool_t * pool_data = (tbb_memory_pool_t * )pool ;
294
312
TLS_last_allocation_error = UMF_RESULT_SUCCESS ;
295
- void * ptr = pool_data -> tbb_callbacks .pool_malloc (pool_data -> tbb_pool , size );
313
+ void * ptr = tbb_callbacks .pool_malloc (pool_data -> tbb_pool , size );
296
314
if (ptr == NULL ) {
297
315
if (TLS_last_allocation_error == UMF_RESULT_SUCCESS ) {
298
316
TLS_last_allocation_error = UMF_RESULT_ERROR_UNKNOWN ;
@@ -319,8 +337,7 @@ static void *tbb_calloc(void *pool, size_t num, size_t size) {
319
337
static void * tbb_realloc (void * pool , void * ptr , size_t size ) {
320
338
tbb_memory_pool_t * pool_data = (tbb_memory_pool_t * )pool ;
321
339
TLS_last_allocation_error = UMF_RESULT_SUCCESS ;
322
- void * new_ptr =
323
- pool_data -> tbb_callbacks .pool_realloc (pool_data -> tbb_pool , ptr , size );
340
+ void * new_ptr = tbb_callbacks .pool_realloc (pool_data -> tbb_pool , ptr , size );
324
341
if (new_ptr == NULL ) {
325
342
if (TLS_last_allocation_error == UMF_RESULT_SUCCESS ) {
326
343
TLS_last_allocation_error = UMF_RESULT_ERROR_UNKNOWN ;
@@ -334,8 +351,8 @@ static void *tbb_realloc(void *pool, void *ptr, size_t size) {
334
351
static void * tbb_aligned_malloc (void * pool , size_t size , size_t alignment ) {
335
352
tbb_memory_pool_t * pool_data = (tbb_memory_pool_t * )pool ;
336
353
TLS_last_allocation_error = UMF_RESULT_SUCCESS ;
337
- void * ptr = pool_data -> tbb_callbacks . pool_aligned_malloc (
338
- pool_data -> tbb_pool , size , alignment );
354
+ void * ptr =
355
+ tbb_callbacks . pool_aligned_malloc ( pool_data -> tbb_pool , size , alignment );
339
356
if (ptr == NULL ) {
340
357
if (TLS_last_allocation_error == UMF_RESULT_SUCCESS ) {
341
358
TLS_last_allocation_error = UMF_RESULT_ERROR_UNKNOWN ;
@@ -360,7 +377,7 @@ static umf_result_t tbb_free(void *pool, void *ptr) {
360
377
utils_annotate_release (pool );
361
378
362
379
tbb_memory_pool_t * pool_data = (tbb_memory_pool_t * )pool ;
363
- if (pool_data -> tbb_callbacks .pool_free (pool_data -> tbb_pool , ptr )) {
380
+ if (tbb_callbacks .pool_free (pool_data -> tbb_pool , ptr )) {
364
381
return UMF_RESULT_SUCCESS ;
365
382
}
366
383
@@ -373,7 +390,7 @@ static umf_result_t tbb_free(void *pool, void *ptr) {
373
390
374
391
static size_t tbb_malloc_usable_size (void * pool , void * ptr ) {
375
392
tbb_memory_pool_t * pool_data = (tbb_memory_pool_t * )pool ;
376
- return pool_data -> tbb_callbacks .pool_msize (pool_data -> tbb_pool , ptr );
393
+ return tbb_callbacks .pool_msize (pool_data -> tbb_pool , ptr );
377
394
}
378
395
379
396
static umf_result_t tbb_get_last_allocation_error (void * pool ) {
0 commit comments