@@ -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,50 @@ 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+ if (n_items && !upstreamDoesNotFree ) {
425+ if (pool ) {
426+ LOG_ERR (
427+ "tracking provider of pool %p is not empty! (%zu items left)" ,
428+ (void * )pool , n_items );
429+ } else {
430+ LOG_ERR ("tracking provider is not empty! (%zu items left)" ,
431+ n_items );
427432 }
428433 }
434+ #else /* DEBUG */
435+ (void )upstreamDoesNotFree ; // unused in DEBUG build
436+ (void )n_items ; // unused in DEBUG build
437+ #endif /* DEBUG */
429438}
430- #endif /* NDEBUG */
431439
432440static void trackingFinalize (void * provider ) {
433441 umf_tracking_memory_provider_t * p =
434442 (umf_tracking_memory_provider_t * )provider ;
443+
435444 critnib_delete (p -> ipcCache );
436- #ifndef NDEBUG
437- check_if_tracker_is_empty (p -> hTracker , p -> pool );
438- #endif /* NDEBUG */
445+
446+ // Do not clear the tracker if we are running in the proxy library,
447+ // because it may need those resources till
448+ // the very end of exiting the application.
449+ if (!utils_is_running_in_proxy_lib ()) {
450+ clear_tracker_for_the_pool (p -> hTracker , p -> pool ,
451+ p -> upstreamDoesNotFree );
452+ }
439453
440454 umf_ba_global_free (provider );
441455}
@@ -661,10 +675,11 @@ umf_memory_provider_ops_t UMF_TRACKING_MEMORY_PROVIDER_OPS = {
661675
662676umf_result_t umfTrackingMemoryProviderCreate (
663677 umf_memory_provider_handle_t hUpstream , umf_memory_pool_handle_t hPool ,
664- umf_memory_provider_handle_t * hTrackingProvider ) {
678+ umf_memory_provider_handle_t * hTrackingProvider , bool upstreamDoesNotFree ) {
665679
666680 umf_tracking_memory_provider_t params ;
667681 params .hUpstream = hUpstream ;
682+ params .upstreamDoesNotFree = upstreamDoesNotFree ;
668683 params .hTracker = TRACKER ;
669684 if (!params .hTracker ) {
670685 LOG_ERR ("failed, TRACKER is NULL" );
@@ -746,9 +761,7 @@ void umfMemoryTrackerDestroy(umf_memory_tracker_handle_t handle) {
746761 return ;
747762 }
748763
749- #ifndef NDEBUG
750- check_if_tracker_is_empty (handle , NULL );
751- #endif /* NDEBUG */
764+ clear_tracker_for_the_pool (handle , NULL , false);
752765
753766 // We have to zero all inner pointers,
754767 // because the tracker handle can be copied
0 commit comments