Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Profile: Minor fixes. Signal handling fix. #44199

Merged
merged 6 commits into from
Feb 17, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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