@@ -608,17 +608,6 @@ static umf_result_t trackingAllocationMerge(void *hProvider, void *lowPtr,
608608 umf_tracking_memory_provider_t * provider =
609609 (umf_tracking_memory_provider_t * )hProvider ;
610610
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-
622611 // any different negative values
623612 int lowLevel = -2 ;
624613 int highLevel = -1 ;
@@ -629,87 +618,83 @@ static umf_result_t trackingAllocationMerge(void *hProvider, void *lowPtr,
629618 }
630619
631620 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 */ );
634622 if (!lowValue ) {
635623 LOG_FATAL ("no left value" );
636624 ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
637- goto err_assert ;
625+ goto err_fatal ;
638626 }
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 */ );
642636 if (!highValue ) {
643637 LOG_FATAL ("no right value" );
644638 ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
645- goto err_assert ;
639+ goto err_fatal ;
646640 }
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+
647647 if (lowLevel != highLevel ) {
648648 LOG_FATAL ("tracker level mismatch" );
649649 ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
650- goto err_assert ;
650+ goto err_fatal ;
651651 }
652652 if (lowValue -> pool != highValue -> pool ) {
653653 LOG_FATAL ("pool mismatch" );
654654 ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
655- goto err_assert ;
655+ goto err_fatal ;
656656 }
657657 if (lowValue -> size + highValue -> size != totalSize ) {
658658 LOG_FATAL ("lowValue->size + highValue->size != totalSize" );
659659 ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
660- goto err_assert ;
660+ goto err_fatal ;
661661 }
662662
663- mergedValue -> n_children = lowValue -> n_children + highValue -> n_children ;
664-
665663 ret = umfMemoryProviderAllocationMerge (provider -> hUpstream , lowPtr , highPtr ,
666664 totalSize );
667665 if (ret != UMF_RESULT_SUCCESS ) {
668666 LOG_WARN ("upstream provider failed to merge regions" );
669- goto not_merged ;
667+ goto cannot_merge ;
670668 }
671669
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 );
686672
687673 void * erasedhighValue = critnib_remove (
688674 provider -> hTracker -> alloc_segments_map [highLevel ], (uintptr_t )highPtr );
689675 assert (erasedhighValue == highValue );
690-
691- umf_ba_free (provider -> hTracker -> alloc_info_allocator , erasedhighValue );
676+ (void )erasedhighValue ; // unused in the Release build
692677
693678 utils_mutex_unlock (& provider -> hTracker -> splitMergeMutex );
694679
695680 LOG_DEBUG ("merged memory regions (level=%i): lowPtr=%p (child=%zu), "
696681 "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 );
698686
699687 return UMF_RESULT_SUCCESS ;
700688
701- err_assert :
689+ err_fatal :
702690 LOG_FATAL ("failed to merge memory regions: lowPtr=%p (level=%i), "
703691 "highPtr=%p (level=%i), totalSize=%zu" ,
704692 lowPtr , lowLevel , highPtr , highLevel , totalSize );
705- assert (0 );
706693
707- not_merged :
694+ cannot_merge :
708695 utils_mutex_unlock (& provider -> hTracker -> splitMergeMutex );
709696
710697err_lock :
711- umf_ba_free (provider -> hTracker -> alloc_info_allocator , mergedValue );
712-
713698 LOG_ERR ("failed to merge memory regions: lowPtr=%p (level=%i), highPtr=%p "
714699 "(level=%i), totalSize=%zu" ,
715700 lowPtr , lowLevel , highPtr , highLevel , totalSize );
0 commit comments