diff --git a/base/Base.jl b/base/Base.jl index cbfa5ede6aef9..a5a42235cb99e 100644 --- a/base/Base.jl +++ b/base/Base.jl @@ -504,6 +504,10 @@ function __init__() nothing end +# enable threads support +@eval PCRE PCRE_COMPILE_LOCK = Threads.SpinLock() + end + end # baremodule Base diff --git a/base/client.jl b/base/client.jl index 124bfd281c6a1..842389224637f 100644 --- a/base/client.jl +++ b/base/client.jl @@ -514,10 +514,6 @@ MainInclude.include function _start() empty!(ARGS) append!(ARGS, Core.ARGS) - if ccall(:jl_generating_output, Cint, ()) != 0 && JLOptions().incremental == 0 - # clear old invalid pointers - PCRE.__init__() - end try exec_options(JLOptions()) catch diff --git a/base/pcre.jl b/base/pcre.jl index a8edaaa089c31..81e9b1d4d0ff8 100644 --- a/base/pcre.jl +++ b/base/pcre.jl @@ -24,28 +24,47 @@ function create_match_context() return ctx end -const THREAD_MATCH_CONTEXTS = Ptr{Cvoid}[C_NULL] +THREAD_MATCH_CONTEXTS::Vector{Ptr{Cvoid}} = [C_NULL] PCRE_COMPILE_LOCK = nothing -_tid() = Int(ccall(:jl_threadid, Int16, ())+1) +_tid() = Int(ccall(:jl_threadid, Int16, ())) + 1 _nth() = Int(unsafe_load(cglobal(:jl_n_threads, Cint))) function get_local_match_context() + global THREAD_MATCH_CONTEXTS tid = _tid() - ctx = @inbounds THREAD_MATCH_CONTEXTS[tid] + ctxs = THREAD_MATCH_CONTEXTS + if length(ctxs) < tid + # slow path to allocate it + l = PCRE_COMPILE_LOCK::Threads.SpinLock + lock(l) + try + THREAD_MATCH_CONTEXTS = ctxs = copyto!(fill(C_NULL, _nth()), THREAD_MATCH_CONTEXTS) + finally + unlock(l) + end + end + ctx = @inbounds ctxs[tid] if ctx == C_NULL - @inbounds THREAD_MATCH_CONTEXTS[tid] = ctx = create_match_context() + # slow path to allocate it + ctx = create_match_context() + l = PCRE_COMPILE_LOCK + if l === nothing + THREAD_MATCH_CONTEXTS[tid] = ctx + else + l = l::Threads.SpinLock + lock(l) + try + THREAD_MATCH_CONTEXTS[tid] = ctx + finally + unlock(l) + end + end end return ctx end -function __init__() - resize!(THREAD_MATCH_CONTEXTS, _nth()) - fill!(THREAD_MATCH_CONTEXTS, C_NULL) - global PCRE_COMPILE_LOCK = Threads.SpinLock() -end - # supported options for different use cases # arguments to pcre2_compile