Last active
November 9, 2023 00:04
-
-
Save smj-edison/0410d5942f5999a11cd4a84c2687ef95 to your computer and use it in GitHub Desktop.
Fix filename
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::{ | |
alloc::Layout, | |
cell::UnsafeCell, | |
fmt::Debug, | |
mem::size_of, | |
ptr::{self, NonNull}, | |
}; | |
use allocator_api2::alloc::AllocError; | |
use buddy_system_allocator::Heap; | |
pub struct Alloc<'a, T> { | |
pub value: &'a mut T, | |
buddy_ref: &'a BuddyArena, | |
ptr: NonNull<u8>, | |
layout: Layout, | |
} | |
impl<'a, T: Debug> Debug for Alloc<'a, T> { | |
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | |
write!(f, "Allocation {{ ")?; | |
self.value.fmt(f)?; | |
write!(f, " }}") | |
} | |
} | |
impl<'a, T> Drop for Alloc<'a, T> { | |
fn drop(&mut self) { | |
unsafe { | |
ptr::drop_in_place(self.value as *mut T); | |
} | |
unsafe { &mut *self.buddy_ref.heap.get() }.dealloc(self.ptr, self.layout); | |
} | |
} | |
pub struct BuddyArena { | |
_space: Vec<usize>, | |
heap: UnsafeCell<Heap<32>>, | |
} | |
impl BuddyArena { | |
pub fn new(bytes: usize) -> BuddyArena { | |
let size = bytes / size_of::<usize>(); | |
let mut heap = Heap::<32>::new(); | |
let space = vec![0; size]; | |
unsafe { | |
heap.init( | |
space.as_slice().as_ptr() as usize, | |
size * size_of::<usize>(), | |
); | |
} | |
BuddyArena { | |
_space: space, | |
heap: heap.into(), | |
} | |
} | |
pub fn alloc_with<'a, T, F>(&'a self, f: F) -> Result<Alloc<'a, T>, AllocError> | |
where | |
F: FnOnce() -> T, | |
{ | |
let layout = Layout::new::<T>(); | |
let alloc = unsafe { self.heap_ref() } | |
.alloc(layout) | |
.map_err(|_| AllocError)?; | |
let p = alloc.as_ptr() as *mut T; | |
let ref_to_x = unsafe { | |
ptr::write(p, f()); | |
&mut *p | |
}; | |
Ok(Alloc { | |
value: ref_to_x, | |
buddy_ref: &self, | |
ptr: alloc, | |
layout, | |
}) | |
} | |
unsafe fn heap_ref(&self) -> &mut Heap<32> { | |
&mut *self.heap.get() | |
} | |
} | |
#[test] | |
fn test_alloc() { | |
let arena = BuddyArena::new(1_000_000); | |
let hello = arena.alloc_with(|| "hello").unwrap(); | |
let world = arena.alloc_with(|| "world").unwrap(); | |
let arr = arena.alloc_with(|| [hello, world]).unwrap(); | |
println!("{:?}", arr); | |
println!("{:?}", unsafe { arena.heap_ref() }); | |
println!("{:?}", unsafe { arena.heap_ref() }); | |
drop(arr); | |
println!("done"); | |
println!("{:?}", unsafe { arena.heap_ref() }); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[package] | |
name = "api-test" | |
version = "0.1.0" | |
edition = "2021" | |
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | |
[dependencies] | |
allocator-api2 = "0.2.15" | |
buddy_system_allocator = "0.9.0" | |
self_cell = "1.0.1" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
pub mod buddy_arena; | |
use std::cell::UnsafeCell; | |
use buddy_arena::Alloc; | |
use buddy_arena::BuddyArena; | |
use self_cell::self_cell; | |
#[derive(Debug, Clone)] | |
pub enum Osc { | |
NoteOn { channel: u8, note: u8, velocity: u8 }, | |
NoteOff { channel: u8, note: u8, velocity: u8 }, | |
} | |
struct TraverserIo<'arena> { | |
osc_io: Vec<UnsafeCell<Alloc<'arena, Osc>>>, | |
} | |
self_cell!( | |
struct TraverserIoWithArena { | |
owner: BuddyArena, | |
#[covariant] | |
dependent: TraverserIo, | |
} | |
); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment