Skip to content

Commit 67600e0

Browse files
committed
free even more state for exited threads
1 parent 7c7fd1e commit 67600e0

File tree

3 files changed

+40
-11
lines changed

3 files changed

+40
-11
lines changed

src/gc-stacks.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,8 @@ void sweep_stack_pools(void)
203203
assert(gc_n_threads);
204204
for (int i = 0; i < gc_n_threads; i++) {
205205
jl_ptls_t ptls2 = gc_all_tls_states[i];
206+
if (ptls2 == NULL)
207+
continue;
206208

207209
// free half of stacks that remain unused since last sweep
208210
for (int p = 0; p < JL_N_STACK_POOLS; p++) {
@@ -227,6 +229,9 @@ void sweep_stack_pools(void)
227229
small_arraylist_free(al);
228230
}
229231
}
232+
if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) {
233+
small_arraylist_free(ptls2->heap.free_stacks);
234+
}
230235

231236
small_arraylist_t *live_tasks = &ptls2->heap.live_tasks;
232237
size_t n = 0;

src/gc.c

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1655,6 +1655,18 @@ void gc_free_pages(void)
16551655
}
16561656
}
16571657

1658+
void gc_move_to_global_page_pool(jl_gc_page_stack_t *pgstack)
1659+
{
1660+
while (1) {
1661+
jl_gc_pagemeta_t *pg = pop_lf_back(pgstack);
1662+
if (pg == NULL) {
1663+
break;
1664+
}
1665+
jl_gc_free_page(pg);
1666+
push_lf_back(&global_page_pool_freed, pg);
1667+
}
1668+
}
1669+
16581670
// setup the data-structures for a sweep over all memory pools
16591671
static void gc_sweep_pool(void)
16601672
{
@@ -1667,7 +1679,7 @@ static void gc_sweep_pool(void)
16671679

16681680
// allocate enough space to hold the end of the free list chain
16691681
// for every thread and pool size
1670-
jl_taggedvalue_t ***pfl = (jl_taggedvalue_t ***) alloca(n_threads * JL_GC_N_POOLS * sizeof(jl_taggedvalue_t**));
1682+
jl_taggedvalue_t ***pfl = (jl_taggedvalue_t ***) malloc(n_threads * JL_GC_N_POOLS * sizeof(jl_taggedvalue_t**));
16711683

16721684
// update metadata of pages that were pointed to by freelist or newpages from a pool
16731685
// i.e. pages being the current allocation target
@@ -1709,7 +1721,7 @@ static void gc_sweep_pool(void)
17091721
}
17101722

17111723
// the actual sweeping
1712-
jl_gc_page_stack_t *tmp = (jl_gc_page_stack_t *)alloca(n_threads * sizeof(jl_gc_page_stack_t));
1724+
jl_gc_page_stack_t *tmp = (jl_gc_page_stack_t *)malloc(n_threads * sizeof(jl_gc_page_stack_t));
17131725
memset(tmp, 0, n_threads * sizeof(jl_gc_page_stack_t));
17141726
jl_atomic_store(&gc_allocd_scratch, tmp);
17151727
gc_sweep_wake_all();
@@ -1726,6 +1738,7 @@ static void gc_sweep_pool(void)
17261738
}
17271739
}
17281740
}
1741+
free(tmp);
17291742

17301743
// merge free lists
17311744
for (int t_i = 0; t_i < n_threads; t_i++) {
@@ -1756,6 +1769,7 @@ static void gc_sweep_pool(void)
17561769
}
17571770
}
17581771
}
1772+
free(pfl);
17591773

17601774
#ifdef _P64 // only enable concurrent sweeping on 64bit
17611775
// wake thread up to sweep concurrently
@@ -2980,11 +2994,13 @@ void gc_mark_clean_reclaim_sets(void)
29802994
// Clean up `reclaim-sets`
29812995
for (int i = 0; i < gc_n_threads; i++) {
29822996
jl_ptls_t ptls2 = gc_all_tls_states[i];
2983-
arraylist_t *reclaim_set2 = &ptls2->mark_queue.reclaim_set;
2984-
ws_array_t *a = NULL;
2985-
while ((a = (ws_array_t *)arraylist_pop(reclaim_set2)) != NULL) {
2986-
free(a->buffer);
2987-
free(a);
2997+
if (ptls2 != NULL) {
2998+
arraylist_t *reclaim_set2 = &ptls2->mark_queue.reclaim_set;
2999+
ws_array_t *a = NULL;
3000+
while ((a = (ws_array_t *)arraylist_pop(reclaim_set2)) != NULL) {
3001+
free(a->buffer);
3002+
free(a);
3003+
}
29883004
}
29893005
}
29903006
}
@@ -3500,7 +3516,7 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
35003516
ptls2->heap.remset->len = 0;
35013517
}
35023518
// free empty GC state for threads that have exited
3503-
if (ptls2->current_task == NULL) {
3519+
if (jl_atomic_load_relaxed(&ptls2->current_task) == NULL) {
35043520
jl_thread_heap_t *heap = &ptls2->heap;
35053521
if (heap->weak_refs.len == 0)
35063522
small_arraylist_free(&heap->weak_refs);
@@ -3511,9 +3527,14 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
35113527
if (heap->last_remset->len == 0)
35123528
arraylist_free(heap->last_remset);
35133529
if (ptls2->finalizers.len == 0)
3514-
arraylist_free(&ptls->finalizers);
3530+
arraylist_free(&ptls2->finalizers);
35153531
if (ptls2->sweep_objs.len == 0)
3516-
arraylist_free(&ptls->sweep_objs);
3532+
arraylist_free(&ptls2->sweep_objs);
3533+
gc_move_to_global_page_pool(&ptls2->page_metadata_buffered);
3534+
if (ptls2->page_metadata_allocd.bottom == NULL) {
3535+
free(ptls2);
3536+
gc_all_tls_states[t_i] = NULL;
3537+
}
35173538
}
35183539
}
35193540

src/threading.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,8 @@ JL_DLLEXPORT jl_gcframe_t **jl_adopt_thread(void)
435435

436436
void jl_task_frame_noreturn(jl_task_t *ct) JL_NOTSAFEPOINT;
437437

438+
void jl_free_thread_gc_state(jl_ptls_t ptls);
439+
438440
static void jl_delete_thread(void *value) JL_NOTSAFEPOINT_ENTER
439441
{
440442
#ifndef _OS_WINDOWS_
@@ -511,9 +513,10 @@ static void jl_delete_thread(void *value) JL_NOTSAFEPOINT_ENTER
511513
pthread_mutex_unlock(&in_signal_lock);
512514
#endif
513515
free(ptls->bt_data);
516+
small_arraylist_free(&ptls->locks);
517+
ptls->previous_exception = NULL;
514518
// allow the page root_task is on to be freed
515519
ptls->root_task = NULL;
516-
void jl_free_thread_gc_state(jl_ptls_t ptls);
517520
jl_free_thread_gc_state(ptls);
518521
// then park in safe-region
519522
(void)jl_gc_safe_enter(ptls);

0 commit comments

Comments
 (0)