Policy on Atomics (and interior mutability, eg Mutex)
IMO Atomic
should be used sparingly. (Usually the justificataion will be performance.) When they are used, they should be wrapped up in something "cooked" that has appropriate and documented semantics.
Using Atomic
directly:
- Doesn't enforce correct use of the appropriate
Ordering
(which ought to beSeqCst
unless there is a formal argument for the correctness of a weaker ordering). - If there are other elements of state that the atomic is supposed to have some relationship to, doesn't tie that state and the atomic together (the way eg
Mutx
does). (And if there aren't, doesn't provide a clear statement the the atomic is just "loose") - Complicates refactorings that expand the retained state to a nonprimitive type.
- Prevents use of newtypes for the state.
Atomics are widely used within our codebase,in an ad-hoc manner. I think this is wrong. But apparently not everyone agrees. !525 (comment 2826517) IMO we need to resolve this disagreement.
Additionally, we have a few places where multiple interrelated elements of state are stored within multiple different variables with separate interior mutability. This is an antipattern, because it makes it possible for the elements of state to be concurrently accessed and mutated in different threads, in ways that will be memory safe but could be logically completely incorrect.
This is a kind of multithreaded race bug that Rust was supposed to protect us from. Mutable state elements that are linked by invariants should be contained within a Mutex
or similar. (Exceptions could be made for performance reasons.)