use super::*;
pub trait RuntimeMemoryPermit: std::fmt::Debug + Send + Sync {
fn bytes(&self) -> u64;
fn merge(
&mut self,
incoming: Box<dyn RuntimeMemoryPermit>,
) -> Result<(), Box<dyn RuntimeMemoryPermit>> {
Err(incoming)
}
#[doc(hidden)]
fn as_any_mut(&mut self) -> Option<&mut dyn std::any::Any> {
None
}
}
pub trait RuntimeMemoryController: std::fmt::Debug + Send + Sync {
fn reserve(
&self,
bytes: u64,
ceiling: u64,
) -> Result<Box<dyn RuntimeMemoryPermit>, RuntimeMemoryError>;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RuntimeMemoryError {
Stopped(RuntimeCancellationReason),
ReservationExceeded {
requested_bytes: u64,
available_bytes: u64,
},
AdmissionDenied {
requested_bytes: u64,
available_bytes: u64,
retryable: bool,
},
Closed,
Pressure,
}
impl Display for RuntimeMemoryError {
fn fmt(&self, formatter: &mut Formatter<'_>) -> fmt::Result {
match self {
Self::Stopped(reason) => Display::fmt(reason, formatter),
Self::ReservationExceeded { requested_bytes, available_bytes } => write!(formatter,
"runtime memory allocation requested {requested_bytes} bytes, exceeding the {available_bytes}-byte remaining reservation"),
Self::AdmissionDenied { requested_bytes, available_bytes, retryable } => write!(formatter,
"runtime memory allocation admission denied: requested {requested_bytes} bytes, available {available_bytes} bytes, retryable {retryable}"),
Self::Closed => formatter.write_str("runtime memory reservation is closed"),
Self::Pressure => formatter.write_str("background memory pressure defers allocation"),
}
}
}
impl Error for RuntimeMemoryError {
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {
Self::Stopped(reason) => Some(reason),
_ => None,
}
}
}