Skip to content

Commit

Permalink
Profile: Minor fixes. Signal handling fix. (#44199)
Browse files Browse the repository at this point in the history
(cherry picked from commit 072c041)
  • Loading branch information
IanButterworth authored and KristofferC committed Feb 18, 2022
1 parent dfd7bb4 commit ed41f7c
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 15 deletions.
11 changes: 6 additions & 5 deletions src/signal-handling.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,22 +132,23 @@ static size_t jl_safe_read_mem(const volatile char *ptr, char *out, size_t len)
static double profile_autostop_time = -1.0;
static double profile_peek_duration = 1.0; // seconds

double jl_get_profile_peek_duration(void) {
double jl_get_profile_peek_duration(void)
{
return profile_peek_duration;
}
void jl_set_profile_peek_duration(double t) {
void jl_set_profile_peek_duration(double t)
{
profile_peek_duration = t;
return;
}

uintptr_t profile_show_peek_cond_loc;
JL_DLLEXPORT void jl_set_peek_cond(uintptr_t cond)
{
profile_show_peek_cond_loc = cond;
return;
}

static void jl_check_profile_autostop(void) {
static void jl_check_profile_autostop(void)
{
if ((profile_autostop_time != -1.0) && (jl_hrtime() > profile_autostop_time)) {
profile_autostop_time = -1.0;
jl_profile_stop_timer();
Expand Down
20 changes: 15 additions & 5 deletions src/signals-unix.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,9 +539,13 @@ JL_DLLEXPORT int jl_profile_start_timer(void)

JL_DLLEXPORT void jl_profile_stop_timer(void)
{
if (running)
if (running) {
timer_delete(timerprof);
running = 0;
// Because SIGUSR1 is multipurpose, care must be taken for running = 0 to be set after the timer has fully stopped.
// There may be a pending signal emitted from the timer so wait a few timer cycles
sleep_ms((nsecprof / GIGA) * 1000 * 3);
running = 0;
}
}

#elif defined(HAVE_ITIMER)
Expand All @@ -556,18 +560,24 @@ JL_DLLEXPORT int jl_profile_start_timer(void)
timerprof.it_interval.tv_usec = 0;
timerprof.it_value.tv_sec = nsecprof / GIGA;
timerprof.it_value.tv_usec = ((nsecprof % GIGA) + 999) / 1000;
if (setitimer(ITIMER_PROF, &timerprof, NULL) == -1)
return -3;
// Because SIGUSR1 is multipurpose, set `running` before so that we know that the first SIGUSR1 came from the timer
running = 1;
if (setitimer(ITIMER_PROF, &timerprof, NULL) == -1) {
running = 0;
return -3;
}
return 0;
}

JL_DLLEXPORT void jl_profile_stop_timer(void)
{
if (running) {
running = 0;
memset(&timerprof, 0, sizeof(timerprof));
setitimer(ITIMER_PROF, &timerprof, NULL);
// Because SIGUSR1 is multipurpose, care must be taken for running = 0 to be set after the timer has fully stopped.
// There may be a pending signal emitted from the timer so wait a few timer cycles
sleep_ms((nsecprof / GIGA) * 1000 * 3);
running = 0;
}
}

Expand Down
3 changes: 2 additions & 1 deletion stdlib/Profile/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"

[extras]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
Serialization = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Logging", "Serialization", "Test"]
test = ["Base64", "Logging", "Serialization", "Test"]
5 changes: 3 additions & 2 deletions stdlib/Profile/src/Profile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ function _peek_report()
iob = IOBuffer()
ioc = IOContext(IOContext(iob, stdout), :displaysize=>displaysize(stdout))
print(ioc, groupby = [:thread, :task])
Base.print(stdout, String(resize!(iob.data, iob.size)))
Base.print(stdout, String(take!(iob)))
end
# This is a ref so that it can be overridden by other profile info consumers.
const peek_report = Ref{Function}(_peek_report)
Expand All @@ -73,7 +73,8 @@ Set the duration in seconds of the profile "peek" that is triggered via `SIGINFO
set_peek_duration(t::Float64) = ccall(:jl_set_profile_peek_duration, Cvoid, (Float64,), t)

precompile_script = """
Profile.@profile sleep(0.5)
import Profile
Profile.@profile while Profile.len_data() < 1000; rand(10,10) * rand(10,10); end
Profile.peek_report[]()
Profile.clear()
"""
Expand Down
2 changes: 0 additions & 2 deletions stdlib/Profile/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,6 @@ if Sys.isbsd() || Sys.islinux()
end
end
end
else
@warn "Skipping \"SIGINFO/SIGUSR1 profile triggering\" test as it is not supported on this platform"
end

@testset "FlameGraphs" begin
Expand Down

0 comments on commit ed41f7c

Please sign in to comment.