Skip to content

Commit d97d399

Browse files
authored
speed up ReentrantLock by sinking try blocks (#32406)
1 parent d958419 commit d97d399

File tree

1 file changed

+49
-39
lines changed

1 file changed

+49
-39
lines changed

base/lock.jl

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,18 @@ Each successful `trylock` must be matched by an [`unlock`](@ref).
4040
function trylock(rl::ReentrantLock)
4141
t = current_task()
4242
lock(rl.cond_wait)
43-
try
44-
if rl.reentrancy_cnt == 0
45-
rl.locked_by = t
46-
rl.reentrancy_cnt = 1
47-
return true
48-
elseif t == notnothing(rl.locked_by)
49-
rl.reentrancy_cnt += 1
50-
return true
51-
end
52-
return false
53-
finally
54-
unlock(rl.cond_wait)
43+
if rl.reentrancy_cnt == 0
44+
rl.locked_by = t
45+
rl.reentrancy_cnt = 1
46+
got = true
47+
elseif t === notnothing(rl.locked_by)
48+
rl.reentrancy_cnt += 1
49+
got = true
50+
else
51+
got = false
5552
end
53+
unlock(rl.cond_wait)
54+
return got
5655
end
5756

5857
"""
@@ -67,21 +66,24 @@ Each `lock` must be matched by an [`unlock`](@ref).
6766
function lock(rl::ReentrantLock)
6867
t = current_task()
6968
lock(rl.cond_wait)
70-
try
71-
while true
72-
if rl.reentrancy_cnt == 0
73-
rl.locked_by = t
74-
rl.reentrancy_cnt = 1
75-
return
76-
elseif t == notnothing(rl.locked_by)
77-
rl.reentrancy_cnt += 1
78-
return
79-
end
69+
while true
70+
if rl.reentrancy_cnt == 0
71+
rl.locked_by = t
72+
rl.reentrancy_cnt = 1
73+
break
74+
elseif t === notnothing(rl.locked_by)
75+
rl.reentrancy_cnt += 1
76+
break
77+
end
78+
try
8079
wait(rl.cond_wait)
80+
catch
81+
unlock(rl.cond_wait)
82+
rethrow()
8183
end
82-
finally
83-
unlock(rl.cond_wait)
8484
end
85+
unlock(rl.cond_wait)
86+
return
8587
end
8688

8789
"""
@@ -95,33 +97,41 @@ internal counter and return immediately.
9597
function unlock(rl::ReentrantLock)
9698
t = current_task()
9799
rl.reentrancy_cnt == 0 && error("unlock count must match lock count")
98-
rl.locked_by == t || error("unlock from wrong thread")
100+
rl.locked_by === t || error("unlock from wrong thread")
99101
lock(rl.cond_wait)
100-
try
101-
rl.reentrancy_cnt -= 1
102-
if rl.reentrancy_cnt == 0
103-
rl.locked_by = nothing
104-
notify(rl.cond_wait)
102+
rl.reentrancy_cnt -= 1
103+
if rl.reentrancy_cnt == 0
104+
rl.locked_by = nothing
105+
if !isempty(rl.cond_wait.waitq)
106+
try
107+
notify(rl.cond_wait)
108+
catch
109+
unlock(rl.cond_wait)
110+
rethrow()
111+
end
105112
end
106-
finally
107-
unlock(rl.cond_wait)
108113
end
114+
unlock(rl.cond_wait)
109115
return
110116
end
111117

112118
function unlockall(rl::ReentrantLock)
113119
t = current_task()
114120
n = rl.reentrancy_cnt
115-
rl.locked_by == t || error("unlock from wrong thread")
121+
rl.locked_by === t || error("unlock from wrong thread")
116122
n == 0 && error("unlock count must match lock count")
117123
lock(rl.cond_wait)
118-
try
119-
rl.reentrancy_cnt = 0
120-
rl.locked_by = nothing
121-
notify(rl.cond_wait)
122-
finally
123-
unlock(rl.cond_wait)
124+
rl.reentrancy_cnt = 0
125+
rl.locked_by = nothing
126+
if !isempty(rl.cond_wait.waitq)
127+
try
128+
notify(rl.cond_wait)
129+
catch
130+
unlock(rl.cond_wait)
131+
rethrow()
132+
end
124133
end
134+
unlock(rl.cond_wait)
125135
return n
126136
end
127137

0 commit comments

Comments
 (0)