Skip to content

Commit

Permalink
all tasks profiler
Browse files Browse the repository at this point in the history
  • Loading branch information
d-netto committed Oct 1, 2024
1 parent 8654a8a commit d48fd77
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 28 deletions.
6 changes: 5 additions & 1 deletion src/julia_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,13 +206,17 @@ JL_DLLEXPORT void jl_unlock_profile_wr(void) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_LEA
int jl_lock_stackwalk(void) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_ENTER;
void jl_unlock_stackwalk(int lockret) JL_NOTSAFEPOINT JL_NOTSAFEPOINT_LEAVE;

arraylist_t jl_get_all_tasks_arraylist(void) JL_NOTSAFEPOINT;
arraylist_t *jl_get_all_tasks_arraylist(void) JL_NOTSAFEPOINT;
int jl_rec_backtrace(jl_task_t *t) JL_NOTSAFEPOINT;
extern volatile struct _jl_bt_element_t *profile_bt_data_prof;
extern volatile size_t profile_bt_size_max;
extern volatile size_t profile_bt_size_cur;
extern volatile int profile_running;
extern volatile int profile_all_tasks;
STATIC_INLINE int all_tasks_profile_running(void) JL_NOTSAFEPOINT
{
return profile_running && profile_all_tasks;
}

// number of cycles since power-on
static inline uint64_t cycleclock(void) JL_NOTSAFEPOINT
Expand Down
7 changes: 4 additions & 3 deletions src/signals-unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -724,11 +724,11 @@ void jl_profile_task_unix(void)
// Get a random task for which we know that we won't
// drop a sample in the profiler
// TODO(Diogo, Nick): should we put an upper bound on the number of iterations?
arraylist_t tasks = jl_get_all_tasks_arraylist();
arraylist_t *tasks = jl_get_all_tasks_arraylist();
jl_task_t *t = NULL;
uint64_t seed = jl_rand();
while (1) {
t = tasks.items[cong(tasks.len, UINT64_MAX, &seed)];
t = tasks->items[cong(tasks->len, UINT64_MAX, &seed)];
assert(t == NULL || jl_is_task(t));
if (t == NULL) {
continue;
Expand All @@ -739,7 +739,8 @@ void jl_profile_task_unix(void)
}
break;
}
arraylist_free(&tasks);
arraylist_free(tasks);
free(tasks);
assert(t != NULL);

