diff options
Diffstat (limited to 'crates/alloc_buddy/src/free_list.rs')
-rw-r--r-- | crates/alloc_buddy/src/free_list.rs | 32 |
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() + } } |