From 2a4eea8a7bdf588c6828b80e76609c041bd4e3d6 Mon Sep 17 00:00:00 2001 From: Valentin Churavy Date: Wed, 23 Jun 2021 17:15:22 +0200 Subject: [PATCH] [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