{"id":17946505,"url":"https://github.com/fklr/atomalloc","last_synced_at":"2025-03-24T20:32:44.610Z","repository":{"id":259592828,"uuid":"878175462","full_name":"fklr/atomalloc","owner":"fklr","description":"atomalloc is an asynchronous, atomic, and lock-free memory allocator written in pure safe Rust","archived":false,"fork":false,"pushed_at":"2025-03-07T04:24:36.000Z","size":27,"stargazers_count":29,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-22T10:18:11.680Z","etag":null,"topics":["allocator","async","atomic","lock-free","malloc","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fklr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"mekaem","ko_fi":"mekaem","liberapay":"em"}},"created_at":"2024-10-24T22:37:58.000Z","updated_at":"2025-03-11T05:29:25.000Z","dependencies_parsed_at":"2024-10-26T19:42:03.898Z","dependency_job_id":"e4353242-0336-4310-83cb-689a8a859a43","html_url":"https://github.com/fklr/atomalloc","commit_stats":null,"previous_names":["ovnanova/atomalloc","mekaem/atomalloc","fklr/atomalloc"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fklr%2Fatomalloc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fklr%2Fatomalloc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fklr%2Fatomalloc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fklr%2Fatomalloc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fklr","download_url":"https://codeload.github.com/fklr/atomalloc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245348289,"owners_count":20600622,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["allocator","async","atomic","lock-free","malloc","rust"],"created_at":"2024-10-29T07:05:56.434Z","updated_at":"2025-03-24T20:32:44.591Z","avatar_url":"https://github.com/fklr.png","language":"Rust","funding_links":["https://github.com/sponsors/mekaem","https://ko-fi.com/mekaem","https://liberapay.com/em"],"categories":[],"sub_categories":[],"readme":"# ⚛️ AtomAlloc ⚛️\n\n[![Build](https://github.com/ovnanova/atomalloc/actions/workflows/rust.yml/badge.svg)](https://github.com/ovnanova/atomalloc/actions/workflows/rust.yml) [![Rust](https://img.shields.io/badge/rust-stable-orange.svg)](https://www.rust-lang.org)\n\nAn experimental async-first memory allocator exploring atomic \u0026 lock-free allocation patterns in Rust.\n\n\u003e **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.\n\n## Overview\n\nAtomAlloc 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.\n\n## Design Goals vs Reality\n\n### ✅ Successfully Achieved\n- 🛡️ **Zero Unsafe Code**: Fully safe Rust implementation\n- 🔓 **Lock-Free Design**: Atomic operations throughout\n- 💾 **Task Awareness**: Generations and task-local caching\n- 🔄 **Async Interface**: Full async/await support\n\n### ❌ Current Limitations\n- **Performance**: slower than system allocator for common cases\n- **Memory Overhead**: higher memory usage due to atomic metadata\n- **Cache Efficiency**: poor cache locality from atomic operations\n- **Cold Start**: initial allocation overhead from block initialization\n- **Compatibility**: incompatible with GlobalAlloc trait or the unstable allocator_api feature\n\n## Usage\n\nIf you'd like to experiment with this allocator, download this repo.\n\nBasic usage:\n\n```rust\n// Create allocator instance\nlet alloc = AtomAlloc::new().await;\n\n// Allocation\nlet layout = Layout::new::\u003c[u8; 1024]\u003e();\nlet block = alloc.allocate(layout).await?;\n\n// Write data\nblock.write(0, \u0026[1, 2, 3, 4]).await?;\n\n// Read data\nlet data = block.read(0, 4).await?;\n\n// Deallocation\nalloc.deallocate(block).await;\n\n// Get allocation stats\nlet stats = alloc.stats().await;\nprintln!(\"Cache hit rate: {}%\",\n    stats.cache_hits as f64 / (stats.cache_hits + stats.cache_misses) as f64 * 100.0);\n```\n\n## Configuration\n\nThe allocator can be configured via `AtomAllocConfig`:\n\n```rust\nlet config = AtomAllocConfig {\n    max_memory: 1024 * 1024 * 1024, // 1GB\n    max_block_size: 64 * 1024,      // 64KB\n    min_block_size: 64,             // 64B\n    alignment: 16,\n    cache_ttl: Duration::from_secs(300),\n    max_caches: 1000,\n    initial_pool_size: 1024 * 1024, // 1MB\n    zero_on_dealloc: true,\n};\n\nlet alloc = AtomAlloc::with_config(config).await;\n```\n\n## Technical Architecture\n\n### Core Components\n\n```rust\npub struct AtomAlloc {\n    pool: Arc\u003cMemoryPool\u003e,\n    cache: Arc\u003cBlockCache\u003e,\n    block_manager: Arc\u003cBlockManager\u003e,\n    stats: Arc\u003cAtomAllocStats\u003e,\n    config: Arc\u003cAtomAllocConfig\u003e,\n}\n\npub struct Block {\n    state: AtomicU64,      // Packs generation + flags\n    size: AtomicUsize,     // Block size\n    data: Box\u003c[AtomicU8]\u003e, // Actual memory storage\n}\n```\n\n### Memory Model\n\nAllocation follows a three-tier hierarchy:\n1. Block Cache with Hot/Cold Queues\n2. Size Class Pool with Power-of-2 Classes\n3. Global Memory Pool\n\nEach level uses atomic operations and lock-free data structures for synchronization.\n\n### Generation Safety\n\n```rust\nimpl BlockManager {\n    pub async fn verify_generation(\u0026self, block: \u0026Pin\u003cArc\u003cBlock\u003e\u003e) -\u003e Result\u003c(), AtomAllocError\u003e {\n        let block_gen = block.generation();\n        let current_gen = self.current_generation.load(Ordering::Acquire);\n\n        if block_gen \u003e current_gen {\n            return Err(AtomAllocError::BlockError(BlockError::InvalidGeneration {\n                block: block_gen,\n                expected: current_gen,\n            }));\n        }\n        Ok(())\n    }\n}\n```\n\nMemory safety is enforced through a generation system that tracks block validity.\n\n## Critical Implementation Challenges\n\n### 1. Cache Efficiency\n\nThe block cache implements a hot/cold queue system to balance reuse and memory pressure:\n\n```rust\npub struct BlockCache {\n    manager: Arc\u003cBlockManager\u003e,\n    pool: Arc\u003cMemoryPool\u003e,\n    size_classes: Vec\u003cArc\u003cSizeClass\u003e\u003e,\n    stats: Arc\u003cAtomAllocStats\u003e,\n}\n```\n\n### 2. Memory Ordering\n\nEnsuring correct ordering without locks requires careful atomic operations:\n\n```rust\npub struct Block {\n    pub async fn write(\u0026self, offset: usize, data: \u0026[u8]) -\u003e Result\u003c(), BlockError\u003e {\n        let size = self.size.load(Ordering::Acquire);\n        // Atomic writes with proper ordering\n        self.state.fetch_and(!ZEROED_FLAG, Ordering::Release);\n        Ok(())\n    }\n}\n```\n\n### 3. Zero-on-Free Overhead\n\nMemory zeroing for security has performance implications:\n\n```rust\nasync fn zero_block(\u0026self, block: \u0026Pin\u003cArc\u003cBlock\u003e\u003e) {\n    if self.config.zero_on_dealloc {\n        block.clear().await;\n    }\n}\n```\n\n## Further Improvements\n\nCurrent areas of investigation:\n1. Cache-friendly atomic operations\n2. Improved size class distribution\n3. Memory coalescing techniques\n4. Alternative cache hierarchies\n5. Reduce generation verification overhead\n\n## Contributing\n\nThis is an experiment that I would like to improve further over time.\n\nI welcome contributions that would:\n- Explore new async allocation patterns\n- Improve performance characteristics\n\n## License\n\n[![License: MPL 2.0](https://img.shields.io/badge/License-MPL%202.0-brightgreen.svg)](LICENSE)\n\n## Why This Exists\n\nThis allocator serves as an investigation into several questions:\n- Can we build a fully async-first allocator?\n- What are the real costs of lock-free memory management?\n- How do we handle task isolation efficiently?\n- What patterns emerge in async memory usage?\n\nWhile the current implementation is not performance-competitive, I think it offers some insights on where to go next.\n\n## Final Disclaimer\n\nThis 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.\n\n---\n*Last updated: October 26, 2024*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffklr%2Fatomalloc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffklr%2Fatomalloc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffklr%2Fatomalloc/lists"}