@@ -141,6 +141,9 @@ typedef struct umf_tracking_memory_provider_t {
141
141
umf_memory_tracker_handle_t hTracker ;
142
142
umf_memory_pool_handle_t pool ;
143
143
critnib * ipcCache ;
144
+
145
+ // the upstream provider does not support the free() operation
146
+ bool upstreamDoesNotFree ;
144
147
} umf_tracking_memory_provider_t ;
145
148
146
149
typedef struct umf_tracking_memory_provider_t umf_tracking_memory_provider_t ;
@@ -392,9 +395,9 @@ static umf_result_t trackingInitialize(void *params, void **ret) {
392
395
return UMF_RESULT_SUCCESS ;
393
396
}
394
397
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 ) {
398
401
uintptr_t rkey ;
399
402
void * rvalue ;
400
403
size_t n_items = 0 ;
@@ -403,39 +406,50 @@ static void check_if_tracker_is_empty(umf_memory_tracker_handle_t hTracker,
403
406
while (1 == critnib_find ((critnib * )hTracker -> map , last_key , FIND_G , & rkey ,
404
407
& rvalue )) {
405
408
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 ;
408
412
}
409
413
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
+
410
420
last_key = rkey ;
411
421
}
412
422
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 );
427
432
}
428
433
}
434
+ #else /* DEBUG */
435
+ (void )upstreamDoesNotFree ; // unused in DEBUG build
436
+ (void )n_items ; // unused in DEBUG build
437
+ #endif /* DEBUG */
429
438
}
430
- #endif /* NDEBUG */
431
439
432
440
static void trackingFinalize (void * provider ) {
433
441
umf_tracking_memory_provider_t * p =
434
442
(umf_tracking_memory_provider_t * )provider ;
443
+
435
444
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
+ }
439
453
440
454
umf_ba_global_free (provider );
441
455
}
@@ -661,10 +675,11 @@ umf_memory_provider_ops_t UMF_TRACKING_MEMORY_PROVIDER_OPS = {
661
675
662
676
umf_result_t umfTrackingMemoryProviderCreate (
663
677
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 ) {
665
679
666
680
umf_tracking_memory_provider_t params ;
667
681
params .hUpstream = hUpstream ;
682
+ params .upstreamDoesNotFree = upstreamDoesNotFree ;
668
683
params .hTracker = TRACKER ;
669
684
if (!params .hTracker ) {
670
685
LOG_ERR ("failed, TRACKER is NULL" );
@@ -746,9 +761,7 @@ void umfMemoryTrackerDestroy(umf_memory_tracker_handle_t handle) {
746
761
return ;
747
762
}
748
763
749
- #ifndef NDEBUG
750
- check_if_tracker_is_empty (handle , NULL );
751
- #endif /* NDEBUG */
764
+ clear_tracker_for_the_pool (handle , NULL , false);
752
765
753
766
// We have to zero all inner pointers,
754
767
// because the tracker handle can be copied
0 commit comments