//! Fixed two-page shared object authority and mapping model. //! See ../CONTRACT.md for the kernel adapter boundary. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct Handle { generation: u32, holder: P } impl Handle

{ pub const fn forge(generation: u32, holder: P) -> Self { Self {generation, holder} } pub const fn generation(self) -> u32 { self.generation } } #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum Error { Access, Stale, Invalid, Busy } #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct Snapshot { pub generation: u32, pub recipient: Option

, pub acquired: bool, pub owner_maps: [bool; 2], pub recipient_maps: [bool; 2], pub closed: bool, pub mapped_count: usize, } pub struct SharedPages { owner: P, frames: [u64; 2], generation: u32, recipient: Option

, acquired: bool, owner_maps: [bool; 2], recipient_maps: [bool; 2], closed: bool, } impl SharedPages

{ pub fn new(owner: P, frames: [u64; 2]) -> Result { if frames[0] == 0 || frames[1] == 0 || frames[0] == frames[1] { return Err(Error::Invalid); } Ok(Self {owner, frames, generation: 1, recipient: None, acquired: false, owner_maps: [false; 2], recipient_maps: [false; 2], closed: false}) } pub fn owner_handle(&self, caller: P) -> Result, Error> { if caller != self.owner { return Err(Error::Access); } if self.closed { return Err(Error::Stale); } Ok(Handle {generation: self.generation, holder: caller}) } pub fn grant(&mut self, caller: P, recipient: P) -> Result, Error> { if caller != self.owner { return Err(Error::Access); } if self.closed { return Err(Error::Stale); } if recipient == self.owner { return Err(Error::Invalid); } if self.recipient.is_some() { return Err(Error::Busy); } self.recipient = Some(recipient); Ok(Handle {generation: self.generation, holder: recipient}) } pub fn acquire(&mut self, caller: P, handle: Handle

) -> Result<(), Error> { if self.closed || handle.generation != self.generation { return Err(Error::Stale); } if caller != handle.holder || self.recipient != Some(caller) { return Err(Error::Access); } self.acquired = true; Ok(()) } pub fn map(&mut self, caller: P, handle: Handle

, page: usize) -> Result { if self.closed || handle.generation != self.generation { return Err(Error::Stale); } let frame = *self.frames.get(page).ok_or(Error::Invalid)?; if caller != handle.holder { return Err(Error::Access); } if caller == self.owner { self.owner_maps[page] = true; } else if self.recipient == Some(caller) && self.acquired { self.recipient_maps[page] = true; } else { return Err(Error::Access); } Ok(frame) } pub fn revoke(&mut self, caller: P) -> Result<(), Error> { if caller != self.owner { return Err(Error::Access); } if self.closed { return Err(Error::Stale); } self.recipient = None; self.acquired = false; self.recipient_maps = [false; 2]; Ok(()) } pub fn close(&mut self, caller: P) -> Result<(), Error> { if caller != self.owner { return Err(Error::Access); } if self.closed { return Err(Error::Stale); } self.owner_maps = [false; 2]; self.recipient_maps = [false; 2]; self.recipient = None; self.acquired = false; self.closed = true; Ok(()) } pub fn snapshot(&self) -> Snapshot

{ Snapshot {generation: self.generation, recipient: self.recipient, acquired: self.acquired, owner_maps: self.owner_maps, recipient_maps: self.recipient_maps, closed: self.closed, mapped_count: self.owner_maps.into_iter().filter(|bit| *bit).count() + self.recipient_maps.into_iter().filter(|bit| *bit).count()} } }