Further clarificarion for atomic and UnsafeCell docs: · qinheping/verify-rust-std@81fcbcd (original) (raw)
`@@ -33,12 +33,6 @@
`
33
33
`//! atomic load (via the operations provided in this module). A "modification of an atomic object"
`
34
34
`//! refers to an atomic store.
`
35
35
`//!
`
36
``
`-
//! The most important aspect of this model is that conflicting non-synchronized accesses are
`
37
``
`-
//! Undefined Behavior unless both accesses are atomic. Here, accesses are conflicting if they
`
38
``
`-
//! affect overlapping regions of memory and at least one of them is a write. They are
`
39
``
`-
//! non-synchronized if neither of them happens-before the other, according to the
`
40
``
`-
//! happens-before order of the memory model.
`
41
``
`-
//!
`
42
36
`//! The end result is almost equivalent to saying that creating a shared reference to one of the
`
43
37
`` //! Rust atomic types corresponds to creating an atomic_ref
in C++, with the atomic_ref
being
``
44
38
`//! destroyed when the lifetime of the shared reference ends. The main difference is that Rust
`
`@@ -47,20 +41,25 @@
`
47
41
`` //! objects" and "non-atomic objects" (with atomic_ref
temporarily converting a non-atomic object
``
48
42
`//! into an atomic object).
`
49
43
`//!
`
50
``
`-
//! That said, Rust does inherit the C++ limitation that non-synchronized conflicting atomic
`
51
``
`-
//! accesses may not partially overlap: they must be either disjoint or access the exact same
`
52
``
`-
//! memory. This in particular rules out non-synchronized differently-sized atomic accesses to the
`
53
``
`-
//! same data unless all accesses are reads.
`
``
44
`+
//! The most important aspect of this model is that data races are undefined behavior. A data race
`
``
45
`+
//! is defined as conflicting non-synchronized accesses where at least one of the accesses is
`
``
46
`+
//! non-atomic. Here, accesses are conflicting if they affect overlapping regions of memory and at
`
``
47
`+
//! least one of them is a write. They are non-synchronized if neither of them happens-before
`
``
48
`+
//! the other, according to the happens-before order of the memory model.
`
54
49
`//!
`
55
``
`-
//! [cpp]: https://en.cppreference.com/w/cpp/atomic
`
56
``
`-
//! [cpp-intro.races]: https://timsong-cpp.github.io/cppwp/n4868/intro.multithread#intro.races
`
``
50
`+
//! The other possible cause of undefined behavior in the memory model are mixed-size accesses: Rust
`
``
51
`+
//! inherits the C++ limitation that non-synchronized conflicting atomic accesses may not partially
`
``
52
`+
//! overlap. In other words, every pair of non-synchronized atomic accesses must be either disjoint,
`
``
53
`+
//! access the exact same memory (including using the same access size), or both be reads.
`
57
54
`//!
`
58
``
`` -
//! Each method takes an [Ordering
] which represents the strength of
``
59
``
`-
//! the memory barrier for that operation. These orderings behave the
`
60
``
`-
//! same as the corresponding [C++20 atomic orderings][1]. For more information see the [nomicon][2].
`
``
55
`` +
//! Each atomic access takes an [Ordering
] which defines how the operation interacts with the
``
``
56
`+
//! happens-before order. These orderings behave the same as the corresponding [C++20 atomic
`
``
57
`+
//! orderings][cpp_memory_order]. For more information, see the [nomicon].
`
61
58
`//!
`
62
``
`-
//! [1]: https://en.cppreference.com/w/cpp/atomic/memory_order
`
63
``
`-
//! [2]: ../../../nomicon/atomics.html
`
``
59
`+
//! [cpp]: https://en.cppreference.com/w/cpp/atomic
`
``
60
`+
//! [cpp-intro.races]: https://timsong-cpp.github.io/cppwp/n4868/intro.multithread#intro.races
`
``
61
`+
//! [cpp_memory_order]: https://en.cppreference.com/w/cpp/atomic/memory_order
`
``
62
`+
//! [nomicon]: ../../../nomicon/atomics.html
`
64
63
`//!
`
65
64
```` //! ```rust,no_run undefined_behavior
````
66
65
`//! use std::sync::atomic::{AtomicU16, AtomicU8, Ordering};
`
157
156
`//!
`
158
157
`//! # Atomic accesses to read-only memory
`
159
158
`//!
`
160
``
`-
//! In general, all atomic accesses on read-only memory are Undefined Behavior. For instance, attempting
`
``
159
`+
//! In general, all atomic accesses on read-only memory are undefined behavior. For instance, attempting
`
161
160
`` //! to do a compare_exchange
that will definitely fail (making it conceptually a read-only
``
162
161
`//! operation) can still cause a segmentation fault if the underlying memory page is mapped read-only. Since
`
163
162
`` //! atomic load
s might be implemented using compare-exchange operations, even a load
can fault
``
`@@ -173,7 +172,7 @@
`
173
172
`//!
`
174
173
`//! As an exception from the general rule stated above, "sufficiently small" atomic loads with
`
175
174
`` //! Ordering::Relaxed
are implemented in a way that works on read-only memory, and are hence not
``
176
``
`-
//! Undefined Behavior. The exact size limit for what makes a load "sufficiently small" varies
`
``
175
`+
//! undefined behavior. The exact size limit for what makes a load "sufficiently small" varies
`
177
176
`//! depending on the target:
`
178
177
`//!
`
179
178
`` //! | target_arch
| Size limit |
``