about summary refs log tree commit diff
path: root/src/liballoc
diff options
context:
space:
mode:
authorLuqman Aden <laden@csclub.uwaterloo.ca>2014-12-04 13:29:47 -0500
committerLuqman Aden <laden@csclub.uwaterloo.ca>2014-12-28 19:40:47 -0500
commit4af50548b9ed283acb62768624a8cd942eabe964 (patch)
tree5aef71b845c938a7087df51b718519e5eea77c53 /src/liballoc
parent0d48f76224371e884496182f6cfb3e2dad7690a2 (diff)
downloadrust-4af50548b9ed283acb62768624a8cd942eabe964.tar.gz
rust-4af50548b9ed283acb62768624a8cd942eabe964.zip
liballoc: Use NonZero in Arc.
Diffstat (limited to 'src/liballoc')
-rw-r--r--src/liballoc/arc.rs29
1 files changed, 17 insertions, 12 deletions
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 8d8bbb42932..290617535bb 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -79,8 +79,7 @@ use core::mem;
 use core::ops::{Drop, Deref};
 use core::option::Option;
 use core::option::Option::{Some, None};
-use core::ptr::RawPtr;
-use core::ptr;
+use core::ptr::{mod, NonZero, RawPtr};
 use heap::deallocate;
 
 /// An atomically reference counted wrapper for shared state.
@@ -114,7 +113,7 @@ use heap::deallocate;
 pub struct Arc<T> {
     // FIXME #12808: strange name to try to avoid interfering with
     // field accesses of the contained type via Deref
-    _ptr: *mut ArcInner<T>,
+    _ptr: NonZero<*mut ArcInner<T>>,
 }
 
 unsafe impl<T: Sync + Send> Send for Arc<T> { }
@@ -130,7 +129,7 @@ unsafe impl<T: Sync + Send> Sync for Arc<T> { }
 pub struct Weak<T> {
     // FIXME #12808: strange name to try to avoid interfering with
     // field accesses of the contained type via Deref
-    _ptr: *mut ArcInner<T>,
+    _ptr: NonZero<*mut ArcInner<T>>,
 }
 
 unsafe impl<T: Sync + Send> Send for Weak<T> { }
@@ -165,7 +164,7 @@ impl<T> Arc<T> {
             weak: atomic::AtomicUint::new(1),
             data: data,
         };
-        Arc { _ptr: unsafe { mem::transmute(x) } }
+        Arc { _ptr: NonZero(unsafe { mem::transmute(x) }) }
     }
 
     /// Downgrades the `Arc<T>` to a `Weak<T>` reference.
@@ -194,7 +193,8 @@ impl<T> Arc<T> {
         // pointer is valid. Furthermore, we know that the `ArcInner` structure itself is `Sync`
         // because the inner data is `Sync` as well, so we're ok loaning out an immutable pointer
         // to these contents.
-        unsafe { &*self._ptr }
+        let NonZero(ptr) = self._ptr;
+        unsafe { &*ptr }
     }
 }
 
@@ -281,7 +281,8 @@ impl<T: Send + Sync + Clone> Arc<T> {
         // pointer that will ever be returned to T. Our reference count is guaranteed to be 1 at
         // this point, and we required the Arc itself to be `mut`, so we're returning the only
         // possible reference to the inner data.
-        let inner = unsafe { &mut *self._ptr };
+        let NonZero(ptr) = self._ptr;
+        let inner = unsafe { &mut *ptr };
         &mut inner.data
     }
 }
@@ -316,7 +317,8 @@ impl<T: Sync + Send> Drop for Arc<T> {
     fn drop(&mut self) {
         // This structure has #[unsafe_no_drop_flag], so this drop glue may run more than once (but
         // it is guaranteed to be zeroed after the first if it's run more than once)
-        if self._ptr.is_null() { return }
+        let NonZero(ptr) = self._ptr;
+        if ptr.is_null() { return }
 
         // Because `fetch_sub` is already atomic, we do not need to synchronize with other threads
         // unless we are going to delete the object. This same logic applies to the below
@@ -346,7 +348,7 @@ impl<T: Sync + Send> Drop for Arc<T> {
 
         if self.inner().weak.fetch_sub(1, atomic::Release) == 1 {
             atomic::fence(atomic::Acquire);
-            unsafe { deallocate(self._ptr as *mut u8, size_of::<ArcInner<T>>(),
+            unsafe { deallocate(ptr as *mut u8, size_of::<ArcInner<T>>(),
                                 min_align_of::<ArcInner<T>>()) }
         }
     }
@@ -386,7 +388,8 @@ impl<T: Sync + Send> Weak<T> {
     #[inline]
     fn inner(&self) -> &ArcInner<T> {
         // See comments above for why this is "safe"
-        unsafe { &*self._ptr }
+        let NonZero(ptr) = self._ptr;
+        unsafe { &*ptr }
     }
 }
 
@@ -442,14 +445,16 @@ impl<T: Sync + Send> Drop for Weak<T> {
     /// } // implicit drop
     /// ```
     fn drop(&mut self) {
+        let NonZero(ptr) = self._ptr;
+
         // see comments above for why this check is here
-        if self._ptr.is_null() { return }
+        if ptr.is_null() { return }
 
         // If we find out that we were the last weak pointer, then its time to deallocate the data
         // entirely. See the discussion in Arc::drop() about the memory orderings
         if self.inner().weak.fetch_sub(1, atomic::Release) == 1 {
             atomic::fence(atomic::Acquire);
-            unsafe { deallocate(self._ptr as *mut u8, size_of::<ArcInner<T>>(),
+            unsafe { deallocate(ptr as *mut u8, size_of::<ArcInner<T>>(),
                                 min_align_of::<ArcInner<T>>()) }
         }
     }