@@ -141,6 +141,9 @@ typedef struct umf_tracking_memory_provider_t {
141141 umf_memory_tracker_handle_t hTracker ;
142142 umf_memory_pool_handle_t pool ;
143143 critnib * ipcCache ;
144+
145+ // the upstream provider does not support the free() operation
146+ bool upstreamDoesNotFree ;
144147} umf_tracking_memory_provider_t ;
145148
146149typedef struct umf_tracking_memory_provider_t umf_tracking_memory_provider_t ;
@@ -392,9 +395,9 @@ static umf_result_t trackingInitialize(void *params, void **ret) {
392395 return UMF_RESULT_SUCCESS ;
393396}
394397
395- #ifndef NDEBUG
396- static void check_if_tracker_is_empty ( umf_memory_tracker_handle_t hTracker ,
397- umf_memory_pool_handle_t pool ) {
398+ static void clear_tracker_for_the_pool ( umf_memory_tracker_handle_t hTracker ,
399+ umf_memory_pool_handle_t pool ,
400+ bool upstreamDoesNotFree ) {
398401 uintptr_t rkey ;
399402 void * rvalue ;
400403 size_t n_items = 0 ;
@@ -403,39 +406,55 @@ static void check_if_tracker_is_empty(umf_memory_tracker_handle_t hTracker,
403406 while (1 == critnib_find ((critnib * )hTracker -> map , last_key , FIND_G , & rkey ,
404407 & rvalue )) {
405408 tracker_value_t * value = (tracker_value_t * )rvalue ;
406- if (value -> pool == pool || pool == NULL ) {
407- n_items ++ ;
409+ if (value -> pool != pool && pool != NULL ) {
410+ last_key = rkey ;
411+ continue ;
408412 }
409413
414+ n_items ++ ;
415+
416+ void * removed_value = critnib_remove (hTracker -> map , rkey );
417+ assert (removed_value == rvalue );
418+ umf_ba_free (hTracker -> tracker_allocator , removed_value );
419+
410420 last_key = rkey ;
411421 }
412422
413- if (n_items ) {
414- // Do not assert if we are running in the proxy library,
415- // because it may need those resources till
416- // the very end of exiting the application.
417- if (!utils_is_running_in_proxy_lib ()) {
418- if (pool ) {
419- LOG_ERR ("tracking provider of pool %p is not empty! "
420- "(%zu items left)" ,
421- (void * )pool , n_items );
422- } else {
423- LOG_ERR ("tracking provider is not empty! (%zu items "
424- "left)" ,
425- n_items );
426- }
423+ #ifndef NDEBUG
424+ // print error messages only if provider supports the free() operation
425+ if (n_items && !upstreamDoesNotFree ) {
426+ if (pool ) {
427+ LOG_ERR (
428+ "tracking provider of pool %p is not empty! (%zu items left)" ,
429+ (void * )pool , n_items );
430+ } else {
431+ LOG_ERR ("tracking provider is not empty! (%zu items left)" ,
432+ n_items );
427433 }
428434 }
435+ #else /* DEBUG */
436+ (void )upstreamDoesNotFree ; // unused in DEBUG build
437+ (void )n_items ; // unused in DEBUG build
438+ #endif /* DEBUG */
439+ }
440+
441+ static void clear_tracker (umf_memory_tracker_handle_t hTracker ) {
442+ clear_tracker_for_the_pool (hTracker , NULL , false);
429443}
430- #endif /* NDEBUG */
431444
432445static void trackingFinalize (void * provider ) {
433446 umf_tracking_memory_provider_t * p =
434447 (umf_tracking_memory_provider_t * )provider ;
448+
435449 critnib_delete (p -> ipcCache );
436- #ifndef NDEBUG
437- check_if_tracker_is_empty (p -> hTracker , p -> pool );
438- #endif /* NDEBUG */
450+
451+ // Do not clear the tracker if we are running in the proxy library,
452+ // because it may need those resources till
453+ // the very end of exiting the application.
454+ if (!utils_is_running_in_proxy_lib ()) {
455+ clear_tracker_for_the_pool (p -> hTracker , p -> pool ,
456+ p -> upstreamDoesNotFree );
457+ }
439458
440459 umf_ba_global_free (provider );
441460}
@@ -661,10 +680,11 @@ umf_memory_provider_ops_t UMF_TRACKING_MEMORY_PROVIDER_OPS = {
661680
662681umf_result_t umfTrackingMemoryProviderCreate (
663682 umf_memory_provider_handle_t hUpstream , umf_memory_pool_handle_t hPool ,
664- umf_memory_provider_handle_t * hTrackingProvider ) {
683+ umf_memory_provider_handle_t * hTrackingProvider , bool upstreamDoesNotFree ) {
665684
666685 umf_tracking_memory_provider_t params ;
667686 params .hUpstream = hUpstream ;
687+ params .upstreamDoesNotFree = upstreamDoesNotFree ;
668688 params .hTracker = TRACKER ;
669689 if (!params .hTracker ) {
670690 LOG_ERR ("failed, TRACKER is NULL" );
@@ -739,16 +759,14 @@ void umfMemoryTrackerDestroy(umf_memory_tracker_handle_t handle) {
739759 return ;
740760 }
741761
742- // Do not destroy if we are running in the proxy library,
762+ // Do not destroy the tracket if we are running in the proxy library,
743763 // because it may need those resources till
744764 // the very end of exiting the application.
745765 if (utils_is_running_in_proxy_lib ()) {
746766 return ;
747767 }
748768
749- #ifndef NDEBUG
750- check_if_tracker_is_empty (handle , NULL );
751- #endif /* NDEBUG */
769+ clear_tracker (handle );
752770
753771 // We have to zero all inner pointers,
754772 // because the tracker handle can be copied
0 commit comments