Skip to content

Commit

Permalink
Fix enq_work behavior when single-threaded
Browse files Browse the repository at this point in the history
If there's only one thread in the task's preferred thread pool, use that
thread's work queue.
  • Loading branch information
kpamnany committed Mar 6, 2023
1 parent 38727be commit a3a92e8
Showing 1 changed file with 20 additions and 9 deletions.
29 changes: 20 additions & 9 deletions base/task.jl
Original file line number Diff line number Diff line change
Expand Up @@ -767,22 +767,33 @@ end

function enq_work(t::Task)
(t._state === task_state_runnable && t.queue === nothing) || error("schedule: Task not runnable")
if t.sticky || Threads.threadpoolsize() == 1

# Sticky tasks go into their thread's work queue.
if t.sticky
tid = Threads.threadid(t)
if tid == 0
# Issue #41324
# t.sticky && tid == 0 is a task that needs to be co-scheduled with
# the parent task. If the parent (current_task) is not sticky we must
# set it to be sticky.
# XXX: Ideally we would be able to unset this
current_task().sticky = true
# The task is not yet stuck to a thread. Stick it to the current
# thread and do the same to the parent task (the current task) so
# that the tasks are correctly co-scheduled (issue #41324).
# XXX: Ideally we would be able to unset this.
tid = Threads.threadid()
ccall(:jl_set_task_tid, Cint, (Any, Cint), t, tid-1)
current_task().sticky = true
end
push!(workqueue_for(tid), t)
else
Partr.multiq_insert(t, t.priority)
tid = 0
tp = Threads.threadpool(t)
if Threads.threadpoolsize(tp) == 1
# There's only one thread in the task's assigned thread pool;
# use its work queue.
tid = (tp === :default) ? 1 : Threads.threadpoolsize(:default)+1
ccall(:jl_set_task_tid, Cint, (Any, Cint), t, tid-1)
push!(workqueue_for(tid), t)
else
# Otherwise, put the task in the multiqueue.
Partr.multiq_insert(t, t.priority)
tid = 0
end
end
ccall(:jl_wakeup_thread, Cvoid, (Int16,), (tid - 1) % Int16)
return t
Expand Down

0 comments on commit a3a92e8

Please sign in to comment.