From 2a4eea8a7bdf588c6828b80e76609c041bd4e3d6 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Wed, 23 Jun 2021 17:15:22 +0200 Subject: [PATCH 1/2] [Tasks] Mark parent as sticky if we use `@async` Fixes #41324 for 1.7 --- base/task.jl | 6 ++++++ test/threads_exec.jl | 12 ++++++++++++ 2 files changed, 18 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..a0cac726b8e27 100644 --- a/test/threads_exec.jl +++ b/test/threads_exec.jl @@ -840,6 +840,18 @@ 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 + 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 From 093f7e54984925d221f4f331e0716fdaa8b30b05 Mon Sep 17 00:00:00 2001 From: Jeff Bezanson Date: Tue, 29 Jun 2021 16:15:46 -0400 Subject: [PATCH 2/2] Update test/threads_exec.jl Co-authored-by: Valentin Churavy --- test/threads_exec.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/test/threads_exec.jl b/test/threads_exec.jl index a0cac726b8e27..f3d2dc9577c64 100644 --- a/test/threads_exec.jl +++ b/test/threads_exec.jl @@ -846,6 +846,7 @@ fib34666(x) = @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)