summaryrefslogtreecommitdiff
path: root/crates/buddy_allocator/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/buddy_allocator/src/lib.rs')
-rw-r--r--crates/buddy_allocator/src/lib.rs27
1 files changed, 13 insertions, 14 deletions
diff --git a/crates/buddy_allocator/src/lib.rs b/crates/buddy_allocator/src/lib.rs
index f0c8daa..c543ca6 100644
--- a/crates/buddy_allocator/src/lib.rs
+++ b/crates/buddy_allocator/src/lib.rs
@@ -48,8 +48,6 @@ mod bitvec;
mod free_list;
mod tree;
-// mod stripe;
-
use crate::{
bitvec::{Bitset, SubregionStatus},
free_list::{FreeList, FreeListNode},
@@ -176,7 +174,7 @@ impl<
while let Some((ptr, mut len_pages)) = free_list_alloc.pop() {
while len_pages > 0 {
let size_class = (len_pages.trailing_zeros() as usize).min(SIZE_CLASS_COUNT - 1);
- trees[i].base_ptr = ptr.cast().as_ptr();
+ trees[i].base_ptr = Some(ptr.cast());
trees[i].size_class = size_class;
i += 1;
len_pages -= 1 << size_class;
@@ -192,7 +190,7 @@ impl<
// Slice the trees slice to fit how many trees actually remained, then sort them by
// address.
let trees = &mut trees[..i];
- trees.sort_by_key(|tree| tree.base_ptr as usize);
+ trees.sort_by_key(|tree| tree.base_addr());
// Compute the number of bits that belong to each tree and assign them.
let mut bitset_offset = 0;
@@ -213,16 +211,12 @@ impl<
unsafe { metadata.cast::<u8>().add(metadata.len()).as_ptr() } as usize;
for tree in &mut *trees {
// SAFETY: This is the one-past-the-end address.
- let tree_addr_hi = unsafe { tree.base_ptr.add(1 << tree.size_class) } as usize;
+ let tree_addr_hi = tree.base_addr() + (PAGE_SIZE << tree.size_class);
if metadata_addr_hi == tree_addr_hi {
// If the metadata was present inside the tree... TODO.
std::eprintln!("TODO");
} else {
// Otherwise, we can take the whole range of the tree and add it to the free list.
- //
- // UNWRAP: The pointer must have been non-null when it was in the free-list
- // allocator.
- let ptr = NonNull::new(tree.base_ptr as *mut u8).unwrap();
// SAFETY: There are as many sentinels as size classes, so this will be in-bounds.
let sentinel = unsafe { free_list_sentinels.add(tree.size_class) };
@@ -233,7 +227,7 @@ impl<
// SAFETY: This region is not owned or borrowed by anything else (the only thing it
// could be would be the metadata, but that's not in this tree), is of the correct
// size, and is composed of untyped memory.
- unsafe { free_list.push(ptr) };
+ unsafe { free_list.push(tree.base_ptr.unwrap().cast()) };
// Then, set a bit in the bitset to say that this region is present.
tree.bitset_mark_as_present(bitset, tree.size_class, 0);
@@ -276,7 +270,7 @@ impl<
/// - `ptr` must have been returned by a call to `alloc` with the same `size_class`.
/// - `ptr` must convey ownership over the entire region.
#[requires(size_class < SIZE_CLASS_COUNT)]
- pub unsafe fn dealloc(&mut self, ptr: NonNull<u8>, mut size_class: usize) {
+ pub unsafe fn dealloc(&mut self, ptr: NonNull<u8>, size_class: usize) {
// Find the corresponding tree and the offset of the subregion in the tree.
let (tree_index, offset) = self.tree_index_and_offset(ptr);
let tree = &mut self.trees[tree_index];
@@ -288,12 +282,17 @@ impl<
);
// Start combining size classes.
+ assert!(size_class <= tree.size_class);
while size_class < tree.size_class {
let buddy_offset = offset ^ (PAGE_SIZE << size_class);
todo!("{buddy_offset:#x} {offset:#x}");
}
- todo!("{tree:#?}")
+ // Mark the pointer as being in the tree.
+ tree.bitset_mark_as_present(&mut self.bitset, size_class, offset);
+
+ // Return the pointer to the appropriate free list.
+ self.free_list(size_class).push(ptr);
}
/// Returns the free list with the given size class.
@@ -313,7 +312,7 @@ impl<
let addr = ptr.as_ptr() as usize;
let tree_index = self
.trees
- .binary_search_by_key(&addr, |tree| tree.base_ptr as usize);
+ .binary_search_by_key(&addr, |tree| tree.base_addr());
let tree_index = match tree_index {
Ok(i) => i,
Err(i) => {
@@ -321,7 +320,7 @@ impl<
i - 1
}
};
- let offset = addr - self.trees[tree_index].base_ptr as usize;
+ let offset = addr - self.trees[tree_index].base_addr();
(tree_index, offset)
}
}