Skip to content

Commit

Permalink
alloc: minor changes of allocator API
Browse files Browse the repository at this point in the history
  • Loading branch information
equation314 committed Jul 28, 2023
1 parent 5be216b commit 2b545ba
Show file tree
Hide file tree
Showing 13 changed files with 136 additions and 54 deletions.
17 changes: 9 additions & 8 deletions Cargo.lock

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

6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export PATH=`pwd`/x86_64-linux-musl-cross/bin:`pwd`/aarch64-linux-musl-cross/bin

```bash
# in arceos directory
make A=path/to/app ARCH=<arch> LOG=<log> NET=[y|n] BLK=[y|n]
make A=path/to/app ARCH=<arch> LOG=<log>
```

Where `<arch>` should be one of `riscv64`, `aarch64``x86_64`.
Expand All @@ -106,9 +106,11 @@ More arguments and targets can be found in [Makefile](Makefile).
For example, to run the [httpserver](apps/net/httpserver/) on `qemu-system-aarch64` with 4 cores:

```bash
make A=apps/net/httpserver ARCH=aarch64 LOG=info NET=y SMP=4 run
make A=apps/net/httpserver ARCH=aarch64 LOG=info SMP=4 run NET=y
```

Note that the `NET=y` argument is required to enable the network device in QEMU. These arguments (`BLK`, `GRAPHIC`, etc.) only take effect at runtime not build time.

### Your custom apps

#### Rust
Expand Down
3 changes: 3 additions & 0 deletions crates/allocator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ homepage = "https://github.com/rcore-os/arceos"
repository = "https://github.com/rcore-os/arceos/tree/main/crates/allocator"
documentation = "https://rcore-os.github.io/arceos/allocator/index.html"

[features]
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" }
Expand Down
13 changes: 7 additions & 6 deletions crates/allocator/src/buddy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use buddy_system_allocator::Heap;
use core::alloc::Layout;
use core::num::NonZeroUsize;

use crate::{AllocError, AllocResult, BaseAllocator, ByteAllocator};

Expand Down Expand Up @@ -35,17 +36,17 @@ impl BaseAllocator for BuddyByteAllocator {
}

