twizzler/alloc.rs
1use std::{
2 alloc::{AllocError, Layout},
3 mem::MaybeUninit,
4};
5
6use crate::ptr::{GlobalPtr, RefMut};
7
8pub mod arena;
9mod global;
10pub mod invbox;
11
12pub use global::OwnedGlobalPtr;
13
14/// Basic allocation trait.
15pub trait Allocator: Clone {
16 /// Allocate based on layout within this allocator. Returns a global pointer
17 /// to the start of the allocation.
18 ///
19 /// Note: Using this function by itself can leak memory, particularly on failure.
20 /// Users should consider using InvBox instead.
21 fn alloc(&self, layout: Layout) -> Result<GlobalPtr<u8>, AllocError>;
22
23 /// Allocate based on layout within this allocator. Returns a global pointer
24 /// to the start of the allocation.
25 ///
26 /// Note: Using this function by itself can leak memory, particularly on failure.
27 /// Users should consider using InvBox instead.
28 fn alloc_with<T>(
29 &self,
30 f: impl FnOnce(RefMut<MaybeUninit<T>>) -> Result<RefMut<T>, AllocError>,
31 ) -> Result<GlobalPtr<u8>, AllocError> {
32 let res = self.alloc(Layout::new::<T>())?;
33 let res = res.cast::<MaybeUninit<T>>();
34 let res = unsafe { res.resolve_mut() };
35 Ok(f(res)?.global().cast())
36 }
37
38 /// Free an allocation.
39 ///
40 /// # Safety
41 /// Caller must ensure that the pointer is valid and was allocated by this allocator, and
42 /// refers to memory that matches the provided layout.
43 unsafe fn dealloc(&self, ptr: GlobalPtr<u8>, layout: Layout);
44
45 /// Reallocate an allocation.
46 ///
47 /// # Safety
48 /// Caller must ensure that the pointer is valid and was allocated by this allocator, and
49 /// refers to memory that matches the provided layout.
50 unsafe fn realloc(
51 &self,
52 ptr: GlobalPtr<u8>,
53 layout: Layout,
54 newsize: usize,
55 ) -> Result<GlobalPtr<u8>, AllocError> {
56 let new_layout =
57 Layout::from_size_align(newsize, layout.align()).map_err(|_| AllocError)?;
58
59 let new_alloc = self.alloc(new_layout)?;
60 unsafe {
61 if !ptr.is_null() {
62 let new_res = new_alloc.resolve_mut();
63 let old_res = ptr.resolve_mut();
64 let copy_len = std::cmp::min(layout.size(), new_layout.size());
65 new_res.raw().copy_from(old_res.raw(), copy_len);
66 }
67 }
68 Ok(new_alloc)
69 }
70}
71
72/// Allocator ensures that all allocations will take place within one object.
73pub trait SingleObjectAllocator {}