@@ -590,17 +590,6 @@ static umf_result_t trackingAllocationMerge(void *hProvider, void *lowPtr,
590
590
umf_tracking_memory_provider_t * provider =
591
591
(umf_tracking_memory_provider_t * )hProvider ;
592
592
593
- tracker_alloc_info_t * mergedValue =
594
- umf_ba_alloc (provider -> hTracker -> alloc_info_allocator );
595
-
596
- if (!mergedValue ) {
597
- return UMF_RESULT_ERROR_OUT_OF_HOST_MEMORY ;
598
- }
599
-
600
- mergedValue -> pool = provider -> pool ;
601
- mergedValue -> size = totalSize ;
602
- mergedValue -> n_children = 0 ;
603
-
604
593
// any different negative values
605
594
int lowLevel = -2 ;
606
595
int highLevel = -1 ;
@@ -611,87 +600,83 @@ static umf_result_t trackingAllocationMerge(void *hProvider, void *lowPtr,
611
600
}
612
601
613
602
tracker_alloc_info_t * lowValue = get_most_nested_alloc_segment (
614
- provider -> hTracker , lowPtr , & lowLevel , NULL , NULL ,
615
- 0 /* no_children */ ); // can have children
603
+ provider -> hTracker , lowPtr , & lowLevel , NULL , NULL , 0 /* no_children */ );
616
604
if (!lowValue ) {
617
605
LOG_FATAL ("no left value" );
618
606
ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
619
- goto err_assert ;
607
+ goto err_fatal ;
620
608
}
621
- tracker_alloc_info_t * highValue = get_most_nested_alloc_segment (
622
- provider -> hTracker , highPtr , & highLevel , NULL , NULL ,
623
- 0 /* no_children */ ); // can have children
609
+ if (lowValue -> n_children ) {
610
+ LOG_FATAL ("left value is used (has children)" );
611
+ ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
612
+ goto err_fatal ;
613
+ }
614
+
615
+ tracker_alloc_info_t * highValue =
616
+ get_most_nested_alloc_segment (provider -> hTracker , highPtr , & highLevel ,
617
+ NULL , NULL , 0 /* no_children */ );
624
618
if (!highValue ) {
625
619
LOG_FATAL ("no right value" );
626
620
ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
627
- goto err_assert ;
621
+ goto err_fatal ;
622
+ }
623
+ if (highValue -> n_children ) {
624
+ LOG_FATAL ("right value is used (has children)" );
625
+ ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
626
+ goto err_fatal ;
628
627
}
628
+
629
629
if (lowLevel != highLevel ) {
630
630
LOG_FATAL ("tracker level mismatch" );
631
631
ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
632
- goto err_assert ;
632
+ goto err_fatal ;
633
633
}
634
634
if (lowValue -> pool != highValue -> pool ) {
635
635
LOG_FATAL ("pool mismatch" );
636
636
ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
637
- goto err_assert ;
637
+ goto err_fatal ;
638
638
}
639
639
if (lowValue -> size + highValue -> size != totalSize ) {
640
640
LOG_FATAL ("lowValue->size + highValue->size != totalSize" );
641
641
ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
642
- goto err_assert ;
642
+ goto err_fatal ;
643
643
}
644
644
645
- mergedValue -> n_children = lowValue -> n_children + highValue -> n_children ;
646
-
647
645
ret = umfMemoryProviderAllocationMerge (provider -> hUpstream , lowPtr , highPtr ,
648
646
totalSize );
649
647
if (ret != UMF_RESULT_SUCCESS ) {
650
648
LOG_WARN ("upstream provider failed to merge regions" );
651
- goto not_merged ;
649
+ goto cannot_merge ;
652
650
}
653
651
654
- size_t lno = lowValue -> n_children ;
655
- size_t hno = highValue -> n_children ;
656
-
657
- // We'll have a duplicate entry for the range [highPtr, highValue->size] but this is fine,
658
- // the value is the same anyway and we forbid removing that range concurrently
659
- int cret =
660
- critnib_insert (provider -> hTracker -> alloc_segments_map [lowLevel ],
661
- (uintptr_t )lowPtr , (void * )mergedValue , 1 /* update */ );
662
- // this cannot fail since we know the element exists (nothing to allocate)
663
- assert (cret == 0 );
664
- (void )cret ;
665
-
666
- // free old value that we just replaced with mergedValue
667
- umf_ba_free (provider -> hTracker -> alloc_info_allocator , lowValue );
652
+ // we only need to update the size of the first part
653
+ utils_atomic_store_release_u64 ((uint64_t * )& lowValue -> size , totalSize );
668
654
669
655
void * erasedhighValue = critnib_remove (
670
656
provider -> hTracker -> alloc_segments_map [highLevel ], (uintptr_t )highPtr );
671
657
assert (erasedhighValue == highValue );
672
-
673
- umf_ba_free (provider -> hTracker -> alloc_info_allocator , erasedhighValue );
658
+ (void )erasedhighValue ; // unused in the Release build
674
659
675
660
utils_mutex_unlock (& provider -> hTracker -> splitMergeMutex );
676
661
677
662
LOG_DEBUG ("merged memory regions (level=%i): lowPtr=%p (child=%zu), "
678
663
"highPtr=%p (child=%zu), totalSize=%zu" ,
679
- lowLevel , lowPtr , lno , highPtr , hno , totalSize );
664
+ lowLevel , lowPtr , lowValue -> n_children , highPtr ,
665
+ highValue -> n_children , totalSize );
666
+
667
+ umf_ba_free (provider -> hTracker -> alloc_info_allocator , highValue );
680
668
681
669
return UMF_RESULT_SUCCESS ;
682
670
683
- err_assert :
671
+ err_fatal :
684
672
LOG_FATAL ("failed to merge memory regions: lowPtr=%p (level=%i), "
685
673
"highPtr=%p (level=%i), totalSize=%zu" ,
686
674
lowPtr , lowLevel , highPtr , highLevel , totalSize );
687
- assert (0 );
688
675
689
- not_merged :
676
+ cannot_merge :
690
677
utils_mutex_unlock (& provider -> hTracker -> splitMergeMutex );
691
678
692
679
err_lock :
693
- umf_ba_free (provider -> hTracker -> alloc_info_allocator , mergedValue );
694
-
695
680
LOG_ERR ("failed to merge memory regions: lowPtr=%p (level=%i), highPtr=%p "
696
681
"(level=%i), totalSize=%zu" ,
697
682
lowPtr , lowLevel , highPtr , highLevel , totalSize );
0 commit comments