Description
I have a type in a library for embedded development, called VolatileCell<T>
, which sits over a memory address, and provides shared volatile access. However, I have been told this is unsound, as it uses &VolatileCell<T>
, which allows synthesized reads.
This, however, got me thinking. Would this not also apply inherently to any Sync
wrapper on an UnsafeCell, which offers mutation, such as Atomic or Mutex? After all, if the compiler can insert normal reads to the bytes behind an UnsafeCell, and a different thread performs even an atomic write that's not protected by a happens-before relationship, that a data race and immediate UB (according, at least, to the C++ memory model, which I have not heard rust diverge from enough to save this).
I'm wondering if it makes sense to relax the rules for references, to "if a read occurs, it can be moved anywhere in the function (absent operations that bar reordering), even if the read may not be evaluated", rather than "the compiler can invent reads out of thin air", at least for things that contain an UnsafeCell.
Note: While the post is asking specifically about VolatileCell
and a similar AtomicCell
which derives from it (and locks interrupts on reads/writes, giving interrupt-level atomicy), it generalizes to any such abstraction.