diff --git a/Cargo.toml b/Cargo.toml index 2bbc443756df362913354b117a6e320ab24a4818..ce8de4c18857a9ccdbf21cf8f53820416d4c1aa5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ backtrace = "0.3" [dev-dependencies] test-generator = "0.3.0" crossbeam-utils = "0.7.0" +lazy_static = "1.4.0" [lib] crate-type = ["cdylib"] diff --git a/src/runtime/experimental/api.rs b/src/runtime/experimental/api.rs index 66b3e4eef8aefe06947e71ddddf42c4c8d5a5da0..b2fb237337db0cbd99dede2e0181562eb8e11620 100644 --- a/src/runtime/experimental/api.rs +++ b/src/runtime/experimental/api.rs @@ -1,3 +1,4 @@ +use super::bits::{usizes_for_bits, BitChunkIter, BitMatrix}; use super::vec_storage::VecStorage; use crate::common::*; use crate::runtime::endpoint::EndpointExt; @@ -410,6 +411,7 @@ impl Connecting { endpoint_exts, native_ports, family, + ephemeral: Default::default(), }) } ///////// @@ -437,6 +439,11 @@ pub struct Connected { endpoint_exts: VecStorage, components: VecStorage, family: Family, + ephemeral: Ephemeral, +} +#[derive(Debug, Default)] +struct Ephemeral { + bit_matrix: BitMatrix, } impl Connected { pub fn new_component( @@ -585,7 +592,6 @@ unsafe fn c_sync_set( 0 } -use super::bits::{usizes_for_bits, BitChunkIter}; unsafe fn c_sync_subset( connected: &mut Connected, inbuflen: usize, @@ -637,28 +643,43 @@ fn api_connecting() { "127.0.0.1:8889".parse().unwrap(), "127.0.0.1:8890".parse().unwrap(), ]; + + lazy_static::lazy_static! { + static ref PROTOCOL: Arc = { + static PDL: &[u8] = b" + primitive sync(in i, out o) { + while(true) synchronous { + put(o, get(i)); + } + } + "; + Arc::new(ProtocolD::parse(PDL).unwrap()) + }; + } + const TIMEOUT: Option = Some(Duration::from_secs(1)); let handles = vec![ std::thread::spawn(move || { let mut connecting = Connecting::default(); - let _a: OutPort = connecting.bind(Coupling::Passive, addrs[0]); - let _b: OutPort = connecting.bind(Coupling::Active, addrs[1]); - let connected = connecting.connect(TIMEOUT); - println!("A: {:#?}", connected); + let p_in: InPort = connecting.bind(Coupling::Passive, addrs[0]); + let p_out: OutPort = connecting.bind(Coupling::Active, addrs[1]); + let mut connected = connecting.connect(TIMEOUT).unwrap(); + let identifier = b"sync".to_vec().into(); + println!("connected {:#?}", &connected); + connected.new_component(&PROTOCOL, &identifier, &[p_in.into(), p_out.into()]).unwrap(); + println!("connected {:#?}", &connected); }), std::thread::spawn(move || { let mut connecting = Connecting::default(); - let _a: InPort = connecting.bind(Coupling::Active, addrs[0]); + let _a: OutPort = connecting.bind(Coupling::Active, addrs[0]); let _b: InPort = connecting.bind(Coupling::Passive, addrs[1]); let _c: InPort = connecting.bind(Coupling::Active, addrs[2]); - let connected = connecting.connect(TIMEOUT); - println!("B: {:#?}", connected); + let _connected = connecting.connect(TIMEOUT).unwrap(); }), std::thread::spawn(move || { let mut connecting = Connecting::default(); let _a: OutPort = connecting.bind(Coupling::Passive, addrs[2]); - let connected = connecting.connect(TIMEOUT); - println!("C: {:#?}", connected); + let _connected = connecting.connect(TIMEOUT).unwrap(); }), ]; for h in handles { diff --git a/src/runtime/experimental/bits.rs b/src/runtime/experimental/bits.rs index fec93fb0942028ef87466554336ba86637a8f20c..ebe9b0a6c41e6585190951947255e9ae498bc4d4 100644 --- a/src/runtime/experimental/bits.rs +++ b/src/runtime/experimental/bits.rs @@ -107,7 +107,12 @@ impl From<[u32; 2]> for Pair { Pair { entity, property } } } -struct BitMatrix { +impl Default for BitMatrix { + fn default() -> Self { + Self::new(Pair { entity: 0, property: 0 }) + } +} +pub struct BitMatrix { buffer: *mut usize, bounds: Pair, layout: Layout, // layout of the currently-allocated buffer @@ -122,29 +127,39 @@ impl Drop for BitMatrix { } impl Debug for BitMatrix { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { - let row_chunks = Self::row_chunks(self.bounds.property as usize); - let column_chunks = Self::column_chunks(self.bounds.entity as usize); - for property in 0..row_chunks { - for entity_chunk in 0..column_chunks { + struct FmtRow<'a> { + me: &'a BitMatrix, + property: usize, + }; + impl Debug for FmtRow<'_> { + fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { + let row_chunks = BitMatrix::row_chunks(self.me.bounds.property as usize); + let column_chunks = BitMatrix::column_chunks(self.me.bounds.entity as usize); write!(f, "|")?; - let mut chunk = unsafe { *self.buffer.add(row_chunks * entity_chunk + property) }; - let end = if entity_chunk + 1 == column_chunks { - self.bounds.entity % usize_bits() as u32 - } else { - usize_bits() as u32 - }; - for _ in 0..end { - let c = match chunk & 1 { - 0 => '0', - _ => '1', + for entity_chunk in 0..column_chunks { + let mut chunk = + unsafe { *self.me.buffer.add(row_chunks * entity_chunk + self.property) }; + let end = if entity_chunk + 1 == column_chunks { + self.me.bounds.entity % usize_bits() as u32 + } else { + usize_bits() as u32 }; - write!(f, "{}", c)?; - chunk >>= 1; + for _ in 0..end { + let c = match chunk & 1 { + 0 => '0', + _ => '1', + }; + write!(f, "{}", c)?; + chunk >>= 1; + } + write!(f, "_")?; } + Ok(()) } - write!(f, "|\n")?; } - Ok(()) + let row_chunks = BitMatrix::row_chunks(self.bounds.property as usize); + let iter = (0..row_chunks).map(move |property| FmtRow { me: self, property }); + f.debug_list().entries(iter).finish() } } impl BitMatrix { diff --git a/src/runtime/experimental/vec_storage.rs b/src/runtime/experimental/vec_storage.rs index 9fb241c250abd9eb2c13ff5760a795255f250f21..eaed13575a8f1ec095491a317c6f6e0ed023eb31 100644 --- a/src/runtime/experimental/vec_storage.rs +++ b/src/runtime/experimental/vec_storage.rs @@ -84,16 +84,20 @@ impl Default for VecStorage { impl Debug for VecStorage { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { enum FmtT<'a, T> { - Vacant, - Reserved, - Occupied(&'a T), + Vacant(usize), + Reserved(usize), + Occupied(usize, &'a T), }; impl Debug for FmtT<'_, T> { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { match self { - FmtT::Vacant => write!(f, "Vacant"), - FmtT::Reserved => write!(f, "Reserved"), - FmtT::Occupied(t) => write!(f, "Occupied({:?})", t), + FmtT::Vacant(i) => write!(f, "{} => Vacant", i), + FmtT::Reserved(i) => write!(f, "{} =>Reserved", i), + FmtT::Occupied(i, t) => { + write!(f, "{} => Occupied(", i)?; + t.fmt(f)?; + write!(f, ")") + } } } } @@ -103,11 +107,11 @@ impl Debug for VecStorage { // 2. occupied index => valid data is read. // 3. bitset bounds are ensured by invariant E. if self.occupied.contains(i) { - FmtT::Occupied(&*self.data.get_unchecked(i).as_ptr()) + FmtT::Occupied(i, &*self.data.get_unchecked(i).as_ptr()) } else if self.vacant.contains(i) { - FmtT::Vacant + FmtT::Vacant(i) } else { - FmtT::Reserved + FmtT::Reserved(i) } }); f.debug_list().entries(iter).finish() @@ -122,10 +126,10 @@ impl VecStorage { // ASSUMES that i in 0..self.data.len() unsafe fn get_occupied_unchecked(&self, i: usize) -> Option<&T> { if self.occupied.contains(i) { - None - } else { // 2. Invariant A => reading valid ata Some(&*self.data.get_unchecked(i).as_ptr()) + } else { + None } } //////////////