Skip to content

Commit 61a737a

Browse files
committed
liballoc: Use NonZero in Arc.
1 parent 98fdf0f commit 61a737a

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

src/liballoc/arc.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ use core::mem;
2424
use core::ops::{Drop, Deref};
2525
use core::option::Option;
2626
use core::option::Option::{Some, None};
27-
use core::ptr::RawPtr;
28-
use core::ptr;
27+
use core::ptr::{mod, NonZero, RawPtr};
2928
use heap::deallocate;
3029

3130
/// An atomically reference counted wrapper for shared state.
@@ -59,7 +58,7 @@ use heap::deallocate;
5958
pub struct Arc<T> {
6059
// FIXME #12808: strange name to try to avoid interfering with
6160
// field accesses of the contained type via Deref
62-
_ptr: *mut ArcInner<T>,
61+
_ptr: NonZero<*mut ArcInner<T>>,
6362
}
6463

6564
/// A weak pointer to an `Arc`.
@@ -71,7 +70,7 @@ pub struct Arc<T> {
7170
pub struct Weak<T> {
7271
// FIXME #12808: strange name to try to avoid interfering with
7372
// field accesses of the contained type via Deref
74-
_ptr: *mut ArcInner<T>,
73+
_ptr: NonZero<*mut ArcInner<T>>,
7574
}
7675

7776
struct ArcInner<T> {
@@ -92,7 +91,7 @@ impl<T: Sync + Send> Arc<T> {
9291
weak: atomic::AtomicUint::new(1),
9392
data: data,
9493
};
95-
Arc { _ptr: unsafe { mem::transmute(x) } }
94+
Arc { _ptr: NonZero(unsafe { mem::transmute(x) }) }
9695
}
9796

9897
/// Downgrades a strong pointer to a weak pointer.
@@ -116,7 +115,8 @@ impl<T> Arc<T> {
116115
// `ArcInner` structure itself is `Sync` because the inner data is
117116
// `Sync` as well, so we're ok loaning out an immutable pointer to
118117
// these contents.
119-
unsafe { &*self._ptr }
118+
let NonZero(ptr) = self._ptr;
119+
unsafe { &*ptr }
120120
}
121121
}
122122

@@ -184,7 +184,8 @@ impl<T: Send + Sync + Clone> Arc<T> {
184184
// reference count is guaranteed to be 1 at this point, and we required
185185
// the Arc itself to be `mut`, so we're returning the only possible
186186
// reference to the inner data.
187-
let inner = unsafe { &mut *self._ptr };
187+
let NonZero(ptr) = self._ptr;
188+
let inner = unsafe { &mut *ptr };
188189
&mut inner.data
189190
}
190191
}
@@ -193,10 +194,11 @@ impl<T: Send + Sync + Clone> Arc<T> {
193194
#[experimental = "waiting on stability of Drop"]
194195
impl<T: Sync + Send> Drop for Arc<T> {
195196
fn drop(&mut self) {
197+
let NonZero(ptr) = self._ptr;
196198
// This structure has #[unsafe_no_drop_flag], so this drop glue may run
197199
// more than once (but it is guaranteed to be zeroed after the first if
198200
// it's run more than once)
199-
if self._ptr.is_null() { return }
201+
if ptr.is_null() { return }
200202

201203
// Because `fetch_sub` is already atomic, we do not need to synchronize
202204
// with other threads unless we are going to delete the object. This
@@ -228,7 +230,7 @@ impl<T: Sync + Send> Drop for Arc<T> {
228230

229231
if self.inner().weak.fetch_sub(1, atomic::Release) == 1 {
230232
atomic::fence(atomic::Acquire);
231-
unsafe { deallocate(self._ptr as *mut u8, size_of::<ArcInner<T>>(),
233+
unsafe { deallocate(ptr as *mut u8, size_of::<ArcInner<T>>(),
232234
min_align_of::<ArcInner<T>>()) }
233235
}
234236
}
@@ -256,7 +258,8 @@ impl<T: Sync + Send> Weak<T> {
256258
#[inline]
257259
fn inner(&self) -> &ArcInner<T> {
258260
// See comments above for why this is "safe"
259-
unsafe { &*self._ptr }
261+
let NonZero(ptr) = self._ptr;
262+
unsafe { &*ptr }
260263
}
261264
}
262265

@@ -274,15 +277,17 @@ impl<T: Sync + Send> Clone for Weak<T> {
274277
#[experimental = "Weak pointers may not belong in this module."]
275278
impl<T: Sync + Send> Drop for Weak<T> {
276279
fn drop(&mut self) {
280+
let NonZero(ptr) = self._ptr;
281+
277282
// see comments above for why this check is here
278-
if self._ptr.is_null() { return }
283+
if ptr.is_null() { return }
279284

280285
// If we find out that we were the last weak pointer, then its time to
281286
// deallocate the data entirely. See the discussion in Arc::drop() about
282287
// the memory orderings
283288
if self.inner().weak.fetch_sub(1, atomic::Release) == 1 {
284289
atomic::fence(atomic::Acquire);
285-
unsafe { deallocate(self._ptr as *mut u8, size_of::<ArcInner<T>>(),
290+
unsafe { deallocate(ptr as *mut u8, size_of::<ArcInner<T>>(),
286291
min_align_of::<ArcInner<T>>()) }
287292
}
288293
}

0 commit comments

Comments
 (0)