Struct coco::epoch::Ptr
[−]
[src]
pub struct Ptr<'scope, T: 'scope> { /* fields omitted */ }
A pointer to an object protected by the epoch GC.
The pointer is valid for use only within 'scope
.
The pointer must be properly aligned. Since it is aligned, a tag can be stored into the unused least significant bits of the address.
Methods
impl<'scope, T> Ptr<'scope, T>
[src]
fn null() -> Self
Returns a new null pointer.
Examples
use coco::epoch::Ptr; let p = Ptr::<i32>::null(); assert!(p.is_null());
unsafe fn from_raw(raw: *const T) -> Self
Returns a new pointer initialized with raw
.
Panics
Panics if raw
is not properly aligned.
Examples
use coco::epoch::Ptr; let p = unsafe { Ptr::from_raw(Box::into_raw(Box::new(1234))) }; assert!(!p.is_null());
fn is_null(&self) -> bool
Returns true
if the pointer is null.
Examples
use coco::epoch::{self, Atomic, Owned}; use std::sync::atomic::Ordering::SeqCst; let a = Atomic::null(); epoch::pin(|scope| { assert!(a.load(SeqCst, scope).is_null()); a.store_owned(Owned::new(1234), SeqCst); assert!(!a.load(SeqCst, scope).is_null()); });
fn as_raw(&self) -> *const T
Converts the pointer to a raw pointer (without the tag).
Examples
use coco::epoch::{self, Atomic, Owned}; use std::sync::atomic::Ordering::SeqCst; let o = Owned::new(1234); let raw = &*o as *const _; let a = Atomic::from_owned(o); epoch::pin(|scope| { let p = a.load(SeqCst, scope); assert_eq!(p.as_raw(), raw); });
unsafe fn deref(&self) -> &'scope T
Dereferences the pointer.
Returns a reference to the pointee that is valid in 'scope
.
Safety
Dereferencing a pointer to an invalid object is not a concern, since invalid Ptr
s
can only be constructed via other unsafe functions.
However, this method doesn't check whether the pointer is null, so dereferencing a null pointer is unsafe.
Another source of unsafety is the possibility of unsynchronized reads to the objects. For example, the following scenario is unsafe:
- A thread stores a new object:
a.store_owned(Owned::new(10), Relaxed)
- Another thread reads it:
*a.load(Relaxed, scope).as_ref().unwrap()
The problem is that relaxed orderings don't synchronize initialization of the object with
the read from the second thread. This is a data race. A possible solution would be to use
Release
and Acquire
orderings (or stronger).
Examples
use coco::epoch::{self, Atomic}; use std::sync::atomic::Ordering::SeqCst; let a = Atomic::new(1234); epoch::pin(|scope| { let p = a.load(SeqCst, scope); unsafe { assert_eq!(p.deref(), &1234); } });
unsafe fn as_ref(&self) -> Option<&'scope T>
Converts the pointer to a reference.
Returns None
if the pointer is null, or else a reference to the object wrapped in Some
.
Safety
This method checks whether the pointer is null, and if not, assumes that it's pointing to a
valid object. However, this is not considered a source of unsafety because invalid Ptr
s
can only be constructed via other unsafe functions.
The only source of unsafety is the possibility of unsynchronized reads to the objects. For example, the following scenario is unsafe:
- A thread stores a new object:
a.store_owned(Owned::new(10), Relaxed)
- Another thread reads it:
*a.load(Relaxed, scope).as_ref().unwrap()
The problem is that relaxed orderings don't synchronize initialization of the object with
the read from the second thread. This is a data race. A possible solution would be to use
Release
and Acquire
orderings (or stronger).
Examples
use coco::epoch::{self, Atomic}; use std::sync::atomic::Ordering::SeqCst; let a = Atomic::new(1234); epoch::pin(|scope| { let p = a.load(SeqCst, scope); unsafe { assert_eq!(p.as_ref(), Some(&1234)); } });
fn tag(&self) -> usize
Returns the tag stored within the pointer.
Examples
use coco::epoch::{self, Atomic, Owned}; use std::sync::atomic::Ordering::SeqCst; let a = Atomic::from_owned(Owned::new(0u64).with_tag(5)); epoch::pin(|scope| { let p = a.load(SeqCst, scope); assert_eq!(p.tag(), 5); });
fn with_tag(&self, tag: usize) -> Self
Returns the same pointer, but tagged with tag
.
Examples
use coco::epoch::{self, Atomic}; use std::sync::atomic::Ordering::SeqCst; let a = Atomic::new(0u64); epoch::pin(|scope| { let p1 = a.load(SeqCst, scope); let p2 = p1.with_tag(5); assert_eq!(p1.tag(), 0); assert_eq!(p2.tag(), 5); assert_eq!(p1.as_raw(), p2.as_raw()); });
Trait Implementations
impl<'scope, T: Debug + 'scope> Debug for Ptr<'scope, T>
[src]
impl<'scope, T> Clone for Ptr<'scope, T>
[src]
fn clone(&self) -> Self
Returns a copy of the value. Read more
fn clone_from(&mut self, source: &Self)
1.0.0
Performs copy-assignment from source
. Read more