67 lines
2.3 KiB
Rust
67 lines
2.3 KiB
Rust
//! [TSM.ID].[11031972] — Platform X Ecosystem
|
|
//! Slab allocator with free-list management
|
|
|
|
use crate::{PoolConfig, PoolError, PoolStats, Result};
|
|
|
|
struct Block {
|
|
data: Vec<u8>,
|
|
in_use: bool,
|
|
}
|
|
|
|
pub struct SlabAllocator {
|
|
blocks: Vec<Block>,
|
|
free_list: Vec<usize>,
|
|
block_size: usize,
|
|
alloc_count: u64,
|
|
free_count: u64,
|
|
peak_usage: usize,
|
|
}
|
|
|
|
impl SlabAllocator {
|
|
pub fn new(config: &PoolConfig) -> Result<Self> {
|
|
if config.block_size == 0 || config.num_blocks == 0 {
|
|
return Err(PoolError::InvalidBlockSize);
|
|
}
|
|
let aligned = (config.block_size + config.alignment - 1) & !(config.alignment - 1);
|
|
let blocks: Vec<Block> = (0..config.num_blocks)
|
|
.map(|_| Block { data: vec![0u8; aligned], in_use: false })
|
|
.collect();
|
|
let free_list: Vec<usize> = (0..config.num_blocks).rev().collect();
|
|
Ok(Self { blocks, free_list, block_size: aligned, alloc_count: 0, free_count: 0, peak_usage: 0 })
|
|
}
|
|
|
|
pub fn allocate(&mut self) -> Result<(usize, &mut [u8])> {
|
|
let idx = self.free_list.pop().ok_or(PoolError::PoolExhausted)?;
|
|
self.blocks[idx].in_use = true;
|
|
self.alloc_count += 1;
|
|
let used = self.blocks.iter().filter(|b| b.in_use).count();
|
|
if used > self.peak_usage { self.peak_usage = used; }
|
|
let block = &mut self.blocks[idx];
|
|
Ok((idx, &mut block.data))
|
|
}
|
|
|
|
pub fn deallocate(&mut self, idx: usize) -> Result<()> {
|
|
if idx >= self.blocks.len() { return Err(PoolError::InvalidPointer); }
|
|
if !self.blocks[idx].in_use { return Err(PoolError::DoubleFree); }
|
|
self.blocks[idx].in_use = false;
|
|
self.blocks[idx].data.fill(0);
|
|
self.free_list.push(idx);
|
|
self.free_count += 1;
|
|
Ok(())
|
|
}
|
|
|
|
pub fn stats(&self) -> PoolStats {
|
|
let used = self.blocks.iter().filter(|b| b.in_use).count();
|
|
PoolStats {
|
|
total_blocks: self.blocks.len(),
|
|
used_blocks: used,
|
|
free_blocks: self.blocks.len() - used,
|
|
total_bytes: self.blocks.len() * self.block_size,
|
|
used_bytes: used * self.block_size,
|
|
peak_usage: self.peak_usage,
|
|
alloc_count: self.alloc_count,
|
|
free_count: self.free_count,
|
|
}
|
|
}
|
|
}
|