Skip to content

Commit 5f234f0

Browse files
committed
create separate function to spawn GC threads (JuliaLang#55108)
Third-party GCs (e.g. MMTk) will probably have their own function to spawn GC threads.
1 parent 7ae4e32 commit 5f234f0

File tree

6 files changed

+35
-18
lines changed

6 files changed

+35
-18
lines changed

src/gc.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3881,6 +3881,26 @@ void jl_init_thread_heap(jl_ptls_t ptls)
38813881
jl_atomic_store_relaxed(&ptls->gc_tls.gc_num.allocd, -(int64_t)gc_num.interval);
38823882
}
38833883

3884+
void jl_start_gc_threads(void)
3885+
{
3886+
int nthreads = jl_atomic_load_relaxed(&jl_n_threads);
3887+
int ngcthreads = jl_n_gcthreads;
3888+
int nmutator_threads = nthreads - ngcthreads;
3889+
uv_thread_t uvtid;
3890+
for (int i = nmutator_threads; i < nthreads; ++i) {
3891+
jl_threadarg_t *t = (jl_threadarg_t *)malloc_s(sizeof(jl_threadarg_t)); // ownership will be passed to the thread
3892+
t->tid = i;
3893+
t->barrier = &thread_init_done;
3894+
if (i == nthreads - 1 && jl_n_sweepthreads == 1) {
3895+
uv_thread_create(&uvtid, jl_concurrent_gc_threadfun, t);
3896+
}
3897+
else {
3898+
uv_thread_create(&uvtid, jl_parallel_gc_threadfun, t);
3899+
}
3900+
uv_thread_detach(&uvtid);
3901+
}
3902+
}
3903+
38843904
// System-wide initializations
38853905
void jl_gc_init(void)
38863906
{

src/gc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,7 @@ extern uv_cond_t gc_threads_cond;
562562
extern uv_sem_t gc_sweep_assists_needed;
563563
extern _Atomic(int) gc_n_threads_marking;
564564
extern _Atomic(int) gc_n_threads_sweeping;
565+
extern uv_barrier_t thread_init_done;
565566
void gc_mark_queue_all_roots(jl_ptls_t ptls, jl_gc_markqueue_t *mq);
566567
void gc_mark_finlist_(jl_gc_markqueue_t *mq, jl_value_t *fl_parent, jl_value_t **fl_begin, jl_value_t **fl_end) JL_NOTSAFEPOINT;
567568
void gc_mark_finlist(jl_gc_markqueue_t *mq, arraylist_t *list, size_t start) JL_NOTSAFEPOINT;

src/init.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,8 @@ static NOINLINE void _finish_julia_init(JL_IMAGE_SEARCH rel, jl_ptls_t ptls, jl_
899899
jl_n_threads_per_pool[1] = 0;
900900
}
901901
jl_start_threads();
902+
jl_start_gc_threads();
903+
uv_barrier_wait(&thread_init_done);
902904

903905
jl_init_heartbeat();
904906

src/julia_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,8 +942,10 @@ extern JL_DLLEXPORT ssize_t jl_tls_offset;
942942
extern JL_DLLEXPORT const int jl_tls_elf_support;
943943
void jl_init_threading(void);
944944
void jl_start_threads(void);
945+
void jl_start_gc_threads(void);
945946

946947
// Whether the GC is running
948+
extern uv_mutex_t safepoint_lock;
947949
extern char *jl_safepoint_pages;
948950
STATIC_INLINE int jl_addr_is_safepoint(uintptr_t addr)
949951
{

src/threading.c

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,7 @@ void jl_init_threading(void)
712712
gc_first_tid = nthreads + nthreadsi;
713713
}
714714

715-
static uv_barrier_t thread_init_done;
715+
uv_barrier_t thread_init_done;
716716

717717
void jl_start_threads(void)
718718
{
@@ -751,30 +751,20 @@ void jl_start_threads(void)
751751
uv_barrier_init(&thread_init_done, nthreads);
752752

753753
// GC/System threads need to be after the worker threads.
754-
int nworker_threads = nthreads - ngcthreads;
754+
int nmutator_threads = nthreads - ngcthreads;
755755

756-
for (i = 1; i < nthreads; ++i) {
756+
for (i = 1; i < nmutator_threads; ++i) {
757757
jl_threadarg_t *t = (jl_threadarg_t *)malloc_s(sizeof(jl_threadarg_t)); // ownership will be passed to the thread
758758
t->tid = i;
759759
t->barrier = &thread_init_done;
760-
if (i < nworker_threads) {
761-
uv_thread_create(&uvtid, jl_threadfun, t);
762-
if (exclusive) {
763-
mask[i] = 1;
764-
uv_thread_setaffinity(&uvtid, mask, NULL, cpumasksize);
765-
mask[i] = 0;
766-
}
767-
}
768-
else if (i == nthreads - 1 && jl_n_sweepthreads == 1) {
769-
uv_thread_create(&uvtid, jl_concurrent_gc_threadfun, t);
770-
}
771-
else {
772-
uv_thread_create(&uvtid, jl_parallel_gc_threadfun, t);
760+
uv_thread_create(&uvtid, jl_threadfun, t);
761+
if (exclusive) {
762+
mask[i] = 1;
763+
uv_thread_setaffinity(&uvtid, mask, NULL, cpumasksize);
764+
mask[i] = 0;
773765
}
774766
uv_thread_detach(&uvtid);
775767
}
776-
777-
uv_barrier_wait(&thread_init_done);
778768
}
779769

780770
_Atomic(unsigned) _threadedregion; // HACK: keep track of whether to prioritize IO or threading

src/threading.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ extern "C" {
1212

1313
#define PROFILE_JL_THREADING 0
1414

15+
extern uv_barrier_t thread_init_done;
16+
1517
extern _Atomic(jl_ptls_t*) jl_all_tls_states JL_GLOBALLY_ROOTED; /* thread local storage */
1618

1719
typedef struct _jl_threadarg_t {

0 commit comments

Comments
 (0)