//! Interprocess communication. use alloc::vec::Vec; use crate::{proccess::PID, time::Time}; extern crate alloc; /// 131070 * 128 pub const TINY_MESSAGE_COUNT: usize = 131070; /// 16384 * 1024 pub const SMALL_MESSAGE_COUNT: usize = 16384; /// 65536 * 256 pub const MEDIUM_MESSAGE_COUNT: usize = 256; /// 262144 * 16 pub const LARGE_MESSAGE_COUNT: usize = 16; /// 16777216 * 4 pub const HUGE_MESSAGE_COUNT: usize = 4; /// 128 Bytes pub type Tiny = [u8; 128]; /// 1 KiB pub type Small = [u8; 1024]; /// 65.536 KiB pub type Medium = [u8; 65536]; /// 1MiB pub type Large = [u8; 1048576]; /// 16MiB pub type Huge = [u8; 16777216]; /// An internal message to be held in a process message pub enum Message { /// A Tiny message /// /// The message is 128 bytes long Tiny(Tiny), /// A Small message /// /// The message is 1 KiB long Small(Small), /// A Medium message /// /// The message is 65.536 KiB long Medium(Medium), /// A Large message /// /// The message is 1 MiB long Large(Large), /// A Huge message /// /// The message is 16 MiB long Huge(Huge), } /// A message that can be sent between processes pub struct ProcessMessage { /// The sender of the message pub to_pid: PID, /// The receiver of the message pub from_pid: PID, /// The message pub message: Message, /// The time the message was sent pub sender_time: Time, /// The time the message was received pub receiver_time: Time, } impl ProcessMessage { /// Return the size of the message pub fn size(&self) -> usize { match &self.message { Message::Tiny(_) => 128, Message::Small(_) => 1024, Message::Medium(_) => 65536, Message::Large(_) => 1048576, Message::Huge(_) => 16777216, } } } #[derive(Debug)] /// An enum of all possible errors that can occur when sending a message pub enum MessagingError { /// The message is too large to be sent MessageTooLarge, /// The reciever of the message is not valid ProcessNonExistant, /// The message Queue is full TooManyMessages, } /// A mailbox that holds messages and PipeState pub struct Mailbox { /// The messages in the mailbox pub messages: Vec, /// The count of messages in the mailbox pub message_count: MessageCount, } impl Mailbox { /// append a message to the mailbox pub fn append(&mut self, message: ProcessMessage) -> Result<(), MessagingError> { let msg_size = message.size(); if self.message_count.total() > 147730 { return Err(MessagingError::TooManyMessages); } match msg_size { TINY_MESSAGE_COUNT => { if self.message_count.tiny < TINY_MESSAGE_COUNT { self.messages.push(message); self.message_count.tiny += 1; Ok(()) } else { Err(MessagingError::TooManyMessages) } } SMALL_MESSAGE_COUNT => { if self.message_count.small < SMALL_MESSAGE_COUNT { self.messages.push(message); self.message_count.small += 1; Ok(()) } else { Err(MessagingError::TooManyMessages) } } MEDIUM_MESSAGE_COUNT => { if self.message_count.medium < MEDIUM_MESSAGE_COUNT { self.messages.push(message); self.message_count.medium += 1; Ok(()) } else { Err(MessagingError::TooManyMessages) } } LARGE_MESSAGE_COUNT => { if self.message_count.large < LARGE_MESSAGE_COUNT { self.messages.push(message); self.message_count.large += 1; Ok(()) } else { Err(MessagingError::TooManyMessages) } } HUGE_MESSAGE_COUNT => { if self.message_count.huge < HUGE_MESSAGE_COUNT { self.messages.push(message); self.message_count.huge += 1; Ok(()) } else { return Err(MessagingError::TooManyMessages); } } _ => Err(MessagingError::MessageTooLarge), } } } /// A proper struct to list the number of messages in the mailbox pub struct MessageCount { /// The number of tiny messages in the mailbox pub tiny: usize, /// The number of small messages in the mailbox pub small: usize, /// The number of medium messages in the mailbox pub medium: usize, /// The number of large messages in the mailbox pub large: usize, /// The number of huge messages in the mailbox pub huge: usize, } impl MessageCount { /// Return the total number of messages in the mailbox pub fn total(&self) -> usize { self.tiny + self.small + self.medium + self.large + self.huge } } impl Default for MessageCount { fn default() -> Self { MessageCount { tiny: 0, small: 0, medium: 0, large: 0, huge: 0, } } }