@@ -425,8 +425,9 @@ pub use non_null::NonNull;
425425mod unique;
426426#[ unstable( feature = "ptr_internals" , issue = "none" ) ]
427427pub use unique:: Unique ;
428+
428429#[ stable( feature = "volatile" , since = "1.9.0" ) ]
429- pub use volatile:: read_volatile;
430+ pub use volatile:: { read_volatile, write_volatile } ;
430431
431432mod const_ptr;
432433mod mut_ptr;
@@ -1672,86 +1673,6 @@ pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
16721673 }
16731674}
16741675
1675- /// Performs a volatile write of a memory location with the given value without
1676- /// reading or dropping the old value.
1677- ///
1678- /// Volatile operations are intended to act on I/O memory, and are guaranteed
1679- /// to not be elided or reordered by the compiler across other volatile
1680- /// operations.
1681- ///
1682- /// `write_volatile` does not drop the contents of `dst`. This is safe, but it
1683- /// could leak allocations or resources, so care should be taken not to overwrite
1684- /// an object that should be dropped.
1685- ///
1686- /// Additionally, it does not drop `src`. Semantically, `src` is moved into the
1687- /// location pointed to by `dst`.
1688- ///
1689- /// # Notes
1690- ///
1691- /// Rust does not currently have a rigorously and formally defined memory model,
1692- /// so the precise semantics of what "volatile" means here is subject to change
1693- /// over time. That being said, the semantics will almost always end up pretty
1694- /// similar to [C11's definition of volatile][c11].
1695- ///
1696- /// The compiler shouldn't change the relative order or number of volatile
1697- /// memory operations. However, volatile memory operations on zero-sized types
1698- /// (e.g., if a zero-sized type is passed to `write_volatile`) are noops
1699- /// and may be ignored.
1700- ///
1701- /// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
1702- ///
1703- /// # Safety
1704- ///
1705- /// Behavior is undefined if any of the following conditions are violated:
1706- ///
1707- /// * `dst` must be [valid] for writes.
1708- ///
1709- /// * `dst` must be properly aligned.
1710- ///
1711- /// Note that even if `T` has size `0`, the pointer must be properly aligned.
1712- ///
1713- /// [valid]: self#safety
1714- ///
1715- /// Just like in C, whether an operation is volatile has no bearing whatsoever
1716- /// on questions involving concurrent access from multiple threads. Volatile
1717- /// accesses behave exactly like non-atomic accesses in that regard. In particular,
1718- /// a race between a `write_volatile` and any other operation (reading or writing)
1719- /// on the same location is undefined behavior.
1720- ///
1721- /// # Examples
1722- ///
1723- /// Basic usage:
1724- ///
1725- /// ```
1726- /// let mut x = 0;
1727- /// let y = &mut x as *mut i32;
1728- /// let z = 12;
1729- ///
1730- /// unsafe {
1731- /// std::ptr::write_volatile(y, z);
1732- /// assert_eq!(std::ptr::read_volatile(y), 12);
1733- /// }
1734- /// ```
1735- #[ inline]
1736- #[ stable( feature = "volatile" , since = "1.9.0" ) ]
1737- #[ rustc_diagnostic_item = "ptr_write_volatile" ]
1738- #[ cfg_attr( miri, track_caller) ] // even without panics, this helps for Miri backtraces
1739- pub unsafe fn write_volatile < T > ( dst : * mut T , src : T ) {
1740- // SAFETY: the caller must uphold the safety contract for `volatile_store`.
1741- unsafe {
1742- ub_checks:: assert_unsafe_precondition!(
1743- check_language_ub,
1744- "ptr::write_volatile requires that the pointer argument is aligned and non-null" ,
1745- (
1746- addr: * mut ( ) = dst as * mut ( ) ,
1747- align: usize = align_of:: <T >( ) ,
1748- is_zst: bool = T :: IS_ZST ,
1749- ) => ub_checks:: maybe_is_aligned_and_not_null( addr, align, is_zst)
1750- ) ;
1751- intrinsics:: volatile_store ( dst, src) ;
1752- }
1753- }
1754-
17551676/// Align pointer `p`.
17561677///
17571678/// Calculate offset (in terms of elements of `size_of::<T>()` stride) that has to be applied
0 commit comments