From 75858d73322e29a665bd06947c20dc2b9d996f9f Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Wed, 30 Jun 2021 04:43:55 +0200 Subject: [PATCH] [Tasks] Mark parent as sticky if we use `@async` (#41334) Fixes #41324 for 1.7 --- base/task.jl | 6 ++++++ test/threads_exec.jl | 13 +++++++++++++ 2 files changed, 19 insertions(+) diff --git a/base/task.jl b/base/task.jl index 1ed68f70f7ab7..bfb105accef14 100644 --- a/base/task.jl +++ b/base/task.jl @@ -621,6 +621,12 @@ function enq_work(t::Task) # 3. The multiq is full (can be fixed by making it growable). if t.sticky || Threads.nthreads() == 1 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 tid = Threads.threadid() ccall(:jl_set_task_tid, Cvoid, (Any, Cint), t, tid-1) end diff --git a/test/threads_exec.jl b/test/threads_exec.jl index b7e4c37631d83..f3d2dc9577c64 100644 --- a/test/threads_exec.jl +++ b/test/threads_exec.jl @@ -840,6 +840,19 @@ fib34666(x) = end @test fib34666(25) == 75025 +# issue #41324 +@testset "Co-schedule" begin + parent = Threads.@spawn begin + @test current_task().sticky == false + child = @async begin end + @test current_task().sticky == true + @test Threads.threadid() == Threads.threadid(child) + wait(child) + end + wait(parent) + @test parent.sticky == true +end + function jitter_channel(f, k, delay, ntasks, schedule) x = Channel(ch -> foreach(i -> put!(ch, i), 1:k), 1) y = Channel(k) do ch