Struct lamellar::darc::Darc

source ·
pub struct Darc<T: 'static> { /* private fields */ }
Expand description

Distributed atomic reference counter

The atomic reference counter, Arc, is a backbone of safe concurrent programming in Rust, and, in particular, shared ownership.

The Darc provides a similar abstraction within a distributed environment.

  • Darc’s have global lifetime, meaning that the pointed to objects remain valid and accessible as long as one reference exists on any PE.
  • Inner mutability is disallowed by default. If you need to mutate through a Darc use Mutex, RwLock, or one of the Atomic types. Alternatively you can also use a LocalRwDarc or GlobalRwDarc.

Darc’s are intended to be passed via active messages.

  • They allow distributed accesss to and manipulation of generic Rust objects. The inner object can exist on the Rust heap or in a registered memory region.
  • They are instantiated in registered memory regions.

§Examples

 use lamellar::active_messaging::prelude::*;
 use lamellar::darc::prelude::*;
 use std::sync::atomic::{AtomicUsize, Ordering};
 use std::sync::Arc;

 #[lamellar::AmData(Clone)]
 struct DarcAm {
     counter: Darc<AtomicUsize>, //each pe has a local atomicusize
 }

 #[lamellar::am]
 impl LamellarAm for DarcAm {
     async fn exec(self) {
         self.counter.fetch_add(1, Ordering::SeqCst); //this only updates atomic on the executing pe
     }
  }

 fn main(){
     let world = LamellarWorldBuilder::new().build();
     let my_pe = world.my_pe();
     let num_pes = world.num_pes();
     let darc_counter = Darc::new(&world, AtomicUsize::new(0)).unwrap();
     world.exec_am_all(DarcAm {counter: darc_counter.clone()});
     darc_counter.fetch_add(my_pe, Ordering::SeqCst);
     world.wait_all(); // wait for my active message to return
     world.barrier(); //at this point all updates will have been performed
     assert_eq!(darc_counter.load(Ordering::SeqCst),num_pes+my_pe); //NOTE: the value of darc_counter will be different on each PE
 }

Implementations§

source§

impl<T> Darc<T>

source

pub fn new<U: Into<IntoLamellarTeam>>( team: U, item: T ) -> Result<Darc<T>, IdError>

Constructs a new Darc<T> on the PEs specified by team.

This is a blocking collective call amongst all PEs in the team, only returning once every PE in the team has completed the call.

Returns an error if this PE is not a part of team

§Collective Operation

Requires all PEs associated with the team to enter the constructor call otherwise deadlock will occur (i.e. team barriers are being called internally)

§Examples
use lamellar::darc::prelude::*;

let world = LamellarWorldBuilder::new().build();

let five = Darc::new(&world,5).expect("PE in world team");
source

pub fn into_localrw(self) -> LocalRwDarc<T>

Converts this Darc into a LocalRwDarc

This is a blocking collective call amongst all PEs in the Darc’s team, only returning once every PE in the team has completed the call.

Furthermore, this call will block while any additional references outside of the one making this call exist on each PE. It is not possible for the pointed to object to wrapped by both a Darc and a LocalRwDarc simultaneously (on any PE).

§Collective Operation

Requires all PEs associated with the darc to enter the call otherwise deadlock will occur (i.e. team barriers are being called internally)

§Examples
use lamellar::darc::prelude::*;

let world = LamellarWorldBuilder::new().build();

let five = Darc::new(&world,5).expect("PE in world team");
let five_as_localdarc = five.into_localrw();
source

pub fn into_globalrw(self) -> GlobalRwDarc<T>

Converts this Darc into a GlobalRwDarc

This is a blocking collective call amongst all PEs in the Darc’s team, only returning once every PE in the team has completed the call.

Furthermore, this call will block while any additional references outside of the one making this call exist on each PE. It is not possible for the pointed to object to wrapped by both a GlobalRwDarc and a Darc simultaneously (on any PE).

§Collective Operation

Requires all PEs associated with the darc to enter the call otherwise deadlock will occur (i.e. team barriers are being called internally)

§Examples
use lamellar::darc::prelude::*;

let world = LamellarWorldBuilder::new().build();

let five = Darc::new(&world,5).expect("PE in world team");
let five_as_globaldarc = five.into_globalrw();

Trait Implementations§

source§

impl<T> Clone for Darc<T>

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug> Debug for Darc<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<'de, T: 'static> Deserialize<'de> for Darc<T>

source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<T: Display> Display for Darc<T>

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T: 'static> Drop for Darc<T>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more
source§

impl<T> LamellarEnv for Darc<T>

source§

fn my_pe(&self) -> usize

Return the PE id of the calling PE, if called on a team instance, the PE id will be with respect to the team (not to the world)
source§

fn num_pes(&self) -> usize

Return the number of PEs in the execution
source§

fn num_threads_per_pe(&self) -> usize

Return the number of threads per PE
source§

fn world(&self) -> Arc<LamellarTeam>

Return a pointer the world team
source§

fn team(&self) -> Arc<LamellarTeam>

Return a pointer to the LamellarTeam
source§

impl<T: 'static> Serialize for Darc<T>

source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<T> Deref for Darc<T>

§

type Target = T

The resulting type after dereferencing.
source§

fn deref(&self) -> &T

Dereferences the value.
source§

impl<T: Send> Send for Darc<T>

source§

impl<T: Sync> Sync for Darc<T>

Auto Trait Implementations§

§

impl<T> !RefUnwindSafe for Darc<T>

§

impl<T> Unpin for Darc<T>

§

impl<T> !UnwindSafe for Darc<T>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

§

impl<T> Pointable for T

§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
source§

impl<T, U> TeamInto<U> for T
where U: TeamFrom<T>,

source§

fn team_into(self, team: &Pin<Arc<LamellarTeamRT>>) -> U

converts this type into the (usually inferred) input type
source§

impl<T, U> TeamTryInto<U> for T
where U: TeamTryFrom<T>,

source§

fn team_try_into(self, team: &Pin<Arc<LamellarTeamRT>>) -> Result<U, Error>

Trys to convert this type into the (usually inferred) input type
source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more
source§

impl<T> AmDist for T
where T: Serialize + DeserializeOwned + SyncSend + 'static,

source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

source§

impl<T> SyncSend for T
where T: Sync + Send,