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
+ static 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
+ }
150
156
151
- return 0 ;
157
+ static int init_tbb_callbacks (void ) {
158
+ utils_init_once (& tbb_initialized , init_tbb_callbacks_once );
159
+ return tbb_init_result ;
160
+ }
161
+
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_ERR ("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,35 +283,41 @@ 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
+ umf_result_t res = UMF_RESULT_SUCCESS ;
287
+ int ret = init_tbb_callbacks ();
268
288
if (ret != 0 ) {
269
289
LOG_FATAL ("loading TBB symbols failed" );
270
- return UMF_RESULT_ERROR_UNKNOWN ;
290
+ res = UMF_RESULT_ERROR_UNKNOWN ;
291
+ goto err_tbb_init ;
271
292
}
272
293
273
294
pool_data -> mem_provider = provider ;
274
- ret = pool_data -> tbb_callbacks .pool_create_v1 ((intptr_t )pool_data , & policy ,
275
- & (pool_data -> tbb_pool ));
295
+ ret = tbb_callbacks .pool_create_v1 ((intptr_t )pool_data , & policy ,
296
+ & (pool_data -> tbb_pool ));
276
297
if (ret != 0 /* TBBMALLOC_OK */ ) {
277
- return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC ;
298
+ res = UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC ;
299
+ goto err_tbb_init ;
278
300
}
279
301
280
302
* pool = (void * )pool_data ;
281
303
282
- return UMF_RESULT_SUCCESS ;
304
+ return res ;
305
+
306
+ err_tbb_init :
307
+ umf_ba_global_free (pool_data );
308
+ return res ;
283
309
}
284
310
285
311
static void tbb_pool_finalize (void * pool ) {
286
312
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 );
313
+ tbb_callbacks .pool_destroy (pool_data -> tbb_pool );
289
314
umf_ba_global_free (pool_data );
290
315
}
291
316
292
317
static void * tbb_malloc (void * pool , size_t size ) {
293
318
tbb_memory_pool_t * pool_data = (tbb_memory_pool_t * )pool ;
294
319
TLS_last_allocation_error = UMF_RESULT_SUCCESS ;
295
- void * ptr = pool_data -> tbb_callbacks .pool_malloc (pool_data -> tbb_pool , size );
320
+ void * ptr = tbb_callbacks .pool_malloc (pool_data -> tbb_pool , size );
296
321
if (ptr == NULL ) {
297
322
if (TLS_last_allocation_error == UMF_RESULT_SUCCESS ) {
298
323
TLS_last_allocation_error = UMF_RESULT_ERROR_UNKNOWN ;
@@ -319,8 +344,7 @@ static void *tbb_calloc(void *pool, size_t num, size_t size) {
319
344
static void * tbb_realloc (void * pool , void * ptr , size_t size ) {
320
345
tbb_memory_pool_t * pool_data = (tbb_memory_pool_t * )pool ;
321
346
TLS_last_allocation_error = UMF_RESULT_SUCCESS ;
322
- void * new_ptr =
323
- pool_data -> tbb_callbacks .pool_realloc (pool_data -> tbb_pool , ptr , size );
347
+ void * new_ptr = tbb_callbacks .pool_realloc (pool_data -> tbb_pool , ptr , size );
324
348
if (new_ptr == NULL ) {
325
349
if (TLS_last_allocation_error == UMF_RESULT_SUCCESS ) {
326
350
TLS_last_allocation_error = UMF_RESULT_ERROR_UNKNOWN ;
@@ -334,8 +358,8 @@ static void *tbb_realloc(void *pool, void *ptr, size_t size) {
334
358
static void * tbb_aligned_malloc (void * pool , size_t size , size_t alignment ) {
335
359
tbb_memory_pool_t * pool_data = (tbb_memory_pool_t * )pool ;
336
360
TLS_last_allocation_error = UMF_RESULT_SUCCESS ;
337
- void * ptr = pool_data -> tbb_callbacks . pool_aligned_malloc (
338
- pool_data -> tbb_pool , size , alignment );
361
+ void * ptr =
362
+ tbb_callbacks . pool_aligned_malloc ( pool_data -> tbb_pool , size , alignment );
339
363
if (ptr == NULL ) {
340
364
if (TLS_last_allocation_error == UMF_RESULT_SUCCESS ) {
341
365
TLS_last_allocation_error = UMF_RESULT_ERROR_UNKNOWN ;
@@ -360,7 +384,7 @@ static umf_result_t tbb_free(void *pool, void *ptr) {
360
384
utils_annotate_release (pool );
361
385
362
386
tbb_memory_pool_t * pool_data = (tbb_memory_pool_t * )pool ;
363
- if (pool_data -> tbb_callbacks .pool_free (pool_data -> tbb_pool , ptr )) {
387
+ if (tbb_callbacks .pool_free (pool_data -> tbb_pool , ptr )) {
364
388
return UMF_RESULT_SUCCESS ;
365
389
}
366
390
@@ -373,7 +397,7 @@ static umf_result_t tbb_free(void *pool, void *ptr) {
373
397
374
398
static size_t tbb_malloc_usable_size (void * pool , void * ptr ) {
375
399
tbb_memory_pool_t * pool_data = (tbb_memory_pool_t * )pool ;
376
- return pool_data -> tbb_callbacks .pool_msize (pool_data -> tbb_pool , ptr );
400
+ return tbb_callbacks .pool_msize (pool_data -> tbb_pool , ptr );
377
401
}
378
402
379
403
static umf_result_t tbb_get_last_allocation_error (void * pool ) {
0 commit comments