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 theAtomic
types. Alternatively you can also use aLocalRwDarc
orGlobalRwDarc
.
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>
impl<T> Darc<T>
sourcepub fn new<U: Into<IntoLamellarTeam>>(
team: U,
item: T
) -> Result<Darc<T>, IdError>
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");
sourcepub fn into_localrw(self) -> LocalRwDarc<T>
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();
sourcepub fn into_globalrw(self) -> GlobalRwDarc<T>
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();