Skip to content

Commit c1f95b8

Browse files
authored
Merge pull request #1256 from ldorau/Simplify_and_improve_trackingAllocationMerge
Simplify and improve `trackingAllocationMerge()`
2 parents 6c576c1 + 8f255c1 commit c1f95b8

File tree

1 file changed

+31
-46
lines changed

1 file changed

+31
-46
lines changed

src/provider/provider_tracking.c

Lines changed: 31 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -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

692679
err_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

Comments
 (0)