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