Skip to content

Commit

Permalink
Hack in acquire-load of task state to fix tests
Browse files Browse the repository at this point in the history
On x86 loads have implicit acquire semantics, but the same is
not true on other architectures (e.g. aarch64). We've been
observing test failures on aarch64 as a result (#38555).
Currently, we don't really have a good way to modify fields
in an atomic way (pending #37847), so this just achieves
the same thing using llvmcall to try and get the tests passing.
  • Loading branch information
Keno committed Nov 24, 2020
1 parent 809f27c commit e6d3466
Showing 1 changed file with 14 additions and 3 deletions.
17 changes: 14 additions & 3 deletions base/task.jl
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,21 @@ const task_state_runnable = UInt8(0)
const task_state_done = UInt8(1)
const task_state_failed = UInt8(2)

const _state_index = findfirst(==(:_state), fieldnames(Task))
@eval function load_state_acquire(t)
# TODO: Replace this by proper atomic operations when available
@GC.preserve t llvmcall($("""
%ptr = inttoptr i$(Sys.WORD_SIZE) %0 to i8*
%rv = load atomic i8, i8* %ptr acquire, align 8
ret i8 %rv
"""), UInt8, Tuple{Ptr{UInt8}},
Ptr{UInt8}(pointer_from_objref(t) + fieldoffset(Task, _state_index)))
end

@inline function getproperty(t::Task, field::Symbol)
if field === :state
# TODO: this field name should be deprecated in 2.0
st = getfield(t, :_state)
st = load_state_acquire(t)
if st === task_state_runnable
return :runnable
elseif st === task_state_done
Expand Down Expand Up @@ -177,7 +188,7 @@ julia> istaskdone(b)
true
```
"""
istaskdone(t::Task) = t._state !== task_state_runnable
istaskdone(t::Task) = load_state_acquire(t) !== task_state_runnable

"""
istaskstarted(t::Task) -> Bool
Expand Down Expand Up @@ -221,7 +232,7 @@ true
!!! compat "Julia 1.3"
This function requires at least Julia 1.3.
"""
istaskfailed(t::Task) = (t._state === task_state_failed)
istaskfailed(t::Task) = (load_state_acquire(t) === task_state_failed)

Threads.threadid(t::Task) = Int(ccall(:jl_get_task_tid, Int16, (Any,), t)+1)

Expand Down

0 comments on commit e6d3466

Please sign in to comment.