Skip to content

Commit 1755994

Browse files
vtjnashJeffBezanson
authored andcommitted
[Profile] allocate exactly the space requested
With dynamic thread counts, we cannot ensure this count is constant after initialization, and we might like to even profile adding and removing threads.
1 parent 956e0a3 commit 1755994

File tree

4 files changed

+15
-28
lines changed

4 files changed

+15
-28
lines changed

src/signal-handling.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -182,14 +182,10 @@ static int *profile_get_randperm(int size)
182182

183183
JL_DLLEXPORT int jl_profile_is_buffer_full(void)
184184
{
185-
// declare buffer full if there isn't enough room to take samples across all threads
186-
#if defined(_OS_WINDOWS_)
187-
uint64_t nthreads = 1; // windows only profiles the main thread
188-
#else
189-
uint64_t nthreads = jl_n_threads;
190-
#endif
191-
// the `+ 6` is for the two block terminators `0` plus 4 metadata entries
192-
return bt_size_cur + (((JL_BT_MAX_ENTRY_SIZE + 1) + 6) * nthreads) > bt_size_max;
185+
// Declare buffer full if there isn't enough room to sample even just the
186+
// thread metadata and one max-sized frame. The `+ 6` is for the two block
187+
// terminator `0`'s plus the 4 metadata entries.
188+
return bt_size_cur + ((JL_BT_MAX_ENTRY_SIZE + 1) + 6) > bt_size_max;
193189
}
194190

195191
static uint64_t jl_last_sigint_trigger = 0;

src/signals-unix.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -701,7 +701,7 @@ void trigger_profile_peek(void)
701701
if (bt_size_max == 0){
702702
// If the buffer hasn't been initialized, initialize with default size
703703
// Keep these values synchronized with Profile.default_init()
704-
if (jl_profile_init(10000000 * jl_n_threads, 1000000) == -1){
704+
if (jl_profile_init(10000000, 1000000) == -1) {
705705
jl_safe_printf("ERROR: could not initialize the profile buffer");
706706
return;
707707
}

stdlib/Profile/src/Profile.jl

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,6 @@ stored per thread. Each instruction pointer corresponds to a single line of code
8888
list of instruction pointers. Note that 6 spaces for instruction pointers per backtrace are used to store metadata and two
8989
NULL end markers. Current settings can be obtained by calling this function with no arguments, and each can be set independently
9090
using keywords or in the order `(n, delay)`.
91-
92-
!!! compat "Julia 1.8"
93-
As of Julia 1.8, this function allocates space for `n` instruction pointers per thread being profiled.
94-
Previously this was `n` total.
9591
"""
9692
function init(; n::Union{Nothing,Integer} = nothing, delay::Union{Nothing,Real} = nothing, limitwarn::Bool = true)
9793
n_cur = ccall(:jl_profile_maxlen_data, Csize_t, ())
@@ -102,29 +98,25 @@ function init(; n::Union{Nothing,Integer} = nothing, delay::Union{Nothing,Real}
10298
end
10399
delay_cur = ccall(:jl_profile_delay_nsec, UInt64, ())/10^9
104100
if n === nothing && delay === nothing
105-
nthreads = Sys.iswindows() ? 1 : Threads.nthreads() # windows only profiles the main thread
106-
return round(Int, n_cur / nthreads), delay_cur
101+
return n_cur, delay_cur
107102
end
108103
nnew = (n === nothing) ? n_cur : n
109104
delaynew = (delay === nothing) ? delay_cur : delay
110105
init(nnew, delaynew; limitwarn)
111106
end
112107

113108
function init(n::Integer, delay::Real; limitwarn::Bool = true)
114-
nthreads = Sys.iswindows() ? 1 : Threads.nthreads() # windows only profiles the main thread
115109
sample_size_bytes = sizeof(Ptr) # == Sys.WORD_SIZE / 8
116-
buffer_samples = n * nthreads
110+
buffer_samples = n
117111
buffer_size_bytes = buffer_samples * sample_size_bytes
118112
if buffer_size_bytes > 2^29 && Sys.WORD_SIZE == 32
119-
buffer_size_bytes_per_thread = floor(Int, 2^29 / nthreads)
120-
buffer_samples_per_thread = floor(Int, buffer_size_bytes_per_thread / sample_size_bytes)
121-
buffer_samples = buffer_samples_per_thread * nthreads
113+
buffer_samples = floor(Int, 2^29 / sample_size_bytes)
122114
buffer_size_bytes = buffer_samples * sample_size_bytes
123-
limitwarn && @warn "Requested profile buffer limited to 512MB (n = $buffer_samples_per_thread per thread) given that this system is 32-bit"
115+
limitwarn && @warn "Requested profile buffer limited to 512MB (n = $buffer_samples) given that this system is 32-bit"
124116
end
125-
status = ccall(:jl_profile_init, Cint, (Csize_t, UInt64), buffer_samples, round(UInt64,10^9*delay))
117+
status = ccall(:jl_profile_init, Cint, (Csize_t, UInt64), buffer_samples, round(UInt64, 10^9*delay))
126118
if status == -1
127-
error("could not allocate space for ", n, " instruction pointers per thread being profiled ($nthreads threads, $(Base.format_bytes(buffer_size_bytes)) total)")
119+
error("could not allocate space for ", n, " instruction pointers ($(Base.format_bytes(buffer_size_bytes)))")
128120
end
129121
end
130122

stdlib/Profile/test/runtests.jl

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -120,11 +120,10 @@ end
120120
@testset "setting sample count and delay in init" begin
121121
n_, delay_ = Profile.init()
122122
n_original = n_
123-
nthreads = Sys.iswindows() ? 1 : Threads.nthreads()
124123
sample_size_bytes = sizeof(Ptr)
125124
def_n = Sys.iswindows() && Sys.WORD_SIZE == 32 ? 1_000_000 : 10_000_000
126-
if Sys.WORD_SIZE == 32 && (def_n * nthreads * sample_size_bytes) > 2^29
127-
@test n_ * nthreads * sample_size_bytes <= 2^29
125+
if Sys.WORD_SIZE == 32 && (def_n * sample_size_bytes) > 2^29
126+
@test n_ * sample_size_bytes <= 2^29
128127
else
129128
@test n_ == def_n
130129
end
@@ -133,8 +132,8 @@ end
133132
@test delay_ == def_delay
134133
Profile.init(n=1_000_001, delay=0.0005)
135134
n_, delay_ = Profile.init()
136-
if Sys.WORD_SIZE == 32 && (1_000_001 * nthreads * sample_size_bytes) > 2^29
137-
@test n_ * nthreads * sample_size_bytes <= 2^29
135+
if Sys.WORD_SIZE == 32 && (1_000_001 * sample_size_bytes) > 2^29
136+
@test n_ * sample_size_bytes <= 2^29
138137
else
139138
@test n_ == 1_000_001
140139
end

0 commit comments

Comments
 (0)