Skip to content

Commit 2fd6db2

Browse files
Add Base.@acquire for non-closure version of Base.acquire(f, s::Base.Semaphore) (#56845)
1 parent 4b95442 commit 2fd6db2

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

NEWS.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Julia v1.13 Release Notes
44
New language features
55
---------------------
66

7+
- New `Base.@acquire` macro for a non-closure version of `Base.acquire(f, s::Base.Semaphore)`, like `@lock`. ([#56845])
8+
79
Language changes
810
----------------
911

base/lock.jl

+30
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,36 @@ function acquire(f, s::Semaphore)
561561
end
562562
end
563563

564+
"""
565+
Base.@acquire s::Semaphore expr
566+
567+
Macro version of `Base.acquire(f, s::Semaphore)` but with `expr` instead of `f` function.
568+
Expands to:
569+
```julia
570+
Base.acquire(s)
571+
try
572+
expr
573+
finally
574+
Base.release(s)
575+
end
576+
```
577+
This is similar to using [`acquire`](@ref) with a `do` block, but avoids creating a closure.
578+
579+
!!! compat "Julia 1.13"
580+
`Base.@acquire` was added in Julia 1.13
581+
"""
582+
macro acquire(s, expr)
583+
quote
584+
local temp = $(esc(s))
585+
Base.acquire(temp)
586+
try
587+
$(esc(expr))
588+
finally
589+
Base.release(temp)
590+
end
591+
end
592+
end
593+
564594
"""
565595
release(s::Semaphore)
566596

base/public.jl

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public
2828
# Semaphores
2929
Semaphore,
3030
acquire,
31+
@acquire,
3132
release,
3233

3334
# arrays

test/misc.jl

+18
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,24 @@ end
237237
@test all(<=(sem_size), history)
238238
@test all(>=(0), history)
239239
@test history[end] == 0
240+
241+
# macro form
242+
clock = Threads.Atomic{Int}(1)
243+
occupied = Threads.Atomic{Int}(0)
244+
history = fill!(Vector{Int}(undef, 2n), -1)
245+
@sync for _ in 1:n
246+
@async begin
247+
@test Base.@acquire s begin
248+
history[Threads.atomic_add!(clock, 1)] = Threads.atomic_add!(occupied, 1) + 1
249+
sleep(rand(0:0.01:0.1))
250+
history[Threads.atomic_add!(clock, 1)] = Threads.atomic_sub!(occupied, 1) - 1
251+
return :resultvalue
252+
end === :resultvalue
253+
end
254+
end
255+
@test all(<=(sem_size), history)
256+
@test all(>=(0), history)
257+
@test history[end] == 0
240258
end
241259

242260
# task switching

0 commit comments

Comments
 (0)