From c335d2eb2e7da965755e5cbc697c61f8d4f4ea40 Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Tue, 1 Oct 2024 11:17:22 -0300 Subject: [PATCH 1/2] Make threadcall gc safe --- base/threadcall.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/base/threadcall.jl b/base/threadcall.jl index fbc1a87a20980..7a600384ebe22 100644 --- a/base/threadcall.jl +++ b/base/threadcall.jl @@ -43,8 +43,10 @@ macro threadcall(f, rettype, argtypes, argvals...) push!(body, :(p += Core.sizeof($T))) push!(args, arg) end + push!(body, :(gc_state = ccall(:jl_gc_safe_enter, Int8, (), ))) push!(body, :(ret = ccall(fptr, $rettype, ($(argtypes...),), $(args...)))) push!(body, :(unsafe_store!(convert(Ptr{$rettype}, retval_ptr), ret))) + push!(body, :(gc_state = ccall(:jl_gc_safe_leave, Cvoid, (Int8,), gc_state))) push!(body, :(return Int(Core.sizeof($rettype)))) # return code to generate wrapper function and send work request thread queue From d4108efd87ec263031aee4fb036961b9ddf95024 Mon Sep 17 00:00:00 2001 From: Gabriel Baraldi Date: Wed, 2 Oct 2024 11:20:33 -0300 Subject: [PATCH 2/2] Make the call convert before entering the gc safe region. Also preserve the arguments --- base/threadcall.jl | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/base/threadcall.jl b/base/threadcall.jl index 7a600384ebe22..3dcec7b463c92 100644 --- a/base/threadcall.jl +++ b/base/threadcall.jl @@ -39,15 +39,19 @@ macro threadcall(f, rettype, argtypes, argvals...) args = Symbol[] for (i, T) in enumerate(argtypes) arg = Symbol("arg", i) - push!(body, :($arg = unsafe_load(convert(Ptr{$T}, p)))) + push!(body, :($arg = unsafe_convert($T, cconvert($T, unsafe_load(convert(Ptr{$T}, p)))))) push!(body, :(p += Core.sizeof($T))) push!(args, arg) end - push!(body, :(gc_state = ccall(:jl_gc_safe_enter, Int8, (), ))) - push!(body, :(ret = ccall(fptr, $rettype, ($(argtypes...),), $(args...)))) - push!(body, :(unsafe_store!(convert(Ptr{$rettype}, retval_ptr), ret))) - push!(body, :(gc_state = ccall(:jl_gc_safe_leave, Cvoid, (Int8,), gc_state))) - push!(body, :(return Int(Core.sizeof($rettype)))) + append!(body, (quote + GC.@preserve $(args...) begin + gc_state = ccall(:jl_gc_safe_enter, Int8, ()) + ret = ccall(fptr, $rettype, ($(argtypes...),), $(args...)) + ccall(:jl_gc_safe_leave, Cvoid, (Int8,), gc_state) + unsafe_store!(convert(Ptr{$rettype}, retval_ptr), ret) + return Int(Core.sizeof($rettype)) + end + end).args) # return code to generate wrapper function and send work request thread queue wrapper = Expr(:var"hygienic-scope", wrapper, @__MODULE__, __source__)