Skip to content

Commit c75643f

Browse files
committed
editing
1 parent d8b495b commit c75643f

File tree

1 file changed

+33
-38
lines changed

1 file changed

+33
-38
lines changed

library/core/src/ptr/mod.rs

Lines changed: 33 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@
116116
//! fully contiguous (i.e., has no "holes"), there is no guarantee that this
117117
//! will not change in the future.
118118
//!
119+
//! Allocated objects must behave like "normal" memory: in particular, reads must not have
120+
//! side-effects, and writes must become visible to other threads using the usual synchronization
121+
//! primitives.
122+
//!
119123
//! For any allocated object with `base` address, `size`, and a set of
120124
//! `addresses`, the following are guaranteed:
121125
//! - For all addresses `a` in `addresses`, `a` is in the range `base .. (base +
@@ -1755,38 +1759,30 @@ pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
17551759
/// over time. That being said, the semantics will almost always end up pretty
17561760
/// similar to [C11's definition of volatile][c11].
17571761
///
1758-
/// Volatile operations are intended to act on I/O memory, and are guaranteed
1759-
/// to not be elided or reordered by the compiler across other volatile
1760-
/// operations. With this in mind, there are two cases of usage that need to
1761-
/// be distinguished:
1762-
///
1763-
/// - When a volatile operation is used for memory inside an [allocation], all
1764-
/// the typical restrictions of Rust-allocated memory apply, meaning things
1765-
/// like data races and mutable aliasing remain as undefined behavior. In
1766-
/// addition, the volatile rule that the operation won't be elided or
1767-
/// reordered applies, such that the operation will access memory and not e.g.
1768-
/// be lowered to a register access or stack pop. The memory in `src` should
1769-
/// remain unchanged. Just like in C, whether an operation is volatile has no
1770-
/// bearing whatsoever on questions involving concurrent access from multiple
1771-
/// threads. Volatile accesses behave exactly like non-atomic accesses in that
1772-
/// regard. All this is because this kind of target-memory may be used from
1773-
/// safe code at any time, and its validity assumptions must not be violated.
1774-
///
1775-
/// - Volatile operations, however, provide a conditionally valid way to access
1776-
/// memory that is _outside_ of any allocation. The main use-case is CPU and
1777-
/// peripheral registers that must be accessed via an I/O memory mapping, most
1778-
/// commonly at fixed addresses reserved by the hardware. These often have
1779-
/// special semantics associated to their manipulation, and cannot be used as
1780-
/// general purpose memory. Here, any address value is possible, from 0 to
1781-
/// [`usize::MAX`], so long as its semantics are well-defined by the target
1782-
/// hardware. The access is restricted to not trap/interrupt. It can (and
1783-
/// usually will) cause side-effects, but note they shouldn't affect
1784-
/// Rust-allocated memory in any way.
1785-
///
1786-
/// The compiler shouldn't change the relative order or number of volatile
1787-
/// memory operations. However, volatile memory operations on zero-sized types
1788-
/// (e.g., if a zero-sized type is passed to `read_volatile`) are noops
1789-
/// and may be ignored.
1762+
/// Volatile operations are intended to act on I/O memory. As such, they are considered externally
1763+
/// observable events (just like syscalls), and are guaranteed to not be elided or reordered by the
1764+
/// compiler across other externally observable events. With this in mind, there are two cases of
1765+
/// usage that need to be distinguished:
1766+
///
1767+
/// - When a volatile operation is used for memory inside an [allocation], it behaves exactly like
1768+
/// [`read`], except for the additional guarantee that it won't be elided or reordered (see
1769+
/// above). This implies that the operation will actually access memory and not e.g. be lowered to
1770+
/// a register access or stack pop. Other than that, all the usual rules for memory accesses
1771+
/// apply. In particular, just like in C, whether an operation is volatile has no bearing
1772+
/// whatsoever on questions involving concurrent access from multiple threads. Volatile accesses
1773+
/// behave exactly like non-atomic accesses in that regard.
1774+
///
1775+
/// - Volatile operations, however, may also be used access memory that is _outside_ of any Rust
1776+
/// allocation. The main use-case is CPU and peripheral registers that must be accessed via an I/O
1777+
/// memory mapping, most commonly at fixed addresses reserved by the hardware. These often have
1778+
/// special semantics associated to their manipulation, and cannot be used as general purpose
1779+
/// memory. Here, any address value is possible, including 0 and [`usize::MAX`], so long as the
1780+
/// semantics of such a read are well-defined by the target hardware. The access must not trap. It
1781+
/// can (and usually will) cause side-effects, but those must not affect Rust-allocated memory in
1782+
/// any way.
1783+
///
1784+
/// Note that volatile memory operations on zero-sized types (e.g., if a zero-sized type is passed
1785+
/// to `read_volatile`) are noops and may be ignored.
17901786
///
17911787
/// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
17921788
/// [allocation]: crate::ptr#allocated-object
@@ -1795,15 +1791,14 @@ pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
17951791
///
17961792
/// Behavior is undefined if any of the following conditions are violated:
17971793
///
1798-
/// * `src` must be readable without trapping.
1794+
/// * `src` must be either [valid] for reads, or it must point to memory outside of all Rust
1795+
/// allocations and reading from that memory must:
1796+
/// - not trap, and
1797+
/// - not cause any memory inside a Rust allocation to be modified.
17991798
///
18001799
/// * `src` must be properly aligned.
18011800
///
1802-
/// * No Rust memory may be modified.
1803-
///
1804-
/// * If operating on an allocation, `src` must point to a properly initialized
1805-
/// value of type `T`, and the safe usage assumptions of the data must be
1806-
/// satisfied.
1801+
/// * Reading from `src` must produce a properly initialized value of type `T`.
18071802
///
18081803
/// Like [`read`], `read_volatile` creates a bitwise copy of `T`, regardless of
18091804
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the returned

0 commit comments

Comments
 (0)