[TSM.ID].[11031972] PXE : Platform X Ecosystem I [118 Module -LIVE-]
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
//! [TSM.ID].[11031972] — Platform X Ecosystem
|
||||
//! Bump allocator for temporary allocations
|
||||
|
||||
use crate::{PoolError, Result};
|
||||
|
||||
pub struct BumpAllocator {
|
||||
buffer: Vec<u8>,
|
||||
offset: usize,
|
||||
high_water: usize,
|
||||
}
|
||||
|
||||
impl BumpAllocator {
|
||||
pub fn new(capacity: usize) -> Result<Self> {
|
||||
if capacity == 0 { return Err(PoolError::InvalidBlockSize); }
|
||||
Ok(Self { buffer: vec![0u8; capacity], offset: 0, high_water: 0 })
|
||||
}
|
||||
|
||||
pub fn alloc(&mut self, size: usize, align: usize) -> Result<&mut [u8]> {
|
||||
let aligned_offset = (self.offset + align - 1) & !(align - 1);
|
||||
if aligned_offset + size > self.buffer.len() { return Err(PoolError::OutOfMemory); }
|
||||
self.offset = aligned_offset + size;
|
||||
if self.offset > self.high_water { self.high_water = self.offset; }
|
||||
Ok(&mut self.buffer[aligned_offset..self.offset])
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
self.buffer.fill(0);
|
||||
self.offset = 0;
|
||||
}
|
||||
|
||||
pub fn used(&self) -> usize { self.offset }
|
||||
pub fn remaining(&self) -> usize { self.buffer.len() - self.offset }
|
||||
pub fn high_water_mark(&self) -> usize { self.high_water }
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
//! [TSM.ID].[11031972] — Platform X Ecosystem
|
||||
//! xcu-memory-pool — Zero-Copy Slab Memory Allocator
|
||||
#![deny(warnings)]
|
||||
|
||||
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,
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
//! [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,
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user