impl ByteAllocator for BuddyByteAllocator {
fn alloc(&mut self, size: usize, align_pow2: usize) -> AllocResult<usize> {
fn alloc(&mut self, layout: Layout) -> AllocResult<NonZeroUsize> {
self.inner
.alloc(Layout::from_size_align(size, align_pow2).unwrap())
.map(|ptr| ptr.as_ptr() as usize)
.alloc(layout)
.map(|ptr| ptr.addr())
.map_err(|_| AllocError::NoMemory)
}

fn dealloc(&mut self, pos: usize, size: usize, align_pow2: usize) {
fn dealloc(&mut self, pos: NonZeroUsize, layout: Layout) {
self.inner.dealloc(
unsafe { core::ptr::NonNull::new_unchecked(pos as *mut u8) },
Layout::from_size_align(size, align_pow2).unwrap(),
unsafe { core::ptr::NonNull::new_unchecked(pos.get() as _) },
layout,
)
}

Expand Down
57 changes: 55 additions & 2 deletions crates/allocator/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
//! - [`IdAllocator`]: Used to allocate unique IDs.
#![no_std]
#![feature(strict_provenance)]
#![feature(result_option_inspect)]
#![cfg_attr(feature = "allocator_api", feature(allocator_api))]

mod bitmap;
mod buddy;
Expand All @@ -19,6 +21,9 @@ pub use bitmap::BitmapPageAllocator;
pub use buddy::BuddyByteAllocator;
pub use slab::SlabByteAllocator;

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

/// The error type used for allocation.
#[derive(Debug)]
pub enum AllocError {
Expand Down Expand Up @@ -47,10 +52,10 @@ pub trait BaseAllocator {
/// Byte-granularity allocator.
pub trait ByteAllocator: BaseAllocator {
/// Allocate memory with the given size (in bytes) and alignment.
fn alloc(&mut self, size: usize, align_pow2: usize) -> AllocResult<usize>;
fn alloc(&mut self, layout: Layout) -> AllocResult<NonZeroUsize>;

/// Deallocate memory at the given position, size, and alignment.
fn dealloc(&mut self, pos: usize, size: usize, align_pow2: usize);
fn dealloc(&mut self, pos: NonZeroUsize, layout: Layout);

/// Returns total memory size in bytes.
fn total_bytes(&self) -> usize;
Expand Down Expand Up @@ -116,3 +121,51 @@ const fn align_down(pos: usize, align: usize) -> usize {
const fn align_up(pos: usize, align: usize) -> usize {
(pos + align - 1) & !(align - 1)
}

#[cfg(feature = "allocator_api")]
mod allocator_api {
extern crate alloc;

use super::ByteAllocator;
use alloc::rc::Rc;
use core::alloc::{AllocError, Allocator, Layout};
use core::cell::RefCell;
use core::ptr::NonNull;

/// A byte-allocator wrapped in [`Rc<RefCell>`] that implements [`core::alloc::Allocator`].
pub struct AllocatorRc<A: ByteAllocator>(Rc<RefCell<A>>);

impl<A: ByteAllocator> AllocatorRc<A> {
/// Creates a new allocator with the given memory pool.
pub fn new(mut inner: A, pool: &mut [u8]) -> Self {
inner.init(pool.as_mut_ptr() as usize, pool.len());
Self(Rc::new(RefCell::new(inner)))
}
}

unsafe impl<A: ByteAllocator> Allocator for AllocatorRc<A> {
fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
match layout.size() {
0 => Ok(NonNull::slice_from_raw_parts(NonNull::dangling(), 0)),
size => {
let raw_addr = self.0.borrow_mut().alloc(layout).map_err(|_| AllocError)?;
let ptr = unsafe { NonNull::new_unchecked(raw_addr.get() as _) };
Ok(NonNull::slice_from_raw_parts(ptr, size))
}
}
}

unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
self.0.borrow_mut().dealloc(ptr.addr(), layout)
}
}

impl<A: ByteAllocator> Clone for AllocatorRc<A> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
}

#[cfg(feature = "allocator_api")]
pub use allocator_api::AllocatorRc;
13 changes: 6 additions & 7 deletions crates/allocator/src/slab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use super::{AllocError, AllocResult, BaseAllocator, ByteAllocator};
use core::alloc::Layout;
use core::num::NonZeroUsize;
use slab_allocator::Heap;

/// A byte-granularity memory allocator based on the [slab allocator].
Expand Down Expand Up @@ -42,17 +43,15 @@ impl BaseAllocator for SlabByteAllocator {
}

impl ByteAllocator for SlabByteAllocator {
fn alloc(&mut self, size: usize, align_pow2: usize) -> AllocResult<usize> {
fn alloc(&mut self, layout: Layout) -> AllocResult<NonZeroUsize> {
self.inner_mut()
.allocate(Layout::from_size_align(size, align_pow2).unwrap())
.allocate(layout)
.map(|addr| NonZeroUsize::new(addr).unwrap())
.map_err(|_| AllocError::NoMemory)
}

fn dealloc(&mut self, pos: usize, size: usize, align_pow2: usize) {
unsafe {
self.inner_mut()
.deallocate(pos, Layout::from_size_align(size, align_pow2).unwrap())
}
fn dealloc(&mut self, pos: NonZeroUsize, layout: Layout) {
unsafe { self.inner_mut().deallocate(pos.get(), layout) }
}

fn total_bytes(&self) -> usize {
Expand Down
3 changes: 2 additions & 1 deletion modules/axalloc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ documentation = "https://rcore-os.github.io/arceos/axalloc/index.html"

[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"}
axerrno = { path = "../../crates/axerrno" }
29 changes: 21 additions & 8 deletions modules/axalloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod page;
use allocator::{AllocResult, BaseAllocator, ByteAllocator, PageAllocator};
use allocator::{BitmapPageAllocator, SlabByteAllocator};
use core::alloc::{GlobalAlloc, Layout};
use core::num::NonZeroUsize;
use spinlock::SpinNoIrq;

const PAGE_SIZE: usize = 0x1000;
Expand Down Expand Up @@ -46,6 +47,11 @@ impl GlobalAllocator {
}
}

/// Returns the name of the allocator.
pub const fn name(&self) -> &'static str {
"slab"
}

/// Initializes the allocator with the given region.
///
/// It firstly adds the whole region to the page allocator, then allocates
Expand Down Expand Up @@ -77,15 +83,18 @@ impl GlobalAllocator {
///
/// `align_pow2` must be a power of 2, and the returned region bound will be
/// aligned to it.
pub fn alloc(&self, size: usize, align_pow2: usize) -> AllocResult<usize> {
pub fn alloc(&self, layout: Layout) -> AllocResult<NonZeroUsize> {
// simple two-level allocator: if no heap memory, allocate from the page allocator.
let mut balloc = self.balloc.lock();
loop {
if let Ok(ptr) = balloc.alloc(size, align_pow2) {
if let Ok(ptr) = balloc.alloc(layout) {
return Ok(ptr);
} else {
let old_size = balloc.total_bytes();
let expand_size = old_size.max(size).next_power_of_two().max(PAGE_SIZE);
let expand_size = old_size
.max(layout.size())
.next_power_of_two()
.max(PAGE_SIZE);
let heap_ptr = self.alloc_pages(expand_size / PAGE_SIZE, PAGE_SIZE)?;
debug!(
"expand heap memory: [{:#x}, {:#x})",
Expand All @@ -104,8 +113,8 @@ impl GlobalAllocator {
/// undefined.
///
/// [`alloc`]: GlobalAllocator::alloc
pub fn dealloc(&self, pos: usize, size: usize, align_pow2: usize) {
self.balloc.lock().dealloc(pos, size, align_pow2)
pub fn dealloc(&self, pos: NonZeroUsize, layout: Layout) {
self.balloc.lock().dealloc(pos, layout)
}

/// Allocates contiguous pages.
Expand Down Expand Up @@ -152,15 +161,19 @@ impl GlobalAllocator {

unsafe impl GlobalAlloc for GlobalAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
if let Ok(ptr) = GlobalAllocator::alloc(self, layout.size(), layout.align()) {
ptr as _
if let Ok(ptr) = GlobalAllocator::alloc(self, layout) {
ptr.get() as _
} else {
alloc::alloc::handle_alloc_error(layout)
}
}

unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
GlobalAllocator::dealloc(self, ptr as _, layout.size(), layout.align())
GlobalAllocator::dealloc(
self,
NonZeroUsize::new(ptr as _).expect("dealloc null ptr"),
layout,
)
}
}

Expand Down
10 changes: 6 additions & 4 deletions modules/axdriver/src/ixgbe.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use axalloc::global_allocator;
use axhal::mem::{phys_to_virt, virt_to_phys};
use core::ptr::NonNull;
use core::{alloc::Layout, ptr::NonNull};
use driver_net::ixgbe::{IxgbeHal, PhysAddr as IxgbePhysAddr};

pub struct IxgbeHalImpl;

unsafe impl IxgbeHal for IxgbeHalImpl {
fn dma_alloc(size: usize) -> (IxgbePhysAddr, NonNull<u8>) {
let vaddr = if let Ok(vaddr) = global_allocator().alloc(size, 2) {
vaddr
let layout = Layout::from_size_align(size, 8).unwrap();
let vaddr = if let Ok(vaddr) = global_allocator().alloc(layout) {
vaddr.get()
} else {
return (0, NonNull::dangling());
};
Expand All @@ -18,7 +19,8 @@ unsafe impl IxgbeHal for IxgbeHalImpl {
}

unsafe fn dma_dealloc(_paddr: IxgbePhysAddr, vaddr: NonNull<u8>, size: usize) -> i32 {
global_allocator().dealloc(vaddr.as_ptr() as usize, size, 2);
let layout = Layout::from_size_align(size, 8).unwrap();
global_allocator().dealloc(vaddr.addr(), layout);
0
}

Expand Down
1 change: 1 addition & 0 deletions modules/axdriver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
#![no_std]
#![feature(doc_auto_cfg)]
#![feature(associated_type_defaults)]
#![feature(strict_provenance)]

#[macro_use]
extern crate log;
Expand Down
8 changes: 4 additions & 4 deletions modules/axruntime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,7 @@ pub extern "C" fn rust_main(cpu_id: usize, dtb: usize) -> ! {
}

#[cfg(feature = "alloc")]
{
info!("Initialize global memory allocator...");
init_allocator();
}
init_allocator();

#[cfg(feature = "paging")]
{
Expand Down Expand Up @@ -201,6 +198,9 @@ pub extern "C" fn rust_main(cpu_id: usize, dtb: usize) -> ! {
fn init_allocator() {
use axhal::mem::{memory_regions, phys_to_virt, MemRegionFlags};

info!("Initialize global memory allocator...");
info!(" use {} allocator.", axalloc::global_allocator().name());

let mut max_region_size = 0;
let mut max_region_paddr = 0.into();
for r in memory_regions() {
Expand Down
Loading

0 comments on commit 2b545ba

Please sign in to comment.