Skip to content

Commit

Permalink
Make unsafe_free! thread safe.
Browse files Browse the repository at this point in the history
  • Loading branch information
maleadt committed Aug 12, 2023
1 parent 3420a26 commit 5dc0470
Showing 1 changed file with 15 additions and 13 deletions.
28 changes: 15 additions & 13 deletions src/array.jl
Original file line number Diff line number Diff line change
Expand Up @@ -118,22 +118,24 @@ streams) when calling this function from a finalizer. For simplicity, the `unsaf
function does exactly that.
"""
function unsafe_free!(xs::CuArray, stream::CuStream=stream())
# this call should only have an effect once, because both the user and the GC can call it
if xs.storage === nothing
return
elseif (xs.storage::ArrayStorage).refcount[] < 0
throw(ArgumentError("Cannot free an unmanaged buffer."))
end
@lock xs.lock begin
# this call should only have an effect once, because both the user and the GC can call it
if xs.storage === nothing
return
elseif (xs.storage::ArrayStorage).refcount[] < 0
throw(ArgumentError("Cannot free an unmanaged buffer."))
end

refcount = Threads.atomic_add!((xs.storage::ArrayStorage).refcount, -1)
if refcount == 1
context!(context(xs); skip_destroyed=true) do
free((xs.storage::ArrayStorage).buffer; stream)
refcount = Threads.atomic_add!((xs.storage::ArrayStorage).refcount, -1)
if refcount == 1
context!(context(xs); skip_destroyed=true) do
free((xs.storage::ArrayStorage).buffer; stream)
end
end
end

# this array object is now dead, so replace its storage by a dummy one
xs.storage = nothing
# this array object is now dead, so replace its storage by a dummy one
xs.storage = nothing
end

return
end
Expand Down

0 comments on commit 5dc0470

Please sign in to comment.