Mostly mmtk/mmtk-core#1398. The API is_collection_enabled is not thread safe, and there is no way to implement it in a thread safe way in the binding side. The issue is that the check of is_collection_enabled and the update for the GC triggered state cannot happen atomically, so there can be a situation that MMTk checks is_collection_enabled, thinks it is okay to trigger a GC, but when MMTk actually triggers the GC, is_collection_enabled is flipped at the binding side.
We haven't confirmed any bug from this. I think we could just add an assertion in the binding side to make sure that GC is always disabled when we actually stops for a GC.
One potential solution to the bug is to introduce thread-safe GC enabling APIs to MMTk core, and use that API for Julia. Though Julia currently has jl_gc_enable and jl_gc_is_enabled in the interface, it still bypasses the API and checks/sets jl_gc_disable_counter and ptls->disable_gc, specifically in the following places:
- Julia has a global state
jl_gc_disable_counter and a thread local state disable_gc. It seem the runtime code mixes the use of both.
- Julia runtime may directly set
jl_gc_disable_counter without using jl_gc_enable, such as in jl_adopt_thread in threading.c [1], and jl_exit_thread0_cb in signals-unix.c [2].
- Julia runtime may directly set
pltls->disable_gc without using jl_gc_enable, such as in jl_init_threadtls in threading.c [3].
[1] https://github.com/JuliaLang/julia/blob/595757964be1e190e8fe474b74df7a60b315e566/src/threading.c#L434
[2] https://github.com/JuliaLang/julia/blob/595757964be1e190e8fe474b74df7a60b315e566/src/signals-unix.c#L555 and https://github.com/JuliaLang/julia/blob/595757964be1e190e8fe474b74df7a60b315e566/src/signals-unix.c#L1089
[3] https://github.com/JuliaLang/julia/blob/595757964be1e190e8fe474b74df7a60b315e566/src/threading.c#L349
Mostly mmtk/mmtk-core#1398. The API
is_collection_enabledis not thread safe, and there is no way to implement it in a thread safe way in the binding side. The issue is that the check ofis_collection_enabledand the update for the GC triggered state cannot happen atomically, so there can be a situation that MMTk checksis_collection_enabled, thinks it is okay to trigger a GC, but when MMTk actually triggers the GC,is_collection_enabledis flipped at the binding side.We haven't confirmed any bug from this. I think we could just add an assertion in the binding side to make sure that GC is always disabled when we actually stops for a GC.
One potential solution to the bug is to introduce thread-safe GC enabling APIs to MMTk core, and use that API for Julia. Though Julia currently has
jl_gc_enableandjl_gc_is_enabledin the interface, it still bypasses the API and checks/setsjl_gc_disable_counterandptls->disable_gc, specifically in the following places:jl_gc_disable_counterand a thread local statedisable_gc. It seem the runtime code mixes the use of both.jl_gc_disable_counterwithout usingjl_gc_enable, such as injl_adopt_threadinthreading.c[1], andjl_exit_thread0_cbinsignals-unix.c[2].pltls->disable_gcwithout usingjl_gc_enable, such as injl_init_threadtlsinthreading.c[3].[1] https://github.com/JuliaLang/julia/blob/595757964be1e190e8fe474b74df7a60b315e566/src/threading.c#L434
[2] https://github.com/JuliaLang/julia/blob/595757964be1e190e8fe474b74df7a60b315e566/src/signals-unix.c#L555 and https://github.com/JuliaLang/julia/blob/595757964be1e190e8fe474b74df7a60b315e566/src/signals-unix.c#L1089
[3] https://github.com/JuliaLang/julia/blob/595757964be1e190e8fe474b74df7a60b315e566/src/threading.c#L349