From f0b3ffef52d73a8a72500f4ac515070413a5c7b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Guedes?= Date: Thu, 10 Aug 2023 08:07:57 -0300 Subject: [PATCH] Makes IntrusiveLinkedListSynchronized mutable to avoid allocation on poptask (#50802) Currently `poptask` is allocating every time it calls into `jl_task_get_next` due to `StickyWorkqueue` (`IntrusiveLinkedListSynchronized`) being immutable and requiring an allocation to be used as `Any` on the `ccall`. The allocations can be seen in the following snippet: ``` function work() done = 0.0 l = Threads.SpinLock() Threads.@sync for _ in 1:(Threads.nthreads() / 2) Threads.@spawn begin v = 1.0 for i in 1:(1<<33) v *= 1.0001 if i % (1 << 13) == 0 yield() end end Base.@lock_nofail l done += v end end return done end julia> @time work() 15.758794 seconds (5.03 M allocations: 153.523 MiB, 0.35% gc time) ``` Which after the change becomes: ``` julia> @time work() 15.907513 seconds (67 allocations: 4.719 KiB) ``` --- base/task.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/task.jl b/base/task.jl index 92598159e999f..d19189fa3cb5e 100644 --- a/base/task.jl +++ b/base/task.jl @@ -688,7 +688,7 @@ end ## scheduler and work queue -struct IntrusiveLinkedListSynchronized{T} +mutable struct IntrusiveLinkedListSynchronized{T} queue::IntrusiveLinkedList{T} lock::Threads.SpinLock IntrusiveLinkedListSynchronized{T}() where {T} = new(IntrusiveLinkedList{T}(), Threads.SpinLock())