Open mikeleany opened 1 year ago
I'm not sure enough about your question to answer (although I suspect it is unsound both by virtue of the fact that it does an unsynchronized read, and also because of the memory ordering on the update leading to unforeseen interleavings...)
However, there is another thing that might affect you - if you ever intend to free the memory returned from alloc
, then this will race with other threads calling alloc
(since the memory referred to by ptr
may have been freed). Unless you are doing some kind of arena allocator (in which case you might want to attach some lifetimes) then there isn't a good way to synchronize the two.
So the question is, does the race between steps 3 and 4, with Thread 2 writing to X and Thread 1 reading from X, result in undefined behavior, even though the value that was read is never used in circumstances where a race occurs.
Yes. Following the C++ memory model, read-write data races in Rust are UB even if the read result is unused.
I apologize in advance if this or an equivalent question is considered elsewhere. I haven't been able to find it.
Consider the following code, which uses an atomic linked list to allocate memory frames. Note that deallocation isn't considered here for simplicity (which saves us from having to worry about the ABA problem).
Now imagine that there are two concurrent calls to
FrameAlloc::alloc
as follows (with numbered lines indicating synchronization events):self.head
and assignsptr
(in the closure) to point to some location X.self.head
and also assigns itsptr
to point to X.ptr.read().next
) to get a pointer to some location Y.self.head
is unchanged and assigns it to point to Y.Option<NonNull<Frame>>
).ptr.read().next
), resulting in a race with the write by Thread 2.self.head
has changed and assignsptr
to point to Y. Note that the value read from X is now disregarded.So the question is, does the race between steps 3 and 4, with Thread 2 writing to X and Thread 1 reading from X, result in undefined behavior, even though the value that was read is never used in circumstances where a race occurs.