merge from dev-abandon

This commit is contained in:
daanx 2024-02-29 18:34:50 -08:00
commit f57c9e16bd
3 changed files with 15 additions and 8 deletions

View File

@ -404,10 +404,14 @@ static mi_decl_noinline void _mi_free_block_mt(mi_page_t* page, mi_block_t* bloc
// first see if the segment was abandoned and we can reclaim it
mi_segment_t* const segment = _mi_page_segment(page);
if (mi_option_is_enabled(mi_option_abandoned_reclaim_on_free) &&
#if MI_HUGE_PAGE_ABANDON
segment->page_kind != MI_PAGE_HUGE &&
#endif
mi_atomic_load_relaxed(&segment->thread_id) == 0)
{
// the segment is abandoned, try to reclaim it into our heap
if (_mi_segment_attempt_reclaim(mi_prim_get_default_heap(), segment)) {
mi_heap_t* heap = mi_heap_get_default();
if (heap->tld != NULL && _mi_segment_attempt_reclaim(heap, segment)) {
mi_assert_internal(_mi_prim_thread_id() == mi_atomic_load_relaxed(&segment->thread_id));
mi_free(block); // recursively free as now it will be a local free in our heap
return;
@ -419,7 +423,7 @@ static mi_decl_noinline void _mi_free_block_mt(mi_page_t* page, mi_block_t* bloc
mi_check_padding(page, block);
_mi_padding_shrink(page, block, sizeof(mi_block_t)); // for small size, ensure we can fit the delayed thread pointers without triggering overflow detection
// huge page segments are always abandoned and can be freed immediately
// huge page segments are always abandoned and can be freed immediately
if (segment->kind == MI_SEGMENT_HUGE) {
#if MI_HUGE_PAGE_ABANDON
// huge page segments are always abandoned and can be freed immediately

View File

@ -1226,8 +1226,9 @@ static mi_segment_t* mi_segment_reclaim(mi_segment_t* segment, mi_heap_t* heap,
bool _mi_segment_attempt_reclaim(mi_heap_t* heap, mi_segment_t* segment) {
if (mi_atomic_load_relaxed(&segment->thread_id) != 0) return false; // it is not abandoned
if (_mi_arena_segment_clear_abandoned(segment->memid)) { // atomically unabandon
mi_atomic_decrement_relaxed(&abandoned_count);
mi_segment_t* res = mi_segment_reclaim(segment, heap, 0, NULL, &heap->tld->segments);
mi_assert_internal(res != NULL);
mi_assert_internal(res == segment);
return (res != NULL);
}
return false;

View File

@ -301,13 +301,14 @@ static void run_os_threads(size_t nthreads, void (*fun)(intptr_t)) {
thread_entry_fun = fun;
DWORD* tids = (DWORD*)custom_calloc(nthreads,sizeof(DWORD));
HANDLE* thandles = (HANDLE*)custom_calloc(nthreads,sizeof(HANDLE));
for (uintptr_t i = 0; i < nthreads; i++) {
for (uintptr_t i = 1; i < nthreads; i++) {
thandles[i] = CreateThread(0, 8*1024, &thread_entry, (void*)(i), 0, &tids[i]);
}
for (size_t i = 0; i < nthreads; i++) {
fun(0); // run the main thread as well
for (size_t i = 1; i < nthreads; i++) {
WaitForSingleObject(thandles[i], INFINITE);
}
for (size_t i = 0; i < nthreads; i++) {
for (size_t i = 1; i < nthreads; i++) {
CloseHandle(thandles[i]);
}
custom_free(tids);
@ -335,10 +336,11 @@ static void run_os_threads(size_t nthreads, void (*fun)(intptr_t)) {
pthread_t* threads = (pthread_t*)custom_calloc(nthreads,sizeof(pthread_t));
memset(threads, 0, sizeof(pthread_t) * nthreads);
//pthread_setconcurrency(nthreads);
for (size_t i = 0; i < nthreads; i++) {
for (size_t i = 1; i < nthreads; i++) {
pthread_create(&threads[i], NULL, &thread_entry, (void*)i);
}
for (size_t i = 0; i < nthreads; i++) {
fun(0); // run the main thread as well
for (size_t i = 1; i < nthreads; i++) {
pthread_join(threads[i], NULL);
}
custom_free(threads);