Giter Site home page Giter Site logo

ferroc's Introduction

Ferroc: A Multithread Lock-free Memory Allocator

Build Status Cargo Coverage Documentation License

Ferroc (combined from "ferrum" and "malloc") is a lock-free concurrent memory allocator written in Rust, primarily inspired by mimalloc.

This memory allocator is designed to work as fast as other mainstream memory allocators while providing flexible configurations such as embedded/bare-metal environment integrations.

Examples

If you simply want to utilize another memory allocator, you can use Ferroc as the global allocator with default features:

use ferroc::Ferroc;

#[global_allocator]
static FERROC: Ferroc = Ferroc;

fn main() {
    // Using the global allocator API.
    let _vec = vec![10; 100];

    // Manually allocate memory.
    let layout = std::alloc::Layout::new::<u8>();
    let ptr = Ferroc.allocate(layout).unwrap();
    unsafe { Ferroc.deallocate(ptr, layout) };

    // Immediately run some delayed clean-up operations.
    Ferroc.collect(/* force */false);
}

If you want more control over the allocator, you can disable the default features and enable the ones you need:

ferroc = {version = "*", default-features = false, features = ["base-mmap"]}
#![feature(allocator_api)]

use core::pin::pin;
use ferroc::{
    arena::Arenas,
    heap::{Heap, Context},
    base::Mmap,
};

fn main() {
    let arenas = Arenas::new(Mmap); // `Arenas` are `Send` & `Sync`...
    let cx = pin!(Context::new(&arenas));
    let heap = Heap::new(cx.as_ref()); // ...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.cast(), layout) }.unwrap();

    // Immediately run some delayed clean-up operations.
    heap.collect(/* force */false);
}

Cargo Features

  • Basic features: generic Arenas, Contexts and Heaps;
  • "base-static": Base allocator Static;
  • "base-mmap": Base allocator Mmap based on os-specific virtual memory managers (std and libc required);
  • "global": Global allocator instantiation macros config! and config_mod! (inner thread local statics are leaked by default);
  • "libc": libc dependency (currently required by pthread option in config*! if you want a pthread thread-local destructor);
  • "default": The default global allocator Ferroc provided by Mmap and pthread thread-local destructor (consisting of all the features above);
  • "c": fe_* C functions for C/C++ targets and a generated C/C++ header "ferroc.h" in the root directory;
  • "c-override": Override default allocator functions such as malloc/free and operator new/delete, which can be useful for embedding Ferroc in a C/C++ project (see this section for more details);
  • "track-valgrind": Valgrind memory tracking support based on crabgrind;
  • "finer-grained": Add more object size types to small bins, decreasing fragmentation but also the minimal alignment from 16 to 8, potentially leading some programs that need SIMD to fail for misalignment.

Building process for C/C++ users

  1. Download and install the latest nightly Rust toolchain:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs |\
    sh -- -y --toolchain nightly --profile minimal -c rust-src
  1. Just cmake and make it:
mkdir target && cd target # Required to be `target`. Don't change it to `build` or other names.
cmake .. && make
  1. If you want to install the library:
sudo make install

Common options like --install-prefix and --config are supported naturally by CMake.

There are also some custom options (via cmake -D) you can enable:

  • FE_TRACK_VALGRIND: See "track-valgrind" above;
  • FE_FINER_GRAINED: See "finer-grained" above.
  • FE_PGO_GATHER: Enable PGO (Profile-Guided Optimization) gathering.
  • FE_PGO_USE: Build with optimization from pre-gathered PGO data (which requires appending llvm-tools to the second line of step 1).

Benchmarks

Using a subset of mimalloc-bench for benchmarking. Running on my laptop with 16GB of RAM and an Intel i7-10750H CPU @ 2.60GHz. The process is repeated 10 times.

Time consumed:

Time consumed #1 Time consumed #2

Memory consumed:

Memory consumed #1 Memory consumed #2

Caveats

This crate only supports the latest nightly Rust compiler currently and utilizes many unstable features. Use it with care.

License

Licensed under either of

at your option.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.