@@ -305,6 +305,50 @@ impl AtomicBool {
305
305
AtomicBool { v : UnsafeCell :: new ( v as u8 ) }
306
306
}
307
307
308
+ /// Creates a new `AtomicBool` from a pointer.
309
+ ///
310
+ /// # Examples
311
+ ///
312
+ /// ```
313
+ /// #![feature(atomic_from_ptr, pointer_is_aligned)]
314
+ /// use std::sync::atomic::{self, AtomicBool};
315
+ /// use std::mem::align_of;
316
+ ///
317
+ /// // Get a pointer to an allocated value
318
+ /// let ptr: *mut bool = Box::into_raw(Box::new(false));
319
+ ///
320
+ /// assert!(ptr.is_aligned_to(align_of::<AtomicBool>()));
321
+ ///
322
+ /// {
323
+ /// // Create an atomic view of the allocated value
324
+ /// let atomic = unsafe { AtomicBool::from_ptr(ptr) };
325
+ ///
326
+ /// // Use `atomic` for atomic operations, possibly share it with other threads
327
+ /// atomic.store(true, atomic::Ordering::Relaxed);
328
+ /// }
329
+ ///
330
+ /// // It's ok to non-atomically access the value behind `ptr`,
331
+ /// // since the reference to the atomic ended its lifetime in the block above
332
+ /// assert_eq!(unsafe { *ptr }, true);
333
+ ///
334
+ /// // Deallocate the value
335
+ /// unsafe { drop(Box::from_raw(ptr)) }
336
+ /// ```
337
+ ///
338
+ /// # Safety
339
+ ///
340
+ /// * `ptr` must be aligned to `align_of::<AtomicBool>()` (note that on some platforms this can be bigger than `align_of::<bool>()`).
341
+ /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
342
+ /// * The value behind `ptr` must not be accessed through non-atomic operations for the whole lifetime `'a`.
343
+ ///
344
+ /// [valid]: crate::ptr#safety
345
+ #[ unstable( feature = "atomic_from_ptr" , issue = "none" ) ]
346
+ #[ rustc_const_unstable( feature = "atomic_from_ptr" , issue = "none" ) ]
347
+ pub const unsafe fn from_ptr < ' a > ( ptr : * mut bool ) -> & ' a AtomicBool {
348
+ // SAFETY: guaranteed by the caller
349
+ unsafe { & * ptr. cast ( ) }
350
+ }
351
+
308
352
/// Returns a mutable reference to the underlying [`bool`].
309
353
///
310
354
/// This is safe because the mutable reference guarantees that no other threads are
@@ -1017,6 +1061,50 @@ impl<T> AtomicPtr<T> {
1017
1061
AtomicPtr { p : UnsafeCell :: new ( p) }
1018
1062
}
1019
1063
1064
+ /// Creates a new `AtomicPtr` from a pointer.
1065
+ ///
1066
+ /// # Examples
1067
+ ///
1068
+ /// ```
1069
+ /// #![feature(atomic_from_ptr, pointer_is_aligned)]
1070
+ /// use std::sync::atomic::{self, AtomicPtr};
1071
+ /// use std::mem::align_of;
1072
+ ///
1073
+ /// // Get a pointer to an allocated value
1074
+ /// let ptr: *mut *mut u8 = Box::into_raw(Box::new(std::ptr::null_mut()));
1075
+ ///
1076
+ /// assert!(ptr.is_aligned_to(align_of::<AtomicPtr<u8>>()));
1077
+ ///
1078
+ /// {
1079
+ /// // Create an atomic view of the allocated value
1080
+ /// let atomic = unsafe { AtomicPtr::from_ptr(ptr) };
1081
+ ///
1082
+ /// // Use `atomic` for atomic operations, possibly share it with other threads
1083
+ /// atomic.store(std::ptr::NonNull::dangling().as_ptr(), atomic::Ordering::Relaxed);
1084
+ /// }
1085
+ ///
1086
+ /// // It's ok to non-atomically access the value behind `ptr`,
1087
+ /// // since the reference to the atomic ended its lifetime in the block above
1088
+ /// assert!(!unsafe { *ptr }.is_null());
1089
+ ///
1090
+ /// // Deallocate the value
1091
+ /// unsafe { drop(Box::from_raw(ptr)) }
1092
+ /// ```
1093
+ ///
1094
+ /// # Safety
1095
+ ///
1096
+ /// * `ptr` must be aligned to `align_of::<AtomicPtr<T>>()` (note that on some platforms this can be bigger than `align_of::<*mut T>()`).
1097
+ /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
1098
+ /// * The value behind `ptr` must not be accessed through non-atomic operations for the whole lifetime `'a`.
1099
+ ///
1100
+ /// [valid]: crate::ptr#safety
1101
+ #[ unstable( feature = "atomic_from_ptr" , issue = "none" ) ]
1102
+ #[ rustc_const_unstable( feature = "atomic_from_ptr" , issue = "none" ) ]
1103
+ pub const unsafe fn from_ptr < ' a > ( ptr : * mut * mut T ) -> & ' a AtomicPtr < T > {
1104
+ // SAFETY: guaranteed by the caller
1105
+ unsafe { & * ptr. cast ( ) }
1106
+ }
1107
+
1020
1108
/// Returns a mutable reference to the underlying pointer.
1021
1109
///
1022
1110
/// This is safe because the mutable reference guarantees that no other threads are
@@ -1958,6 +2046,53 @@ macro_rules! atomic_int {
1958
2046
Self { v: UnsafeCell :: new( v) }
1959
2047
}
1960
2048
2049
+ /// Creates a new reference to an atomic integer from a pointer.
2050
+ ///
2051
+ /// # Examples
2052
+ ///
2053
+ /// ```
2054
+ /// #![feature(atomic_from_ptr, pointer_is_aligned)]
2055
+ #[ doc = concat!( $extra_feature, "use std::sync::atomic::{self, " , stringify!( $atomic_type) , "};" ) ]
2056
+ /// use std::mem::align_of;
2057
+ ///
2058
+ /// // Get a pointer to an allocated value
2059
+ #[ doc = concat!( "let ptr: *mut " , stringify!( $int_type) , " = Box::into_raw(Box::new(0));" ) ]
2060
+ ///
2061
+ #[ doc = concat!( "assert!(ptr.is_aligned_to(align_of::<" , stringify!( $atomic_type) , ">()));" ) ]
2062
+ ///
2063
+ /// {
2064
+ /// // Create an atomic view of the allocated value
2065
+ // SAFETY: this is a doc comment, tidy, it can't hurt you (also guaranteed by the construction of `ptr` and the assert above)
2066
+ #[ doc = concat!( " let atomic = unsafe {" , stringify!( $atomic_type) , "::from_ptr(ptr) };" ) ]
2067
+ ///
2068
+ /// // Use `atomic` for atomic operations, possibly share it with other threads
2069
+ /// atomic.store(1, atomic::Ordering::Relaxed);
2070
+ /// }
2071
+ ///
2072
+ /// // It's ok to non-atomically access the value behind `ptr`,
2073
+ /// // since the reference to the atomic ended its lifetime in the block above
2074
+ /// assert_eq!(unsafe { *ptr }, 1);
2075
+ ///
2076
+ /// // Deallocate the value
2077
+ /// unsafe { drop(Box::from_raw(ptr)) }
2078
+ /// ```
2079
+ ///
2080
+ /// # Safety
2081
+ ///
2082
+ /// * `ptr` must be aligned to `align_of::<AtomicBool>()` (note that on some platforms this can be bigger than `align_of::<bool>()`).
2083
+ #[ doc = concat!( " * `ptr` must be aligned to `align_of::<" , stringify!( $atomic_type) , ">()` (note that on some platforms this can be bigger than `align_of::<" , stringify!( $int_type) , ">()`)." ) ]
2084
+ /// * `ptr` must be [valid] for both reads and writes for the whole lifetime `'a`.
2085
+ /// * The value behind `ptr` must not be accessed through non-atomic operations for the whole lifetime `'a`.
2086
+ ///
2087
+ /// [valid]: crate::ptr#safety
2088
+ #[ unstable( feature = "atomic_from_ptr" , issue = "none" ) ]
2089
+ #[ rustc_const_unstable( feature = "atomic_from_ptr" , issue = "none" ) ]
2090
+ pub const unsafe fn from_ptr<' a>( ptr: * mut $int_type) -> & ' a $atomic_type {
2091
+ // SAFETY: guaranteed by the caller
2092
+ unsafe { & * ptr. cast( ) }
2093
+ }
2094
+
2095
+
1961
2096
/// Returns a mutable reference to the underlying integer.
1962
2097
///
1963
2098
/// This is safe because the mutable reference guarantees that no other threads are
0 commit comments