vkml 0.0.3

High-level Vulkan-based machine learning library
use std::sync::atomic::{AtomicU64, Ordering};

pub struct MemoryTracker {
    maximum: u64,
    in_use: AtomicU64,
}

// This implementation doesn't require a mutable reference to update
// The trade off of checking after the change is that there's only one operation, so no race conditions

impl MemoryTracker {
    pub fn new(maximum: u64) -> Self {
        Self {
            maximum,
            in_use: AtomicU64::new(0),
        }
    }

    pub fn allocate(&self, size: u64) {
        let prev = self.in_use.fetch_add(size, Ordering::Release);

        if prev + size > self.maximum {
            panic!(
                "Memory limit exceeded: tried to allocate {} bytes when {} of {} bytes are used",
                size, prev, self.maximum
            );
        }
    }

    pub fn get_current(&self) -> u64 {
        self.in_use.load(Ordering::Acquire)
    }

    pub fn get_available(&self) -> u64 {
        self.maximum - self.get_current()
    }

    pub fn get_maximum(&self) -> u64 {
        self.maximum
    }
}