@@ -1639,9 +1639,11 @@ void gc_sweep_wake_all(jl_ptls_t ptls, jl_gc_padded_page_stack_t *new_gc_allocd_
1639
1639
if (parallel_sweep_worthwhile && !page_profile_enabled ) {
1640
1640
jl_atomic_store (& gc_allocd_scratch , new_gc_allocd_scratch );
1641
1641
uv_mutex_lock (& gc_threads_lock );
1642
- for (int i = gc_first_tid ; i < gc_first_tid + jl_n_markthreads ; i ++ ) {
1642
+ int first = gc_first_parallel_collector_thread_id ();
1643
+ int last = gc_last_parallel_collector_thread_id ();
1644
+ for (int i = first ; i <= last ; i ++ ) {
1643
1645
jl_ptls_t ptls2 = gc_all_tls_states [i ];
1644
- assert (ptls2 != NULL ); // should be a GC thread
1646
+ gc_check_ptls_of_parallel_collector_thread (ptls2 );
1645
1647
jl_atomic_fetch_add (& ptls2 -> gc_sweeps_requested , 1 );
1646
1648
}
1647
1649
uv_cond_broadcast (& gc_threads_cond );
@@ -1653,9 +1655,11 @@ void gc_sweep_wake_all(jl_ptls_t ptls, jl_gc_padded_page_stack_t *new_gc_allocd_
1653
1655
// collecting a page profile.
1654
1656
// wait for all to leave in order to ensure that a straggler doesn't
1655
1657
// try to enter sweeping after we set `gc_allocd_scratch` below.
1656
- for (int i = gc_first_tid ; i < gc_first_tid + jl_n_markthreads ; i ++ ) {
1658
+ int first = gc_first_parallel_collector_thread_id ();
1659
+ int last = gc_last_parallel_collector_thread_id ();
1660
+ for (int i = first ; i <= last ; i ++ ) {
1657
1661
jl_ptls_t ptls2 = gc_all_tls_states [i ];
1658
- assert (ptls2 != NULL ); // should be a GC thread
1662
+ gc_check_ptls_of_parallel_collector_thread (ptls2 );
1659
1663
while (jl_atomic_load_acquire (& ptls2 -> gc_sweeps_requested ) != 0 ) {
1660
1664
jl_cpu_pause ();
1661
1665
}
@@ -3006,19 +3010,25 @@ void gc_mark_and_steal(jl_ptls_t ptls)
3006
3010
// since we know chunks will likely expand into a lot
3007
3011
// of work for the mark loop
3008
3012
steal : {
3013
+ int first = gc_first_parallel_collector_thread_id ();
3014
+ int last = gc_last_parallel_collector_thread_id ();
3009
3015
// Try to steal chunk from random GC thread
3010
3016
for (int i = 0 ; i < 4 * jl_n_markthreads ; i ++ ) {
3011
- uint32_t v = gc_first_tid + cong (UINT64_MAX , UINT64_MAX , & ptls -> rngseed ) % jl_n_markthreads ;
3012
- jl_gc_markqueue_t * mq2 = & gc_all_tls_states [v ]-> mark_queue ;
3017
+ int v = gc_random_parallel_collector_thread_id (ptls );
3018
+ jl_ptls_t ptls2 = gc_all_tls_states [v ];
3019
+ gc_check_ptls_of_parallel_collector_thread (ptls2 );
3020
+ jl_gc_markqueue_t * mq2 = & ptls2 -> mark_queue ;
3013
3021
c = gc_chunkqueue_steal_from (mq2 );
3014
3022
if (c .cid != GC_empty_chunk ) {
3015
3023
gc_mark_chunk (ptls , mq , & c );
3016
3024
goto pop ;
3017
3025
}
3018
3026
}
3019
3027
// Sequentially walk GC threads to try to steal chunk
3020
- for (int i = gc_first_tid ; i < gc_first_tid + jl_n_markthreads ; i ++ ) {
3021
- jl_gc_markqueue_t * mq2 = & gc_all_tls_states [i ]-> mark_queue ;
3028
+ for (int i = first ; i <= last ; i ++ ) {
3029
+ jl_ptls_t ptls2 = gc_all_tls_states [i ];
3030
+ gc_check_ptls_of_parallel_collector_thread (ptls2 );
3031
+ jl_gc_markqueue_t * mq2 = & ptls2 -> mark_queue ;
3022
3032
c = gc_chunkqueue_steal_from (mq2 );
3023
3033
if (c .cid != GC_empty_chunk ) {
3024
3034
gc_mark_chunk (ptls , mq , & c );
@@ -3035,15 +3045,19 @@ void gc_mark_and_steal(jl_ptls_t ptls)
3035
3045
}
3036
3046
// Try to steal pointer from random GC thread
3037
3047
for (int i = 0 ; i < 4 * jl_n_markthreads ; i ++ ) {
3038
- uint32_t v = gc_first_tid + cong (UINT64_MAX , UINT64_MAX , & ptls -> rngseed ) % jl_n_markthreads ;
3039
- jl_gc_markqueue_t * mq2 = & gc_all_tls_states [v ]-> mark_queue ;
3048
+ int v = gc_random_parallel_collector_thread_id (ptls );
3049
+ jl_ptls_t ptls2 = gc_all_tls_states [v ];
3050
+ gc_check_ptls_of_parallel_collector_thread (ptls2 );
3051
+ jl_gc_markqueue_t * mq2 = & ptls2 -> mark_queue ;
3040
3052
new_obj = gc_ptr_queue_steal_from (mq2 );
3041
3053
if (new_obj != NULL )
3042
3054
goto mark ;
3043
3055
}
3044
3056
// Sequentially walk GC threads to try to steal pointer
3045
- for (int i = gc_first_tid ; i < gc_first_tid + jl_n_markthreads ; i ++ ) {
3046
- jl_gc_markqueue_t * mq2 = & gc_all_tls_states [i ]-> mark_queue ;
3057
+ for (int i = first ; i <= last ; i ++ ) {
3058
+ jl_ptls_t ptls2 = gc_all_tls_states [i ];
3059
+ gc_check_ptls_of_parallel_collector_thread (ptls2 );
3060
+ jl_gc_markqueue_t * mq2 = & ptls2 -> mark_queue ;
3047
3061
new_obj = gc_ptr_queue_steal_from (mq2 );
3048
3062
if (new_obj != NULL )
3049
3063
goto mark ;
@@ -3103,12 +3117,13 @@ int gc_should_mark(void)
3103
3117
}
3104
3118
int tid = jl_atomic_load_relaxed (& gc_master_tid );
3105
3119
assert (tid != -1 );
3120
+ assert (gc_all_tls_states != NULL );
3106
3121
size_t work = gc_count_work_in_queue (gc_all_tls_states [tid ]);
3107
- for ( tid = gc_first_tid ; tid < gc_first_tid + jl_n_markthreads ; tid ++ ) {
3108
- jl_ptls_t ptls2 = gc_all_tls_states [ tid ] ;
3109
- if ( ptls2 == NULL ) {
3110
- continue ;
3111
- }
3122
+ int first = gc_first_parallel_collector_thread_id ();
3123
+ int last = gc_last_parallel_collector_thread_id () ;
3124
+ for ( int i = first ; i <= last ; i ++ ) {
3125
+ jl_ptls_t ptls2 = gc_all_tls_states [ i ] ;
3126
+ gc_check_ptls_of_parallel_collector_thread ( ptls2 );
3112
3127
work += gc_count_work_in_queue (ptls2 );
3113
3128
}
3114
3129
// if there is a lot of work left, enter the mark loop
@@ -3486,7 +3501,8 @@ static int _jl_gc_collect(jl_ptls_t ptls, jl_gc_collection_t collection)
3486
3501
jl_ptls_t ptls_dest = ptls ;
3487
3502
jl_gc_markqueue_t * mq_dest = mq ;
3488
3503
if (!single_threaded_mark ) {
3489
- ptls_dest = gc_all_tls_states [gc_first_tid + t_i % jl_n_markthreads ];
3504
+ int dest_tid = gc_ith_parallel_collector_thread_id (t_i % jl_n_markthreads );
3505
+ ptls_dest = gc_all_tls_states [dest_tid ];
3490
3506
mq_dest = & ptls_dest -> mark_queue ;
3491
3507
}
3492
3508
if (ptls2 != NULL ) {
0 commit comments