df65fe0696
- FIX #1: xcu-command-center — KOSONG -> REAL (CommandCenter + PriorityQueue + 3 tests) - FIX #2: xcu-tesseract — remove unwrap() -> pattern match - FIX #3: xcu-omni — hardcoded 0.0.0.0 -> bind_addr param - FIX #4: xcu-billing-matrix — add deny(warnings), env var bind - FIX #5: xcu-garbage-collector — add 3 unit tests (alloc/collect/promote) - FIX #6: xcu-memory-pool — add 3 unit tests (alloc/dealloc/double-free/exhaust) - FIX #7: xcu-neural-chat — env var bind address - FIX #8: xcu-quic — add REAL QUIC VarInt + packet parser + 3 tests - FIX #9: xcu-sfu-a — add 3 unit tests (dominant speaker/core assign/svc) - FIX #10: xcu-wasm-sdk — add utility fn + 3 tests
92 lines
2.6 KiB
Rust
92 lines
2.6 KiB
Rust
//! [TSM.ID].[11031972] — Platform X Ecosystem
|
|
//! xcu-memory-pool — Zero-Copy Slab Memory Allocator
|
|
#![deny(warnings)]
|
|
#![allow(dead_code)]
|
|
|
|
pub mod pool;
|
|
pub mod allocator;
|
|
|
|
#[derive(Debug)]
|
|
pub enum PoolError {
|
|
OutOfMemory,
|
|
InvalidBlockSize,
|
|
DoubleFree,
|
|
InvalidPointer,
|
|
PoolExhausted,
|
|
}
|
|
|
|
impl std::fmt::Display for PoolError {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
Self::OutOfMemory => write!(f, "Out of memory"),
|
|
Self::InvalidBlockSize => write!(f, "Invalid block size"),
|
|
Self::DoubleFree => write!(f, "Double free detected"),
|
|
Self::InvalidPointer => write!(f, "Invalid pointer"),
|
|
Self::PoolExhausted => write!(f, "Pool exhausted"),
|
|
}
|
|
}
|
|
}
|
|
impl std::error::Error for PoolError {}
|
|
pub type Result<T> = std::result::Result<T, PoolError>;
|
|
|
|
pub struct PoolConfig {
|
|
pub block_size: usize,
|
|
pub num_blocks: usize,
|
|
pub alignment: usize,
|
|
}
|
|
|
|
impl Default for PoolConfig {
|
|
fn default() -> Self {
|
|
Self { block_size: 4096, num_blocks: 256, alignment: 8 }
|
|
}
|
|
}
|
|
|
|
pub struct PoolStats {
|
|
pub total_blocks: usize,
|
|
pub used_blocks: usize,
|
|
pub free_blocks: usize,
|
|
pub total_bytes: usize,
|
|
pub used_bytes: usize,
|
|
pub peak_usage: usize,
|
|
pub alloc_count: u64,
|
|
pub free_count: u64,
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::pool::SlabAllocator;
|
|
|
|
#[test]
|
|
fn test_alloc_dealloc() {
|
|
let config = PoolConfig { block_size: 64, num_blocks: 4, alignment: 8 };
|
|
let mut slab = SlabAllocator::new(&config).expect("init");
|
|
let (idx, buf) = slab.allocate().expect("alloc");
|
|
buf[0] = 42;
|
|
assert_eq!(buf[0], 42);
|
|
slab.deallocate(idx).expect("dealloc");
|
|
let stats = slab.stats();
|
|
assert_eq!(stats.used_blocks, 0);
|
|
assert_eq!(stats.alloc_count, 1);
|
|
assert_eq!(stats.free_count, 1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_double_free() {
|
|
let config = PoolConfig::default();
|
|
let mut slab = SlabAllocator::new(&config).expect("init");
|
|
let (idx, _) = slab.allocate().expect("alloc");
|
|
slab.deallocate(idx).expect("first free");
|
|
assert!(slab.deallocate(idx).is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn test_pool_exhaustion() {
|
|
let config = PoolConfig { block_size: 32, num_blocks: 2, alignment: 8 };
|
|
let mut slab = SlabAllocator::new(&config).expect("init");
|
|
let _ = slab.allocate().expect("1");
|
|
let _ = slab.allocate().expect("2");
|
|
assert!(slab.allocate().is_err());
|
|
}
|
|
}
|