@@ -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,50 +395,62 @@ 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 ;
401
404
uintptr_t last_key = 0 ;
402
405
406
+ int in_proxy_lib = utils_is_running_in_proxy_lib ();
407
+
403
408
while (1 == critnib_find ((critnib * )hTracker -> map , last_key , FIND_G , & rkey ,
404
409
& rvalue )) {
405
410
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 ;
408
414
}
409
415
410
- last_key = rkey ;
411
- }
416
+ n_items ++ ;
412
417
413
- if (n_items ) {
414
- // Do not assert if we are running in the proxy library,
418
+ // Do not clear the tracker if we are running in the proxy library,
415
419
// because it may need those resources till
416
420
// 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
- }
421
+ if (!in_proxy_lib ) {
422
+ void * removed_value = critnib_remove (hTracker -> map , rkey );
423
+ assert (removed_value == rvalue );
424
+ umf_ba_free (hTracker -> tracker_allocator , removed_value );
427
425
}
426
+
427
+ last_key = rkey ;
428
428
}
429
+
430
+ #ifndef NDEBUG
431
+ if (n_items && !in_proxy_lib && !upstreamDoesNotFree ) {
432
+ if (pool ) {
433
+ LOG_ERR (
434
+ "tracking provider of pool %p is not empty! (%zu items left)" ,
435
+ (void * )pool , n_items );
436
+ } else {
437
+ LOG_ERR ("tracking provider is not empty! (%zu items left)" ,
438
+ n_items );
439
+ }
440
+ }
441
+ #else /* DEBUG */
442
+ (void )upstreamDoesNotFree ; // unused in DEBUG build
443
+ (void )n_items ; // unused in DEBUG build
444
+ #endif /* DEBUG */
429
445
}
430
- #endif /* NDEBUG */
431
446
432
447
static void trackingFinalize (void * provider ) {
433
448
umf_tracking_memory_provider_t * p =
434
449
(umf_tracking_memory_provider_t * )provider ;
450
+
435
451
critnib_delete (p -> ipcCache );
436
- #ifndef NDEBUG
437
- check_if_tracker_is_empty (p -> hTracker , p -> pool );
438
- #endif /* NDEBUG */
452
+
453
+ clear_tracker_for_the_pool (p -> hTracker , p -> pool , p -> upstreamDoesNotFree );
439
454
440
455
umf_ba_global_free (provider );
441
456
}
@@ -661,10 +676,11 @@ umf_memory_provider_ops_t UMF_TRACKING_MEMORY_PROVIDER_OPS = {
661
676
662
677
umf_result_t umfTrackingMemoryProviderCreate (
663
678
umf_memory_provider_handle_t hUpstream , umf_memory_pool_handle_t hPool ,
664
- umf_memory_provider_handle_t * hTrackingProvider ) {
679
+ umf_memory_provider_handle_t * hTrackingProvider , bool upstreamDoesNotFree ) {
665
680
666
681
umf_tracking_memory_provider_t params ;
667
682
params .hUpstream = hUpstream ;
683
+ params .upstreamDoesNotFree = upstreamDoesNotFree ;
668
684
params .hTracker = TRACKER ;
669
685
if (!params .hTracker ) {
670
686
LOG_ERR ("failed, TRACKER is NULL" );
@@ -746,9 +762,7 @@ void umfMemoryTrackerDestroy(umf_memory_tracker_handle_t handle) {
746
762
return ;
747
763
}
748
764
749
- #ifndef NDEBUG
750
- check_if_tracker_is_empty (handle , NULL );
751
- #endif /* NDEBUG */
765
+ clear_tracker_for_the_pool (handle , NULL , false);
752
766
753
767
// We have to zero all inner pointers,
754
768
// because the tracker handle can be copied
0 commit comments