File tree 4 files changed +84
-0
lines changed
4 files changed +84
-0
lines changed Original file line number Diff line number Diff line change @@ -22,6 +22,7 @@ New language features
22
22
The available metrics are:
23
23
- actual running time for the task (` Base.Experimental.task_running_time_ns ` ), and
24
24
- wall-time for the task (` Base.Experimental.task_wall_time_ns ` ).
25
+ - New ` Base.@acquire ` macro for a non-closure version of ` Base.acquire(f, s::Base.Semaphore) ` , like ` @lock ` . ([ #xxx] )
25
26
26
27
Language changes
27
28
----------------
Original file line number Diff line number Diff line change @@ -479,6 +479,70 @@ function acquire(f, s::Semaphore)
479
479
end
480
480
end
481
481
482
+ """
483
+ @acquire s::Semaphore expr
484
+
485
+ Execute `f` after acquiring from Semaphore `s`,
486
+ and `release` on completion or error.
487
+
488
+ For example, a do-block form that ensures only 2
489
+ calls of `foo` will be active at the same time:
490
+
491
+ ```julia
492
+ s = Base.Semaphore(2)
493
+ @sync for _ in 1:100
494
+ Threads.@spawn begin
495
+ Base.acquire(s) do
496
+ foo()
497
+ end
498
+ end
499
+ end
500
+ ```
501
+
502
+ !!! compat "Julia 1.8"
503
+ This method requires at least Julia 1.8.
504
+
505
+ """
506
+ function acquire (f, s:: Semaphore )
507
+ acquire (s)
508
+ try
509
+ return f ()
510
+ finally
511
+ release (s)
512
+ end
513
+ end
514
+
515
+ """
516
+ @acquire s::Semaphore expr
517
+
518
+ Macro version of `Base.acquire(f, s::Semaphore)` but with `expr` instead of `f` function.
519
+ Expands to:
520
+ ```julia
521
+ Base.acquire(s)
522
+ try
523
+ expr
524
+ finally
525
+ Base.release(s)
526
+ end
527
+ ```
528
+ This is similar to using [`acquire`](@ref) with a `do` block, but avoids creating a closure
529
+ and thus can improve the performance.
530
+
531
+ !!! compat
532
+ `@acquire` was added in Julia 1.12
533
+ """
534
+ macro acquire (s, expr)
535
+ quote
536
+ temp = $ (esc (s))
537
+ Base. acquire (temp)
538
+ try
539
+ $ (esc (expr))
540
+ finally
541
+ Base. release (temp)
542
+ end
543
+ end
544
+ end
545
+
482
546
"""
483
547
release(s::Semaphore)
484
548
Original file line number Diff line number Diff line change 26
26
# Semaphores
27
27
Semaphore,
28
28
acquire,
29
+ @acquire ,
29
30
release,
30
31
31
32
# arrays
Original file line number Diff line number Diff line change 237
237
@test all (<= (sem_size), history)
238
238
@test all (>= (0 ), history)
239
239
@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, 2 n), - 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
240
258
end
241
259
242
260
# task switching
You can’t perform that action at this time.
0 commit comments