slotpool
Fixed-capacity object pools for no_std / embedded Rust — static memory, no heap allocation.
Two pool variants
| Variant | Allocate | Drop behaviour | Use case |
|---|---|---|---|
BoxPool |
alloc(value) — writes a value |
runs T's destructor |
owned objects |
ObjectPool |
request() — no copy, data persists |
no destructor | buffers, messages |
Both share the same pluggable-backend architecture (CriticalSlots by default, CasSlots behind feature cas).
Quick start
BoxPool — owned values
use ;
static POOL: = new;
let pool: &'static = POOL.init_pool;
let guard = pool.alloc.unwrap;
// guard is returned when dropped — destructor runs
ObjectPool — persistent buffers
use ;
static POOL: = new;
let pool: &'static = POOL.init_pool;
let mut buf = pool.request.unwrap;
buf.copy_from_slice;
// buf is returned when dropped — no destructor, data persists for next request()
Backends
use CriticalSlots; // default — critical-section based
use CasSlots; // lock-free CAS (Treiber stack)
type MyPool = ; // CriticalSlots
type MyCasPool = ; // CasSlots
| Backend | Mechanism | Portability |
|---|---|---|
CriticalSlots |
critical_section::Mutex + heapless::Vec |
any target with critical-section |
CasSlots |
lock-free Treiber stack (atomic CAS) | Cortex-M3+, RISC-V, x86 |
Features
cas— enables theCasSlotslock-free backend (requires hardware CAS instructions).async— enablesAsyncBoxPool/AsyncObjectPoolwith.awaitsupport viaembassy-sync.
Design
- Free-index chain is separate from
T's slot memory — not an intrusive free list, so slot layout is unaffected. - Pools must live in
staticmemory;alloc/requesttake&'static self, eliminating lifetime parameters on guards — convenient for async frameworks like Embassy. BoxPool::alloc/ObjectPool::requestblock and await when the pool is full (featureasync).BoxGuardsupportstry_clone(fallible, no panic on exhaustion) andinto_raw/from_rawfor DMA / FFI.
License
Licensed under either of Apache License 2.0 or MIT license at your option.