Skip to content

Commit

Permalink
Add option to use @spawn :samepool for using the same threadpool as…
Browse files Browse the repository at this point in the history
… the caller (#57109)
  • Loading branch information
IanButterworth authored Jan 27, 2025
1 parent 47a6ad0 commit cc3e7b6
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 4 deletions.
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ New language features
- actual running time for the task (`Base.Experimental.task_running_time_ns`), and
- wall-time for the task (`Base.Experimental.task_wall_time_ns`).
- Support for Unicode 16 ([#56925]).
- `Threads.@spawn` now takes a `:samepool` argument to specify the same threadpool as the caller.
`Threads.@spawn :samepool foo()` which is shorthand for `Threads.@spawn Threads.threadpool() foo()` ([#57109])

Language changes
----------------
Expand Down
16 changes: 12 additions & 4 deletions base/threadingconstructs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -440,10 +440,11 @@ function _spawn_set_thrpool(t::Task, tp::Symbol)
end

"""
Threads.@spawn [:default|:interactive] expr
Threads.@spawn [:default|:interactive|:samepool] expr
Create a [`Task`](@ref) and [`schedule`](@ref) it to run on any available
thread in the specified threadpool (`:default` if unspecified). The task is
thread in the specified threadpool: `:default`, `:interactive`, or `:samepool`
to use the same as the caller. `:default` is used if unspecified. The task is
allocated to a thread once one becomes available. To wait for the task to
finish, call [`wait`](@ref) on the result of this macro, or call
[`fetch`](@ref) to wait and then obtain its return value.
Expand All @@ -468,6 +469,9 @@ the variable's value in the current task.
!!! compat "Julia 1.9"
A threadpool may be specified as of Julia 1.9.
!!! compat "Julia 1.12"
The same threadpool may be specified as of Julia 1.12.
# Examples
```julia-repl
julia> t() = println("Hello from ", Threads.threadid());
Expand All @@ -486,7 +490,7 @@ macro spawn(args...)
ttype, ex = args
if ttype isa QuoteNode
ttype = ttype.value
if ttype !== :interactive && ttype !== :default
if !in(ttype, (:interactive, :default, :samepool))
throw(ArgumentError(LazyString("unsupported threadpool in @spawn: ", ttype)))
end
tp = QuoteNode(ttype)
Expand All @@ -507,7 +511,11 @@ macro spawn(args...)
let $(letargs...)
local task = Task($thunk)
task.sticky = false
_spawn_set_thrpool(task, $(esc(tp)))
local tp = $(esc(tp))
if tp == :samepool
tp = Threads.threadpool()
end
_spawn_set_thrpool(task, tp)
if $(Expr(:islocal, var))
put!($var, task)
end
Expand Down
9 changes: 9 additions & 0 deletions test/threadpool_use.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ using Base.Threads
@test fetch(Threads.@spawn Threads.threadpool()) === :default
@test fetch(Threads.@spawn :default Threads.threadpool()) === :default
@test fetch(Threads.@spawn :interactive Threads.threadpool()) === :interactive
@test fetch(Threads.@spawn :samepool Threads.threadpool()) === Threads.threadpool()
@sync for tp in [:interactive, :default]
Threads.@spawn tp begin
@test fetch(Threads.@spawn :samepool Threads.threadpool()) === Threads.threadpool()
end
end
wait(Threads.@spawn :interactive begin
@test fetch(Threads.@spawn :samepool Threads.threadpool()) === Threads.threadpool()
end)
tp = :default
@test fetch(Threads.@spawn tp Threads.threadpool()) === :default
tp = :interactive
Expand Down

0 comments on commit cc3e7b6

Please sign in to comment.