use std::sync::Arc;
use std::thread;
use std::time::{Duration, Instant};
use zipora::memory::{
SecureMemoryPool, SecurePoolConfig, get_global_pool_for_size, get_global_secure_pool_stats,
size_to_class,
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("ð Secure Memory Pool Demo");
println!("==========================\n");
demo_basic_allocation()?;
demo_security_features()?;
demo_thread_safety()?;
demo_performance_comparison()?;
demo_global_pools()?;
demo_statistics_monitoring()?;
println!("\nâ
All demos completed successfully!");
println!("The SecureMemoryPool provides production-ready memory management");
println!("with comprehensive security guarantees and high performance.");
Ok(())
}
fn demo_basic_allocation() -> Result<(), Box<dyn std::error::Error>> {
println!("ðĶ Demo 1: Basic Secure Allocation");
println!("----------------------------------");
let config = SecurePoolConfig::small_secure();
let pool = SecureMemoryPool::new(config)?;
println!(
"â Created secure memory pool with {} byte chunks",
pool.config().chunk_size
);
let ptr = pool.allocate()?;
println!(
"â Allocated {} bytes at generation {}",
ptr.size(),
ptr.generation()
);
ptr.validate()?;
println!("â Chunk validation passed");
let slice = ptr.as_slice();
println!("â Safe slice access: {} bytes available", slice.len());
let mut_ptr = unsafe { std::slice::from_raw_parts_mut(ptr.as_ptr(), ptr.size()) };
mut_ptr[0] = 0x42;
mut_ptr[ptr.size() - 1] = 0x84;
println!("â Wrote test data to allocation");
drop(ptr);
println!("â Memory automatically freed with RAII");
let stats = pool.stats();
println!(
"â Pool stats: {} allocs, {} deallocs, {} corruptions detected",
stats.alloc_count, stats.dealloc_count, stats.corruption_detected
);
println!();
Ok(())
}
fn demo_security_features() -> Result<(), Box<dyn std::error::Error>> {
println!("ðĄïļ Demo 2: Security Features");
println!("-----------------------------");
let config = SecurePoolConfig::medium_secure();
let pool = SecureMemoryPool::new(config)?;
println!("â Created secure pool with security features:");
println!(" - Zero on free: {}", pool.config().zero_on_free);
println!(" - Guard pages: {}", pool.config().use_guard_pages);
println!(" - Generation counters: enabled");
println!(" - Corruption detection: enabled");
let ptr1 = pool.allocate()?;
let gen1 = ptr1.generation();
drop(ptr1);
let ptr2 = pool.allocate()?;
let gen2 = ptr2.generation();
drop(ptr2);
println!("â Generation counter incremented: {} â {}", gen1, gen2);
println!(" This prevents use-after-free attacks");
let ptr = pool.allocate()?;
println!("â Allocated chunk with generation {}", ptr.generation());
drop(ptr);
println!("â RAII design makes double-free structurally impossible");
let ptr = pool.allocate()?;
ptr.validate()?;
println!("â Chunk validation detects corruption attempts");
drop(ptr);
let stats = pool.stats();
println!(
"â Security stats: {} double-free attempts blocked, {} corruptions detected",
stats.double_free_detected, stats.corruption_detected
);
println!();
Ok(())
}
fn demo_thread_safety() -> Result<(), Box<dyn std::error::Error>> {
println!("ð§ĩ Demo 3: Thread Safety");
println!("------------------------");
let config = SecurePoolConfig::small_secure();
let pool = SecureMemoryPool::new(config)?;
println!("â Creating pool shared across threads");
println!(" No manual Send/Sync implementation needed!");
let start = Instant::now();
let total_allocations = Arc::new(std::sync::atomic::AtomicUsize::new(0));
let handles: Vec<_> = (0..8)
.map(|thread_id| {
let pool = pool.clone();
let counter = total_allocations.clone();
thread::spawn(move || {
println!(" Thread {} starting allocations", thread_id);
for i in 0..1000 {
let ptr = pool.allocate().unwrap();
counter.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
ptr.validate().unwrap();
let mut_slice =
unsafe { std::slice::from_raw_parts_mut(ptr.as_ptr(), ptr.size()) };
mut_slice[0] = thread_id as u8;
mut_slice[1] = (i % 256) as u8;
if i % 100 == 0 {
thread::sleep(Duration::from_micros(10));
}
}
println!(" Thread {} completed", thread_id);
})
})
.collect();
for handle in handles {
handle.join().unwrap();
}
let duration = start.elapsed();
let total = total_allocations.load(std::sync::atomic::Ordering::Relaxed);
println!(
"â Completed {} concurrent allocations in {:?}",
total, duration
);
println!(
" Throughput: {:.0} allocs/sec",
total as f64 / duration.as_secs_f64()
);
let stats = pool.stats();
println!("â Thread safety verified:");
println!(" - {} total allocations", stats.alloc_count);
println!(" - {} local cache hits", stats.local_cache_hits);
println!(" - {} cross-thread steals", stats.cross_thread_steals);
println!(" - {} corruptions detected", stats.corruption_detected);
println!(" - {} double-free attempts", stats.double_free_detected);
println!();
Ok(())
}
fn demo_performance_comparison() -> Result<(), Box<dyn std::error::Error>> {
println!("⥠Demo 4: Performance Comparison");
println!("---------------------------------");
const ITERATIONS: usize = 10_000;
let start = Instant::now();
for _ in 0..ITERATIONS {
let layout = std::alloc::Layout::from_size_align(1024, 8).unwrap();
let ptr = unsafe { std::alloc::alloc(layout) };
if ptr.is_null() {
panic!("Allocation failed");
}
unsafe { std::alloc::dealloc(ptr, layout) };
}
let std_duration = start.elapsed();
let config = SecurePoolConfig::small_secure();
let pool = SecureMemoryPool::new(config)?;
let start = Instant::now();
for _ in 0..ITERATIONS {
let ptr = pool.allocate()?;
drop(ptr);
}
let pool_duration = start.elapsed();
println!("Performance comparison ({} iterations):", ITERATIONS);
println!(
" Standard allocator: {:?} ({:.0} allocs/sec)",
std_duration,
ITERATIONS as f64 / std_duration.as_secs_f64()
);
println!(
" Secure pool: {:?} ({:.0} allocs/sec)",
pool_duration,
ITERATIONS as f64 / pool_duration.as_secs_f64()
);
let ratio = std_duration.as_nanos() as f64 / pool_duration.as_nanos() as f64;
if ratio < 1.0 {
println!(
" ð Secure pool is {:.1}x FASTER than standard allocator!",
1.0 / ratio
);
} else {
println!(
" ð Secure pool is {:.1}x slower than standard allocator",
ratio
);
println!(" (This includes security overhead for memory safety)");
}
let stats = pool.stats();
println!(
" Pool efficiency: {:.1}% cache hits",
(stats.pool_hits + stats.local_cache_hits) as f64 / stats.alloc_count as f64 * 100.0
);
println!();
Ok(())
}
fn demo_global_pools() -> Result<(), Box<dyn std::error::Error>> {
println!("ð Demo 5: Global Pools");
println!("-----------------------");
let sizes = [64, 1024, 32768, 1048576];
for size in sizes {
let size_class = size_to_class(size);
let pool = get_global_pool_for_size(size);
println!(
"Size {} â class {} â pool with {} byte chunks",
size,
size_class,
pool.config().chunk_size
);
let ptr = pool.allocate()?;
println!(
" â Allocated from global pool, generation {}",
ptr.generation()
);
drop(ptr);
}
let global_stats = get_global_secure_pool_stats();
println!("\nGlobal pool statistics:");
println!(" Total allocations: {}", global_stats.alloc_count);
println!(" Total deallocations: {}", global_stats.dealloc_count);
println!(
" Cache hits: {}",
global_stats.pool_hits + global_stats.local_cache_hits
);
println!(
" Security events: {} corruptions, {} double-free attempts",
global_stats.corruption_detected, global_stats.double_free_detected
);
println!();
Ok(())
}
fn demo_statistics_monitoring() -> Result<(), Box<dyn std::error::Error>> {
println!("ð Demo 6: Statistics & Monitoring");
println!("----------------------------------");
let config = SecurePoolConfig::small_secure();
let pool = SecureMemoryPool::new(config)?;
let mut allocations = Vec::new();
for i in 0..100 {
let ptr = pool.allocate()?;
if i % 10 == 0 {
allocations.push(ptr);
} else {
drop(ptr);
}
}
let stats = pool.stats();
println!("Detailed pool statistics:");
println!("âââââââââââââââââââââââââââŽââââââââââââââ");
println!("â Metric â Value â");
println!("âââââââââââââââââââââââââââžââââââââââââââĪ");
println!("â Total allocations â {:>11} â", stats.alloc_count);
println!("â Total deallocations â {:>11} â", stats.dealloc_count);
println!("â Pool hits â {:>11} â", stats.pool_hits);
println!("â Pool misses â {:>11} â", stats.pool_misses);
println!(
"â Local cache hits â {:>11} â",
stats.local_cache_hits
);
println!(
"â Cross-thread steals â {:>11} â",
stats.cross_thread_steals
);
println!(
"â Corruptions detected â {:>11} â",
stats.corruption_detected
);
println!(
"â Double-free attempts â {:>11} â",
stats.double_free_detected
);
println!("âââââââââââââââââââââââââââīââââââââââââââ");
let hit_rate = if stats.alloc_count > 0 {
(stats.pool_hits + stats.local_cache_hits) as f64 / stats.alloc_count as f64 * 100.0
} else {
0.0
};
let cache_efficiency = if stats.pool_hits + stats.local_cache_hits > 0 {
stats.local_cache_hits as f64 / (stats.pool_hits + stats.local_cache_hits) as f64 * 100.0
} else {
0.0
};
println!("\nDerived metrics:");
println!(" Cache hit rate: {:.1}%", hit_rate);
println!(" Local cache efficiency: {:.1}%", cache_efficiency);
println!(
" Memory safety events: {} total",
stats.corruption_detected + stats.double_free_detected
);
pool.validate()?;
println!(" â Pool integrity validation passed");
drop(allocations);
let final_stats = pool.stats();
println!(
" Final allocations active: {}",
final_stats.alloc_count - final_stats.dealloc_count
);
println!();
Ok(())
}
#[allow(dead_code)]
fn format_duration(duration: Duration) -> String {
let nanos = duration.as_nanos();
if nanos < 1_000 {
format!("{}ns", nanos)
} else if nanos < 1_000_000 {
format!("{:.1}Ξs", nanos as f64 / 1_000.0)
} else if nanos < 1_000_000_000 {
format!("{:.1}ms", nanos as f64 / 1_000_000.0)
} else {
format!("{:.1}s", nanos as f64 / 1_000_000_000.0)
}
}