Expand description
The Ferroc Memory Allocator
§Usage
Ferroc can be used in many ways by various features. Pick one you prefer:
§The default allocator
The simplest use of this crate is to configure it as the default global
allocator. Simply add the dependency of this crate, mark an instance of
Ferroc
using the #[global_allocator]
attribute, and done!
use ferroc::Ferroc;
#[global_allocator]
static FERROC: Ferroc = Ferroc;
let _vec = vec![10; 100];
Or, if you don’t want to use it as the global allocator, Ferroc
provides
methods of all the functions you need, as well as the implementation of
core::alloc::Allocator
:
#![feature(allocator_api)]
use ferroc::Ferroc;
let mut vec = Vec::with_capacity_in(10, Ferroc);
vec.extend([1, 2, 3, 4, 5]);
let layout = std::alloc::Layout::new::<[u32; 10]>();
let memory = Ferroc.allocate(layout).unwrap();
unsafe { Ferroc.deallocate(memory.cast(), layout) };
§The default allocator (custom configuration)
An instance of Ferroc type consists of thread-local contexts and heaps and a global arena collection based on a specified base allocator, which can be configured as you like.
To do so, disable the default feature and enable the global
feature as
well as other necessary features to configure it! Take the
embedded use case for example:
[dependencies.ferroc]
version = "*"
default-features = false
features = ["global", "base-static"]
// This is the capacity of the necessary additional static
// memory space used by ferroc as the metadata storage.
const HEADER_CAP: usize = 4096;
ferroc::config!(pub Custom => ferroc::base::Static::<HEADER_CAP>);
#[global_allocator]
static CUSTOM: Custom = Custom;
// Multiple manageable static memory chunks can be loaded at runtime.
let chunk = unsafe { Chunk::from_static(/* ... */) };
CUSTOM.manage(chunk);
// ...And you can start allocation.
let _vec = vec![10; 100];
§MORE customizations
If the configurations of the default allocator can’t satisfy your need, you can use the intermediate structures manually while disabling unnecessary features:
#![feature(allocator_api)]
use ferroc::{
arena::Arenas,
heap::{Heap, Context},
base::Mmap,
};
let arenas = Arenas::new(Mmap); // `Arenas` are `Send` & `Sync`...
let cx = Context::new(&arenas);
let heap = Heap::new(&cx); // ...while `Context`s and `Heap`s are not.
// Using the allocator API.
let mut vec = Vec::new_in(&heap);
vec.extend([1, 2, 3, 4]);
assert_eq!(vec.iter().sum::<i32>(), 10);
// Manually allocate memory.
let layout = std::alloc::Layout::new::<u8>();
let ptr = heap.allocate(layout).unwrap();
unsafe { heap.deallocate(ptr, layout) };
// Immediately run some delayed clean-up operations.
heap.collect(/* force */false);
§Using as a dynamic library for malloc
function series
Simply enable the c
feature and compile it, and you can retrieve the
library binary alongside with a ferroc.h
C/C++ compatible header.
If you want to replace the default malloc
implementation, add a rustc
flag --cfg sys_alloc
when compiling.
§Statistics
You can get statistics by enabling the stat
feature and call the stat
method on the default allocator or other instances like
Heap
.
Modules§
- The module of the arena collection.
- The module of base allocators.
- The module of heaps and contexts.
Macros§
- Configures and instantiates a global instance of a
ferroc
ator in place. - Configures and instantiates a global instance of a
ferroc
ator in an inline module.
Structs§
- The configured allocator backed by
crate::base::Mmap
.
Type Aliases§
- The arena collection type of the
crate::base::Mmap
backend. - The chunk type of the
crate::base::Mmap
backend. - The context type of the
crate::base::Mmap
backend. - The error type of the
crate::base::Mmap
backend. - The heap type of the
crate::base::Mmap
backend.