use super::{RelocationNeed, RelocationReason};
use crate::memory_management::ErrorGraph;
use crate::server::ServerError;
pub trait RelocatableStream {
fn recording(&self) -> bool;
fn has_outdated(&self) -> bool;
fn relocation_need(&self) -> RelocationNeed;
fn bytes_allocated(&self) -> u64;
fn relocate(&mut self, reason: RelocationReason, failures: &mut ErrorGraph);
fn cleanup_memory(&mut self, failures: &mut ErrorGraph);
}
pub trait RelocatingStreams {
fn recording(&mut self) -> bool;
fn has_outdated(&mut self) -> bool;
fn relocation_need(&mut self) -> RelocationNeed;
fn bytes_allocated(&mut self) -> u64;
fn finish(&mut self);
fn relocate_memory(&mut self, reason: RelocationReason);
fn device_has_outdated(&mut self) -> bool;
fn relocate_device_memory(&mut self, reason: RelocationReason);
fn cleanup_memory(&mut self);
fn refuse_while_recording(&mut self) -> Result<(), ServerError> {
if self.recording() {
return Err(ServerError::graph_state(
"memory_cleanup: a stream is recording a graph, whose pages keep their addresses \
until it seals",
));
}
Ok(())
}
fn reclaim(&mut self) -> Result<(), ServerError> {
self.refuse_while_recording()?;
self.relocate(RelocationReason::Explicit);
self.cleanup_memory();
Ok(())
}
fn relocate_when_wanted(&mut self) {
let need = self.relocation_need();
if need == RelocationNeed::Nothing || self.recording() {
return;
}
if let Some(reason) = need.reason(|| self.bytes_allocated()) {
self.finish();
self.relocate_memory(reason);
}
}
fn relocate(&mut self, reason: RelocationReason) {
if self.recording() || !self.has_outdated() {
return;
}
self.finish();
self.relocate_memory(reason);
}
fn relocate_device(&mut self, reason: RelocationReason) {
if self.recording() || !self.device_has_outdated() {
return;
}
self.finish();
self.relocate_device_memory(reason);
}
}