Skip to content

Commit

Permalink
create separate function to spawn GC threads (JuliaLang#55108)
Browse files Browse the repository at this point in the history
Third-party GCs (e.g. MMTk) will probably have their own function to
spawn GC threads.
  • Loading branch information
d-netto committed Jul 25, 2024
1 parent 7ae4e32 commit 5f234f0
Show file tree
Hide file tree
Showing 6 changed files with 35 additions and 18 deletions.
20 changes: 20 additions & 0 deletions src/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3881,6 +3881,26 @@ void jl_init_thread_heap(jl_ptls_t ptls)
jl_atomic_store_relaxed(&ptls->gc_tls.gc_num.allocd, -(int64_t)gc_num.interval);
}

void jl_start_gc_threads(void)
{
int nthreads = jl_atomic_load_relaxed(&jl_n_threads);
int ngcthreads = jl_n_gcthreads;
int nmutator_threads = nthreads - ngcthreads;
uv_thread_t uvtid;
for (int i = nmutator_threads; i < nthreads; ++i) {
jl_threadarg_t *t = (jl_threadarg_t *)malloc_s(sizeof(jl_threadarg_t)); // ownership will be passed to the thread
t->tid = i;
t->barrier = &thread_init_done;
if (i == nthreads - 1 && jl_n_sweepthreads == 1) {
uv_thread_create(&uvtid, jl_concurrent_gc_threadfun, t);
}
else {
uv_thread_create(&uvtid, jl_parallel_gc_threadfun, t);
}
uv_thread_detach(&uvtid);
}
}

// System-wide initializations
void jl_gc_init(void)
{
Expand Down
1 change: 1 addition & 0 deletions src/gc.h
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,7 @@ extern uv_cond_t gc_threads_cond;
extern uv_sem_t gc_sweep_assists_needed;
extern _Atomic(int) gc_n_threads_marking;
extern _Atomic(int) gc_n_threads_sweeping;
extern uv_barrier_t thread_init_done;
void gc_mark_queue_all_roots(jl_ptls_t ptls, jl_gc_markqueue_t *mq);
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;
void gc_mark_finlist(jl_gc_markqueue_t *mq, arraylist_t *list, size_t start) JL_NOTSAFEPOINT;
Expand Down
2 changes: 2 additions & 0 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,8 @@ static NOINLINE void _finish_julia_init(JL_IMAGE_SEARCH rel, jl_ptls_t ptls, jl_
jl_n_threads_per_pool[1] = 0;
}
jl_start_threads();
jl_start_gc_threads();
uv_barrier_wait(&thread_init_done);

jl_init_heartbeat();

Expand Down
2 changes: 2 additions & 0 deletions src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -942,8 +942,10 @@ extern JL_DLLEXPORT ssize_t jl_tls_offset;
extern JL_DLLEXPORT const int jl_tls_elf_support;
void jl_init_threading(void);
void jl_start_threads(void);
void jl_start_gc_threads(void);

// Whether the GC is running
extern uv_mutex_t safepoint_lock;
extern char *jl_safepoint_pages;
STATIC_INLINE int jl_addr_is_safepoint(uintptr_t addr)
{
Expand Down
26 changes: 8 additions & 18 deletions src/threading.c
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@ void jl_init_threading(void)
gc_first_tid = nthreads + nthreadsi;
}

static uv_barrier_t thread_init_done;
uv_barrier_t thread_init_done;

void jl_start_threads(void)
{
Expand Down Expand Up @@ -751,30 +751,20 @@ void jl_start_threads(void)
uv_barrier_init(&thread_init_done, nthreads);

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

for (i = 1; i < nthreads; ++i) {
for (i = 1; i < nmutator_threads; ++i) {
jl_threadarg_t *t = (jl_threadarg_t *)malloc_s(sizeof(jl_threadarg_t)); // ownership will be passed to the thread
t->tid = i;
t->barrier = &thread_init_done;
if (i < nworker_threads) {
uv_thread_create(&uvtid, jl_threadfun, t);
if (exclusive) {
mask[i] = 1;
uv_thread_setaffinity(&uvtid, mask, NULL, cpumasksize);
mask[i] = 0;
}
}
else if (i == nthreads - 1 && jl_n_sweepthreads == 1) {
uv_thread_create(&uvtid, jl_concurrent_gc_threadfun, t);
}
else {
uv_thread_create(&uvtid, jl_parallel_gc_threadfun, t);
uv_thread_create(&uvtid, jl_threadfun, t);
if (exclusive) {
mask[i] = 1;
uv_thread_setaffinity(&uvtid, mask, NULL, cpumasksize);
mask[i] = 0;
}
uv_thread_detach(&uvtid);
}

uv_barrier_wait(&thread_init_done);
}

_Atomic(unsigned) _threadedregion; // HACK: keep track of whether to prioritize IO or threading
Expand Down
2 changes: 2 additions & 0 deletions src/threading.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ extern "C" {

#define PROFILE_JL_THREADING 0

extern uv_barrier_t thread_init_done;

extern _Atomic(jl_ptls_t*) jl_all_tls_states JL_GLOBALLY_ROOTED; /* thread local storage */

typedef struct _jl_threadarg_t {
Expand Down

0 comments on commit 5f234f0

Please sign in to comment.