diff --git a/base/Enums.jl b/base/Enums.jl index aea3aeeee188e..b93bfa112585a 100644 --- a/base/Enums.jl +++ b/base/Enums.jl @@ -21,6 +21,14 @@ Base.cconvert(::Type{T}, x::Enum{T2}) where {T<:Integer,T2<:Integer} = T(x)::T Base.write(io::IO, x::Enum{T}) where {T<:Integer} = write(io, T(x)) Base.read(io::IO, ::Type{T}) where {T<:Enum} = T(read(io, basetype(T))) +""" + _enum_hash(x::Enum, h::UInt) + +Compute hash for an enum value `x`. This internal method will be specialized +for every enum type created through [`@enum`](@ref). +""" +_enum_hash(x::Enum, h::UInt) = invoke(hash, Tuple{Any, UInt}, x, h) +Base.hash(x::Enum, h::UInt) = _enum_hash(x, h) Base.isless(x::T, y::T) where {T<:Enum} = isless(basetype(T)(x), basetype(T)(y)) Base.Symbol(x::Enum) = namemap(typeof(x))[Integer(x)]::Symbol @@ -206,8 +214,12 @@ macro enum(T::Union{Symbol,Expr}, syms...) Enums.namemap(::Type{$(esc(typename))}) = $(esc(namemap)) Base.typemin(x::Type{$(esc(typename))}) = $(esc(typename))($lo) Base.typemax(x::Type{$(esc(typename))}) = $(esc(typename))($hi) - let enum_hash = hash($(esc(typename))) - Base.hash(x::$(esc(typename)), h::UInt) = hash(enum_hash, hash(Integer(x), h)) + let type_hash = hash($(esc(typename))) + # Use internal `_enum_hash` to allow users to specialize + # `Base.hash` for their own enum types without overwriting the + # method we would define here. This avoids a warning for + # precompilation. + Enums._enum_hash(x::$(esc(typename)), h::UInt) = hash(type_hash, hash(Integer(x), h)) end let insts = (Any[ $(esc(typename))(v) for v in $values ]...,) Base.instances(::Type{$(esc(typename))}) = insts diff --git a/base/compiler/abstractinterpretation.jl b/base/compiler/abstractinterpretation.jl index b17a48f893cd1..8f917e03f472e 100644 --- a/base/compiler/abstractinterpretation.jl +++ b/base/compiler/abstractinterpretation.jl @@ -2441,11 +2441,9 @@ function abstract_eval_globalref(interp::AbstractInterpreter, g::GlobalRef, fram nothrow = false if isa(rt, Const) consistent = ALWAYS_TRUE + nothrow = true if is_mutation_free_argtype(rt) inaccessiblememonly = ALWAYS_TRUE - nothrow = true - else - nothrow = true end elseif isdefined_globalref(g) nothrow = true diff --git a/base/compiler/ssair/inlining.jl b/base/compiler/ssair/inlining.jl index c1c4ee18e8742..5c89a41a22cba 100644 --- a/base/compiler/ssair/inlining.jl +++ b/base/compiler/ssair/inlining.jl @@ -1401,7 +1401,7 @@ function compute_inlining_cases(@nospecialize(info::CallInfo), flag::UInt8, sig: fully_covered &= split_fully_covered end - joint_effects = Effects(joint_effects; nothrow=fully_covered) + fully_covered || (joint_effects = Effects(joint_effects; nothrow=false)) if handled_all_cases && revisit_idx !== nothing # we handled everything except one match with unmatched sparams, diff --git a/base/compiler/tfuncs.jl b/base/compiler/tfuncs.jl index ec8b76cf1a7c3..1b6fe75a61a5f 100644 --- a/base/compiler/tfuncs.jl +++ b/base/compiler/tfuncs.jl @@ -1488,7 +1488,7 @@ function apply_type_nothrow(@specialize(lattice::AbstractLattice), argtypes::Vec end else istype || return false - if !(T <: u.var.ub) + if isa(u.var.ub, TypeVar) || !(T <: u.var.ub) return false end if exact ? !(u.var.lb <: T) : !(u.var.lb === Bottom) diff --git a/base/compiler/typeinfer.jl b/base/compiler/typeinfer.jl index fe84849f15d14..698bf4238f1ef 100644 --- a/base/compiler/typeinfer.jl +++ b/base/compiler/typeinfer.jl @@ -367,10 +367,9 @@ end function transform_result_for_cache(interp::AbstractInterpreter, linfo::MethodInstance, valid_worlds::WorldRange, result::InferenceResult) inferred_result = result.src - # If we decided not to optimize, drop the OptimizationState now. - # External interpreters can override as necessary to cache additional information if inferred_result isa OptimizationState{typeof(interp)} - inferred_result = ir_to_codeinf!(inferred_result) + # TODO respect must_be_codeinf setting here? + result.src = inferred_result = ir_to_codeinf!(inferred_result) end if inferred_result isa CodeInfo inferred_result.min_world = first(valid_worlds) diff --git a/base/expr.jl b/base/expr.jl index 26203c210adea..c5ca69f00f1b2 100644 --- a/base/expr.jl +++ b/base/expr.jl @@ -925,6 +925,7 @@ end @atomic order ex Mark `var` or `ex` as being performed atomically, if `ex` is a supported expression. +If no `order` is specified it defaults to :sequentially_consistent. @atomic a.b.x = new @atomic a.b.x += addend diff --git a/base/gmp.jl b/base/gmp.jl index 42979df0382c2..b881723832862 100644 --- a/base/gmp.jl +++ b/base/gmp.jl @@ -808,8 +808,8 @@ Base.deepcopy_internal(x::BigInt, stackdict::IdDict) = get!(() -> MPZ.set(x), st ## streamlined hashing for BigInt, by avoiding allocation from shifts ## -if Limb === UInt - # this condition is true most (all?) of the time, and in this case we can define +if Limb === UInt64 === UInt + # On 64 bit systems we can define # an optimized version for BigInt of hash_integer (used e.g. for Rational{BigInt}), # and of hash @@ -819,7 +819,7 @@ if Limb === UInt GC.@preserve n begin s = n.size s == 0 && return hash_integer(0, h) - p = convert(Ptr{UInt}, n.d) + p = convert(Ptr{UInt64}, n.d) b = unsafe_load(p) h ⊻= hash_uint(ifelse(s < 0, -b, b) ⊻ h) for k = 2:abs(s) @@ -829,14 +829,11 @@ if Limb === UInt end end - _divLimb(n) = UInt === UInt64 ? n >>> 6 : n >>> 5 - _modLimb(n) = UInt === UInt64 ? n & 63 : n & 31 - function hash(x::BigInt, h::UInt) GC.@preserve x begin sz = x.size sz == 0 && return hash(0, h) - ptr = Ptr{UInt}(x.d) + ptr = Ptr{UInt64}(x.d) if sz == 1 return hash(unsafe_load(ptr), h) elseif sz == -1 @@ -845,8 +842,8 @@ if Limb === UInt end pow = trailing_zeros(x) nd = Base.ndigits0z(x, 2) - idx = _divLimb(pow) + 1 - shift = _modLimb(pow) % UInt + idx = (pow >>> 6) + 1 + shift = (pow & 63) % UInt upshift = BITS_PER_LIMB - shift asz = abs(sz) if shift == 0 diff --git a/base/initdefs.jl b/base/initdefs.jl index 002984b83dd97..8a5f9e440a089 100644 --- a/base/initdefs.jl +++ b/base/initdefs.jl @@ -354,6 +354,7 @@ const atexit_hooks = Callable[ () -> Filesystem.temp_cleanup_purge(force=true) ] const _atexit_hooks_lock = ReentrantLock() +global _atexit_hooks_finished::Bool = false """ atexit(f) @@ -374,12 +375,40 @@ exit code `n` (instead of the original exit code). If more than one exit hook calls `exit(n)`, then Julia will exit with the exit code corresponding to the last called exit hook that calls `exit(n)`. (Because exit hooks are called in LIFO order, "last called" is equivalent to "first registered".) + +Note: Once all exit hooks have been called, no more exit hooks can be registered, +and any call to `atexit(f)` after all hooks have completed will throw an exception. +This situation may occur if you are registering exit hooks from background Tasks that +may still be executing concurrently during shutdown. """ -atexit(f::Function) = Base.@lock _atexit_hooks_lock (pushfirst!(atexit_hooks, f); nothing) +function atexit(f::Function) + Base.@lock _atexit_hooks_lock begin + _atexit_hooks_finished && error("cannot register new atexit hook; already exiting.") + pushfirst!(atexit_hooks, f) + return nothing + end +end function _atexit(exitcode::Cint) - while !isempty(atexit_hooks) - f = popfirst!(atexit_hooks) + # Don't hold the lock around the iteration, just in case any other thread executing in + # parallel tries to register a new atexit hook while this is running. We don't want to + # block that thread from proceeding, and we can allow it to register its hook which we + # will immediately run here. + while true + local f + Base.@lock _atexit_hooks_lock begin + # If this is the last iteration, atomically disable atexit hooks to prevent + # someone from registering a hook that will never be run. + # (We do this inside the loop, so that it is atomic: no one can have registered + # a hook that never gets run, and we run all the hooks we know about until + # the vector is empty.) + if isempty(atexit_hooks) + global _atexit_hooks_finished = true + break + end + + f = popfirst!(atexit_hooks) + end try if hasmethod(f, (Cint,)) f(exitcode) diff --git a/base/loading.jl b/base/loading.jl index cfed2091b6d4b..5c000e3bb8ce7 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -1810,7 +1810,7 @@ function _require(pkg::PkgId, env=nothing) else @warn "The call to compilecache failed to create a usable precompiled cache file for $pkg" exception=m end - # fall-through to loading the file locally + # fall-through to loading the file locally if not incremental else cachefile, ocachefile = cachefile::Tuple{String, Union{Nothing, String}} m = _tryrequire_from_serialized(pkg, cachefile, ocachefile) @@ -1820,6 +1820,10 @@ function _require(pkg::PkgId, env=nothing) return m end end + if JLOptions().incremental != 0 + # during incremental precompilation, this should be fail-fast + throw(PrecompilableError()) + end end end diff --git a/base/options.jl b/base/options.jl index dda0e8b377076..b9fa5b6ec5508 100644 --- a/base/options.jl +++ b/base/options.jl @@ -53,6 +53,7 @@ struct JLOptions rr_detach::Int8 strip_metadata::Int8 strip_ir::Int8 + permalloc_pkgimg::Int8 heap_size_hint::UInt64 end diff --git a/base/sort.jl b/base/sort.jl index 5ea8d37e446dc..7fe194692ecf3 100644 --- a/base/sort.jl +++ b/base/sort.jl @@ -43,6 +43,7 @@ export # not exported by Base SMALL_ALGORITHM, SMALL_THRESHOLD +abstract type Algorithm end ## functions requiring only ordering ## @@ -414,19 +415,18 @@ macro getkw(syms...) Expr(:block, (:($(esc(:((kw, $sym) = $getter(v, o, kw))))) for (sym, getter) in zip(syms, getters))...) end -for (sym, deps, exp, type) in [ - (:lo, (), :(firstindex(v)), Integer), - (:hi, (), :(lastindex(v)), Integer), - (:mn, (), :(throw(ArgumentError("mn is needed but has not been computed"))), :(eltype(v))), - (:mx, (), :(throw(ArgumentError("mx is needed but has not been computed"))), :(eltype(v))), - (:scratch, (), nothing, :(Union{Nothing, Vector})), # could have different eltype - (:allow_legacy_dispatch, (), true, Bool)] +for (sym, exp, type) in [ + (:lo, :(firstindex(v)), Integer), + (:hi, :(lastindex(v)), Integer), + (:mn, :(throw(ArgumentError("mn is needed but has not been computed"))), :(eltype(v))), + (:mx, :(throw(ArgumentError("mx is needed but has not been computed"))), :(eltype(v))), + (:scratch, nothing, :(Union{Nothing, Vector})), # could have different eltype + (:legacy_dispatch_entry, nothing, Union{Nothing, Algorithm})] usym = Symbol(:_, sym) @eval function $usym(v, o, kw) # using missing instead of nothing because scratch could === nothing. res = get(kw, $(Expr(:quote, sym)), missing) res !== missing && return kw, res::$type - @getkw $(deps...) $sym = $exp (;kw..., $sym), $sym::$type end @@ -484,8 +484,6 @@ internal or recursive calls. """ function _sort! end -abstract type Algorithm end - """ MissingOptimization(next) <: Algorithm @@ -509,12 +507,12 @@ struct WithoutMissingVector{T, U} <: AbstractVector{T} new{nonmissingtype(eltype(data)), typeof(data)}(data) end end -Base.@propagate_inbounds function Base.getindex(v::WithoutMissingVector, i) +Base.@propagate_inbounds function Base.getindex(v::WithoutMissingVector, i::Integer) out = v.data[i] @assert !(out isa Missing) out::eltype(v) end -Base.@propagate_inbounds function Base.setindex!(v::WithoutMissingVector, x, i) +Base.@propagate_inbounds function Base.setindex!(v::WithoutMissingVector, x, i::Integer) v.data[i] = x v end @@ -575,8 +573,10 @@ function _sort!(v::AbstractVector, a::MissingOptimization, o::Ordering, kw) # we can assume v is equal to eachindex(o.data) which allows a copying partition # without allocations. lo_i, hi_i = lo, hi - for (i,x) in zip(eachindex(o.data), o.data) - if ismissing(x) == (o.order == Reverse) # should i go at the beginning? + cv = eachindex(o.data) # equal to copy(v) + for i in lo:hi + x = o.data[cv[i]] + if ismissing(x) == (o.order == Reverse) # should x go at the beginning/end? v[lo_i] = i lo_i += 1 else @@ -2120,25 +2120,25 @@ end # Support 3-, 5-, and 6-argument versions of sort! for calling into the internals in the old way sort!(v::AbstractVector, a::Algorithm, o::Ordering) = sort!(v, firstindex(v), lastindex(v), a, o) function sort!(v::AbstractVector, lo::Integer, hi::Integer, a::Algorithm, o::Ordering) - _sort!(v, a, o, (; lo, hi, allow_legacy_dispatch=false)) + _sort!(v, a, o, (; lo, hi, legacy_dispatch_entry=a)) v end sort!(v::AbstractVector, lo::Integer, hi::Integer, a::Algorithm, o::Ordering, _) = sort!(v, lo, hi, a, o) function sort!(v::AbstractVector, lo::Integer, hi::Integer, a::Algorithm, o::Ordering, scratch::Vector) - _sort!(v, a, o, (; lo, hi, scratch, allow_legacy_dispatch=false)) + _sort!(v, a, o, (; lo, hi, scratch, legacy_dispatch_entry=a)) v end # Support dispatch on custom algorithms in the old way # sort!(::AbstractVector, ::Integer, ::Integer, ::MyCustomAlgorithm, ::Ordering) = ... function _sort!(v::AbstractVector, a::Algorithm, o::Ordering, kw) - @getkw lo hi scratch allow_legacy_dispatch - if allow_legacy_dispatch + @getkw lo hi scratch legacy_dispatch_entry + if legacy_dispatch_entry === a + # This error prevents infinite recursion for unknown algorithms + throw(ArgumentError("Base.Sort._sort!(::$(typeof(v)), ::$(typeof(a)), ::$(typeof(o)), ::Any) is not defined")) + else sort!(v, lo, hi, a, o) scratch - else - # This error prevents infinite recursion for unknown algorithms - throw(ArgumentError("Base.Sort._sort!(::$(typeof(v)), ::$(typeof(a)), ::$(typeof(o))) is not defined")) end end diff --git a/base/threadingconstructs.jl b/base/threadingconstructs.jl index 6cc538c4b2ec4..a802aac5a4745 100644 --- a/base/threadingconstructs.jl +++ b/base/threadingconstructs.jl @@ -8,6 +8,25 @@ export threadid, nthreads, @threads, @spawn, Get the ID number of the current thread of execution. The master thread has ID `1`. + +# Examples +```julia-repl +julia> Threads.threadid() +1 + +julia> Threads.@threads for i in 1:4 + println(Threads.threadid()) + end +4 +2 +5 +4 +``` + +!!! note + The thread that a task runs on may change if the task yields, which is known as [`Task Migration`](@ref man-task-migration). + For this reason in most cases it is not safe to use `threadid()` to index into, say, a vector of buffer or stateful objects. + """ threadid() = Int(ccall(:jl_threadid, Int16, ())+1) @@ -40,11 +59,23 @@ function _nthreads_in_pool(tpid::Int8) end function _tpid_to_sym(tpid::Int8) - return tpid == 0 ? :interactive : :default + if tpid == 0 + return :interactive + elseif tpid == 1 + return :default + else + throw(ArgumentError("Unrecognized threadpool id $tpid")) + end end function _sym_to_tpid(tp::Symbol) - return tp === :interactive ? Int8(0) : Int8(1) + if tp === :interactive + return Int8(0) + elseif tp === :default + return Int8(1) + else + throw(ArgumentError("Unrecognized threadpool name `$(repr(tp))`")) + end end """ @@ -207,8 +238,8 @@ For example, the above conditions imply that: - Communicating between iterations using blocking primitives like `Channel`s is incorrect. - Write only to locations not shared across iterations (unless a lock or atomic operation is used). -- The value of [`threadid()`](@ref Threads.threadid) may change even within a single - iteration. +- Unless the `:static` schedule is used, the value of [`threadid()`](@ref Threads.threadid) + may change even within a single iteration. See [`Task Migration`](@ref man-task-migration). ## Schedulers @@ -334,8 +365,10 @@ the _value_ of a variable, isolating the asynchronous code from changes to the variable's value in the current task. !!! note - See the manual chapter on [multi-threading](@ref man-multithreading) - for important caveats. See also the chapter on [threadpools](@ref man-threadpools). + The thread that the task runs on may change if the task yields, therefore `threadid()` should not + be treated as constant for a task. See [`Task Migration`](@ref man-task-migration), and the broader + [multi-threading](@ref man-multithreading) manual for further important caveats. + See also the chapter on [threadpools](@ref man-threadpools). !!! compat "Julia 1.3" This macro is available as of Julia 1.3. @@ -347,20 +380,18 @@ the variable's value in the current task. A threadpool may be specified as of Julia 1.9. """ macro spawn(args...) - tp = :default + tp = QuoteNode(:default) na = length(args) if na == 2 ttype, ex = args if ttype isa QuoteNode ttype = ttype.value - elseif ttype isa Symbol - # TODO: allow unquoted symbols - ttype = nothing - end - if ttype === :interactive || ttype === :default - tp = ttype + if ttype !== :interactive && ttype !== :default + throw(ArgumentError("unsupported threadpool in @spawn: $ttype")) + end + tp = QuoteNode(ttype) else - throw(ArgumentError("unsupported threadpool in @spawn: $ttype")) + tp = ttype end elseif na == 1 ex = args[1] @@ -376,7 +407,7 @@ macro spawn(args...) let $(letargs...) local task = Task($thunk) task.sticky = false - _spawn_set_thrpool(task, $(QuoteNode(tp))) + _spawn_set_thrpool(task, $(esc(tp))) if $(Expr(:islocal, var)) put!($var, task) end diff --git a/deps/checksums/Pkg-3fa06b9f96fc8a180f9285447584c84e4d8d8278.tar.gz/md5 b/deps/checksums/Pkg-3fa06b9f96fc8a180f9285447584c84e4d8d8278.tar.gz/md5 deleted file mode 100644 index 1202ff6a2e2f9..0000000000000 --- a/deps/checksums/Pkg-3fa06b9f96fc8a180f9285447584c84e4d8d8278.tar.gz/md5 +++ /dev/null @@ -1 +0,0 @@ -203b01484d8550eeb8e08d18099b56e0 diff --git a/deps/checksums/Pkg-3fa06b9f96fc8a180f9285447584c84e4d8d8278.tar.gz/sha512 b/deps/checksums/Pkg-3fa06b9f96fc8a180f9285447584c84e4d8d8278.tar.gz/sha512 deleted file mode 100644 index 9fbec4bfd1ffd..0000000000000 --- a/deps/checksums/Pkg-3fa06b9f96fc8a180f9285447584c84e4d8d8278.tar.gz/sha512 +++ /dev/null @@ -1 +0,0 @@ -e0818e7542a360668119cc7bc9f57a136f5fdcb0d0786bb02a98eceaf7d993790bd81c60915857baff84a3ec97a39eadb735d666bf12666e24fcad28035eddc0 diff --git a/deps/checksums/Pkg-cc71837381da2569b0d8e9d2c6130a13f3f5b8f4.tar.gz/md5 b/deps/checksums/Pkg-cc71837381da2569b0d8e9d2c6130a13f3f5b8f4.tar.gz/md5 new file mode 100644 index 0000000000000..947a0387285fe --- /dev/null +++ b/deps/checksums/Pkg-cc71837381da2569b0d8e9d2c6130a13f3f5b8f4.tar.gz/md5 @@ -0,0 +1 @@ +70d0f8bdd4733f4e988c06cd05807e7e diff --git a/deps/checksums/Pkg-cc71837381da2569b0d8e9d2c6130a13f3f5b8f4.tar.gz/sha512 b/deps/checksums/Pkg-cc71837381da2569b0d8e9d2c6130a13f3f5b8f4.tar.gz/sha512 new file mode 100644 index 0000000000000..09e01ee04dc23 --- /dev/null +++ b/deps/checksums/Pkg-cc71837381da2569b0d8e9d2c6130a13f3f5b8f4.tar.gz/sha512 @@ -0,0 +1 @@ +083453c516574124f21dced91b7406b87764ff7aaf6d2a345ce466767cfc39e746954ede3ed292ec31c4623c4ea3debce658fe95c6eb43b916eb1ebfd32a8b1f diff --git a/deps/checksums/compilersupportlibraries b/deps/checksums/compilersupportlibraries index 098c181ca5c87..4830109bd7aea 100644 --- a/deps/checksums/compilersupportlibraries +++ b/deps/checksums/compilersupportlibraries @@ -1,92 +1,92 @@ -CompilerSupportLibraries.v1.0.2+0.aarch64-apple-darwin-libgfortran5.tar.gz/md5/20ebaad57850393b6ac9fa924e511fe4 -CompilerSupportLibraries.v1.0.2+0.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/020de4d8b0ff6bedbadaa305ff8445e6849f12053762ea4aa68412d1ec763dbd86f479587a2fbb862487f1feb04d976c38099ddf3887817a3d32b3f029cf85b1 -CompilerSupportLibraries.v1.0.2+0.aarch64-linux-gnu-libgfortran3.tar.gz/md5/3908fa1a2f739b330e787468c9bfb5c8 -CompilerSupportLibraries.v1.0.2+0.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/1741e3403ac7aa99e7cfd9a01222c4153ed300f47cc1b347e1af1a6cd07a82caaa54b9cfbebae8751440420551621cc6524504413446d104f9493dff2c081853 -CompilerSupportLibraries.v1.0.2+0.aarch64-linux-gnu-libgfortran4.tar.gz/md5/2444dbb7637b32cf543675cc12330878 -CompilerSupportLibraries.v1.0.2+0.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/8537f0b243df8544350c884021b21c585fd302e8dd462a30a6ee84c7a36a049133262e5d1bc362f972066b8e8d6a091c32c3b746bab1feb9fccf2e7cca65756c -CompilerSupportLibraries.v1.0.2+0.aarch64-linux-gnu-libgfortran5.tar.gz/md5/d79c1434594c0c5e7d6be798bf52c99e -CompilerSupportLibraries.v1.0.2+0.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/7e71accc401a45b51b298702fb4c79a2fc856c7b28f0935f6ad3a0db5381c55fe5432daff371842930d718024b7c6c1d80e2bd09d397145203673bebbe3496ae -CompilerSupportLibraries.v1.0.2+0.aarch64-linux-musl-libgfortran3.tar.gz/md5/f212059053d99558a9b0bf54b20180e1 -CompilerSupportLibraries.v1.0.2+0.aarch64-linux-musl-libgfortran3.tar.gz/sha512/5c104b1282cec8a944e5d008f44a4d60f4394fd5d797fec7d1f487d13e7328cd9c88ec4916dabf18596d87160756bda914e4f8c5a356b5577f9349d0d9e976d6 -CompilerSupportLibraries.v1.0.2+0.aarch64-linux-musl-libgfortran4.tar.gz/md5/3e3b3795ee93ef317223050e803a9875 -CompilerSupportLibraries.v1.0.2+0.aarch64-linux-musl-libgfortran4.tar.gz/sha512/85d3c955e15f66bfe8bfec2f28c9160bc03d4d531ea4ffe6bc6b51e0d69ccea3ab67a16ca752dabc870861c407381c4519d75c6be3832e8dccd6122ec8c6ed75 -CompilerSupportLibraries.v1.0.2+0.aarch64-linux-musl-libgfortran5.tar.gz/md5/cf2d1315f6a348af2e6c065e2a286e7a -CompilerSupportLibraries.v1.0.2+0.aarch64-linux-musl-libgfortran5.tar.gz/sha512/58420377bc77aa7678034ee5f708eb6be7db359faef2c2638869765453633da9bf455512bd88e95b38ae0428ecc4053561517b176b2371129bdaef9d8d5dadfd -CompilerSupportLibraries.v1.0.2+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/f5c09ed7e0eeb8d345d328f950582f26 -CompilerSupportLibraries.v1.0.2+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/9c657f55c8fcdeb404be168a3a63a5e84304730fe34f25673d92cdae4b0a1fcc6a877ee1433f060e1be854c7811d66632e32510a2ed591d88330f1340b9c20de -CompilerSupportLibraries.v1.0.2+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/c685518aca4721cd8621d510e2039683 -CompilerSupportLibraries.v1.0.2+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/b760468c6377dcd2b8dd50200daaabe604006afc070984d78152b2becd0680b59036c9a6e91dea490121bd85b58d285bfc1e1cf696d29af236528400101de36c -CompilerSupportLibraries.v1.0.2+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/8faf5c8ad62ab10f71dd2ec9683053e2 -CompilerSupportLibraries.v1.0.2+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/921239f241a5c89710cf07272d7f6c3f10201a7533068ed1e9643f9fb2f439e1bb765a4966d913829866ee0ce4f1589d30d06e4b5c1361e3c016a9473f087177 -CompilerSupportLibraries.v1.0.2+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/b38fcb70691ac2621379d298eef8c79e -CompilerSupportLibraries.v1.0.2+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/06c7f64257ce721f5941f6e50a0d2717cdc9394fc532ded19ce3eaacd5e92a416969534227562e4fee04d2b6340c650d8bc9779e14519b90038bc41e8d1f5ce3 -CompilerSupportLibraries.v1.0.2+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/cdfab2c7bc41765caf4441c3caeed761 -CompilerSupportLibraries.v1.0.2+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/7109d4a7b32c00309c42685f54a86fc2cc63c0c00f65584ad296b6e44ad3320eed1aaf49684a8831841cdffa5555d72f89272fb722a780596e27ef020528026b -CompilerSupportLibraries.v1.0.2+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/441980ebd23d72772cbe603f1c275336 -CompilerSupportLibraries.v1.0.2+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/e273d9f1af259a3080df8f173e1808a1ade976a943aba97216bf59a96178e7c052e7a048b0ceee53ab486ed577a2ecb92579857be2f7b29e76322ee1f13c9d76 -CompilerSupportLibraries.v1.0.2+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/f5c09ed7e0eeb8d345d328f950582f26 -CompilerSupportLibraries.v1.0.2+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/9c657f55c8fcdeb404be168a3a63a5e84304730fe34f25673d92cdae4b0a1fcc6a877ee1433f060e1be854c7811d66632e32510a2ed591d88330f1340b9c20de -CompilerSupportLibraries.v1.0.2+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/c685518aca4721cd8621d510e2039683 -CompilerSupportLibraries.v1.0.2+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/b760468c6377dcd2b8dd50200daaabe604006afc070984d78152b2becd0680b59036c9a6e91dea490121bd85b58d285bfc1e1cf696d29af236528400101de36c -CompilerSupportLibraries.v1.0.2+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/8faf5c8ad62ab10f71dd2ec9683053e2 -CompilerSupportLibraries.v1.0.2+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/921239f241a5c89710cf07272d7f6c3f10201a7533068ed1e9643f9fb2f439e1bb765a4966d913829866ee0ce4f1589d30d06e4b5c1361e3c016a9473f087177 -CompilerSupportLibraries.v1.0.2+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/b38fcb70691ac2621379d298eef8c79e -CompilerSupportLibraries.v1.0.2+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/06c7f64257ce721f5941f6e50a0d2717cdc9394fc532ded19ce3eaacd5e92a416969534227562e4fee04d2b6340c650d8bc9779e14519b90038bc41e8d1f5ce3 -CompilerSupportLibraries.v1.0.2+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/cdfab2c7bc41765caf4441c3caeed761 -CompilerSupportLibraries.v1.0.2+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/7109d4a7b32c00309c42685f54a86fc2cc63c0c00f65584ad296b6e44ad3320eed1aaf49684a8831841cdffa5555d72f89272fb722a780596e27ef020528026b -CompilerSupportLibraries.v1.0.2+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/441980ebd23d72772cbe603f1c275336 -CompilerSupportLibraries.v1.0.2+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/e273d9f1af259a3080df8f173e1808a1ade976a943aba97216bf59a96178e7c052e7a048b0ceee53ab486ed577a2ecb92579857be2f7b29e76322ee1f13c9d76 -CompilerSupportLibraries.v1.0.2+0.i686-linux-gnu-libgfortran3.tar.gz/md5/6decf8fd5afb50451771c761e63a8917 -CompilerSupportLibraries.v1.0.2+0.i686-linux-gnu-libgfortran3.tar.gz/sha512/4984724bcc847724b1bc005b6f760a18b68147f7d5402d0faf4e28fc0d14fa10975368a951f9caf2a8856500046dec8343043274557d58269e77492b929a9e4b -CompilerSupportLibraries.v1.0.2+0.i686-linux-gnu-libgfortran4.tar.gz/md5/39d1e8a3baa144c018d3eaf7f3806482 -CompilerSupportLibraries.v1.0.2+0.i686-linux-gnu-libgfortran4.tar.gz/sha512/fc4d429279c5a93b6c28b6e911b1e7cfd1c1cfe46f11f2e901b3832ce90d45f49d3d29f0ef18518a94af6cc8651f67c4ed81672680f9281ada390440b172a2af -CompilerSupportLibraries.v1.0.2+0.i686-linux-gnu-libgfortran5.tar.gz/md5/37dabd9cd224c9fed9633dedccb6c565 -CompilerSupportLibraries.v1.0.2+0.i686-linux-gnu-libgfortran5.tar.gz/sha512/b253149e72eef9486888fbaace66e9b6945f4477f6b818f64f3047331165b0e2bc17aa6e3fc8c88686a72e478eb62c8f53883415d5419db448d8016fa3a1da5e -CompilerSupportLibraries.v1.0.2+0.i686-linux-musl-libgfortran3.tar.gz/md5/afdd32bfadd465848e6be458817a44ae -CompilerSupportLibraries.v1.0.2+0.i686-linux-musl-libgfortran3.tar.gz/sha512/eebd679c499143014514c7c9d1875dedbbab9e3af51526c4dd445a9e3dbade95d24522da8bbad0a50ab400755e47b018828b324c4ad7705e212ccd990e34439a -CompilerSupportLibraries.v1.0.2+0.i686-linux-musl-libgfortran4.tar.gz/md5/bc4a0f0b7cea328f7e8850583774496b -CompilerSupportLibraries.v1.0.2+0.i686-linux-musl-libgfortran4.tar.gz/sha512/82285b67946212b49cddf6259f2c60ff5469f8c5263ccefe44f1d93ace98ab68e2c152e1b54434b2f075fd8d192c06d5451bc8cca26d951ad15f3453102f02b5 -CompilerSupportLibraries.v1.0.2+0.i686-linux-musl-libgfortran5.tar.gz/md5/177f0232abce8d523882530ed7a93092 -CompilerSupportLibraries.v1.0.2+0.i686-linux-musl-libgfortran5.tar.gz/sha512/db80acf0f2434f28ee7680e1beb34f564940071815d1ad89fb5913cbd9ac24da528e826d0d54be6265a7340ebd661b6d308ed79d96b67fa5d8c98dc3f1bee8d6 -CompilerSupportLibraries.v1.0.2+0.i686-w64-mingw32-libgfortran3.tar.gz/md5/756718e5eaa4547b874a71a8e3545492 -CompilerSupportLibraries.v1.0.2+0.i686-w64-mingw32-libgfortran3.tar.gz/sha512/c21c1be10ca8810f56e435b3629e2ab0678926ea9c4f4c3dd003f9e292c075493b83df04401d3bcf7738f1a44098f674f9b01bba9db4b9a9e45ad7af3497444e -CompilerSupportLibraries.v1.0.2+0.i686-w64-mingw32-libgfortran4.tar.gz/md5/65ce0024bf8fe3276addbf185ed03e48 -CompilerSupportLibraries.v1.0.2+0.i686-w64-mingw32-libgfortran4.tar.gz/sha512/5e8105a12ab04e2949e41eda50a060dea04ccd98660c7528cfc86e120fe61cca8bab878fd2c92a3858f02ac3f3c55d0e48789907e5fbd2392a8e84b183ed4636 -CompilerSupportLibraries.v1.0.2+0.i686-w64-mingw32-libgfortran5.tar.gz/md5/b7727324d550f637209db795238c46a4 -CompilerSupportLibraries.v1.0.2+0.i686-w64-mingw32-libgfortran5.tar.gz/sha512/864b1db2642e68665b9d3322563c7ce964835d0e720325ea00b193e2cbf6791760e0014710e2a79876165ab0daffa6d53d61b87a5034f956ba6e255b0144652c -CompilerSupportLibraries.v1.0.2+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/4e5e4b23dc87450738da33926a07511d -CompilerSupportLibraries.v1.0.2+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/fc09879d94b750e75775d8b64a41ab9924d675fb53c5700467604412928fe7f5cb21911da0f64898d2463fa77ffbaf4c96c397b9060f4746eec152747930cddc -CompilerSupportLibraries.v1.0.2+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/9a92138ed69aa317a932a615c6e62d69 -CompilerSupportLibraries.v1.0.2+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/0b7785379936a2a209b074177b1424dd7e00b29b5165f564e799b0aa4e06a582e9d616525d97274ba2507cb88192028f1ac485d3f99bdc7ee53fc63c1a7e85de -CompilerSupportLibraries.v1.0.2+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/8ffee3d6de5197c7a1f354d72c8238fa -CompilerSupportLibraries.v1.0.2+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/deadc4d7224c84f9b82dc956b69e815c44ae036802838365d870ab9f58c8bcf8ce0645f2f387c8ff344ac2108fc8e7e1ee907fa55e93c91aa5d9fd921bf3fdcb -CompilerSupportLibraries.v1.0.2+0.x86_64-apple-darwin-libgfortran3.tar.gz/md5/87449e72e3f33dbb69b7053cdc2649d4 -CompilerSupportLibraries.v1.0.2+0.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/5ce02ad10c6f4686a476eb2a5de2988cd8b482f5e693db2880c84ad1c82f468ef03fe01b9d0feefe5d4ee741d1d16643d36b144e6261ed32311b3b6f312fac2f -CompilerSupportLibraries.v1.0.2+0.x86_64-apple-darwin-libgfortran4.tar.gz/md5/0407cde92cfa42fa89ac83217ca0ec16 -CompilerSupportLibraries.v1.0.2+0.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/032c831f1166a336551138939ac40eb2c68a048ce786c0c1403b879a20c1b706caac16d22560b2c7f2b3d6373986c347188675674116005ca251336ee048d09f -CompilerSupportLibraries.v1.0.2+0.x86_64-apple-darwin-libgfortran5.tar.gz/md5/23418763b808371ee94772a90d501f4d -CompilerSupportLibraries.v1.0.2+0.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/7867b843551457b11bda7821dd384c1c1cf23b80a308b2058a693de7b7da099f0b37eb0a6de2b84c04b625a68c60eea55138e200d5d6ec6f6af09bd7ce406a96 -CompilerSupportLibraries.v1.0.2+0.x86_64-linux-gnu-libgfortran3.tar.gz/md5/e3d33ae03c18affea74699bdc1fabb68 -CompilerSupportLibraries.v1.0.2+0.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/42013f4921de5a69ad857195ce5c19ad1bca3c920d79699e5501f1f4534ab132fabd422362b2b5056f5d182215d6c069db5df460bafa700903faf962cc00f77b -CompilerSupportLibraries.v1.0.2+0.x86_64-linux-gnu-libgfortran4.tar.gz/md5/d40c1e8c0393213c6057c53a12f44175 -CompilerSupportLibraries.v1.0.2+0.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/fe7baa4de7490065ab7b953cc12f41462a24bcb49d0a4a64b23249e98e7569b19bb1cb455af2f76090e34066a7d3cdd7a48cae6515ce6c7a5c8486b0cacc5106 -CompilerSupportLibraries.v1.0.2+0.x86_64-linux-gnu-libgfortran5.tar.gz/md5/48541b90f715c4c86ee4da0570275947 -CompilerSupportLibraries.v1.0.2+0.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/7f2683fb98e80f12629f4ed3bea9fd59d32b7e7a9ed1699e782d8e238ff0915ecc61bf00adaf4597cfe41caf82cdca0f9be250f595f5f0bea6d8f77dba99eaf4 -CompilerSupportLibraries.v1.0.2+0.x86_64-linux-musl-libgfortran3.tar.gz/md5/4547059eb905995667be48bf85d49911 -CompilerSupportLibraries.v1.0.2+0.x86_64-linux-musl-libgfortran3.tar.gz/sha512/7400fdabc924434ab4a4949248c3603887ac06ffd2f205ae33e14495d86cd4f816bbd1999eeafa0257f518df1e7f7c522f596e847a71dbfbfccff4859f50acc7 -CompilerSupportLibraries.v1.0.2+0.x86_64-linux-musl-libgfortran4.tar.gz/md5/46267543cad6584d7b7b9fcc8f18f21d -CompilerSupportLibraries.v1.0.2+0.x86_64-linux-musl-libgfortran4.tar.gz/sha512/0353d7d724be48d4185d3c181692970b7996f53f6a01723072aa5c94b53a8c5055faeed30df51659c252a46f4b941dec0cb24569323e3c85c166f14c5b7c8e9e -CompilerSupportLibraries.v1.0.2+0.x86_64-linux-musl-libgfortran5.tar.gz/md5/14dba2897a6e9d370fa9091c045375fc -CompilerSupportLibraries.v1.0.2+0.x86_64-linux-musl-libgfortran5.tar.gz/sha512/10b79f9c059839f5b57fa8d2a381a034c4067262c4088bd354d14ea56bec097878069383aa9cfadaa09d73bd20fc348fb61662d863a8d62cb25d7af6b8e29858 -CompilerSupportLibraries.v1.0.2+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/eed836d1addeb10d0901f836724aff1e -CompilerSupportLibraries.v1.0.2+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/e33eca424d1529a1fb23ba9cf7fac345ed1cfc8073c975b6b31ca44d2e8c3f5083af65433df009b22483dceb2e43149f3c1e8433681fec5fb812e1d5b4243ce4 -CompilerSupportLibraries.v1.0.2+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/d5ae9f9519341fdaabf62267c89461d2 -CompilerSupportLibraries.v1.0.2+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/6421aa5d1bd6f08ad43f59ed4dc1bef8b9b598ebbbd3e48149730f3bec3471f8e2c02ffb338427326924290b8f52ef9e626e3313448bc931a61d866c5dc544ae -CompilerSupportLibraries.v1.0.2+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/fc1df521395362a5aaa2e2aeef707207 -CompilerSupportLibraries.v1.0.2+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/f2e5a08e3cae171242ae6a20d2d4838c1529ce042745dc466148b7bbc06896d94476fd05c7787e6e8641bea752dfc0e6b09e95b160bede600d20d2ad68e7705f -CompilerSupportLibraries.v1.0.2+0.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/2338f8aa2696935f7460454e708ce308 -CompilerSupportLibraries.v1.0.2+0.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/5a4b0e97928c26eee16bbec4c3e69e55fa9c768101257c3e2f161118809c778aa0feaf21307198822c3172a58ed12ca0a49285b2941ed0b8f2b367e64ca1c51a -CompilerSupportLibraries.v1.0.2+0.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/b393d2bf0d181d218130ac572c17d369 -CompilerSupportLibraries.v1.0.2+0.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/76e0f7caa24bb734c6f7542be9f834d5b912f082cb3c4c3c52a63e37d4b8c33dd94e576c43f4bee6c04bfb44af2f2b67ba70773fa52ad0de6c8c0059b3e51b83 -CompilerSupportLibraries.v1.0.2+0.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/23db836e6e4142f621862971017fe61e -CompilerSupportLibraries.v1.0.2+0.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/c0b04f7fe5aabfe6af509c77a1f68e0bcfd14714758042fe502b968c4cc272156fc84c8b4c1ee574754bb2fddaa810f6a4215cbd164ddc11b697b3adaef09a81 +CompilerSupportLibraries.v1.0.5+0.aarch64-apple-darwin-libgfortran5.tar.gz/md5/20ebaad57850393b6ac9fa924e511fe4 +CompilerSupportLibraries.v1.0.5+0.aarch64-apple-darwin-libgfortran5.tar.gz/sha512/020de4d8b0ff6bedbadaa305ff8445e6849f12053762ea4aa68412d1ec763dbd86f479587a2fbb862487f1feb04d976c38099ddf3887817a3d32b3f029cf85b1 +CompilerSupportLibraries.v1.0.5+0.aarch64-linux-gnu-libgfortran3.tar.gz/md5/3908fa1a2f739b330e787468c9bfb5c8 +CompilerSupportLibraries.v1.0.5+0.aarch64-linux-gnu-libgfortran3.tar.gz/sha512/1741e3403ac7aa99e7cfd9a01222c4153ed300f47cc1b347e1af1a6cd07a82caaa54b9cfbebae8751440420551621cc6524504413446d104f9493dff2c081853 +CompilerSupportLibraries.v1.0.5+0.aarch64-linux-gnu-libgfortran4.tar.gz/md5/2444dbb7637b32cf543675cc12330878 +CompilerSupportLibraries.v1.0.5+0.aarch64-linux-gnu-libgfortran4.tar.gz/sha512/8537f0b243df8544350c884021b21c585fd302e8dd462a30a6ee84c7a36a049133262e5d1bc362f972066b8e8d6a091c32c3b746bab1feb9fccf2e7cca65756c +CompilerSupportLibraries.v1.0.5+0.aarch64-linux-gnu-libgfortran5.tar.gz/md5/d79c1434594c0c5e7d6be798bf52c99e +CompilerSupportLibraries.v1.0.5+0.aarch64-linux-gnu-libgfortran5.tar.gz/sha512/7e71accc401a45b51b298702fb4c79a2fc856c7b28f0935f6ad3a0db5381c55fe5432daff371842930d718024b7c6c1d80e2bd09d397145203673bebbe3496ae +CompilerSupportLibraries.v1.0.5+0.aarch64-linux-musl-libgfortran3.tar.gz/md5/f212059053d99558a9b0bf54b20180e1 +CompilerSupportLibraries.v1.0.5+0.aarch64-linux-musl-libgfortran3.tar.gz/sha512/5c104b1282cec8a944e5d008f44a4d60f4394fd5d797fec7d1f487d13e7328cd9c88ec4916dabf18596d87160756bda914e4f8c5a356b5577f9349d0d9e976d6 +CompilerSupportLibraries.v1.0.5+0.aarch64-linux-musl-libgfortran4.tar.gz/md5/3e3b3795ee93ef317223050e803a9875 +CompilerSupportLibraries.v1.0.5+0.aarch64-linux-musl-libgfortran4.tar.gz/sha512/85d3c955e15f66bfe8bfec2f28c9160bc03d4d531ea4ffe6bc6b51e0d69ccea3ab67a16ca752dabc870861c407381c4519d75c6be3832e8dccd6122ec8c6ed75 +CompilerSupportLibraries.v1.0.5+0.aarch64-linux-musl-libgfortran5.tar.gz/md5/cf2d1315f6a348af2e6c065e2a286e7a +CompilerSupportLibraries.v1.0.5+0.aarch64-linux-musl-libgfortran5.tar.gz/sha512/58420377bc77aa7678034ee5f708eb6be7db359faef2c2638869765453633da9bf455512bd88e95b38ae0428ecc4053561517b176b2371129bdaef9d8d5dadfd +CompilerSupportLibraries.v1.0.5+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/md5/f5c09ed7e0eeb8d345d328f950582f26 +CompilerSupportLibraries.v1.0.5+0.armv6l-linux-gnueabihf-libgfortran3.tar.gz/sha512/9c657f55c8fcdeb404be168a3a63a5e84304730fe34f25673d92cdae4b0a1fcc6a877ee1433f060e1be854c7811d66632e32510a2ed591d88330f1340b9c20de +CompilerSupportLibraries.v1.0.5+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/md5/c685518aca4721cd8621d510e2039683 +CompilerSupportLibraries.v1.0.5+0.armv6l-linux-gnueabihf-libgfortran4.tar.gz/sha512/b760468c6377dcd2b8dd50200daaabe604006afc070984d78152b2becd0680b59036c9a6e91dea490121bd85b58d285bfc1e1cf696d29af236528400101de36c +CompilerSupportLibraries.v1.0.5+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/md5/8faf5c8ad62ab10f71dd2ec9683053e2 +CompilerSupportLibraries.v1.0.5+0.armv6l-linux-gnueabihf-libgfortran5.tar.gz/sha512/921239f241a5c89710cf07272d7f6c3f10201a7533068ed1e9643f9fb2f439e1bb765a4966d913829866ee0ce4f1589d30d06e4b5c1361e3c016a9473f087177 +CompilerSupportLibraries.v1.0.5+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/md5/b38fcb70691ac2621379d298eef8c79e +CompilerSupportLibraries.v1.0.5+0.armv6l-linux-musleabihf-libgfortran3.tar.gz/sha512/06c7f64257ce721f5941f6e50a0d2717cdc9394fc532ded19ce3eaacd5e92a416969534227562e4fee04d2b6340c650d8bc9779e14519b90038bc41e8d1f5ce3 +CompilerSupportLibraries.v1.0.5+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/md5/cdfab2c7bc41765caf4441c3caeed761 +CompilerSupportLibraries.v1.0.5+0.armv6l-linux-musleabihf-libgfortran4.tar.gz/sha512/7109d4a7b32c00309c42685f54a86fc2cc63c0c00f65584ad296b6e44ad3320eed1aaf49684a8831841cdffa5555d72f89272fb722a780596e27ef020528026b +CompilerSupportLibraries.v1.0.5+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/md5/441980ebd23d72772cbe603f1c275336 +CompilerSupportLibraries.v1.0.5+0.armv6l-linux-musleabihf-libgfortran5.tar.gz/sha512/e273d9f1af259a3080df8f173e1808a1ade976a943aba97216bf59a96178e7c052e7a048b0ceee53ab486ed577a2ecb92579857be2f7b29e76322ee1f13c9d76 +CompilerSupportLibraries.v1.0.5+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/md5/f5c09ed7e0eeb8d345d328f950582f26 +CompilerSupportLibraries.v1.0.5+0.armv7l-linux-gnueabihf-libgfortran3.tar.gz/sha512/9c657f55c8fcdeb404be168a3a63a5e84304730fe34f25673d92cdae4b0a1fcc6a877ee1433f060e1be854c7811d66632e32510a2ed591d88330f1340b9c20de +CompilerSupportLibraries.v1.0.5+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/md5/c685518aca4721cd8621d510e2039683 +CompilerSupportLibraries.v1.0.5+0.armv7l-linux-gnueabihf-libgfortran4.tar.gz/sha512/b760468c6377dcd2b8dd50200daaabe604006afc070984d78152b2becd0680b59036c9a6e91dea490121bd85b58d285bfc1e1cf696d29af236528400101de36c +CompilerSupportLibraries.v1.0.5+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/md5/8faf5c8ad62ab10f71dd2ec9683053e2 +CompilerSupportLibraries.v1.0.5+0.armv7l-linux-gnueabihf-libgfortran5.tar.gz/sha512/921239f241a5c89710cf07272d7f6c3f10201a7533068ed1e9643f9fb2f439e1bb765a4966d913829866ee0ce4f1589d30d06e4b5c1361e3c016a9473f087177 +CompilerSupportLibraries.v1.0.5+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/md5/b38fcb70691ac2621379d298eef8c79e +CompilerSupportLibraries.v1.0.5+0.armv7l-linux-musleabihf-libgfortran3.tar.gz/sha512/06c7f64257ce721f5941f6e50a0d2717cdc9394fc532ded19ce3eaacd5e92a416969534227562e4fee04d2b6340c650d8bc9779e14519b90038bc41e8d1f5ce3 +CompilerSupportLibraries.v1.0.5+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/md5/cdfab2c7bc41765caf4441c3caeed761 +CompilerSupportLibraries.v1.0.5+0.armv7l-linux-musleabihf-libgfortran4.tar.gz/sha512/7109d4a7b32c00309c42685f54a86fc2cc63c0c00f65584ad296b6e44ad3320eed1aaf49684a8831841cdffa5555d72f89272fb722a780596e27ef020528026b +CompilerSupportLibraries.v1.0.5+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/md5/441980ebd23d72772cbe603f1c275336 +CompilerSupportLibraries.v1.0.5+0.armv7l-linux-musleabihf-libgfortran5.tar.gz/sha512/e273d9f1af259a3080df8f173e1808a1ade976a943aba97216bf59a96178e7c052e7a048b0ceee53ab486ed577a2ecb92579857be2f7b29e76322ee1f13c9d76 +CompilerSupportLibraries.v1.0.5+0.i686-linux-gnu-libgfortran3.tar.gz/md5/6decf8fd5afb50451771c761e63a8917 +CompilerSupportLibraries.v1.0.5+0.i686-linux-gnu-libgfortran3.tar.gz/sha512/4984724bcc847724b1bc005b6f760a18b68147f7d5402d0faf4e28fc0d14fa10975368a951f9caf2a8856500046dec8343043274557d58269e77492b929a9e4b +CompilerSupportLibraries.v1.0.5+0.i686-linux-gnu-libgfortran4.tar.gz/md5/39d1e8a3baa144c018d3eaf7f3806482 +CompilerSupportLibraries.v1.0.5+0.i686-linux-gnu-libgfortran4.tar.gz/sha512/fc4d429279c5a93b6c28b6e911b1e7cfd1c1cfe46f11f2e901b3832ce90d45f49d3d29f0ef18518a94af6cc8651f67c4ed81672680f9281ada390440b172a2af +CompilerSupportLibraries.v1.0.5+0.i686-linux-gnu-libgfortran5.tar.gz/md5/37dabd9cd224c9fed9633dedccb6c565 +CompilerSupportLibraries.v1.0.5+0.i686-linux-gnu-libgfortran5.tar.gz/sha512/b253149e72eef9486888fbaace66e9b6945f4477f6b818f64f3047331165b0e2bc17aa6e3fc8c88686a72e478eb62c8f53883415d5419db448d8016fa3a1da5e +CompilerSupportLibraries.v1.0.5+0.i686-linux-musl-libgfortran3.tar.gz/md5/afdd32bfadd465848e6be458817a44ae +CompilerSupportLibraries.v1.0.5+0.i686-linux-musl-libgfortran3.tar.gz/sha512/eebd679c499143014514c7c9d1875dedbbab9e3af51526c4dd445a9e3dbade95d24522da8bbad0a50ab400755e47b018828b324c4ad7705e212ccd990e34439a +CompilerSupportLibraries.v1.0.5+0.i686-linux-musl-libgfortran4.tar.gz/md5/bc4a0f0b7cea328f7e8850583774496b +CompilerSupportLibraries.v1.0.5+0.i686-linux-musl-libgfortran4.tar.gz/sha512/82285b67946212b49cddf6259f2c60ff5469f8c5263ccefe44f1d93ace98ab68e2c152e1b54434b2f075fd8d192c06d5451bc8cca26d951ad15f3453102f02b5 +CompilerSupportLibraries.v1.0.5+0.i686-linux-musl-libgfortran5.tar.gz/md5/177f0232abce8d523882530ed7a93092 +CompilerSupportLibraries.v1.0.5+0.i686-linux-musl-libgfortran5.tar.gz/sha512/db80acf0f2434f28ee7680e1beb34f564940071815d1ad89fb5913cbd9ac24da528e826d0d54be6265a7340ebd661b6d308ed79d96b67fa5d8c98dc3f1bee8d6 +CompilerSupportLibraries.v1.0.5+0.i686-w64-mingw32-libgfortran3.tar.gz/md5/f5795dada5360eb8422f45150b13bae9 +CompilerSupportLibraries.v1.0.5+0.i686-w64-mingw32-libgfortran3.tar.gz/sha512/6acd1bf7c81631cef9b8b0576ccece08723c5ae2f49de2487d3aefd25f9a0ad49df09e3782735267997d40687b04b85c89e00f6889b026af599bf1bbe91803a1 +CompilerSupportLibraries.v1.0.5+0.i686-w64-mingw32-libgfortran4.tar.gz/md5/5e590f83161913f0145ba8d496b2504b +CompilerSupportLibraries.v1.0.5+0.i686-w64-mingw32-libgfortran4.tar.gz/sha512/4a3f36588afcdef26173764597054068e26f2376e6126a9a94c46b258b5d7a29951d47b5e1ba24df6c3d139bbc4decc5c501a266811692d7fadadc7bd7b6960d +CompilerSupportLibraries.v1.0.5+0.i686-w64-mingw32-libgfortran5.tar.gz/md5/27da4a7c890fe1427c33fe214cc5feaf +CompilerSupportLibraries.v1.0.5+0.i686-w64-mingw32-libgfortran5.tar.gz/sha512/310ad00f053f9f3ec715ce2e8d20446f397728dff5acc787ea9c9332346607a3d42b678099c424e6d6e5294acddf2aa26051de657b48d34abfd04486951bf241 +CompilerSupportLibraries.v1.0.5+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/md5/4e5e4b23dc87450738da33926a07511d +CompilerSupportLibraries.v1.0.5+0.powerpc64le-linux-gnu-libgfortran3.tar.gz/sha512/fc09879d94b750e75775d8b64a41ab9924d675fb53c5700467604412928fe7f5cb21911da0f64898d2463fa77ffbaf4c96c397b9060f4746eec152747930cddc +CompilerSupportLibraries.v1.0.5+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/md5/9a92138ed69aa317a932a615c6e62d69 +CompilerSupportLibraries.v1.0.5+0.powerpc64le-linux-gnu-libgfortran4.tar.gz/sha512/0b7785379936a2a209b074177b1424dd7e00b29b5165f564e799b0aa4e06a582e9d616525d97274ba2507cb88192028f1ac485d3f99bdc7ee53fc63c1a7e85de +CompilerSupportLibraries.v1.0.5+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/md5/8ffee3d6de5197c7a1f354d72c8238fa +CompilerSupportLibraries.v1.0.5+0.powerpc64le-linux-gnu-libgfortran5.tar.gz/sha512/deadc4d7224c84f9b82dc956b69e815c44ae036802838365d870ab9f58c8bcf8ce0645f2f387c8ff344ac2108fc8e7e1ee907fa55e93c91aa5d9fd921bf3fdcb +CompilerSupportLibraries.v1.0.5+0.x86_64-apple-darwin-libgfortran3.tar.gz/md5/87449e72e3f33dbb69b7053cdc2649d4 +CompilerSupportLibraries.v1.0.5+0.x86_64-apple-darwin-libgfortran3.tar.gz/sha512/5ce02ad10c6f4686a476eb2a5de2988cd8b482f5e693db2880c84ad1c82f468ef03fe01b9d0feefe5d4ee741d1d16643d36b144e6261ed32311b3b6f312fac2f +CompilerSupportLibraries.v1.0.5+0.x86_64-apple-darwin-libgfortran4.tar.gz/md5/0407cde92cfa42fa89ac83217ca0ec16 +CompilerSupportLibraries.v1.0.5+0.x86_64-apple-darwin-libgfortran4.tar.gz/sha512/032c831f1166a336551138939ac40eb2c68a048ce786c0c1403b879a20c1b706caac16d22560b2c7f2b3d6373986c347188675674116005ca251336ee048d09f +CompilerSupportLibraries.v1.0.5+0.x86_64-apple-darwin-libgfortran5.tar.gz/md5/23418763b808371ee94772a90d501f4d +CompilerSupportLibraries.v1.0.5+0.x86_64-apple-darwin-libgfortran5.tar.gz/sha512/7867b843551457b11bda7821dd384c1c1cf23b80a308b2058a693de7b7da099f0b37eb0a6de2b84c04b625a68c60eea55138e200d5d6ec6f6af09bd7ce406a96 +CompilerSupportLibraries.v1.0.5+0.x86_64-linux-gnu-libgfortran3.tar.gz/md5/e3d33ae03c18affea74699bdc1fabb68 +CompilerSupportLibraries.v1.0.5+0.x86_64-linux-gnu-libgfortran3.tar.gz/sha512/42013f4921de5a69ad857195ce5c19ad1bca3c920d79699e5501f1f4534ab132fabd422362b2b5056f5d182215d6c069db5df460bafa700903faf962cc00f77b +CompilerSupportLibraries.v1.0.5+0.x86_64-linux-gnu-libgfortran4.tar.gz/md5/d40c1e8c0393213c6057c53a12f44175 +CompilerSupportLibraries.v1.0.5+0.x86_64-linux-gnu-libgfortran4.tar.gz/sha512/fe7baa4de7490065ab7b953cc12f41462a24bcb49d0a4a64b23249e98e7569b19bb1cb455af2f76090e34066a7d3cdd7a48cae6515ce6c7a5c8486b0cacc5106 +CompilerSupportLibraries.v1.0.5+0.x86_64-linux-gnu-libgfortran5.tar.gz/md5/48541b90f715c4c86ee4da0570275947 +CompilerSupportLibraries.v1.0.5+0.x86_64-linux-gnu-libgfortran5.tar.gz/sha512/7f2683fb98e80f12629f4ed3bea9fd59d32b7e7a9ed1699e782d8e238ff0915ecc61bf00adaf4597cfe41caf82cdca0f9be250f595f5f0bea6d8f77dba99eaf4 +CompilerSupportLibraries.v1.0.5+0.x86_64-linux-musl-libgfortran3.tar.gz/md5/4547059eb905995667be48bf85d49911 +CompilerSupportLibraries.v1.0.5+0.x86_64-linux-musl-libgfortran3.tar.gz/sha512/7400fdabc924434ab4a4949248c3603887ac06ffd2f205ae33e14495d86cd4f816bbd1999eeafa0257f518df1e7f7c522f596e847a71dbfbfccff4859f50acc7 +CompilerSupportLibraries.v1.0.5+0.x86_64-linux-musl-libgfortran4.tar.gz/md5/46267543cad6584d7b7b9fcc8f18f21d +CompilerSupportLibraries.v1.0.5+0.x86_64-linux-musl-libgfortran4.tar.gz/sha512/0353d7d724be48d4185d3c181692970b7996f53f6a01723072aa5c94b53a8c5055faeed30df51659c252a46f4b941dec0cb24569323e3c85c166f14c5b7c8e9e +CompilerSupportLibraries.v1.0.5+0.x86_64-linux-musl-libgfortran5.tar.gz/md5/14dba2897a6e9d370fa9091c045375fc +CompilerSupportLibraries.v1.0.5+0.x86_64-linux-musl-libgfortran5.tar.gz/sha512/10b79f9c059839f5b57fa8d2a381a034c4067262c4088bd354d14ea56bec097878069383aa9cfadaa09d73bd20fc348fb61662d863a8d62cb25d7af6b8e29858 +CompilerSupportLibraries.v1.0.5+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/md5/eed836d1addeb10d0901f836724aff1e +CompilerSupportLibraries.v1.0.5+0.x86_64-unknown-freebsd-libgfortran3.tar.gz/sha512/e33eca424d1529a1fb23ba9cf7fac345ed1cfc8073c975b6b31ca44d2e8c3f5083af65433df009b22483dceb2e43149f3c1e8433681fec5fb812e1d5b4243ce4 +CompilerSupportLibraries.v1.0.5+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/md5/d5ae9f9519341fdaabf62267c89461d2 +CompilerSupportLibraries.v1.0.5+0.x86_64-unknown-freebsd-libgfortran4.tar.gz/sha512/6421aa5d1bd6f08ad43f59ed4dc1bef8b9b598ebbbd3e48149730f3bec3471f8e2c02ffb338427326924290b8f52ef9e626e3313448bc931a61d866c5dc544ae +CompilerSupportLibraries.v1.0.5+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/md5/fc1df521395362a5aaa2e2aeef707207 +CompilerSupportLibraries.v1.0.5+0.x86_64-unknown-freebsd-libgfortran5.tar.gz/sha512/f2e5a08e3cae171242ae6a20d2d4838c1529ce042745dc466148b7bbc06896d94476fd05c7787e6e8641bea752dfc0e6b09e95b160bede600d20d2ad68e7705f +CompilerSupportLibraries.v1.0.5+0.x86_64-w64-mingw32-libgfortran3.tar.gz/md5/0c2fc6fae4ebe293a7f0dc1e91f6531a +CompilerSupportLibraries.v1.0.5+0.x86_64-w64-mingw32-libgfortran3.tar.gz/sha512/fdb0ad061cacad0557fde3ec216fd3666284f24ad6a86f4a4b6f946dccb112c9704f52edba86f3b17d84c824affbcfef740720348ef227380cf6017811bda80b +CompilerSupportLibraries.v1.0.5+0.x86_64-w64-mingw32-libgfortran4.tar.gz/md5/005e608dbef2b5cdb7624702ccc426be +CompilerSupportLibraries.v1.0.5+0.x86_64-w64-mingw32-libgfortran4.tar.gz/sha512/8bb2bcd0a6b1901e8a9be20f505bead5c78ecafbe5a8271cd13385553e5744e0c7bff62976ac9e7d74b8f3bd467603d4c0f5658e6b120bb23066c15e0a644ed4 +CompilerSupportLibraries.v1.0.5+0.x86_64-w64-mingw32-libgfortran5.tar.gz/md5/d6c2c7ad72bff7f7e5c43678d716a57a +CompilerSupportLibraries.v1.0.5+0.x86_64-w64-mingw32-libgfortran5.tar.gz/sha512/36f5eba1b0be440797467cb7104652b74709913d2bad1b08ee2dc70f450fb8eab81b28f2b0bc8dfc238b3c46982c69aac831b4fad5bcee4e9dd114852fcb4a0b diff --git a/deps/llvm.mk b/deps/llvm.mk index 93e4cd0b80e48..673f2f8ae747a 100644 --- a/deps/llvm.mk +++ b/deps/llvm.mk @@ -230,6 +230,8 @@ $$(LLVM_BUILDDIR_withtype)/build-compiled: $$(SRCCACHE)/$$(LLVM_SRC_DIR)/$1.patc LLVM_PATCH_PREV := $$(SRCCACHE)/$$(LLVM_SRC_DIR)/$1.patch-applied endef +$(eval $(call LLVM_PATCH,llvm-ittapi-cmake)) + ifeq ($(USE_SYSTEM_ZLIB), 0) $(LLVM_BUILDDIR_withtype)/build-configured: | $(build_prefix)/manifest/zlib endif @@ -288,7 +290,7 @@ fastcheck-llvm: #none check-llvm: $(LLVM_BUILDDIR_withtype)/build-checked ifeq ($(USE_INTEL_JITEVENTS),1) -extract-llvm: $(SRCCACHE)/$(ITTAPI_SRC_DIR)/source-extracted +$(SRCCACHE)/$(LLVM_SRC_DIR)/source-extracted: $(SRCCACHE)/$(ITTAPI_SRC_DIR)/source-extracted endif #todo: LLVM make check target is broken on julia.mit.edu (and really slow elsewhere) diff --git a/deps/patches/llvm-ittapi-cmake.patch b/deps/patches/llvm-ittapi-cmake.patch new file mode 100644 index 0000000000000..6746d21754283 --- /dev/null +++ b/deps/patches/llvm-ittapi-cmake.patch @@ -0,0 +1,47 @@ +diff --git a/lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt b/lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt +index 0c5017c359d6..92777133e9de 100644 +--- a/lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt ++++ b/lib/ExecutionEngine/IntelJITEvents/CMakeLists.txt +@@ -12,23 +12,23 @@ if(NOT DEFINED ITTAPI_SOURCE_DIR) + set(ITTAPI_SOURCE_DIR ${PROJECT_BINARY_DIR}) + endif() + +-if(NOT EXISTS ${ITTAPI_SOURCE_DIR}/ittapi) +- execute_process(COMMAND ${GIT_EXECUTABLE} clone ${ITTAPI_GIT_REPOSITORY} +- WORKING_DIRECTORY ${ITTAPI_SOURCE_DIR} ++if(NOT EXISTS ${ITTAPI_SOURCE_DIR}) ++ execute_process(COMMAND ${GIT_EXECUTABLE} clone ${ITTAPI_GIT_REPOSITORY} ${ITTAPI_SOURCE_DIR} ++ WORKING_DIRECTORY ${ITTAPI_SOURCE_DIR}/.. + RESULT_VARIABLE GIT_CLONE_RESULT) + if(NOT GIT_CLONE_RESULT EQUAL "0") + message(FATAL_ERROR "git clone ${ITTAPI_GIT_REPOSITORY} failed with ${GIT_CLONE_RESULT}, please clone ${ITTAPI_GIT_REPOSITORY}") + endif() +-endif() + +-execute_process(COMMAND ${GIT_EXECUTABLE} checkout ${ITTAPI_GIT_TAG} +- WORKING_DIRECTORY ${ITTAPI_SOURCE_DIR}/ittapi +- RESULT_VARIABLE GIT_CHECKOUT_RESULT) +-if(NOT GIT_CHECKOUT_RESULT EQUAL "0") +- message(FATAL_ERROR "git checkout ${ITTAPI_GIT_TAG} failed with ${GIT_CHECKOUT_RESULT}, please checkout ${ITTAPI_GIT_TAG} at ${ITTAPI_SOURCE_DIR}/ittapi") ++ execute_process(COMMAND ${GIT_EXECUTABLE} checkout ${ITTAPI_GIT_TAG} ++ WORKING_DIRECTORY ${ITTAPI_SOURCE_DIR} ++ RESULT_VARIABLE GIT_CHECKOUT_RESULT) ++ if(NOT GIT_CHECKOUT_RESULT EQUAL "0") ++ message(FATAL_ERROR "git checkout ${ITTAPI_GIT_TAG} failed with ${GIT_CHECKOUT_RESULT}, please checkout ${ITTAPI_GIT_TAG} at ${ITTAPI_SOURCE_DIR}") ++ endif() + endif() + +-include_directories( ${ITTAPI_SOURCE_DIR}/ittapi/include/ ) ++include_directories( ${ITTAPI_SOURCE_DIR}/include/ ) + + if( HAVE_LIBDL ) + set(LLVM_INTEL_JIT_LIBS ${CMAKE_DL_LIBS}) +@@ -40,7 +40,7 @@ set(LLVM_INTEL_JIT_LIBS ${LLVM_PTHREAD_LIB} ${LLVM_INTEL_JIT_LIBS}) + add_llvm_component_library(LLVMIntelJITEvents + IntelJITEventListener.cpp + jitprofiling.c +- ${ITTAPI_SOURCE_DIR}/ittapi/src/ittnotify/ittnotify_static.c ++ ${ITTAPI_SOURCE_DIR}/src/ittnotify/ittnotify_static.c + + LINK_LIBS ${LLVM_INTEL_JIT_LIBS} + diff --git a/deps/tools/common.mk b/deps/tools/common.mk index b09786682b941..f9af993122ee9 100644 --- a/deps/tools/common.mk +++ b/deps/tools/common.mk @@ -20,6 +20,10 @@ CMAKE_CXX_ARG := $(CXX_ARG) CMAKE_COMMON := -DCMAKE_INSTALL_PREFIX:PATH=$(build_prefix) -DCMAKE_PREFIX_PATH=$(build_prefix) CMAKE_COMMON += -DLIB_INSTALL_DIR=$(build_shlibdir) +ifneq ($(OS),WINNT) +CMAKE_COMMON += -DCMAKE_INSTALL_LIBDIR=$(build_libdir) +endif + ifeq ($(OS), Darwin) CMAKE_COMMON += -DCMAKE_MACOSX_RPATH=1 endif diff --git a/doc/src/devdocs/sysimg.md b/doc/src/devdocs/sysimg.md index a21e3ba265f9b..18af16918d3bb 100644 --- a/doc/src/devdocs/sysimg.md +++ b/doc/src/devdocs/sysimg.md @@ -39,6 +39,9 @@ All features supported by LLVM are supported and a feature can be disabled with (`+` prefix is also allowed and ignored to be consistent with LLVM syntax). Additionally, a few special features are supported to control the function cloning behavior. +!!! note + It is good practice to specify either `clone_all` or `base()` for every target apart from the first one. This makes it explicit which targets have all functions cloned, and which targets are based on other targets. If this is not done, the default behavior is to not clone every function, and to use the first target's function definition as the fallback when not cloning a function. + 1. `clone_all` By default, only functions that are the most likely to benefit from diff --git a/doc/src/manual/multi-threading.md b/doc/src/manual/multi-threading.md index b012de27ac81f..f8c4e34812e8b 100644 --- a/doc/src/manual/multi-threading.md +++ b/doc/src/manual/multi-threading.md @@ -223,6 +223,68 @@ julia> a Note that [`Threads.@threads`](@ref) does not have an optional reduction parameter like [`@distributed`](@ref). +### Using `@threads` without data races + +Taking the example of a naive sum + +```julia-repl +julia> function sum_single(a) + s = 0 + for i in a + s += i + end + s + end +sum_single (generic function with 1 method) + +julia> sum_single(1:1_000_000) +500000500000 +``` + +Simply adding `@threads` exposes a data race with multiple threads reading and writing `s` at the same time. +```julia-repl +julia> function sum_multi_bad(a) + s = 0 + Threads.@threads for i in a + s += i + end + s + end +sum_multi_bad (generic function with 1 method) + +julia> sum_multi_bad(1:1_000_000) +70140554652 +``` + +Note that the result is not `500000500000` as it should be, and will most likely change each evaluation. + +To fix this, buffers that are specific to the task may be used to segment the sum into chunks that are race-free. +Here `sum_single` is reused, with its own internal buffer `s`, and vector `a` is split into `nthreads()` +chunks for parallel work via `nthreads()` `@spawn`-ed tasks. + +```julia-repl +julia> function sum_multi_good(a) + chunks = Iterators.partition(a, length(a) ÷ Threads.nthreads()) + tasks = map(chunks) do chunk + Threads.@spawn sum_single(chunk) + end + chunk_sums = fetch.(tasks) + return sum_single(chunk_sums) + end +sum_multi_good (generic function with 1 method) + +julia> sum_multi_good(1:1_000_000) +500000500000 +``` +!!! Note + Buffers should not be managed based on `threadid()` i.e. `buffers = zeros(Threads.nthreads())` because concurrent tasks + can yield, meaning multiple concurrent tasks may use the same buffer on a given thread, introducing risk of data races. + Further, when more than one thread is available tasks may change thread at yield points, which is known as + [task migration](@ref man-task-migration). + +Another option is the use of atomic operations on variables shared across tasks/threads, which may be more performant +depending on the characteristics of the operations. + ## Atomic Operations Julia supports accessing and modifying values *atomically*, that is, in a thread-safe way to avoid @@ -372,6 +434,20 @@ threads in Julia: This may require some transitional work across the ecosystem before threading can be widely adopted with confidence. See the next section for further details. +## [Task Migration](@id man-task-migration) + +After a task starts running on a certain thread it may move to a different thread if the task yields. + +Such tasks may have been started with [`@spawn`](@ref Threads.@spawn) or [`@threads`](@ref Threads.@threads), +although the `:static` schedule option for `@threads` does freeze the threadid. + +This means that in most cases [`threadid()`](@ref Threads.threadid) should not be treated as constant within a task, +and therefore should not be used to index into a vector of buffers or stateful objects. + +!!! compat "Julia 1.7" + Task migration was introduced in Julia 1.7. Before this tasks always remained on the same thread that they were + started on. + ## Safe use of Finalizers Because finalizers can interrupt any code, they must be very careful in how diff --git a/doc/src/manual/running-external-programs.md b/doc/src/manual/running-external-programs.md index e643ffff3ee61..ed3fe85194d93 100644 --- a/doc/src/manual/running-external-programs.md +++ b/doc/src/manual/running-external-programs.md @@ -41,7 +41,7 @@ hello ``` The `hello` is the output of the `echo` command, sent to [`stdout`](@ref). If the external command fails to run -successfully, the run method throws an [`ErrorException`](@ref). +successfully, the run method throws an [`ProcessFailedException`](@ref). If you want to read the output of the external command, [`read`](@ref) or [`readchomp`](@ref) can be used instead: diff --git a/src/gc.c b/src/gc.c index da79a58065b8c..5e25c8af5c940 100644 --- a/src/gc.c +++ b/src/gc.c @@ -3201,7 +3201,7 @@ static void sweep_finalizer_list(arraylist_t *list) } // collector entry point and control -static _Atomic(uint32_t) jl_gc_disable_counter = 1; +_Atomic(uint32_t) jl_gc_disable_counter = 1; JL_DLLEXPORT int jl_gc_enable(int on) { @@ -3654,7 +3654,7 @@ JL_DLLEXPORT void jl_gc_collect(jl_gc_collection_t collection) jl_task_t *ct = jl_current_task; jl_ptls_t ptls = ct->ptls; - if (jl_atomic_load_relaxed(&jl_gc_disable_counter)) { + if (jl_atomic_load_acquire(&jl_gc_disable_counter)) { size_t localbytes = jl_atomic_load_relaxed(&ptls->gc_num.allocd) + gc_num.interval; jl_atomic_store_relaxed(&ptls->gc_num.allocd, -(int64_t)gc_num.interval); static_assert(sizeof(_Atomic(uint64_t)) == sizeof(gc_num.deferred_alloc), ""); @@ -3665,11 +3665,10 @@ JL_DLLEXPORT void jl_gc_collect(jl_gc_collection_t collection) int8_t old_state = jl_atomic_load_relaxed(&ptls->gc_state); jl_atomic_store_release(&ptls->gc_state, JL_GC_STATE_WAITING); - // `jl_safepoint_start_gc()` makes sure only one thread can - // run the GC. + // `jl_safepoint_start_gc()` makes sure only one thread can run the GC. uint64_t t0 = jl_hrtime(); if (!jl_safepoint_start_gc()) { - // Multithread only. See assertion in `safepoint.c` + // either another thread is running GC, or the GC got disabled just now. jl_gc_state_set(ptls, old_state, JL_GC_STATE_WAITING); return; } @@ -3702,7 +3701,7 @@ JL_DLLEXPORT void jl_gc_collect(jl_gc_collection_t collection) gc_invoke_callbacks(jl_gc_cb_pre_gc_t, gc_cblist_pre_gc, (collection)); - if (!jl_atomic_load_relaxed(&jl_gc_disable_counter)) { + if (!jl_atomic_load_acquire(&jl_gc_disable_counter)) { JL_LOCK_NOGC(&finalizers_lock); if (_jl_gc_collect(ptls, collection)) { // recollect diff --git a/src/intrinsics.cpp b/src/intrinsics.cpp index a641110412433..e0ef95e177c00 100644 --- a/src/intrinsics.cpp +++ b/src/intrinsics.cpp @@ -932,7 +932,11 @@ static jl_cgval_t emit_atomic_pointerop(jl_codectx_t &ctx, intrinsic f, const jl bool isboxed; Type *ptrty = julia_type_to_llvm(ctx, ety, &isboxed); assert(!isboxed); - Value *thePtr = emit_unbox(ctx, ptrty->getPointerTo(), e, e.typ); + Value *thePtr; + if (!type_is_ghost(ptrty)) + thePtr = emit_unbox(ctx, ptrty->getPointerTo(), e, e.typ); + else + thePtr = nullptr; // could use any value here, since typed_store will not use it jl_cgval_t ret = typed_store(ctx, thePtr, nullptr, x, y, ety, ctx.tbaa().tbaa_data, nullptr, nullptr, isboxed, llvm_order, llvm_failorder, nb, false, issetfield, isreplacefield, isswapfield, ismodifyfield, false, modifyop, "atomic_pointermodify"); if (issetfield) diff --git a/src/jloptions.c b/src/jloptions.c index 5d2dee81ddc79..988078c7c58d9 100644 --- a/src/jloptions.c +++ b/src/jloptions.c @@ -86,6 +86,7 @@ JL_DLLEXPORT void jl_init_options(void) 0, // rr-detach 0, // strip-metadata 0, // strip-ir + 0, // permalloc_pkgimg 0, // heap-size-hint }; jl_options_initialized = 1; @@ -207,6 +208,7 @@ static const char opts_hidden[] = " --trace-compile={stderr,name}\n" " Print precompile statements for methods compiled during execution or save to a path\n" " --image-codegen Force generate code in imaging mode\n" + " --permalloc-pkgimg={yes|no*} Copy the data section of package images into memory\n" ; JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) @@ -251,6 +253,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) opt_strip_metadata, opt_strip_ir, opt_heap_size_hint, + opt_permalloc_pkgimg }; static const char* const shortopts = "+vhqH:e:E:L:J:C:it:p:O:g:"; static const struct option longopts[] = { @@ -309,6 +312,7 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) { "rr-detach", no_argument, 0, opt_rr_detach }, { "strip-metadata", no_argument, 0, opt_strip_metadata }, { "strip-ir", no_argument, 0, opt_strip_ir }, + { "permalloc-pkgimg",required_argument, 0, opt_permalloc_pkgimg }, { "heap-size-hint", required_argument, 0, opt_heap_size_hint }, { 0, 0, 0, 0 } }; @@ -815,6 +819,14 @@ JL_DLLEXPORT void jl_parse_opts(int *argcp, char ***argvp) jl_errorf("julia: invalid argument to --heap-size-hint without memory size specified"); break; + case opt_permalloc_pkgimg: + if (!strcmp(optarg,"yes")) + jl_options.permalloc_pkgimg = 1; + else if (!strcmp(optarg,"no")) + jl_options.permalloc_pkgimg = 0; + else + jl_errorf("julia: invalid argument to --permalloc-pkgimg={yes|no} (%s)", optarg); + break; default: jl_errorf("julia: unhandled option -- %c\n" "This is a bug, please report it.", c); diff --git a/src/jloptions.h b/src/jloptions.h index d0aba777027e7..0b72b4c3be062 100644 --- a/src/jloptions.h +++ b/src/jloptions.h @@ -57,6 +57,7 @@ typedef struct { int8_t rr_detach; int8_t strip_metadata; int8_t strip_ir; + int8_t permalloc_pkgimg; uint64_t heap_size_hint; } jl_options_t; diff --git a/src/jltypes.c b/src/jltypes.c index bf1fd6d455f27..0767e9493bbc0 100644 --- a/src/jltypes.c +++ b/src/jltypes.c @@ -1171,7 +1171,7 @@ jl_datatype_t *jl_apply_modify_type(jl_value_t *dt) return rettyp; } -jl_datatype_t *jl_apply_cmpswap_type(jl_value_t *dt) +jl_datatype_t *jl_apply_cmpswap_type(jl_value_t *ty) { jl_value_t *params[2]; jl_value_t *names = jl_atomic_load_relaxed(&cmpswap_names); @@ -1182,12 +1182,12 @@ jl_datatype_t *jl_apply_cmpswap_type(jl_value_t *dt) if (jl_atomic_cmpswap(&cmpswap_names, &names, lnames)) names = jl_atomic_load_relaxed(&cmpswap_names); // == lnames } - params[0] = dt; + params[0] = ty; params[1] = (jl_value_t*)jl_bool_type; - jl_datatype_t *tuptyp = jl_apply_tuple_type_v(params, 2); - JL_GC_PROMISE_ROOTED(tuptyp); // (JL_ALWAYS_LEAFTYPE) - jl_datatype_t *rettyp = (jl_datatype_t*)jl_apply_type2((jl_value_t*)jl_namedtuple_type, names, (jl_value_t*)tuptyp); - JL_GC_PROMISE_ROOTED(rettyp); // (JL_ALWAYS_LEAFTYPE) + jl_value_t *tuptyp = (jl_value_t*)jl_apply_tuple_type_v(params, 2); + JL_GC_PUSH1(&tuptyp); + jl_datatype_t *rettyp = (jl_datatype_t*)jl_apply_type2((jl_value_t*)jl_namedtuple_type, names, tuptyp); + JL_GC_POP(); return rettyp; } diff --git a/src/julia_internal.h b/src/julia_internal.h index 15e004e0ba0b4..e5419efd2a2ac 100644 --- a/src/julia_internal.h +++ b/src/julia_internal.h @@ -890,6 +890,7 @@ STATIC_INLINE int jl_addr_is_safepoint(uintptr_t addr) return addr >= safepoint_addr && addr < safepoint_addr + jl_page_size * 3; } extern _Atomic(uint32_t) jl_gc_running; +extern _Atomic(uint32_t) jl_gc_disable_counter; // All the functions are safe to be called from within a signal handler // provided that the thread will not be interrupted by another asynchronous // signal. diff --git a/src/processor_x86.cpp b/src/processor_x86.cpp index c61712ada787a..c79788fe76aac 100644 --- a/src/processor_x86.cpp +++ b/src/processor_x86.cpp @@ -224,8 +224,11 @@ constexpr auto bdver2 = bdver1 | get_feature_masks(f16c, bmi, tbm, fma); constexpr auto bdver3 = bdver2 | get_feature_masks(xsaveopt, fsgsbase); constexpr auto bdver4 = bdver3 | get_feature_masks(avx2, bmi2, mwaitx, movbe, rdrnd); +// technically xsaves is part of znver1, znver2, and znver3 +// Disabled due to Erratum 1386 +// See: https://github.com/JuliaLang/julia/issues/50102 constexpr auto znver1 = haswell | get_feature_masks(adx, aes, clflushopt, clzero, mwaitx, prfchw, - rdseed, sha, sse4a, xsavec, xsaves); + rdseed, sha, sse4a, xsavec); constexpr auto znver2 = znver1 | get_feature_masks(clwb, rdpid, wbnoinvd); constexpr auto znver3 = znver2 | get_feature_masks(shstk, pku, vaes, vpclmulqdq); diff --git a/src/runtime_intrinsics.c b/src/runtime_intrinsics.c index a170c81c609cf..d46ed4c9c8e84 100644 --- a/src/runtime_intrinsics.c +++ b/src/runtime_intrinsics.c @@ -429,6 +429,8 @@ JL_DLLEXPORT jl_value_t *jl_atomic_pointerreplace(jl_value_t *p, jl_value_t *exp jl_atomic_error("atomic_pointerreplace: invalid atomic ordering"); // TODO: filter other invalid orderings jl_value_t *ety = jl_tparam0(jl_typeof(p)); + if (!is_valid_intrinsic_elptr(ety)) + jl_error("atomic_pointerreplace: invalid pointer"); char *pp = (char*)jl_unbox_long(p); jl_datatype_t *rettyp = jl_apply_cmpswap_type(ety); JL_GC_PROMISE_ROOTED(rettyp); // (JL_ALWAYS_LEAFTYPE) @@ -447,8 +449,6 @@ JL_DLLEXPORT jl_value_t *jl_atomic_pointerreplace(jl_value_t *p, jl_value_t *exp return result; } else { - if (!is_valid_intrinsic_elptr(ety)) - jl_error("atomic_pointerreplace: invalid pointer"); if (jl_typeof(x) != ety) jl_type_error("atomic_pointerreplace", ety, x); size_t nb = jl_datatype_size(ety); diff --git a/src/safepoint.c b/src/safepoint.c index 1ff26d616a5d8..04bc2a8ac1d46 100644 --- a/src/safepoint.c +++ b/src/safepoint.c @@ -124,6 +124,14 @@ int jl_safepoint_start_gc(void) jl_safepoint_wait_gc(); return 0; } + // Foreign thread adoption disables the GC and waits for it to finish, however, that may + // introduce a race between it and this thread checking if the GC is enabled and only + // then setting jl_gc_running. To avoid that, check again now that we won that race. + if (jl_atomic_load_acquire(&jl_gc_disable_counter)) { + jl_atomic_store_release(&jl_gc_running, 0); + uv_mutex_unlock(&safepoint_lock); + return 0; + } jl_safepoint_enable(1); jl_safepoint_enable(2); uv_mutex_unlock(&safepoint_lock); diff --git a/src/staticdata.c b/src/staticdata.c index 2e84e72df3b42..c12c9b4b58562 100644 --- a/src/staticdata.c +++ b/src/staticdata.c @@ -71,6 +71,7 @@ External links: */ #include #include +#include #include // printf #include // PRIxPTR @@ -3297,7 +3298,7 @@ static jl_value_t *jl_validate_cache_file(ios_t *f, jl_array_t *depmods, uint64_ } // TODO?: refactor to make it easier to create the "package inspector" -static jl_value_t *jl_restore_package_image_from_stream(ios_t *f, jl_image_t *image, jl_array_t *depmods, int completeinfo) +static jl_value_t *jl_restore_package_image_from_stream(ios_t *f, jl_image_t *image, jl_array_t *depmods, int completeinfo, bool needs_permalloc) { uint64_t checksum = 0; int64_t dataendpos = 0; @@ -3308,7 +3309,7 @@ static jl_value_t *jl_restore_package_image_from_stream(ios_t *f, jl_image_t *im return verify_fail; assert(datastartpos > 0 && datastartpos < dataendpos); - + needs_permalloc = jl_options.permalloc_pkgimg || needs_permalloc; jl_value_t *restored = NULL; jl_array_t *init_order = NULL, *extext_methods = NULL, *new_specializations = NULL, *method_roots_list = NULL, *ext_targets = NULL, *edges = NULL; jl_svec_t *cachesizes_sv = NULL; @@ -3320,14 +3321,22 @@ static jl_value_t *jl_restore_package_image_from_stream(ios_t *f, jl_image_t *im ios_bufmode(f, bm_none); JL_SIGATOMIC_BEGIN(); size_t len = dataendpos - datastartpos; - char *sysimg = (char*)jl_gc_perm_alloc(len, 0, 64, 0); + char *sysimg; + bool success = !needs_permalloc; ios_seek(f, datastartpos); - if (ios_readall(f, sysimg, len) != len || jl_crc32c(0, sysimg, len) != (uint32_t)checksum) { - restored = jl_get_exceptionf(jl_errorexception_type, "Error reading system image file."); + if (needs_permalloc) + sysimg = (char*)jl_gc_perm_alloc(len, 0, 64, 0); + else + sysimg = &f->buf[f->bpos]; + if (needs_permalloc) + success = ios_readall(f, sysimg, len) == len; + if (!success || jl_crc32c(0, sysimg, len) != (uint32_t)checksum) { + restored = jl_get_exceptionf(jl_errorexception_type, "Error reading package image file."); JL_SIGATOMIC_END(); } else { - ios_close(f); + if (needs_permalloc) + ios_close(f); ios_static_buffer(f, sysimg, len); pkgcachesizes cachesizes; jl_restore_system_image_from_stream_(f, image, depmods, checksum, (jl_array_t**)&restored, &init_order, &extext_methods, &new_specializations, &method_roots_list, &ext_targets, &edges, &base, &ccallable_list, &cachesizes); @@ -3372,11 +3381,11 @@ static void jl_restore_system_image_from_stream(ios_t *f, jl_image_t *image, uin jl_restore_system_image_from_stream_(f, image, NULL, checksum | ((uint64_t)0xfdfcfbfa << 32), NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); } -JL_DLLEXPORT jl_value_t *jl_restore_incremental_from_buf(const char *buf, jl_image_t *image, size_t sz, jl_array_t *depmods, int completeinfo) +JL_DLLEXPORT jl_value_t *jl_restore_incremental_from_buf(const char *buf, jl_image_t *image, size_t sz, jl_array_t *depmods, int completeinfo, bool needs_permalloc) { ios_t f; ios_static_buffer(&f, (char*)buf, sz); - jl_value_t *ret = jl_restore_package_image_from_stream(&f, image, depmods, completeinfo); + jl_value_t *ret = jl_restore_package_image_from_stream(&f, image, depmods, completeinfo, needs_permalloc); ios_close(&f); return ret; } @@ -3389,7 +3398,7 @@ JL_DLLEXPORT jl_value_t *jl_restore_incremental(const char *fname, jl_array_t *d "Cache file \"%s\" not found.\n", fname); } jl_image_t pkgimage = {}; - jl_value_t *ret = jl_restore_package_image_from_stream(&f, &pkgimage, depmods, completeinfo); + jl_value_t *ret = jl_restore_package_image_from_stream(&f, &pkgimage, depmods, completeinfo, true); ios_close(&f); return ret; } @@ -3491,7 +3500,7 @@ JL_DLLEXPORT jl_value_t *jl_restore_package_image_from_file(const char *fname, j } #endif - jl_value_t* mod = jl_restore_incremental_from_buf(pkgimg_data, &pkgimage, *plen, depmods, completeinfo); + jl_value_t* mod = jl_restore_incremental_from_buf(pkgimg_data, &pkgimage, *plen, depmods, completeinfo, false); return mod; } diff --git a/src/threading.c b/src/threading.c index f81924ab9f063..50a5362482f22 100644 --- a/src/threading.c +++ b/src/threading.c @@ -399,16 +399,26 @@ jl_ptls_t jl_init_threadtls(int16_t tid) JL_DLLEXPORT jl_gcframe_t **jl_adopt_thread(void) { + // `jl_init_threadtls` puts us in a GC unsafe region, so ensure GC isn't running. + // we can't use a normal safepoint because we don't have signal handlers yet. + // we also can't use jl_safepoint_wait_gc because that assumes we're in a task. + jl_atomic_fetch_add(&jl_gc_disable_counter, 1); + while (jl_atomic_load_acquire(&jl_gc_running)) { + jl_cpu_pause(); + } + // this check is coupled with the one in `jl_safepoint_wait_gc`, where we observe if a + // foreign thread has asked to disable the GC, guaranteeing the order of events. + // initialize this thread (assign tid, create heap, set up root task) jl_ptls_t ptls = jl_init_threadtls(-1); void *stack_lo, *stack_hi; jl_init_stack_limits(0, &stack_lo, &stack_hi); - (void)jl_gc_unsafe_enter(ptls); // warning: this changes `jl_current_task`, so be careful not to call that from this function - jl_task_t *ct = jl_init_root_task(ptls, stack_lo, stack_hi); + jl_task_t *ct = jl_init_root_task(ptls, stack_lo, stack_hi); // assumes the GC is disabled JL_GC_PROMISE_ROOTED(ct); uv_random(NULL, NULL, &ct->rngState, sizeof(ct->rngState), 0, NULL); + jl_atomic_fetch_add(&jl_gc_disable_counter, -1); return &ct->gcstack; } diff --git a/stdlib/CompilerSupportLibraries_jll/Project.toml b/stdlib/CompilerSupportLibraries_jll/Project.toml index fc5883cc79802..4c7aa35a99730 100644 --- a/stdlib/CompilerSupportLibraries_jll/Project.toml +++ b/stdlib/CompilerSupportLibraries_jll/Project.toml @@ -4,7 +4,7 @@ uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" # NOTE: When updating this, also make sure to update the value # `CSL_NEXT_GLIBCXX_VERSION` in `deps/csl.mk`, to properly disable # automatic usage of BB-built CSLs on extremely up-to-date systems! -version = "1.0.2+0" +version = "1.0.5+0" [deps] Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/stdlib/Distributed/src/cluster.jl b/stdlib/Distributed/src/cluster.jl index d2cbe55e63270..554a3d9185080 100644 --- a/stdlib/Distributed/src/cluster.jl +++ b/stdlib/Distributed/src/cluster.jl @@ -1317,6 +1317,20 @@ end write_cookie(io::IO) = print(io.in, string(cluster_cookie(), "\n")) +function get_threads_spec(opts) + if opts.nthreads > 0 + @assert opts.nthreadpools >= 1 + @assert opts.nthreads_per_pool != C_NULL + thr = "$(unsafe_load(opts.nthreads_per_pool))" + if opts.nthreadpools == 2 + thr = "$(thr),$(unsafe_load(opts.nthreads_per_pool, 2))" + end + `--threads=$(thr)` + else + `` + end +end + # Starts workers specified by (-n|--procs) and --machine-file command line options function process_opts(opts) # startup worker. @@ -1331,7 +1345,9 @@ function process_opts(opts) end # Propagate --threads to workers - exeflags = opts.nthreads > 0 ? `--threads=$(opts.nthreads)` : `` + threads = get_threads_spec(opts) + + exeflags = `$threads` # add processors if opts.nprocs > 0 diff --git a/stdlib/LibGit2/src/types.jl b/stdlib/LibGit2/src/types.jl index 1ea6c797d1636..0b653f9b6ad21 100644 --- a/stdlib/LibGit2/src/types.jl +++ b/stdlib/LibGit2/src/types.jl @@ -904,12 +904,13 @@ end Matches the [`git_config_entry`](https://libgit2.org/libgit2/#HEAD/type/git_config_entry) struct. """ -@kwdef struct ConfigEntry - name::Cstring = Cstring(C_NULL) - value::Cstring = Cstring(C_NULL) - level::GIT_CONFIG = Consts.CONFIG_LEVEL_DEFAULT - free::Ptr{Cvoid} = C_NULL - payload::Any = nothing +struct ConfigEntry + name::Cstring + value::Cstring + include_depth::Cuint + level::GIT_CONFIG + free::Ptr{Cvoid} + payload::Ptr{Cvoid} # User is not permitted to read or write this field end @assert Base.allocatedinline(ConfigEntry) diff --git a/stdlib/LinearAlgebra/src/lapack.jl b/stdlib/LinearAlgebra/src/lapack.jl index bef018307fcf7..b21f2cbeaa042 100644 --- a/stdlib/LinearAlgebra/src/lapack.jl +++ b/stdlib/LinearAlgebra/src/lapack.jl @@ -554,9 +554,9 @@ for (gebrd, gelqf, geqlf, geqrf, geqp3, geqrt, geqrt3, gerqf, getrf, elty, relty # * .. Array Arguments .. # INTEGER IPIV( * ) # DOUBLE PRECISION A( LDA, * ) - function getrf!(A::AbstractMatrix{$elty}) + function getrf!(A::AbstractMatrix{$elty}; check = true) require_one_based_indexing(A) - chkfinite(A) + check && chkfinite(A) chkstride1(A) m, n = size(A) lda = max(1,stride(A, 2)) diff --git a/stdlib/LinearAlgebra/src/lu.jl b/stdlib/LinearAlgebra/src/lu.jl index 95fbe6344e88f..5832fe661d7d2 100644 --- a/stdlib/LinearAlgebra/src/lu.jl +++ b/stdlib/LinearAlgebra/src/lu.jl @@ -78,7 +78,7 @@ transpose(F::LU) = Transpose(F) # the following method is meant to catch calls to lu!(A::LAPACKArray) without a pivoting stategy lu!(A::StridedMatrix{<:BlasFloat}; check::Bool = true) = lu!(A, RowMaximum(); check=check) function lu!(A::StridedMatrix{T}, ::RowMaximum; check::Bool = true) where {T<:BlasFloat} - lpt = LAPACK.getrf!(A) + lpt = LAPACK.getrf!(A; check) check && checknonsingular(lpt[3]) return LU{T,typeof(lpt[1]),typeof(lpt[2])}(lpt[1], lpt[2], lpt[3]) end diff --git a/stdlib/Pkg.version b/stdlib/Pkg.version index d0e5ef33678c9..f2e07c71216f9 100644 --- a/stdlib/Pkg.version +++ b/stdlib/Pkg.version @@ -1,4 +1,4 @@ PKG_BRANCH = release-1.9 -PKG_SHA1 = 3fa06b9f96fc8a180f9285447584c84e4d8d8278 +PKG_SHA1 = cc71837381da2569b0d8e9d2c6130a13f3f5b8f4 PKG_GIT_URL := https://github.com/JuliaLang/Pkg.jl.git PKG_TAR_URL = https://api.github.com/repos/JuliaLang/Pkg.jl/tarball/$1 diff --git a/stdlib/SuiteSparse_jll/src/SuiteSparse_jll.jl b/stdlib/SuiteSparse_jll/src/SuiteSparse_jll.jl index 2940970ceff9f..a4a7b6c4c70c3 100644 --- a/stdlib/SuiteSparse_jll/src/SuiteSparse_jll.jl +++ b/stdlib/SuiteSparse_jll/src/SuiteSparse_jll.jl @@ -82,30 +82,32 @@ else end function __init__() - global libamd_handle = dlopen(libamd) - global libamd_path = dlpath(libamd_handle) - global libbtf_handle = dlopen(libbtf) - global libbtf_path = dlpath(libbtf_handle) - global libcamd_handle = dlopen(libcamd) - global libcamd_path = dlpath(libcamd_handle) - global libccolamd_handle = dlopen(libccolamd) - global libccolamd_path = dlpath(libccolamd_handle) - global libcholmod_handle = dlopen(libcholmod) - global libcholmod_path = dlpath(libcholmod_handle) - global libcolamd_handle = dlopen(libcolamd) - global libcolamd_path = dlpath(libcolamd_handle) - global libklu_handle = dlopen(libklu) - global libklu_path = dlpath(libklu_handle) - global libldl_handle = dlopen(libldl) - global libldl_path = dlpath(libldl_handle) - global librbio_handle = dlopen(librbio) - global librbio_path = dlpath(librbio_handle) - global libspqr_handle = dlopen(libspqr) - global libspqr_path = dlpath(libspqr_handle) - global libsuitesparseconfig_handle = dlopen(libsuitesparseconfig) - global libsuitesparseconfig_path = dlpath(libsuitesparseconfig_handle) - global libumfpack_handle = dlopen(libumfpack) - global libumfpack_path = dlpath(libumfpack_handle) + if Base.USE_GPL_LIBS + global libamd_handle = dlopen(libamd) + global libamd_path = dlpath(libamd_handle) + global libbtf_handle = dlopen(libbtf) + global libbtf_path = dlpath(libbtf_handle) + global libcamd_handle = dlopen(libcamd) + global libcamd_path = dlpath(libcamd_handle) + global libccolamd_handle = dlopen(libccolamd) + global libccolamd_path = dlpath(libccolamd_handle) + global libcholmod_handle = dlopen(libcholmod) + global libcholmod_path = dlpath(libcholmod_handle) + global libcolamd_handle = dlopen(libcolamd) + global libcolamd_path = dlpath(libcolamd_handle) + global libklu_handle = dlopen(libklu) + global libklu_path = dlpath(libklu_handle) + global libldl_handle = dlopen(libldl) + global libldl_path = dlpath(libldl_handle) + global librbio_handle = dlopen(librbio) + global librbio_path = dlpath(librbio_handle) + global libspqr_handle = dlopen(libspqr) + global libspqr_path = dlpath(libspqr_handle) + global libsuitesparseconfig_handle = dlopen(libsuitesparseconfig) + global libsuitesparseconfig_path = dlpath(libsuitesparseconfig_handle) + global libumfpack_handle = dlopen(libumfpack) + global libumfpack_path = dlpath(libumfpack_handle) + end global artifact_dir = dirname(Sys.BINDIR) end diff --git a/test/atexit.jl b/test/atexit.jl index bf46edae6eaad..5b4fbc0b44a40 100644 --- a/test/atexit.jl +++ b/test/atexit.jl @@ -4,8 +4,9 @@ using Test @testset "atexit.jl" begin function _atexit_tests_gen_cmd_eval(expr::String) + # We run the atexit tests with 2 threads, for the parallelism tests at the end. cmd_eval = ``` - $(Base.julia_cmd()) -e $(expr) + $(Base.julia_cmd()) -t2 -e $(expr) ``` return cmd_eval end @@ -13,8 +14,9 @@ using Test script, io = mktemp(temp_dir) println(io, expr) close(io) + # We run the atexit tests with 2 threads, for the parallelism tests at the end. cmd_script = ``` - $(Base.julia_cmd()) $(script) + $(Base.julia_cmd()) -t2 $(script) ``` return cmd_script end @@ -172,5 +174,98 @@ using Test @test p_script.exitcode == expected_exit_code end end + @testset "test calling atexit() in parallel with running atexit hooks." begin + # These tests cover 3 parallelism cases, as described by the following comments. + julia_expr_list = Dict( + # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # 1. registering a hook from inside a hook + """ + atexit() do + atexit() do + exit(11) + end + end + # This will attempt to exit 0, but the execution of the atexit hook will + # register another hook, which will exit 11. + exit(0) + """ => 11, + # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # 2. registering a hook from another thread while hooks are running + """ + c = Channel() + # This hook must execute _last_. (Execution is LIFO.) + atexit() do + put!(c, nothing) + put!(c, nothing) + end + atexit() do + # This will run in a concurrent task, testing that we can register atexit + # hooks from another task while running atexit hooks. + Threads.@spawn begin + Core.println("INSIDE") + take!(c) # block on c + Core.println("go") + atexit() do + Core.println("exit11") + exit(11) + end + take!(c) # keep the _atexit() loop alive until we've added another item. + Core.println("done") + end + end + exit(0) + """ => 11, + # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + # 3. attempting to register a hook after all hooks have finished (disallowed) + """ + const atexit_has_finished = Threads.Atomic{Bool}(false) + atexit() do + Threads.@spawn begin + # Block until the atexit hooks have all finished. We use a manual "spin + # lock" because task switch is disallowed inside the finalizer, below. + while !atexit_has_finished[] end + Core.println("done") + try + # By the time this runs, all the atexit hooks will be done. + # So this will throw. + atexit() do + exit(11) + end + catch + # Meaning we _actually_ exit 22. + exit(22) + end + end + end + # Finalizers run after the atexit hooks, so this blocks exit until the spawned + # task above gets a chance to run. + x = [] + finalizer(x) do x + Core.println("FINALIZER") + # Allow the spawned task to finish + atexit_has_finished[] = true + Core.println("ready") + # Then spin forever to prevent exit. + while atexit_has_finished[] end + Core.println("exiting") + end + exit(0) + """ => 22, + # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + ) + for julia_expr in keys(julia_expr_list) + cmd_eval = _atexit_tests_gen_cmd_eval(julia_expr) + cmd_script = _atexit_tests_gen_cmd_script(atexit_temp_dir, julia_expr) + expected_exit_code = julia_expr_list[julia_expr] + @test_throws(ProcessFailedException, run(cmd_eval)) + @test_throws(ProcessFailedException, run(cmd_script)) + p_eval = run(cmd_eval; wait = false) + p_script = run(cmd_script; wait = false) + wait(p_eval) + wait(p_script) + @test p_eval.exitcode == expected_exit_code + @test p_script.exitcode == expected_exit_code + end + end rm(atexit_temp_dir; force = true, recursive = true) end diff --git a/test/compiler/inference.jl b/test/compiler/inference.jl index 7366e56f34e7a..295f7dd9245ce 100644 --- a/test/compiler/inference.jl +++ b/test/compiler/inference.jl @@ -4329,3 +4329,17 @@ bar47688() = foo47688() @test it_count47688 == 7 @test isa(foo47688(), NTuple{6, Int}) @test it_count47688 == 14 + +struct Issue49785{S, T<:S} end +let 𝕃 = Core.Compiler.OptimizerLattice() + argtypes = Any[Core.Compiler.Const(Issue49785), + Union{Type{String},Type{Int}}, + Union{Type{String},Type{Int}}] + rt = Type{Issue49785{<:Any, Int}} + # the following should not throw + @test !Core.Compiler.apply_type_nothrow(𝕃, argtypes, rt) + @test code_typed() do + S = Union{Type{String},Type{Int}}[Int][1] + map(T -> Issue49785{S,T}, (a = S,)) + end isa Vector +end diff --git a/test/compiler/inline.jl b/test/compiler/inline.jl index 09f32c827f3f9..516dc603367e4 100644 --- a/test/compiler/inline.jl +++ b/test/compiler/inline.jl @@ -709,6 +709,27 @@ end end end +# callsite inlining with cached frames +issue49823_events = @NamedTuple{evid::Int8, base_time::Float64}[ + (evid = 1, base_time = 0.0), (evid = -1, base_time = 0.0)] +issue49823_fl1(t, events) = @inline findlast(x -> x.evid ∈ (1, 4) && x.base_time <= t, events) +issue49823_fl3(t, events) = @inline findlast(x -> any(==(x.evid), (1,4)) && x.base_time <= t, events) +issue49823_fl5(t, events) = begin + f = let t=t + x -> x.evid ∈ (1, 4) && x.base_time <= t + end + @inline findlast(f, events) +end +let src = @code_typed1 issue49823_fl1(0.0, issue49823_events) + @test count(isinvoke(:findlast), src.code) == 0 # successful inlining +end +let src = @code_typed1 issue49823_fl3(0.0, issue49823_events) + @test count(isinvoke(:findlast), src.code) == 0 # successful inlining +end +let src = @code_typed1 issue49823_fl5(0.0, issue49823_events) + @test count(isinvoke(:findlast), src.code) == 0 # successful inlining +end + # Issue #42264 - crash on certain union splits let f(x) = (x...,) # Test splatting with a Union of non-{Tuple, SimpleVector} types that require creating new `iterate` calls diff --git a/test/compiler/irutils.jl b/test/compiler/irutils.jl index 76f883d6cea2c..438c1f2717835 100644 --- a/test/compiler/irutils.jl +++ b/test/compiler/irutils.jl @@ -1,9 +1,13 @@ import Core: CodeInfo, ReturnNode, MethodInstance import Core.Compiler: IRCode, IncrementalCompact, argextype, singleton_type import Base.Meta: isexpr +using InteractiveUtils: gen_call_with_extracted_types_and_kwargs argextype(@nospecialize args...) = argextype(args..., Any[]) code_typed1(args...; kwargs...) = first(only(code_typed(args...; kwargs...)))::CodeInfo +macro code_typed1(ex0...) + return gen_call_with_extracted_types_and_kwargs(__module__, :code_typed1, ex0) +end get_code(args...; kwargs...) = code_typed1(args...; kwargs...).code # check if `x` is a statement with a given `head` diff --git a/test/enums.jl b/test/enums.jl index c7e3e3bf2abdb..6eb9360e08a23 100644 --- a/test/enums.jl +++ b/test/enums.jl @@ -179,6 +179,15 @@ end @enum HashEnum2 Enum2_a=1 @test hash(Enum1_a) != hash(Enum2_a) +# PR #49777: Check that `Base.hash` can be specialized by the user without +# overwriting a method definition. +@enum HashEnum3 Enum3_a=1 +@test which(hash, (HashEnum3, UInt)).sig != Tuple{typeof(hash), HashEnum3, UInt64} + +# Check that generic `hash` on custom enum subtypes works. +struct HashEnum4 <: Enum{Int} end +@test hash(HashEnum4(), zero(UInt)) == invoke(hash, Tuple{Any, UInt}, HashEnum4(), zero(UInt)) + @test (Vector{Fruit}(undef, 3) .= apple) == [apple, apple, apple] # long, discongruous diff --git a/test/hashing.jl b/test/hashing.jl index 9f40e7a4a73ac..4ecadddb7542c 100644 --- a/test/hashing.jl +++ b/test/hashing.jl @@ -8,7 +8,8 @@ types = Any[ Bool, Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Float32, Float64, Rational{Int8}, Rational{UInt8}, Rational{Int16}, Rational{UInt16}, - Rational{Int32}, Rational{UInt32}, Rational{Int64}, Rational{UInt64} + Rational{Int32}, Rational{UInt32}, Rational{Int64}, Rational{UInt64}, + BigFloat, BigInt, Rational{BigInt} ] vals = vcat( typemin(Int64), @@ -51,8 +52,7 @@ let collides = 0 collides += eq end end - # each pair of types has one collision for these values - @test collides <= (length(types) - 1)^2 + @test collides <= 516 end @test hash(0.0) != hash(-0.0) diff --git a/test/intrinsics.jl b/test/intrinsics.jl index dec4412ffd4d5..78c6af93e0078 100644 --- a/test/intrinsics.jl +++ b/test/intrinsics.jl @@ -215,14 +215,14 @@ swap(i, j) = j for TT in (Int8, Int16, Int32, Int64, Int128, Int256, Int512, Complex{Int32}, Complex{Int512}, Any) r = Ref{TT}(10) GC.@preserve r begin - (function (::Type{TT}) where TT + (@noinline function (::Type{TT}) where TT p = Base.unsafe_convert(Ptr{TT}, r) T(x) = convert(TT, x) S = UInt32 if TT !== Any @test_throws TypeError Core.Intrinsics.atomic_pointerset(p, S(1), :sequentially_consistent) - @test_throws TypeError Core.Intrinsics.atomic_pointerswap(p, S(100), :sequentially_consistent) - @test_throws TypeError Core.Intrinsics.atomic_pointerreplace(p, T(100), S(2), :sequentially_consistent, :sequentially_consistent) + @test_throws TypeError Core.Intrinsics.atomic_pointerswap(p, S(2), :sequentially_consistent) + @test_throws TypeError Core.Intrinsics.atomic_pointerreplace(p, T(10), S(3), :sequentially_consistent, :sequentially_consistent) end @test Core.Intrinsics.pointerref(p, 1, 1) === T(10) === r[] if sizeof(r) > 8 @@ -235,7 +235,10 @@ for TT in (Int8, Int16, Int32, Int64, Int128, Int256, Int512, Complex{Int32}, Co @test_throws ErrorException("atomic_pointerreplace: invalid pointer for atomic operation") Core.Intrinsics.atomic_pointerreplace(p, S(100), T(2), :sequentially_consistent, :sequentially_consistent) @test Core.Intrinsics.pointerref(p, 1, 1) === T(10) === r[] else - TT !== Any && @test_throws TypeError Core.Intrinsics.atomic_pointermodify(p, swap, S(1), :sequentially_consistent) + if TT !== Any + @test_throws TypeError Core.Intrinsics.atomic_pointermodify(p, swap, S(4), :sequentially_consistent) + @test_throws TypeError Core.Intrinsics.atomic_pointermodify(p, Returns(S(5)), T(10), :sequentially_consistent) + end @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(10) @test Core.Intrinsics.atomic_pointerset(p, T(1), :sequentially_consistent) === p @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(1) @@ -249,10 +252,12 @@ for TT in (Int8, Int16, Int32, Int64, Int128, Int256, Int512, Complex{Int32}, Co @test Core.Intrinsics.atomic_pointerswap(p, T(103), :sequentially_consistent) === T(102) @test Core.Intrinsics.atomic_pointerreplace(p, S(100), T(2), :sequentially_consistent, :sequentially_consistent) === ReplaceType{TT}((T(103), false)) @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(103) + @test Core.Intrinsics.atomic_pointermodify(p, Returns(T(105)), nothing, :sequentially_consistent) === Pair{TT,TT}(T(103), T(105)) + @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === T(105) end if TT === Any - @test Core.Intrinsics.atomic_pointermodify(p, swap, S(103), :sequentially_consistent) === Pair{TT,TT}(T(103), S(103)) - @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === S(103) + @test Core.Intrinsics.atomic_pointermodify(p, swap, S(105), :sequentially_consistent) === Pair{TT,TT}(T(105), S(105)) + @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === S(105) @test Core.Intrinsics.atomic_pointerset(p, S(1), :sequentially_consistent) === p @test Core.Intrinsics.atomic_pointerswap(p, S(100), :sequentially_consistent) === S(1) @test Core.Intrinsics.atomic_pointerreplace(p, T(100), S(2), :sequentially_consistent, :sequentially_consistent) === ReplaceType{TT}((S(100), false)) @@ -263,6 +268,37 @@ for TT in (Int8, Int16, Int32, Int64, Int128, Int256, Int512, Complex{Int32}, Co end end +for TT in (Ptr{Nothing}, Ptr) + r = Ref(nothing) + GC.@preserve r begin + p = Ref{TT}(Base.unsafe_convert(Ptr{Nothing}, r)) + (@noinline function (p::Ref) + p = p[] + S = UInt32 + @test_throws TypeError Core.Intrinsics.atomic_pointerset(p, S(1), :sequentially_consistent) + @test_throws TypeError Core.Intrinsics.atomic_pointerswap(p, S(100), :sequentially_consistent) + @test_throws TypeError Core.Intrinsics.atomic_pointerreplace(p, nothing, S(2), :sequentially_consistent, :sequentially_consistent) + @test Core.Intrinsics.pointerref(p, 1, 1) === nothing === r[] + @test_throws TypeError Core.Intrinsics.atomic_pointermodify(p, swap, S(1), :sequentially_consistent) + @test_throws TypeError Core.Intrinsics.atomic_pointermodify(p, Returns(S(1)), nothing, :sequentially_consistent) + @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === nothing + @test Core.Intrinsics.atomic_pointerset(p, nothing, :sequentially_consistent) === p + @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === nothing + @test Core.Intrinsics.atomic_pointerreplace(p, nothing, nothing, :sequentially_consistent, :sequentially_consistent) === ReplaceType{Nothing}((nothing, true)) + @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === nothing + @test Core.Intrinsics.atomic_pointerreplace(p, S(1), nothing, :sequentially_consistent, :sequentially_consistent) === ReplaceType{Nothing}((nothing, false)) + @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === nothing + @test Core.Intrinsics.atomic_pointermodify(p, Returns(nothing), nothing, :sequentially_consistent) === Pair{Nothing,Nothing}(nothing, nothing) + @test Core.Intrinsics.atomic_pointermodify(p, Returns(nothing), S(1), :sequentially_consistent) === Pair{Nothing,Nothing}(nothing, nothing) + @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === nothing + @test Core.Intrinsics.atomic_pointerswap(p, nothing, :sequentially_consistent) === nothing + @test Core.Intrinsics.atomic_pointerreplace(p, S(100), nothing, :sequentially_consistent, :sequentially_consistent) === ReplaceType{Nothing}((nothing, false)) + @test Core.Intrinsics.atomic_pointerref(p, :sequentially_consistent) === nothing + end)(p,) + end +end + + mutable struct IntWrap <: Signed x::Int end diff --git a/test/precompile.jl b/test/precompile.jl index 1477001386f6b..f465c32496ad7 100644 --- a/test/precompile.jl +++ b/test/precompile.jl @@ -328,17 +328,20 @@ precompile_test_harness(false) do dir cachedir = joinpath(dir, "compiled", "v$(VERSION.major).$(VERSION.minor)") cachedir2 = joinpath(dir2, "compiled", "v$(VERSION.major).$(VERSION.minor)") cachefile = joinpath(cachedir, "$Foo_module.ji") - if Base.JLOptions().use_pkgimages == 1 - ocachefile = Base.ocachefile_from_cachefile(cachefile) - else - ocachefile = nothing - end - # use _require_from_serialized to ensure that the test fails if - # the module doesn't reload from the image: - @test_warn "@ccallable was already defined for this method name" begin - @test_logs (:warn, "Replacing module `$Foo_module`") begin - m = Base._require_from_serialized(Base.PkgId(Foo), cachefile, ocachefile) - @test isa(m, Module) + do_pkgimg = Base.JLOptions().use_pkgimages == 1 && Base.JLOptions().permalloc_pkgimg == 1 + if do_pkgimg || Base.JLOptions().use_pkgimages == 0 + if do_pkgimg + ocachefile = Base.ocachefile_from_cachefile(cachefile) + else + ocachefile = nothing + end + # use _require_from_serialized to ensure that the test fails if + # the module doesn't reload from the image: + @test_warn "@ccallable was already defined for this method name" begin + @test_logs (:warn, "Replacing module `$Foo_module`") begin + m = Base._require_from_serialized(Base.PkgId(Foo), cachefile, ocachefile) + @test isa(m, Module) + end end end diff --git a/test/sorting.jl b/test/sorting.jl index 92853b2812e47..c0cbc79b0546c 100644 --- a/test/sorting.jl +++ b/test/sorting.jl @@ -955,6 +955,46 @@ end test_allocs() end +@testset "MissingOptimization fastpath for Perm ordering when lo:hi ≠ eachindex(v)" begin + v = [rand() < .5 ? missing : rand() for _ in 1:100] + ix = collect(1:100) + sort!(ix, 1, 10, Base.Sort.DEFAULT_STABLE, Base.Order.Perm(Base.Order.Forward, v)) + @test issorted(v[ix[1:10]]) +end + +struct NonScalarIndexingOfWithoutMissingVectorAlg <: Base.Sort.Algorithm end +function Base.Sort._sort!(v::AbstractVector, ::NonScalarIndexingOfWithoutMissingVectorAlg, o::Base.Order.Ordering, kw) + Base.Sort.@getkw lo hi + first_half = v[lo:lo+(hi-lo)÷2] + second_half = v[lo+(hi-lo)÷2+1:hi] + whole = v[lo:hi] + all(vcat(first_half, second_half) .=== whole) || error() + out = Base.Sort._sort!(whole, Base.Sort.DEFAULT_STABLE, o, (;kw..., lo=1, hi=length(whole))) + v[lo:hi] .= whole + out +end + +@testset "Non-scaler indexing of WithoutMissingVector" begin + @testset "Unit test" begin + wmv = Base.Sort.WithoutMissingVector(Union{Missing, Int}[1, 7, 2, 9]) + @test wmv[[1, 3]] == [1, 2] + @test wmv[1:3] == [1, 7, 2] + end + @testset "End to end" begin + alg = Base.Sort.InitialOptimizations(NonScalarIndexingOfWithoutMissingVectorAlg()) + @test issorted(sort(rand(100); alg)) + @test issorted(sort([rand() < .5 ? missing : randstring() for _ in 1:100]; alg)) + end +end + +struct DispatchLoopTestAlg <: Base.Sort.Algorithm end +function Base.sort!(v::AbstractVector, lo::Integer, hi::Integer, ::DispatchLoopTestAlg, order::Base.Order.Ordering) + sort!(view(v, lo:hi); order) +end +@testset "Support dispatch from the old style to the new style and back" begin + @test issorted(sort!(rand(100), Base.Sort.InitialOptimizations(DispatchLoopTestAlg()), Base.Order.Forward)) +end + # This testset is at the end of the file because it is slow. @testset "searchsorted" begin numTypes = [ Int8, Int16, Int32, Int64, Int128, diff --git a/test/threadpool_use.jl b/test/threadpool_use.jl index e5ea5f95cf4ff..7523991fdf6a7 100644 --- a/test/threadpool_use.jl +++ b/test/threadpool_use.jl @@ -9,5 +9,11 @@ using Base.Threads @test fetch(Threads.@spawn Threads.threadpool()) === :default @test fetch(Threads.@spawn :default Threads.threadpool()) === :default @test fetch(Threads.@spawn :interactive Threads.threadpool()) === :interactive +tp = :default +@test fetch(Threads.@spawn tp Threads.threadpool()) === :default +tp = :interactive +@test fetch(Threads.@spawn tp Threads.threadpool()) === :interactive +tp = :foo +@test_throws ArgumentError Threads.@spawn tp Threads.threadpool() @test Threads.threadpooltids(:interactive) == [1] @test Threads.threadpooltids(:default) == [2]