Skip to content

Commit 06b0112

Browse files
move to @time
1 parent 1e01c8e commit 06b0112

File tree

4 files changed

+20
-30
lines changed

4 files changed

+20
-30
lines changed

base/atomics.jl

+6-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,12 @@ end
8080

8181
Atomic() = Atomic{Int}()
8282

83-
LOCK_CONFLICT_COUNT = Threads.Atomic{Int}(0);
83+
const LOCK_PROFILING = Atomic{Int}(0)
84+
lock_profiling(state::Bool) = state ? atomic_add!(LOCK_PROFILING, 1) : atomic_sub!(LOCK_PROFILING, 1)
85+
lock_profiling() = LOCK_PROFILING[] > 0
86+
87+
const LOCK_CONFLICT_COUNT = Atomic{Int}(0);
88+
inc_lock_conflict_count() = atomic_add!(LOCK_CONFLICT_COUNT, 1)
8489

8590
"""
8691
Threads.atomic_cas!(x::Atomic{T}, cmp::T, newval::T) where T

base/lock.jl

+1-4
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,6 @@ end
134134
return false
135135
end
136136

137-
LOCK_PROFILING::Bool = false
138-
inc_lock_conflict_count() = Threads.atomic_add!(Threads.LOCK_CONFLICT_COUNT, 1)
139-
140137
"""
141138
lock(lock)
142139
@@ -148,7 +145,7 @@ Each `lock` must be matched by an [`unlock`](@ref).
148145
"""
149146
@inline function lock(rl::ReentrantLock)
150147
trylock(rl) || (@noinline function slowlock(rl::ReentrantLock)
151-
LOCK_PROFILING && inc_lock_conflict_count()
148+
Threads.lock_profiling() && Threads.inc_lock_conflict_count()
152149
c = rl.cond_wait
153150
lock(c.lock)
154151
try

base/timing.jl

+12-3
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,8 @@ function format_bytes(bytes; binary=true) # also used by InteractiveUtils
146146
end
147147
end
148148

149-
function time_print(io::IO, elapsedtime, bytes=0, gctime=0, allocs=0, compile_time=0, recompile_time=0, newline=false; msg::Union{String,Nothing}=nothing)
149+
function time_print(io::IO, elapsedtime, bytes=0, gctime=0, allocs=0, lock_conflicts=0, compile_time=0, recompile_time=0, newline=false;
150+
msg::Union{String,Nothing}=nothing)
150151
timestr = Ryu.writefixed(Float64(elapsedtime/1e9), 6)
151152
str = sprint() do io
152153
if msg isa String
@@ -172,6 +173,10 @@ function time_print(io::IO, elapsedtime, bytes=0, gctime=0, allocs=0, compile_ti
172173
end
173174
print(io, Ryu.writefixed(Float64(100*gctime/elapsedtime), 2), "% gc time")
174175
end
176+
if lock_conflicts > 0
177+
plural = lock_conflicts == 1 ? "" : "s"
178+
print(io, ", ", lock_conflict, " lock conflict$plural")
179+
end
175180
if compile_time > 0
176181
if bytes != 0 || allocs != 0 || gctime > 0
177182
print(io, ", ")
@@ -282,18 +287,22 @@ end
282287
macro time(msg, ex)
283288
quote
284289
Experimental.@force_compile
290+
Threads.lock_profiling(true)
291+
local lock_conflicts = Threads.LOCK_CONFLICT_COUNT[]
285292
local stats = gc_num()
286293
local elapsedtime = time_ns()
287294
cumulative_compile_timing(true)
288295
local compile_elapsedtimes = cumulative_compile_time_ns()
289296
local val = @__tryfinally($(esc(ex)),
290297
(elapsedtime = time_ns() - elapsedtime;
291298
cumulative_compile_timing(false);
292-
compile_elapsedtimes = cumulative_compile_time_ns() .- compile_elapsedtimes)
299+
compile_elapsedtimes = cumulative_compile_time_ns() .- compile_elapsedtimes;
300+
lock_conflicts = Threads.LOCK_CONFLICT_COUNT[] - lock_conflicts;
301+
Threads.lock_profiling(false))
293302
)
294303
local diff = GC_Diff(gc_num(), stats)
295304
local _msg = $(esc(msg))
296-
time_print(stdout, elapsedtime, diff.allocd, diff.total_time, gc_alloc_count(diff), first(compile_elapsedtimes), last(compile_elapsedtimes), true; msg=_msg)
305+
time_print(stdout, elapsedtime, diff.allocd, diff.total_time, gc_alloc_count(diff), first(compile_elapsedtimes), last(compile_elapsedtimes), lock_conflicts, true; msg=_msg)
297306
val
298307
end
299308
end

stdlib/Profile/src/Profile.jl

+1-22
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ Profiling support.
1010
- `Profile.print()` to print the report.
1111
- `Profile.clear()` to clear the buffer.
1212
- Send a $(Sys.isbsd() ? "SIGINFO (ctrl-t)" : "SIGUSR1") signal to the process to automatically trigger a profile and print.
13-
- `@count_lock_conflicts foo()` to count how many times a task had to wait to acquire a lock.
1413
1514
## Memory profiling
1615
- `Profile.Allocs.@profile [sample_rate=0.1] foo()` to sample allocations within a specific call. A sample rate of 1.0 will record everything; 0.0 will record nothing.
@@ -45,7 +44,7 @@ const nmeta = 4 # number of metadata fields per block (threadid, taskid, cpu_cyc
4544
# deprecated functions: use `getdict` instead
4645
lookup(ip::UInt) = lookup(convert(Ptr{Cvoid}, ip))
4746

48-
export @profile, @count_lock_conflicts
47+
export @profile
4948

5049
"""
5150
@profile
@@ -64,26 +63,6 @@ macro profile(ex)
6463
end
6564
end
6665

67-
68-
"""
69-
@count_lock_conflicts
70-
71-
`count_lock_conflicts <expression>` runs your expression while monitoring how many times a task had to wait
72-
to acquire a lock.
73-
"""
74-
macro count_lock_conflicts(ex)
75-
return quote
76-
Base.LOCK_PROFILING = true
77-
Threads.LOCK_CONFLICT_COUNT[] = 0
78-
try
79-
$(esc(ex))
80-
finally
81-
Base.LOCK_PROFILING = false
82-
end
83-
println("$(Threads.LOCK_CONFLICT_COUNT[]) lock conflicts")
84-
end
85-
end
86-
8766
# An internal function called to show the report after an information request (SIGINFO or SIGUSR1).
8867
function _peek_report()
8968
iob = IOBuffer()

0 commit comments

Comments
 (0)