I’m getting unexpected behavior for atomic_min!(x::Atomic{T}, val::T) with floats. This function returns the old value of x. Works fine for Ints, but for Floats it returns the new value:
julia> E = Atomic{Float64}(10)
Atomic{Float64}(10.0)
julia> atomic_min!(E, 3.0)
3.0
julia> E
Atomic{Float64}(3.0)
If I change the code to use Int64 then atomic_min() returns the old value (10). What is going on?
Thanks. I wonder why the atomic functions return values and not booleans? The way it is now I have to compare the return value with x to see it the value of x changed, which could produce a race condition if x is written to by another thread.
I think it returns the old value to AVOID a race condition. If you atomically retrieve the value then atomically change the value, another thread might have changed it in between those two calls. If the method returns the OLD value, then you know what value was replaced and you can do whatever checks you need to do.
For sure the machine code is the same. It’s just a matter of choosing a higher level API, and there probably isn’t one solution for all cases. I’m used to the GCC atomic builtin functions, such as __sync_bool_compare_and_swap
Right it’s not about race or not. You can get the answer you want without a race.
And the current one is the one solution for all cases since the other one can be implemented using this, but not the other way around…
And fwiw, there’s __sync_val_compare_and_swap and pretty much all the other sync built-in returns the value instead of a boolean. It doesn’t even make much sense to return a boolean anyway since this operation, unlike CAS, is basically always a write operation anyway…