-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add atomic operators for globals, memory, and setonce #52868
Conversation
4456be2
to
cdd101e
Compare
cdd101e
to
48bc10d
Compare
32-bit failing with
but everything else looks ready for review |
@@ -145,10 +151,9 @@ end | |||
|
|||
## Conversions ## | |||
|
|||
convert(::Type{T}, a::AbstractArray) where {T<:GenericMemory} = a isa T ? a : T(a)::T | |||
convert(::Type{T}, a::AbstractArray) where {T<:Memory} = a isa T ? a : T(a)::T |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should the second argument here be AbstracVector
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
apparently not?
julia> @which convert(Vector{Int}, [1 2; 3 4])
convert(::Type{T}, a::AbstractArray) where T<:Array
@ Base array.jl:607
julia> convert(Vector{Int}, [1 2; 3 4])
ERROR: MethodError: no method matching Vector{Int64}(::Matrix{Int64})
48bc10d
to
a872b19
Compare
I will merge tomorrow, and take any post-merge feedback instead then, if not gotten to before then. |
Do you have a list of all the new and deleted intrinsics/builtins? It's a bit hard to glean from the diff, since you also did some (appreciated) clean-up on things. |
@atomiconce :sequentially_consistent :monotonic a.b.x = value | ||
|
||
Perform the conditional assignment of value atomically if it was previously | ||
unset, returning the value `success::Bool`. Where `success` indicates whether |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So one thing is that unset isn't the nomenclature we seem to usually use, we mostly seem to use defined/undefined
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess that should say the field was not set
or the field was undef
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that might be a bit more inline to what we call it in other places?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We use unset at lot for this also (e.g. unsetindex), since we use undefined to mean isbits types that are not initialized, while this is not undef->defined but rather unset->set
Here's the list of new functions, from the docs (though your comment made me realize I had missed adding the rest of the memoryref builtins there): Core.modifyglobal!
Core.swapglobal!
Core.replaceglobal!
Core.setglobalonce!
Core.memoryrefswap!
Core.memoryrefmodify!
Core.memoryrefreplace!
Core.memoryrefsetonce!
Core.setfieldonce! |
@@ -2281,6 +2282,21 @@ instruction, otherwise it'll use a loop. | |||
""" | |||
replacefield! | |||
|
|||
""" | |||
setfieldonce!(value, name::Union{Int,Symbol}, desired, | |||
[success_order::Symbol, [fail_order::Symbol=success_order]) -> success::Bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the default success_order
? (Same for the other docstrings here)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default is not to have a success_order (in some places, equivalent to :not_atomic
, but not identical)
setfield!(value, name, desired, success_order) | ||
end | ||
return ok | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably should also get a compat note?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hopefully I got all those versions right
Adds an AtomicMemory{T} type (GenericMemory{:atomic,T,Core.CPU}) for doing element-wise atomic operations on an array (with a lock per-element if required). Adds the full complement of atomic operations for global variables. Also add a *setonce set of functions for atomically setting a value, but only if it is unset. The complementary operation (Atomic `_unsetindex!` for AtomicMemory) is not yet provided.
a872b19
to
d8d17b8
Compare
This implements
AtomicMemory
, atomic operations for globals, and the class of atomic function for setting a field or global or memory exactly once (setting undef => value). It is quite similar to an@atomicreplace
, but where there was not a previous value. This is not needed for pointers, since it is simply calling C_NULL => pointer in that case, since there is no "undef" value that throws after load.plenty of future work still, for a later PR:
@atomic global x = y
and@atomic closedover = y
Core.AtomicBox
for closure captureatomicsetindex
& friends@atomic x = y
and@atomic x[] = y
, etc@atomiconce f()