https://github.com/fklr/atomalloc
atomalloc is an asynchronous, atomic, and lock-free memory allocator written in pure safe Rust
https://github.com/fklr/atomalloc
allocator async atomic lock-free malloc rust
Last synced: 7 months ago
JSON representation
atomalloc is an asynchronous, atomic, and lock-free memory allocator written in pure safe Rust
- Host: GitHub
- URL: https://github.com/fklr/atomalloc
- Owner: fklr
- License: mpl-2.0
- Created: 2024-10-24T22:37:58.000Z (12 months ago)
- Default Branch: main
- Last Pushed: 2025-03-07T04:24:36.000Z (7 months ago)
- Last Synced: 2025-03-22T10:18:11.680Z (7 months ago)
- Topics: allocator, async, atomic, lock-free, malloc, rust
- Language: Rust
- Homepage:
- Size: 26.4 KB
- Stars: 29
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# ⚛️ AtomAlloc ⚛️
[](https://github.com/ovnanova/atomalloc/actions/workflows/rust.yml) [](https://www.rust-lang.org)
An experimental async-first memory allocator exploring atomic & lock-free allocation patterns in Rust.
> **Research Implementation**: This is an experimental allocator focused on exploring async memory management patterns. It is NOT optimized for production use and currently exhibits higher overhead than traditional allocators.
## Overview
AtomAlloc investigates the intersection of async Rust, atomic operations, and memory management by implementing a fully lock-free, task-aware allocator. While performance is not yet competitive with production allocators, it provides insights into async allocation patterns and challenges.
## Design Goals vs Reality
### ✅ Successfully Achieved
- 🛡️ **Zero Unsafe Code**: Fully safe Rust implementation
- 🔓 **Lock-Free Design**: Atomic operations throughout
- 💾 **Task Awareness**: Generations and task-local caching
- 🔄 **Async Interface**: Full async/await support### ❌ Current Limitations
- **Performance**: slower than system allocator for common cases
- **Memory Overhead**: higher memory usage due to atomic metadata
- **Cache Efficiency**: poor cache locality from atomic operations
- **Cold Start**: initial allocation overhead from block initialization
- **Compatibility**: incompatible with GlobalAlloc trait or the unstable allocator_api feature## Usage
If you'd like to experiment with this allocator, download this repo.
Basic usage:
```rust
// Create allocator instance
let alloc = AtomAlloc::new().await;// Allocation
let layout = Layout::new::<[u8; 1024]>();
let block = alloc.allocate(layout).await?;// Write data
block.write(0, &[1, 2, 3, 4]).await?;// Read data
let data = block.read(0, 4).await?;// Deallocation
alloc.deallocate(block).await;// Get allocation stats
let stats = alloc.stats().await;
println!("Cache hit rate: {}%",
stats.cache_hits as f64 / (stats.cache_hits + stats.cache_misses) as f64 * 100.0);
```## Configuration
The allocator can be configured via `AtomAllocConfig`:
```rust
let config = AtomAllocConfig {
max_memory: 1024 * 1024 * 1024, // 1GB
max_block_size: 64 * 1024, // 64KB
min_block_size: 64, // 64B
alignment: 16,
cache_ttl: Duration::from_secs(300),
max_caches: 1000,
initial_pool_size: 1024 * 1024, // 1MB
zero_on_dealloc: true,
};let alloc = AtomAlloc::with_config(config).await;
```## Technical Architecture
### Core Components
```rust
pub struct AtomAlloc {
pool: Arc,
cache: Arc,
block_manager: Arc,
stats: Arc,
config: Arc,
}pub struct Block {
state: AtomicU64, // Packs generation + flags
size: AtomicUsize, // Block size
data: Box<[AtomicU8]>, // Actual memory storage
}
```### Memory Model
Allocation follows a three-tier hierarchy:
1. Block Cache with Hot/Cold Queues
2. Size Class Pool with Power-of-2 Classes
3. Global Memory PoolEach level uses atomic operations and lock-free data structures for synchronization.
### Generation Safety
```rust
impl BlockManager {
pub async fn verify_generation(&self, block: &Pin>) -> Result<(), AtomAllocError> {
let block_gen = block.generation();
let current_gen = self.current_generation.load(Ordering::Acquire);if block_gen > current_gen {
return Err(AtomAllocError::BlockError(BlockError::InvalidGeneration {
block: block_gen,
expected: current_gen,
}));
}
Ok(())
}
}
```Memory safety is enforced through a generation system that tracks block validity.
## Critical Implementation Challenges
### 1. Cache Efficiency
The block cache implements a hot/cold queue system to balance reuse and memory pressure:
```rust
pub struct BlockCache {
manager: Arc,
pool: Arc,
size_classes: Vec>,
stats: Arc,
}
```### 2. Memory Ordering
Ensuring correct ordering without locks requires careful atomic operations:
```rust
pub struct Block {
pub async fn write(&self, offset: usize, data: &[u8]) -> Result<(), BlockError> {
let size = self.size.load(Ordering::Acquire);
// Atomic writes with proper ordering
self.state.fetch_and(!ZEROED_FLAG, Ordering::Release);
Ok(())
}
}
```### 3. Zero-on-Free Overhead
Memory zeroing for security has performance implications:
```rust
async fn zero_block(&self, block: &Pin>) {
if self.config.zero_on_dealloc {
block.clear().await;
}
}
```## Further Improvements
Current areas of investigation:
1. Cache-friendly atomic operations
2. Improved size class distribution
3. Memory coalescing techniques
4. Alternative cache hierarchies
5. Reduce generation verification overhead## Contributing
This is an experiment that I would like to improve further over time.
I welcome contributions that would:
- Explore new async allocation patterns
- Improve performance characteristics## License
[](LICENSE)
## Why This Exists
This allocator serves as an investigation into several questions:
- Can we build a fully async-first allocator?
- What are the real costs of lock-free memory management?
- How do we handle task isolation efficiently?
- What patterns emerge in async memory usage?While the current implementation is not performance-competitive, I think it offers some insights on where to go next.
## Final Disclaimer
This was built as an exploration of the boundaries of async Rust. Don't use this in production unless you enjoy debugging memory allocation patterns more than having a functional application.
---
*Last updated: October 26, 2024*