memkit 0.1.1-beta.1

Deterministic, intent-driven memory allocation for systems requiring predictable performance
Documentation
use std::time::{Duration, Instant};
use crate::core::tls;

/// Statistics for a completed phase.
#[derive(Debug, Clone, Copy)]
pub struct MkPhaseReport {
    pub name: &'static str,
    pub duration: Duration,
    pub alloc_count: u64,
    pub bytes_allocated: usize,
}

/// A named phase within a frame for profiling and metrics.
pub struct MkPhase {
    name: &'static str,
    start_time: Instant,
    start_alloc_count: u64,
    start_bytes: usize,
}

impl MkPhase {
    /// Begin a new phase for the current thread.
    pub fn begin(name: &'static str) -> Self {
        let (alloc_count, bytes) = tls::with_tls(|tls| {
            let stats = tls.stats();
            (stats.allocation_count, stats.total_allocated)
        });

        Self {
            name,
            start_time: Instant::now(),
            start_alloc_count: alloc_count,
            start_bytes: bytes,
        }
    }

    /// Get the phase name.
    pub fn name(&self) -> &'static str {
        self.name
    }

    /// End the phase and return a report.
    pub fn end(self) -> MkPhaseReport {
        let duration = self.start_time.elapsed();
        let (alloc_count, bytes) = tls::with_tls(|tls| {
            let stats = tls.stats();
            (
                stats.allocation_count.saturating_sub(self.start_alloc_count),
                stats.total_allocated.saturating_sub(self.start_bytes),
            )
        });

        MkPhaseReport {
            name: self.name,
            duration,
            alloc_count,
            bytes_allocated: bytes,
        }
    }
}

impl Drop for MkPhase {
    fn drop(&mut self) {
        // Phases currently just provide metrics on end/drop.
        // In a more complex system, we could log these or send them to a global collector.
    }
}