memkit-async 0.1.0-alpha.1

Async-aware memory allocators for memkit
Documentation

memkit-async

Async-aware memory allocators for the memkit ecosystem.

Version: 0.1.0-alpha.1

Crates.io Documentation License: MPL-2.0

Overview

memkit-async provides async-native memory allocators designed for concurrent workloads. These allocators understand async context and behave correctly across .await points.

Features

  • Task-Local Allocators — Each async task gets isolated allocation context
  • Backpressure Support — Configurable behavior when memory is exhausted
  • Zero-Copy Channels — Transfer ownership between tasks without copying
  • Async Pools — Object pools with async acquire semantics
  • Safe Across .await — Allocations tracked per-task, not per-thread

The Problem

// UNSAFE: Frame data may be invalid after await
let data = alloc.frame_box(value);
some_async_op().await;  // Task may resume on different thread!
use_data(&data);        // Undefined behavior

The Solution

use memkit_async::{MkAsyncFrameAlloc, MkAsyncFrameConfig};

// SAFE: Async-aware allocator tracks task state
let alloc = MkAsyncFrameAlloc::new(MkAsyncFrameConfig::default());

let frame = alloc.begin_frame().await;
let data = alloc.alloc::<MyData>().await;
some_async_op().await;  // Allocator ensures validity
use_data(&data);        // Safe!
drop(frame);

Quick Start

use memkit_async::{MkAsyncPool, MkBackpressure, MkAsyncChannel};

// Async pool with backpressure
let pool = MkAsyncPool::new(100, MkBackpressure::Wait);
pool.add(Buffer::new()).unwrap();

let buffer = pool.acquire().await.unwrap();
// buffer returned to pool on drop

// Zero-copy channel
let channel = MkAsyncChannel::bounded(16);
let (tx, rx) = channel.split();

tx.send(data).await.unwrap();
let received = rx.recv().await.unwrap();

Backpressure Policies

Policy Behavior
Wait Yield and retry until memory available
Fail Return error immediately
Timeout(Duration) Wait up to timeout, then fail
Evict Evict LRU items to make room

Types

Type Description
MkAsyncFrameAlloc Async-aware frame allocator
MkAsyncFrameGuard Frame scope guard
MkAsyncPool<T> Async object pool
MkPoolGuard<T> Pool item guard
MkAsyncChannel<T> Zero-copy async channel
MkAsyncBox<T> Async-safe box
MkAsyncVec<T> Async-safe vector
MkAsyncBarrier Async synchronization barrier
MkAsyncSemaphore Async semaphore

Tokio Integration

Enable the tokio feature for Tokio-specific functionality:

[dependencies]

memkit-async = { version = "0.1.0-alpha.1", features = ["tokio"] }

Task-Local Allocator Context

use memkit_async::{MkAsyncFrameAlloc, MkAsyncFrameConfig};
use memkit_async::{with_allocator, current_allocator, mk_spawn};

#[tokio::main]
async fn main() {
    let alloc = MkAsyncFrameAlloc::new(MkAsyncFrameConfig::default());
    
    // Enter allocation context
    with_allocator(alloc, async {
        // Access allocator from anywhere in this context
        let a = current_allocator();
        let ptr = a.alloc::<[f32; 1024]>().await;
        
        // Spawned tasks inherit the allocator context
        mk_spawn(async {
            let a = current_allocator();
            // Same allocator available here
        }).await.unwrap();
    }).await;
}

Runtime Functions

Function Description
with_allocator(alloc, future) Run future with task-local allocator
current_allocator() Get current task's allocator (panics if none)
try_current_allocator() Get current allocator (returns Option)
mk_spawn(future) Spawn task with inherited allocator
with_timeout(duration, future) Run with Tokio timeout
yield_now() Yield to Tokio runtime
sleep(duration) Tokio sleep

License

This project is licensed under the Mozilla Public License 2.0 - see the LICENSE.md file for details.