int tid = jl_rec_backtrace(t);
Expand Down
18 changes: 9 additions & 9 deletions src/signals-win.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ static DWORD WINAPI profile_bt( LPVOID lparam )
while (1) {
DWORD timeout_ms = nsecprof / (GIGA / 1000);
Sleep(timeout_ms > 0 ? timeout_ms : 1);
if (running) {
if (profile_running) {
if (jl_profile_is_buffer_full()) {
jl_profile_stop_timer(); // does not change the thread state
SuspendThread(GetCurrentThread());
Expand All @@ -420,16 +420,16 @@ static DWORD WINAPI profile_bt( LPVOID lparam )

jl_ptls_t ptls = jl_atomic_load_relaxed(&jl_all_tls_states)[0]; // given only profiling hMainThread

// store threadid but add 1 as 0 is preserved to indicate end of block
// META_OFFSET_THREADID store threadid but add 1 as 0 is preserved to indicate end of block
profile_bt_data_prof[profile_bt_size_cur++].uintptr = ptls->tid + 1;

// store task id (never null)
// META_OFFSET_TASKID store task id (never null)
profile_bt_data_prof[profile_bt_size_cur++].jlvalue = (jl_value_t*)jl_atomic_load_relaxed(&ptls->current_task);

// store cpu cycle clock
// META_OFFSET_CPUCYCLECLOCK store cpu cycle clock
profile_bt_data_prof[profile_bt_size_cur++].uintptr = cycleclock();

// store whether thread is sleeping but add 1 as 0 is preserved to indicate end of block
// META_OFFSET_SLEEPSTATE store whether thread is sleeping but add 1 as 0 is preserved to indicate end of block
profile_bt_data_prof[profile_bt_size_cur++].uintptr = jl_atomic_load_relaxed(&ptls->sleep_check_state) + 1;

// Mark the end of this block with two 0's
Expand Down Expand Up @@ -477,21 +477,21 @@ JL_DLLEXPORT int jl_profile_start_timer(uint8_t all_tasks)
return -2;
}
}
if (running == 0) {
if (profile_running == 0) {
// Failure to change the timer resolution is not fatal. However, it is important to
// ensure that the timeBeginPeriod/timeEndPeriod is paired.
if (TIMERR_NOERROR != timeBeginPeriod(timecaps.wPeriodMin))
timecaps.wPeriodMin = 0;
}
profile_all_tasks = all_tasks;
running = 1; // set `running` finally
profile_running = 1; // set `profile_running` finally
return 0;
}
JL_DLLEXPORT void jl_profile_stop_timer(void)
{
if (running && timecaps.wPeriodMin)
if (profile_running && timecaps.wPeriodMin)
timeEndPeriod(timecaps.wPeriodMin);
running = 0;
profile_running = 0;
profile_all_tasks = 0;
}

Expand Down
10 changes: 2 additions & 8 deletions src/stackwalk.c
Original file line number Diff line number Diff line change
Expand Up @@ -867,20 +867,14 @@ _os_ptr_munge(uintptr_t ptr)
#define _OS_PTR_UNMUNGE(_ptr) _os_ptr_munge((uintptr_t)(_ptr))
#endif


STATIC_INLINE int all_tasks_profile_running(void)
{
return profile_running && profile_all_tasks;
}

int jl_rec_backtrace(jl_task_t *t) JL_NOTSAFEPOINT
{
jl_task_t *ct = NULL;
jl_ptls_t ptls = NULL;
int16_t tid = INT16_MAX;
if (!all_tasks_profile_running()) {
jl_task_t *ct = jl_current_task;
jl_ptls_t ptls = ct->ptls;
ct = jl_current_task;
ptls = ct->ptls;
ptls->bt_size = 0;
tid = ptls->tid;
}
Expand Down
12 changes: 5 additions & 7 deletions src/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -1116,12 +1116,11 @@ JL_DLLEXPORT jl_task_t *jl_get_current_task(void)
}

extern int gc_first_tid;

// Select a task at random to profile. Racy: `live_tasks` can change at any time.
arraylist_t jl_get_all_tasks_arraylist(void) JL_NOTSAFEPOINT
arraylist_t *jl_get_all_tasks_arraylist(void) JL_NOTSAFEPOINT
{
arraylist_t tasks;
arraylist_new(&tasks, 0);
arraylist_t *tasks = (arraylist_t*)malloc_s(sizeof(arraylist_t));
arraylist_new(tasks, 0);
size_t nthreads = jl_atomic_load_acquire(&jl_n_threads);
jl_ptls_t *allstates = jl_atomic_load_relaxed(&jl_all_tls_states);
for (size_t i = 0; i < nthreads; i++) {
Expand All @@ -1135,21 +1134,20 @@ arraylist_t jl_get_all_tasks_arraylist(void) JL_NOTSAFEPOINT
}
jl_task_t *t = ptls2->root_task;
if (t->stkbuf != NULL) {
arraylist_push(&tasks, t);
arraylist_push(tasks, t);
}
small_arraylist_t *live_tasks = &ptls2->gc_tls.heap.live_tasks;
size_t n = mtarraylist_length(live_tasks);
for (size_t i = 0; i < n; i++) {
jl_task_t *t = (jl_task_t*)mtarraylist_get(live_tasks, i);
if (t->stkbuf != NULL) {
arraylist_push(&tasks, t);
arraylist_push(tasks, t);
}
}
}
return tasks;
}


#ifdef JL_HAVE_ASYNCIFY
JL_DLLEXPORT jl_ucontext_t *task_ctx_ptr(jl_task_t *t)
{
Expand Down

0 comments on commit d48fd77

Please sign in to comment.