Skip to content

Commit

Permalink
alloc: add TLSF allocator as the default
Browse files Browse the repository at this point in the history
  • Loading branch information
equation314 committed Jul 29, 2023
1 parent 7d5b910 commit 12cd9dc
Show file tree
Hide file tree
Showing 13 changed files with 215 additions and 19 deletions.
44 changes: 44 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions apps/c/memtest/expect_trace.out
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Found physcial memory regions:
.bss (READ | WRITE | RESERVED)
free memory (READ | WRITE | FREE)
Initialize global memory allocator...
use TLSF allocator.
initialize global allocator at: \[0x[0-9a-f]\+, 0x[0-9a-f]\+)
Initialize kernel page table...
Initialize platform devices...
Expand Down
1 change: 1 addition & 0 deletions apps/memtest/expect_trace.out
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Found physcial memory regions:
.bss (READ | WRITE | RESERVED)
free memory (READ | WRITE | FREE)
Initialize global memory allocator...
use TLSF allocator.
initialize global allocator at: \[0x[0-9a-f]\+, 0x[0-9a-f]\+)
Initialize kernel page table...
Initialize platform devices...
Expand Down
4 changes: 2 additions & 2 deletions apps/memtest/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use std::collections::BTreeMap;
use std::vec::Vec;

