From 7d8cba067334107c26ec7455c18bbd5543a3f1d6 Mon Sep 17 00:00:00 2001 From: Julian P Samaroo Date: Fri, 17 Dec 2021 14:10:04 -0600 Subject: [PATCH] Add USDTs for task switch and allocation --- contrib/bpftrace/rt_all.bt | 21 +++++++++++++++++++++ doc/src/devdocs/probes.md | 7 ++++++- src/julia_internal.h | 6 ++++++ src/task.c | 5 +++++ src/uprobes.d | 4 ++++ 5 files changed, 42 insertions(+), 1 deletion(-) create mode 100755 contrib/bpftrace/rt_all.bt diff --git a/contrib/bpftrace/rt_all.bt b/contrib/bpftrace/rt_all.bt new file mode 100755 index 0000000000000..0bba03e45cee3 --- /dev/null +++ b/contrib/bpftrace/rt_all.bt @@ -0,0 +1,21 @@ +#!/usr/bin/env bpftrace + +BEGIN +{ + printf("Tracing Julia Task events... Hit Ctrl-C to end.\n"); +} + +usdt:usr/lib/libjulia-internal.so:julia:rt__run__task +{ + printf("Task running: %x (with PTLS %x)\n", arg0, arg1); +} + +usdt:usr/lib/libjulia-internal.so:julia:rt__pause__task +{ + printf("Task pausing: %x (with PTLS %x)\n", arg0, arg1); +} + +usdt:usr/lib/libjulia-internal.so:julia:rt__new__task +{ + printf("Task created: %x (Parent %x) (with PTLS %x)\n", arg1, arg0, arg2); +} diff --git a/doc/src/devdocs/probes.md b/doc/src/devdocs/probes.md index 7e2fb96df5ac8..83e63bdb621ce 100644 --- a/doc/src/devdocs/probes.md +++ b/doc/src/devdocs/probes.md @@ -90,10 +90,15 @@ the probe handler. 3. `julia:gc__mark__begin`: Beginning the mark phase 4. `julia:gc__mark_end(scanned_bytes, perm_scanned)`: Mark phase ended 5. `julia:gc__sweep_begin(full)`: Starting sweep -6. `julia:gc__sweep_end()`: Sweep phase finished +6. `julia:gc__sweep_end`: Sweep phase finished 7. `julia:gc__end`: GC is finished, other threads continue work 8. `julia:gc__finalizer`: Initial GC thread has finished running finalizers +### Task runtime probes + +1. `julia:rt__ctx__switch(last, next, ptls)`: Switching from task `last` to task `next` on thread associated with PTLS `ptls`. +2. `julia:rt__new__task(parent, child, ptls)`: Task `parent` created task `child` on thread associated with PTLS `ptls`. + #### GC stop-the-world latency An example `bpftrace` script is given in `contrib/gc_stop_the_world_latency.bt` diff --git a/src/julia_internal.h b/src/julia_internal.h index a8c289f14a145..930848d4eda47 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -1532,6 +1532,9 @@ uint16_t __gnu_f2h_ieee(float param) JL_NOTSAFEPOINT; #define JL_PROBE_GC_SWEEP_END() do ; while (0) #define JL_PROBE_GC_END() do ; while (0) #define JL_PROBE_GC_FINALIZER() do ; while (0) +#define JL_PROBE_RT_RUN_TASK(task, ptls) do ; while (0) +#define JL_PROBE_RT_PAUSE_TASK(task, ptls) do ; while (0) +#define JL_PROBE_RT_NEW_TASK(parent, child, ptls) do ; while (0) #define JL_PROBE_GC_BEGIN_ENABLED() (0) #define JL_PROBE_GC_STOP_THE_WORLD_ENABLED() (0) @@ -1541,6 +1544,9 @@ uint16_t __gnu_f2h_ieee(float param) JL_NOTSAFEPOINT; #define JL_PROBE_GC_SWEEP_END_ENABLED() (0) #define JL_PROBE_GC_END_ENABLED() (0) #define JL_PROBE_GC_FINALIZER_ENABLED() (0) +#define JL_PROBE_RT_RUN_TASK_ENABLED() (0) +#define JL_PROBE_RT_PAUSE_TASK_ENABLED() (0) +#define JL_PROBE_RT_NEW_TASK_ENABLED() (0) #endif #endif diff --git a/src/task.c b/src/task.c index 9f55b9b64a833..bbafc9b06679a 100644 --- a/src/task.c +++ b/src/task.c @@ -532,6 +532,8 @@ JL_DLLEXPORT void jl_switch(void) if (!jl_set_task_tid(t, jl_atomic_load_relaxed(&ct->tid))) // manually yielding to a task jl_error("cannot switch to task running on another thread"); + JL_PROBE_RT_PAUSE_TASK(ct, ptls); + // Store old values on the stack and reset sig_atomic_t defer_signal = ptls->defer_signal; int8_t gc_state = jl_gc_unsafe_enter(ptls); @@ -579,6 +581,8 @@ JL_DLLEXPORT void jl_switch(void) ptls->defer_signal = defer_signal; if (other_defer_signal && !defer_signal) jl_sigint_safepoint(ptls); + + JL_PROBE_RT_RUN_TASK(ct, ptls); } JL_DLLEXPORT void jl_switchto(jl_task_t **pt) @@ -753,6 +757,7 @@ JL_DLLEXPORT jl_task_t *jl_new_task(jl_function_t *start, jl_value_t *completion { jl_task_t *ct = jl_current_task; jl_task_t *t = (jl_task_t*)jl_gc_alloc(ct->ptls, sizeof(jl_task_t), jl_task_type); + JL_PROBE_RT_NEW_TASK(ct, t, ct->ptls); t->copy_stack = 0; if (ssize == 0) { // stack size unspecified; use default diff --git a/src/uprobes.d b/src/uprobes.d index a583daf8c58f4..d96ccbd99203c 100644 --- a/src/uprobes.d +++ b/src/uprobes.d @@ -9,6 +9,10 @@ provider julia { probe gc__sweep__end(); probe gc__end(); probe gc__finalizer(); + + probe rt__run__task(jl_task_t *task, jl_ptls_t ptls); + probe rt__pause__task(jl_task_t *task, jl_ptls_t ptls); + probe rt__new__task(jl_task_t *parent, jl_task_t *child, jl_ptls_t ptls); }; #pragma D attributes Evolving/Evolving/Common provider julia provider