@@ -590,17 +590,6 @@ static umf_result_t trackingAllocationMerge(void *hProvider, void *lowPtr,
590590 umf_tracking_memory_provider_t * provider =
591591 (umf_tracking_memory_provider_t * )hProvider ;
592592
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-
604593 // any different negative values
605594 int lowLevel = -2 ;
606595 int highLevel = -1 ;
@@ -611,87 +600,83 @@ static umf_result_t trackingAllocationMerge(void *hProvider, void *lowPtr,
611600 }
612601
613602 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 */ );
616604 if (!lowValue ) {
617605 LOG_FATAL ("no left value" );
618606 ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
619- goto err_assert ;
607+ goto err_fatal ;
620608 }
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 */ );
624618 if (!highValue ) {
625619 LOG_FATAL ("no right value" );
626620 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 ;
628627 }
628+
629629 if (lowLevel != highLevel ) {
630630 LOG_FATAL ("tracker level mismatch" );
631631 ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
632- goto err_assert ;
632+ goto err_fatal ;
633633 }
634634 if (lowValue -> pool != highValue -> pool ) {
635635 LOG_FATAL ("pool mismatch" );
636636 ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
637- goto err_assert ;
637+ goto err_fatal ;
638638 }
639639 if (lowValue -> size + highValue -> size != totalSize ) {
640640 LOG_FATAL ("lowValue->size + highValue->size != totalSize" );
641641 ret = UMF_RESULT_ERROR_INVALID_ARGUMENT ;
642- goto err_assert ;
642+ goto err_fatal ;
643643 }
644644
645- mergedValue -> n_children = lowValue -> n_children + highValue -> n_children ;
646-
647645 ret = umfMemoryProviderAllocationMerge (provider -> hUpstream , lowPtr , highPtr ,
648646 totalSize );
649647 if (ret != UMF_RESULT_SUCCESS ) {
650648 LOG_WARN ("upstream provider failed to merge regions" );
651- goto not_merged ;
649+ goto cannot_merge ;
652650 }
653651
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 );
668654
669655 void * erasedhighValue = critnib_remove (
670656 provider -> hTracker -> alloc_segments_map [highLevel ], (uintptr_t )highPtr );
671657 assert (erasedhighValue == highValue );
672-
673- umf_ba_free (provider -> hTracker -> alloc_info_allocator , erasedhighValue );
658+ (void )erasedhighValue ; // unused in the Release build
674659
675660 utils_mutex_unlock (& provider -> hTracker -> splitMergeMutex );
676661
677662 LOG_DEBUG ("merged memory regions (level=%i): lowPtr=%p (child=%zu), "
678663 "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 );
680668
681669 return UMF_RESULT_SUCCESS ;
682670
683- err_assert :
671+ err_fatal :
684672 LOG_FATAL ("failed to merge memory regions: lowPtr=%p (level=%i), "
685673 "highPtr=%p (level=%i), totalSize=%zu" ,
686674 lowPtr , lowLevel , highPtr , highLevel , totalSize );
687- assert (0 );
688675
689- not_merged :
676+ cannot_merge :
690677 utils_mutex_unlock (& provider -> hTracker -> splitMergeMutex );
691678
692679err_lock :
693- umf_ba_free (provider -> hTracker -> alloc_info_allocator , mergedValue );
694-
695680 LOG_ERR ("failed to merge memory regions: lowPtr=%p (level=%i), highPtr=%p "
696681 "(level=%i), totalSize=%zu" ,
697682 lowPtr , lowLevel , highPtr , highLevel , totalSize );
0 commit comments