Skip to content

Commit ed41f7c

Browse files
IanButterworthKristofferC
authored andcommitted
Profile: Minor fixes. Signal handling fix. (#44199)
(cherry picked from commit 072c041)
1 parent dfd7bb4 commit ed41f7c

File tree

5 files changed

+26
-15
lines changed

5 files changed

+26
-15
lines changed

src/signal-handling.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -132,22 +132,23 @@ static size_t jl_safe_read_mem(const volatile char *ptr, char *out, size_t len)
132132
static double profile_autostop_time = -1.0;
133133
static double profile_peek_duration = 1.0; // seconds
134134

135-
double jl_get_profile_peek_duration(void) {
135+
double jl_get_profile_peek_duration(void)
136+
{
136137
return profile_peek_duration;
137138
}
138-
void jl_set_profile_peek_duration(double t) {
139+
void jl_set_profile_peek_duration(double t)
140+
{
139141
profile_peek_duration = t;
140-
return;
141142
}
142143

143144
uintptr_t profile_show_peek_cond_loc;
144145
JL_DLLEXPORT void jl_set_peek_cond(uintptr_t cond)
145146
{
146147
profile_show_peek_cond_loc = cond;
147-
return;
148148
}
149149

150-
static void jl_check_profile_autostop(void) {
150+
static void jl_check_profile_autostop(void)
151+
{
151152
if ((profile_autostop_time != -1.0) && (jl_hrtime() > profile_autostop_time)) {
152153
profile_autostop_time = -1.0;
153154
jl_profile_stop_timer();

src/signals-unix.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -539,9 +539,13 @@ JL_DLLEXPORT int jl_profile_start_timer(void)
539539

540540
JL_DLLEXPORT void jl_profile_stop_timer(void)
541541
{
542-
if (running)
542+
if (running) {
543543
timer_delete(timerprof);
544-
running = 0;
544+
// Because SIGUSR1 is multipurpose, care must be taken for running = 0 to be set after the timer has fully stopped.
545+
// There may be a pending signal emitted from the timer so wait a few timer cycles
546+
sleep_ms((nsecprof / GIGA) * 1000 * 3);
547+
running = 0;
548+
}
545549
}
546550

547551
#elif defined(HAVE_ITIMER)
@@ -556,18 +560,24 @@ JL_DLLEXPORT int jl_profile_start_timer(void)
556560
timerprof.it_interval.tv_usec = 0;
557561
timerprof.it_value.tv_sec = nsecprof / GIGA;
558562
timerprof.it_value.tv_usec = ((nsecprof % GIGA) + 999) / 1000;
559-
if (setitimer(ITIMER_PROF, &timerprof, NULL) == -1)
560-
return -3;
563+
// Because SIGUSR1 is multipurpose, set `running` before so that we know that the first SIGUSR1 came from the timer
561564
running = 1;
565+
if (setitimer(ITIMER_PROF, &timerprof, NULL) == -1) {
566+
running = 0;
567+
return -3;
568+
}
562569
return 0;
563570
}
564571

565572
JL_DLLEXPORT void jl_profile_stop_timer(void)
566573
{
567574
if (running) {
568-
running = 0;
569575
memset(&timerprof, 0, sizeof(timerprof));
570576
setitimer(ITIMER_PROF, &timerprof, NULL);
577+
// Because SIGUSR1 is multipurpose, care must be taken for running = 0 to be set after the timer has fully stopped.
578+
// There may be a pending signal emitted from the timer so wait a few timer cycles
579+
sleep_ms((nsecprof / GIGA) * 1000 * 3);
580+
running = 0;
571581
}
572582
}
573583

stdlib/Profile/Project.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@ uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79"
55
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
66

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

1213
[targets]
13-
test = ["Logging", "Serialization", "Test"]
14+
test = ["Base64", "Logging", "Serialization", "Test"]

stdlib/Profile/src/Profile.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ function _peek_report()
5454
iob = IOBuffer()
5555
ioc = IOContext(IOContext(iob, stdout), :displaysize=>displaysize(stdout))
5656
print(ioc, groupby = [:thread, :task])
57-
Base.print(stdout, String(resize!(iob.data, iob.size)))
57+
Base.print(stdout, String(take!(iob)))
5858
end
5959
# This is a ref so that it can be overridden by other profile info consumers.
6060
const peek_report = Ref{Function}(_peek_report)
@@ -73,7 +73,8 @@ Set the duration in seconds of the profile "peek" that is triggered via `SIGINFO
7373
set_peek_duration(t::Float64) = ccall(:jl_set_profile_peek_duration, Cvoid, (Float64,), t)
7474

7575
precompile_script = """
76-
Profile.@profile sleep(0.5)
76+
import Profile
77+
Profile.@profile while Profile.len_data() < 1000; rand(10,10) * rand(10,10); end
7778
Profile.peek_report[]()
7879
Profile.clear()
7980
"""

stdlib/Profile/test/runtests.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,6 @@ if Sys.isbsd() || Sys.islinux()
226226
end
227227
end
228228
end
229-
else
230-
@warn "Skipping \"SIGINFO/SIGUSR1 profile triggering\" test as it is not supported on this platform"
231229
end
232230

233231
@testset "FlameGraphs" begin

0 commit comments

Comments
 (0)