fn test_vec(rng: &mut impl RngCore) {
const N: usize = 1_000_000;
const N: usize = 3_000_000;
let mut v = Vec::with_capacity(N);
for _ in 0..N {
v.push(rng.next_u32());
Expand All @@ -23,7 +23,7 @@ fn test_vec(rng: &mut impl RngCore) {
}

fn test_btree_map(rng: &mut impl RngCore) {
const N: usize = 10_000;
const N: usize = 50_000;
let mut m = BTreeMap::new();
for _ in 0..N {
let value = rng.next_u32();
Expand Down
18 changes: 14 additions & 4 deletions crates/allocator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,25 @@ repository = "https://github.com/rcore-os/arceos/tree/main/crates/allocator"
documentation = "https://rcore-os.github.io/arceos/allocator/index.html"

[features]
default = []
full = ["bitmap", "tlsf", "slab", "buddy", "allocator_api"]

bitmap = ["dep:bitmap-allocator"]

tlsf = ["dep:rlsf"]
slab = ["dep:slab_allocator"]
buddy = ["dep:buddy_system_allocator"]

allocator_api = []

[dependencies]
buddy_system_allocator = { version = "0.9", default-features = false }
bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator.git", rev = "88e871a" }
slab_allocator = { path = "../slab_allocator" }
buddy_system_allocator = { version = "0.9", default-features = false, optional = true }
slab_allocator = { path = "../slab_allocator", optional = true }
rlsf = { version = "0.2", optional = true }
bitmap-allocator = { git = "https://github.com/rcore-os/bitmap-allocator.git", rev = "88e871a", optional = true }

[dev-dependencies]
allocator = { path = ".", features = ["allocator_api"] }
allocator = { path = ".", features = ["full"] }
rand = { version = "0.8", features = ["small_rng"] }
criterion = { version = "0.5", features = ["html_reports"] }

Expand Down
7 changes: 6 additions & 1 deletion crates/allocator/benches/collections.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::alloc::Allocator;
use std::collections::BTreeMap;
use std::io::Write;

use allocator::{AllocatorRc, BuddyByteAllocator, SlabByteAllocator};
use allocator::{AllocatorRc, BuddyByteAllocator, SlabByteAllocator, TlsfByteAllocator};
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use rand::{rngs::SmallRng, seq::SliceRandom, RngCore, SeedableRng};

Expand Down Expand Up @@ -80,6 +80,11 @@ fn bench(c: &mut Criterion, alloc_name: &str, alloc: impl Allocator + Clone) {
fn criterion_benchmark(c: &mut Criterion) {
let mut pool = MemoryPool::new(POOL_SIZE);
bench(c, "system", std::alloc::System);
bench(
c,
"tlsf",
AllocatorRc::new(TlsfByteAllocator::new(), pool.as_slice()),
);
bench(
c,
"slab",
Expand Down
18 changes: 15 additions & 3 deletions crates/allocator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,26 @@
#![feature(result_option_inspect)]
#![cfg_attr(feature = "allocator_api", feature(allocator_api))]

#[cfg(feature = "bitmap")]
mod bitmap;
mod buddy;
mod slab;

#[cfg(feature = "bitmap")]
pub use bitmap::BitmapPageAllocator;

#[cfg(feature = "buddy")]
mod buddy;
#[cfg(feature = "buddy")]
pub use buddy::BuddyByteAllocator;

#[cfg(feature = "slab")]
mod slab;
#[cfg(feature = "slab")]
pub use slab::SlabByteAllocator;

#[cfg(feature = "tlsf")]
mod tlsf;
#[cfg(feature = "tlsf")]
pub use tlsf::TlsfByteAllocator;

use core::alloc::Layout;
use core::num::NonZeroUsize;

Expand Down
81 changes: 81 additions & 0 deletions crates/allocator/src/tlsf.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
//! The TLSF (Two-Level Segregated Fit) dynamic memory allocation algorithm.
//!
//! This module wraps the implementation provided by the [rlsf] crate.

use super::{AllocError, AllocResult, BaseAllocator, ByteAllocator};
use core::alloc::Layout;
use core::num::NonZeroUsize;
use core::ptr::NonNull;
use rlsf::Tlsf;

/// A TLSF (Two-Level Segregated Fit) memory allocator.
///
/// It's just a wrapper structure of [`rlsf::Tlsf`], with `FLLEN` and `SLLEN`
/// fixed to 28 and 32.
pub struct TlsfByteAllocator {
inner: Tlsf<'static, u32, u32, 28, 32>, // max pool size: 32 * 2^28 = 8G
total_bytes: usize,
used_bytes: usize,
}

impl TlsfByteAllocator {
/// Creates a new empty [`TlsfByteAllocator`].
pub const fn new() -> Self {
Self {
inner: Tlsf::new(),
total_bytes: 0,
used_bytes: 0,
}
}
}

impl BaseAllocator for TlsfByteAllocator {
fn init(&mut self, start: usize, size: usize) {
unsafe {
let pool = core::slice::from_raw_parts_mut(start as *mut u8, size);
self.inner
.insert_free_block_ptr(NonNull::new(pool).unwrap())
.unwrap();
}
self.total_bytes = size;
}

fn add_memory(&mut self, start: usize, size: usize) -> AllocResult {
unsafe {
let pool = core::slice::from_raw_parts_mut(start as *mut u8, size);
self.inner
.insert_free_block_ptr(NonNull::new(pool).unwrap())
.ok_or(AllocError::InvalidParam)?;
}
self.total_bytes += size;
Ok(())
}
}

impl ByteAllocator for TlsfByteAllocator {
fn alloc(&mut self, layout: Layout) -> AllocResult<NonZeroUsize> {
let ptr = self.inner.allocate(layout).ok_or(AllocError::NoMemory)?;
self.used_bytes += layout.size();
Ok(ptr.addr())
}

fn dealloc(&mut self, pos: NonZeroUsize, layout: Layout) {
unsafe {
self.inner
.deallocate(NonNull::new_unchecked(pos.get() as _), layout.align())
}
self.used_bytes -= layout.size();
}

fn total_bytes(&self) -> usize {
self.total_bytes
}

fn used_bytes(&self) -> usize {
self.used_bytes
}

fn available_bytes(&self) -> usize {
self.total_bytes - self.used_bytes
}
}
15 changes: 13 additions & 2 deletions crates/allocator/tests/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use std::alloc::{Allocator, Layout};
use std::collections::BTreeMap;
use std::io::Write;

use allocator::{AllocatorRc, BuddyByteAllocator, SlabByteAllocator};
use allocator::{AllocatorRc, BuddyByteAllocator, SlabByteAllocator, TlsfByteAllocator};
use rand::{prelude::SliceRandom, Rng};

const POOL_SIZE: usize = 1024 * 1024 * 128;
Expand Down Expand Up @@ -72,7 +72,6 @@ pub fn test_alignment(n: usize, alloc: &(impl Allocator + Clone)) {
let align = 1 << rng.gen_range(0..8);
let layout = Layout::from_size_align(size, align).unwrap();
let ptr = alloc.allocate(layout).unwrap();
// println!("{:?} {:#x}", layout, ptr.addr());
blocks.push((ptr, layout));
} else {
// delete a block
Expand Down Expand Up @@ -131,3 +130,15 @@ fn slab_alloc() {
test_btree_map(50_000, &alloc);
})
}

#[test]
fn tlsf_alloc() {
run_test(|pool| {
let alloc = AllocatorRc::new(TlsfByteAllocator::new(), pool);
test_alignment(50, &alloc);
test_vec(3_000_000, &alloc);
test_vec2(30_000, 64, &alloc);
test_vec2(7_500, 520, &alloc);
test_btree_map(50_000, &alloc);
})
}
8 changes: 7 additions & 1 deletion modules/axalloc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@ homepage = "https://github.com/rcore-os/arceos"
repository = "https://github.com/rcore-os/arceos/tree/main/modules/axalloc"
documentation = "https://rcore-os.github.io/arceos/axalloc/index.html"

[features]
default = ["tlsf"]
tlsf = ["allocator/tlsf"]
slab = ["allocator/slab"]
buddy = ["allocator/buddy"]

[dependencies]
log = "0.4"
cfg-if = "1.0"
spinlock = { path = "../../crates/spinlock" }
memory_addr = { path = "../../crates/memory_addr" }
allocator = { path = "../../crates/allocator"}
allocator = { path = "../../crates/allocator", features = ["bitmap"] }
axerrno = { path = "../../crates/axerrno" }
Loading

0 comments on commit 12cd9dc

Please sign in to comment.