summaryrefslogtreecommitdiff
path: root/crates/alloc_buddy/src/free_list.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/alloc_buddy/src/free_list.rs')
-rw-r--r--crates/alloc_buddy/src/free_list.rs32
1 files changed, 22 insertions, 10 deletions
diff --git a/crates/alloc_buddy/src/free_list.rs b/crates/alloc_buddy/src/free_list.rs
index 9b470fd..973ad2c 100644
--- a/crates/alloc_buddy/src/free_list.rs
+++ b/crates/alloc_buddy/src/free_list.rs
@@ -56,16 +56,7 @@ impl FreeList {
unsafe {
// UNWRAP: In a valid circular doubly-linked list, the pointers are all non-null.
let node = (*self.0.as_ptr()).next.unwrap();
- let prev = (*node.as_ptr()).prev.unwrap();
- let next = (*node.as_ptr()).next.unwrap();
-
- (*prev.as_ptr()).next = Some(next);
- (*next.as_ptr()).prev = Some(prev);
-
- (*node.as_ptr()).next = None;
- (*node.as_ptr()).prev = None;
- (*node.as_ptr()).magic = USED_NODE_MAGIC;
- Some(node.cast())
+ Some(FreeListNode::unlink(node))
}
}
}
@@ -161,4 +152,25 @@ impl FreeListNode {
});
ptr
}
+
+ /// Unlinks the node from the circular doubly-linked list.
+ ///
+ /// # Safety
+ ///
+ /// The pointer must be a non-sentinel node inside a valid free list.
+ #[requires(unsafe { (*node.as_ptr()).magic } == FREE_NODE_MAGIC)]
+ #[requires(unsafe { (*node.as_ptr()).self_addr } == node.as_ptr() as usize)]
+ pub unsafe fn unlink(node: NonNull<FreeListNode>) -> NonNull<u8> {
+ // UNWRAP: In a valid circular doubly-linked list, the pointers are all non-null.
+ let prev = (*node.as_ptr()).prev.unwrap();
+ let next = (*node.as_ptr()).next.unwrap();
+
+ (*prev.as_ptr()).next = Some(next);
+ (*next.as_ptr()).prev = Some(prev);
+
+ (*node.as_ptr()).next = None;
+ (*node.as_ptr()).prev = None;
+ (*node.as_ptr()).magic = USED_NODE_MAGIC;
+ node.cast()
+ }
}