11/*
22 *
3- * Copyright (C) 2023-2024 Intel Corporation
3+ * Copyright (C) 2023-2025 Intel Corporation
44 *
55 * Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
66 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -47,6 +47,7 @@ typedef struct umf_scalable_pool_params_t {
4747} umf_scalable_pool_params_t ;
4848
4949typedef struct tbb_callbacks_t {
50+ int initialized ;
5051 void * (* pool_malloc )(void * , size_t );
5152 void * (* pool_realloc )(void * , void * , size_t );
5253 void * (* pool_aligned_malloc )(void * , size_t , size_t );
@@ -63,10 +64,11 @@ typedef struct tbb_callbacks_t {
6364#endif
6465} tbb_callbacks_t ;
6566
67+ static tbb_callbacks_t tbb_callbacks = {0 };
68+
6669typedef struct tbb_memory_pool_t {
6770 umf_memory_provider_handle_t mem_provider ;
6871 void * tbb_pool ;
69- tbb_callbacks_t tbb_callbacks ;
7072} tbb_memory_pool_t ;
7173
7274typedef enum tbb_enums_t {
@@ -109,42 +111,46 @@ static const char *tbb_symbol[TBB_POOL_SYMBOLS_MAX] = {
109111#endif
110112};
111113
112- static int init_tbb_callbacks (tbb_callbacks_t * tbb_callbacks ) {
113- assert (tbb_callbacks );
114-
114+ static int init_tbb_callbacks () {
115115 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 ) {
118- LOG_ERR ("%s required by Scalable Pool not found - install TBB malloc "
116+ if (tbb_callbacks .initialized < 1 ) {
117+ tbb_callbacks .lib_handle = utils_open_library (lib_name , 0 );
118+ if (!tbb_callbacks .lib_handle ) {
119+ LOG_ERR (
120+ "%s required by Scalable Pool not found - install TBB malloc "
119121 "or make sure it is in the default search paths." ,
120122 lib_name );
121- return -1 ;
123+ return -1 ;
124+ }
125+ * (void * * )& tbb_callbacks .pool_malloc = utils_get_symbol_addr (
126+ tbb_callbacks .lib_handle , tbb_symbol [TBB_POOL_MALLOC ], lib_name );
127+ * (void * * )& tbb_callbacks .pool_realloc = utils_get_symbol_addr (
128+ tbb_callbacks .lib_handle , tbb_symbol [TBB_POOL_REALLOC ], lib_name );
129+ * (void * * )& tbb_callbacks .pool_aligned_malloc = utils_get_symbol_addr (
130+ tbb_callbacks .lib_handle , tbb_symbol [TBB_POOL_ALIGNED_MALLOC ],
131+ lib_name );
132+ * (void * * )& tbb_callbacks .pool_free = utils_get_symbol_addr (
133+ tbb_callbacks .lib_handle , tbb_symbol [TBB_POOL_FREE ], lib_name );
134+ * (void * * )& tbb_callbacks .pool_create_v1 = utils_get_symbol_addr (
135+ tbb_callbacks .lib_handle , tbb_symbol [TBB_POOL_CREATE_V1 ], lib_name );
136+ * (void * * )& tbb_callbacks .pool_destroy = utils_get_symbol_addr (
137+ tbb_callbacks .lib_handle , tbb_symbol [TBB_POOL_DESTROY ], lib_name );
138+ * (void * * )& tbb_callbacks .pool_identify = utils_get_symbol_addr (
139+ tbb_callbacks .lib_handle , tbb_symbol [TBB_POOL_IDENTIFY ], lib_name );
140+ * (void * * )& tbb_callbacks .pool_msize = utils_get_symbol_addr (
141+ tbb_callbacks .lib_handle , tbb_symbol [TBB_POOL_MSIZE ], lib_name );
122142 }
143+ tbb_callbacks .initialized ++ ;
123144
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 ,
130- 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 ) {
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 ) {
146149 LOG_ERR ("Could not find symbols in %s" , lib_name );
147- utils_close_library (tbb_callbacks -> lib_handle );
150+ if (utils_close_library (tbb_callbacks .lib_handle ) == 0 ) {
151+ tbb_callbacks .initialized -- ;
152+ }
153+
148154 return -1 ;
149155 }
150156
@@ -264,15 +270,15 @@ static umf_result_t tbb_pool_initialize(umf_memory_provider_handle_t provider,
264270 return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY ;
265271 }
266272
267- int ret = init_tbb_callbacks (& pool_data -> tbb_callbacks );
273+ int ret = init_tbb_callbacks ();
268274 if (ret != 0 ) {
269275 LOG_ERR ("loading TBB symbols failed" );
270276 return UMF_RESULT_ERROR_UNKNOWN ;
271277 }
272278
273279 pool_data -> mem_provider = provider ;
274- ret = pool_data -> tbb_callbacks .pool_create_v1 ((intptr_t )pool_data , & policy ,
275- & (pool_data -> tbb_pool ));
280+ ret = tbb_callbacks .pool_create_v1 ((intptr_t )pool_data , & policy ,
281+ & (pool_data -> tbb_pool ));
276282 if (ret != 0 /* TBBMALLOC_OK */ ) {
277283 return UMF_RESULT_ERROR_MEMORY_PROVIDER_SPECIFIC ;
278284 }
@@ -284,15 +290,22 @@ static umf_result_t tbb_pool_initialize(umf_memory_provider_handle_t provider,
284290
285291static void tbb_pool_finalize (void * pool ) {
286292 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 );
293+ tbb_callbacks .pool_destroy (pool_data -> tbb_pool );
294+
295+ if (tbb_callbacks .initialized <= 1 ) {
296+ if (utils_close_library (tbb_callbacks .lib_handle )) {
297+ LOG_ERR ("Could not close TBB lib handler %p" ,
298+ tbb_callbacks .lib_handle );
299+ }
300+ }
301+ tbb_callbacks .initialized -- ;
289302 umf_ba_global_free (pool_data );
290303}
291304
292305static void * tbb_malloc (void * pool , size_t size ) {
293306 tbb_memory_pool_t * pool_data = (tbb_memory_pool_t * )pool ;
294307 TLS_last_allocation_error = UMF_RESULT_SUCCESS ;
295- void * ptr = pool_data -> tbb_callbacks .pool_malloc (pool_data -> tbb_pool , size );
308+ void * ptr = tbb_callbacks .pool_malloc (pool_data -> tbb_pool , size );
296309 if (ptr == NULL ) {
297310 if (TLS_last_allocation_error == UMF_RESULT_SUCCESS ) {
298311 TLS_last_allocation_error = UMF_RESULT_ERROR_UNKNOWN ;
@@ -319,8 +332,7 @@ static void *tbb_calloc(void *pool, size_t num, size_t size) {
319332static void * tbb_realloc (void * pool , void * ptr , size_t size ) {
320333 tbb_memory_pool_t * pool_data = (tbb_memory_pool_t * )pool ;
321334 TLS_last_allocation_error = UMF_RESULT_SUCCESS ;
322- void * new_ptr =
323- pool_data -> tbb_callbacks .pool_realloc (pool_data -> tbb_pool , ptr , size );
335+ void * new_ptr = tbb_callbacks .pool_realloc (pool_data -> tbb_pool , ptr , size );
324336 if (new_ptr == NULL ) {
325337 if (TLS_last_allocation_error == UMF_RESULT_SUCCESS ) {
326338 TLS_last_allocation_error = UMF_RESULT_ERROR_UNKNOWN ;
@@ -334,8 +346,8 @@ static void *tbb_realloc(void *pool, void *ptr, size_t size) {
334346static void * tbb_aligned_malloc (void * pool , size_t size , size_t alignment ) {
335347 tbb_memory_pool_t * pool_data = (tbb_memory_pool_t * )pool ;
336348 TLS_last_allocation_error = UMF_RESULT_SUCCESS ;
337- void * ptr = pool_data -> tbb_callbacks . pool_aligned_malloc (
338- pool_data -> tbb_pool , size , alignment );
349+ void * ptr =
350+ tbb_callbacks . pool_aligned_malloc ( pool_data -> tbb_pool , size , alignment );
339351 if (ptr == NULL ) {
340352 if (TLS_last_allocation_error == UMF_RESULT_SUCCESS ) {
341353 TLS_last_allocation_error = UMF_RESULT_ERROR_UNKNOWN ;
@@ -360,7 +372,7 @@ static umf_result_t tbb_free(void *pool, void *ptr) {
360372 utils_annotate_release (pool );
361373
362374 tbb_memory_pool_t * pool_data = (tbb_memory_pool_t * )pool ;
363- if (pool_data -> tbb_callbacks .pool_free (pool_data -> tbb_pool , ptr )) {
375+ if (tbb_callbacks .pool_free (pool_data -> tbb_pool , ptr )) {
364376 return UMF_RESULT_SUCCESS ;
365377 }
366378
@@ -373,7 +385,7 @@ static umf_result_t tbb_free(void *pool, void *ptr) {
373385
374386static size_t tbb_malloc_usable_size (void * pool , void * ptr ) {
375387 tbb_memory_pool_t * pool_data = (tbb_memory_pool_t * )pool ;
376- return pool_data -> tbb_callbacks .pool_msize (pool_data -> tbb_pool , ptr );
388+ return tbb_callbacks .pool_msize (pool_data -> tbb_pool , ptr );
377389}
378390
379391static umf_result_t tbb_get_last_allocation_error (void * pool ) {
0 commit comments