Skip to content

Commit 7cb8d0e

Browse files
committed
all tasks profiler
1 parent 037dc51 commit 7cb8d0e

File tree

13 files changed

+377
-214
lines changed

13 files changed

+377
-214
lines changed

src/gc.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3927,7 +3927,6 @@ void jl_gc_init(void)
39273927
JL_MUTEX_INIT(&heapsnapshot_lock, "heapsnapshot_lock");
39283928
JL_MUTEX_INIT(&finalizers_lock, "finalizers_lock");
39293929
uv_mutex_init(&page_profile_lock);
3930-
uv_mutex_init(&gc_perm_lock);
39313930
uv_mutex_init(&gc_threads_lock);
39323931
uv_cond_init(&gc_threads_cond);
39333932
uv_sem_init(&gc_sweep_assists_needed, 0);

src/init.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,8 @@ static void init_global_mutexes(void) {
738738
JL_MUTEX_INIT(&typecache_lock, "typecache_lock");
739739
}
740740

741+
extern uv_mutex_t array_to_string_print_lock;
742+
741743
JL_DLLEXPORT void julia_init(JL_IMAGE_SEARCH rel)
742744
{
743745
// initialize many things, in no particular order
@@ -747,6 +749,10 @@ JL_DLLEXPORT void julia_init(JL_IMAGE_SEARCH rel)
747749
// Make sure we finalize the tls callback before starting any threads.
748750
(void)jl_get_pgcstack();
749751

752+
// Initialize a few locks...
753+
uv_mutex_init(&gc_perm_lock);
754+
uv_mutex_init(&array_to_string_print_lock);
755+
750756
// initialize backtraces
751757
jl_init_profile_lock();
752758
#ifdef _OS_WINDOWS_
@@ -773,6 +779,7 @@ JL_DLLEXPORT void julia_init(JL_IMAGE_SEARCH rel)
773779
jl_io_loop = uv_default_loop(); // this loop will internal events (spawning process etc.),
774780
// best to call this first, since it also initializes libuv
775781
jl_init_uv();
782+
jl_init_threading();
776783
init_stdio();
777784
restore_fp_env();
778785
if (jl_options.handle_signals == JL_OPTIONS_HANDLE_SIGNALS_ON)
@@ -818,7 +825,6 @@ JL_DLLEXPORT void julia_init(JL_IMAGE_SEARCH rel)
818825
jl_init_rand();
819826
jl_init_runtime_ccall();
820827
jl_init_tasks();
821-
jl_init_threading();
822828
jl_init_threadinginfra();
823829
if (jl_options.handle_signals == JL_OPTIONS_HANDLE_SIGNALS_ON)
824830
jl_install_default_signal_handlers();
@@ -855,8 +861,6 @@ JL_DLLEXPORT void julia_init(JL_IMAGE_SEARCH rel)
855861

856862
void jl_init_heartbeat(void);
857863

858-
extern uv_mutex_t array_to_string_print_lock;
859-
860864
static NOINLINE void _finish_julia_init(JL_IMAGE_SEARCH rel, jl_ptls_t ptls, jl_task_t *ct)
861865
{
862866
JL_TIMING(JULIA_INIT, JULIA_INIT);
@@ -892,8 +896,9 @@ static NOINLINE void _finish_julia_init(JL_IMAGE_SEARCH rel, jl_ptls_t ptls, jl_
892896
}
893897

894898
if (jl_base_module == NULL) {
895-
// nthreads > 1 requires code in Base
896-
jl_atomic_store_relaxed(&jl_n_threads, 1);
899+
const int num_min_mutator_threads = 1; // main thread
900+
// nthreads > num_min_mutator_threads requires code in Base
901+
jl_atomic_store_relaxed(&jl_n_threads, num_min_mutator_threads);
897902
jl_n_markthreads = 0;
898903
jl_n_sweepthreads = 0;
899904
jl_n_gcthreads = 0;
@@ -904,8 +909,6 @@ static NOINLINE void _finish_julia_init(JL_IMAGE_SEARCH rel, jl_ptls_t ptls, jl_
904909
jl_start_gc_threads();
905910
uv_barrier_wait(&thread_init_done);
906911

907-
uv_mutex_init(&array_to_string_print_lock);
908-
909912
jl_init_heartbeat();
910913

911914
jl_gc_enable(1);

src/julia_internal.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,14 @@ JL_DLLEXPORT void jl_unlock_profile_wr(void) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_LEA
206206
int jl_lock_stackwalk(void) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_ENTER;
207207
void jl_unlock_stackwalk(int lockret) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_LEAVE;
208208

209+
jl_task_t *jl_get_random_task(void) JL_NOTSAFEPOINT;
210+
void jl_rec_backtrace(jl_task_t *t) JL_NOTSAFEPOINT;
211+
extern volatile struct _jl_bt_element_t *bt_data_prof;
212+
extern volatile size_t bt_size_max;
213+
extern volatile size_t bt_size_cur;
214+
extern volatile int running;
215+
extern volatile int profile_all_tasks;
216+
209217
// number of cycles since power-on
210218
static inline uint64_t cycleclock(void) JL_NOTSAFEPOINT
211219
{

src/partr.c

Lines changed: 22 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,23 @@ JL_DLLEXPORT uint32_t jl_rand_ptls(uint32_t max, uint32_t unbias)
9090
return cong(max, -(uint64_t)-unbias, &ptls->rngseed);
9191
}
9292

93+
jl_ptls_t jl_threadfun_preamble(void *arg, uint8_t state)
94+
{
95+
jl_threadarg_t *targ = (jl_threadarg_t*)arg;
96+
// initialize this thread (set tid and create heap)
97+
jl_ptls_t ptls = jl_init_threadtls(targ->tid);
98+
void *stack_lo, *stack_hi;
99+
jl_init_stack_limits(0, &stack_lo, &stack_hi);
100+
// warning: this changes `jl_current_task`, so be careful not to call that from this function
101+
jl_task_t *ct = jl_init_root_task(ptls, stack_lo, stack_hi);
102+
JL_GC_PROMISE_ROOTED(ct);
103+
// wait for all threads
104+
jl_gc_state_set(ptls, state, 0);
105+
uv_barrier_wait(targ->barrier);
106+
free(targ);
107+
return ptls;
108+
}
109+
93110
// initialize the threading infrastructure
94111
// (called only by the main thread)
95112
void jl_init_threadinginfra(void)
@@ -123,19 +140,7 @@ void jl_parallel_gc_threadfun(void *arg)
123140
{
124141
jl_threadarg_t *targ = (jl_threadarg_t*)arg;
125142

126-
// initialize this thread (set tid and create heap)
127-
jl_ptls_t ptls = jl_init_threadtls(targ->tid);
128-
void *stack_lo, *stack_hi;
129-
jl_init_stack_limits(0, &stack_lo, &stack_hi);
130-
// warning: this changes `jl_current_task`, so be careful not to call that from this function
131-
jl_task_t *ct = jl_init_root_task(ptls, stack_lo, stack_hi);
132-
JL_GC_PROMISE_ROOTED(ct);
133-
// wait for all threads
134-
jl_gc_state_set(ptls, JL_GC_PARALLEL_COLLECTOR_THREAD, 0);
135-
uv_barrier_wait(targ->barrier);
136-
137-
// free the thread argument here
138-
free(targ);
143+
jl_ptls_t ptls = jl_threadfun_preamble(targ, JL_GC_PARALLEL_COLLECTOR_THREAD);
139144

140145
while (1) {
141146
uv_mutex_lock(&gc_threads_lock);
@@ -158,19 +163,8 @@ void jl_concurrent_gc_threadfun(void *arg)
158163
{
159164
jl_threadarg_t *targ = (jl_threadarg_t*)arg;
160165

161-
// initialize this thread (set tid and create heap)
162-
jl_ptls_t ptls = jl_init_threadtls(targ->tid);
163-
void *stack_lo, *stack_hi;
164-
jl_init_stack_limits(0, &stack_lo, &stack_hi);
165-
// warning: this changes `jl_current_task`, so be careful not to call that from this function
166-
jl_task_t *ct = jl_init_root_task(ptls, stack_lo, stack_hi);
167-
JL_GC_PROMISE_ROOTED(ct);
168-
// wait for all threads
169-
jl_gc_state_set(ptls, JL_GC_CONCURRENT_COLLECTOR_THREAD, 0);
170-
uv_barrier_wait(targ->barrier);
171-
172-
// free the thread argument here
173-
free(targ);
166+
jl_ptls_t ptls = jl_threadfun_preamble(targ, JL_GC_CONCURRENT_COLLECTOR_THREAD);
167+
(void)ptls;
174168

175169
while (1) {
176170
assert(jl_atomic_load_relaxed(&ptls->gc_state) == JL_GC_CONCURRENT_COLLECTOR_THREAD);
@@ -184,20 +178,8 @@ void jl_threadfun(void *arg)
184178
{
185179
jl_threadarg_t *targ = (jl_threadarg_t*)arg;
186180

187-
// initialize this thread (set tid, create heap, set up root task)
188-
jl_ptls_t ptls = jl_init_threadtls(targ->tid);
189-
void *stack_lo, *stack_hi;
190-
jl_init_stack_limits(0, &stack_lo, &stack_hi);
191-
// warning: this changes `jl_current_task`, so be careful not to call that from this function
192-
jl_task_t *ct = jl_init_root_task(ptls, stack_lo, stack_hi);
193-
JL_GC_PROMISE_ROOTED(ct);
194-
195-
// wait for all threads
196-
jl_gc_state_set(ptls, JL_GC_STATE_SAFE, 0);
197-
uv_barrier_wait(targ->barrier);
198-
199-
// free the thread argument here
200-
free(targ);
181+
jl_ptls_t ptls = jl_threadfun_preamble(targ, JL_GC_STATE_SAFE);
182+
jl_task_t *ct = jl_current_task;
201183

202184
(void)jl_gc_unsafe_enter(ptls);
203185
jl_finish_task(ct); // noreturn

src/signal-handling.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,16 @@ extern "C" {
1818
#include <threading.h>
1919

2020
// Profiler control variables
21-
// Note: these "static" variables are also used in "signals-*.c"
22-
static volatile jl_bt_element_t *bt_data_prof = NULL;
23-
static volatile size_t bt_size_max = 0;
24-
static volatile size_t bt_size_cur = 0;
21+
volatile jl_bt_element_t *bt_data_prof = NULL;
22+
volatile size_t bt_size_max = 0;
23+
volatile size_t bt_size_cur = 0;
2524
static volatile uint64_t nsecprof = 0;
26-
static volatile int running = 0;
27-
static const uint64_t GIGA = 1000000000ULL;
25+
volatile int running = 0;
26+
volatile int profile_all_tasks = 0;
27+
static const uint64_t GIGA = 1000000000ULL;
2828
// Timers to take samples at intervals
2929
JL_DLLEXPORT void jl_profile_stop_timer(void);
30-
JL_DLLEXPORT int jl_profile_start_timer(void);
30+
JL_DLLEXPORT int jl_profile_start_timer(uint8_t);
3131
// File-descriptor for safe logging on signal handling
3232
int jl_sig_fd;
3333

0 commit comments

Comments
 (0)