rlsf

docs.rs

This crate implements the TLSF (Two-Level Segregated Fit) dynamic memory allocation algorithm¹. Requires Rust 1.51.0 or later.

¹ M. Masmano, I. Ripoll, A. Crespo and J. Real, "TLSF: a new dynamic memory allocator for real-time systems," Proceedings. 16th Euromicro Conference on Real-Time Systems, 2004. ECRTS 2004., Catania, Italy, 2004, pp. 79-88, doi: 10.1109/EMRTS.2004.1311009.

² Compiled for and measured on a STM32F401 microcontroller using FarCri.rs.

³ But rlsf can't return free memory blocks to the underlying memory system. In a situation where returning memory blocks is important, you should probably just use the default allocator (and keep the I-cache clean).

Measured Performance

The result of latency measurement on STM32F401 is shown here. rlsf:
260–320 cycles. buddy-alloc: 340–440 cycles. dlmalloc: 450–750 cycles.

The result of code size measurement on WebAssembly is shown here. rlsf:
1267 bytes, rlsf + pool coalescing: 1584 bytes, wee_alloc: 1910 bytes,
dlmalloc: 9613 bytes.

Examples

Tlsf: Core API

```rust use rlsf::Tlsf; use std::{mem::MaybeUninit, alloc::Layout};

let mut pool = [MaybeUninit::uninit(); 65536];

// On 32-bit systems, the maximum block size is 16 << FLLEN = 65536 bytes. // The worst-case fragmentation is (16 << FLLEN) / SLLEN - 2 = 4094 bytes. // 'pool represents the memory pool's lifetime (pool in this case). let mut tlsf: Tlsf<', u16, u16, 12, 16> = Tlsf::INIT; // ^^ ^^ ^^ // | | | // 'pool | SLLEN // FLLEN tlsf.insertfree_block(&mut pool);

unsafe { let mut ptr1 = tlsf.allocate(Layout::new::()).unwrap().cast::(); let mut ptr2 = tlsf.allocate(Layout::new::()).unwrap().cast::(); ptr1.as_mut() = 42; *ptr2.as_mut() = 56; assert_eq!(ptr1.asref(), 42); asserteq!(*ptr2.as_ref(), 56); tlsf.deallocate(ptr1.cast(), Layout::new::().align()); tlsf.deallocate(ptr2.cast(), Layout::new::().align()); } ```

GlobalTlsf: Global Allocator

```rust

[cfg(all(targetarch = "wasm32", not(targetfeature = "atomics")))]

[global_allocator]

static A: rlsf::SmallGlobalTlsf = rlsf::SmallGlobalTlsf::INIT;

let mut m = std::collections::HashMap::new(); m.insert(1, 2); m.insert(5, 3); drop(m); ```

Details

Changes from the Original Algorithm

License

MIT/Apache-2.0