@@ -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,11 @@ 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+ // TODO clearing the tracker is a temporary solution and should be removed.
399+ // The tracker should be cleared using the provider's free() operation.
400+ static void clear_tracker_for_the_pool (umf_memory_tracker_handle_t hTracker ,
401+ umf_memory_pool_handle_t pool ,
402+ bool upstreamDoesNotFree ) {
398403 uintptr_t rkey ;
399404 void * rvalue ;
400405 size_t n_items = 0 ;
@@ -403,39 +408,55 @@ static void check_if_tracker_is_empty(umf_memory_tracker_handle_t hTracker,
403408 while (1 == critnib_find ((critnib * )hTracker -> map , last_key , FIND_G , & rkey ,
404409 & rvalue )) {
405410 tracker_value_t * value = (tracker_value_t * )rvalue ;
406- if (value -> pool == pool || pool == NULL ) {
407- n_items ++ ;
411+ if (value -> pool != pool && pool != NULL ) {
412+ last_key = rkey ;
413+ continue ;
408414 }
409415
416+ n_items ++ ;
417+
418+ void * removed_value = critnib_remove (hTracker -> map , rkey );
419+ assert (removed_value == rvalue );
420+ umf_ba_free (hTracker -> tracker_allocator , removed_value );
421+
410422 last_key = rkey ;
411423 }
412424
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- }
425+ #ifndef NDEBUG
426+ // print error messages only if provider supports the free() operation
427+ if (n_items && !upstreamDoesNotFree ) {
428+ if (pool ) {
429+ LOG_ERR (
430+ "tracking provider of pool %p is not empty! (%zu items left)" ,
431+ (void * )pool , n_items );
432+ } else {
433+ LOG_ERR ("tracking provider is not empty! (%zu items left)" ,
434+ n_items );
427435 }
428436 }
437+ #else /* DEBUG */
438+ (void )upstreamDoesNotFree ; // unused in DEBUG build
439+ (void )n_items ; // unused in DEBUG build
440+ #endif /* DEBUG */
441+ }
442+
443+ static void clear_tracker (umf_memory_tracker_handle_t hTracker ) {
444+ clear_tracker_for_the_pool (hTracker , NULL , false);
429445}
430- #endif /* NDEBUG */
431446
432447static void trackingFinalize (void * provider ) {
433448 umf_tracking_memory_provider_t * p =
434449 (umf_tracking_memory_provider_t * )provider ;
450+
435451 critnib_delete (p -> ipcCache );
436- #ifndef NDEBUG
437- check_if_tracker_is_empty (p -> hTracker , p -> pool );
438- #endif /* NDEBUG */
452+
453+ // Do not clear the tracker if we are running in the proxy library,
454+ // because it may need those resources till
455+ // the very end of exiting the application.
456+ if (!utils_is_running_in_proxy_lib ()) {
457+ clear_tracker_for_the_pool (p -> hTracker , p -> pool ,
458+ p -> upstreamDoesNotFree );
459+ }
439460
440461 umf_ba_global_free (provider );
441462}
@@ -661,10 +682,11 @@ umf_memory_provider_ops_t UMF_TRACKING_MEMORY_PROVIDER_OPS = {
661682
662683umf_result_t umfTrackingMemoryProviderCreate (
663684 umf_memory_provider_handle_t hUpstream , umf_memory_pool_handle_t hPool ,
664- umf_memory_provider_handle_t * hTrackingProvider ) {
685+ umf_memory_provider_handle_t * hTrackingProvider , bool upstreamDoesNotFree ) {
665686
666687 umf_tracking_memory_provider_t params ;
667688 params .hUpstream = hUpstream ;
689+ params .upstreamDoesNotFree = upstreamDoesNotFree ;
668690 params .hTracker = TRACKER ;
669691 if (!params .hTracker ) {
670692 LOG_ERR ("failed, TRACKER is NULL" );
@@ -739,16 +761,14 @@ void umfMemoryTrackerDestroy(umf_memory_tracker_handle_t handle) {
739761 return ;
740762 }
741763
742- // Do not destroy if we are running in the proxy library,
764+ // Do not destroy the tracket if we are running in the proxy library,
743765 // because it may need those resources till
744766 // the very end of exiting the application.
745767 if (utils_is_running_in_proxy_lib ()) {
746768 return ;
747769 }
748770
749- #ifndef NDEBUG
750- check_if_tracker_is_empty (handle , NULL );
751- #endif /* NDEBUG */
771+ clear_tracker (handle );
752772
753773 // We have to zero all inner pointers,
754774 // because the tracker handle can be copied
0 commit comments