From 1867170d185c3480542773a74876175e341b91eb Mon Sep 17 00:00:00 2001 From: Nathan Ringo Date: Sun, 1 Sep 2024 18:32:38 -0500 Subject: Simplify debug printing of the buddy allocator. --- crates/alloc_buddy/src/lib.rs | 98 +++++++++++++++++++++++++++++-------------- 1 file changed, 66 insertions(+), 32 deletions(-) (limited to 'crates/alloc_buddy/src/lib.rs') diff --git a/crates/alloc_buddy/src/lib.rs b/crates/alloc_buddy/src/lib.rs index a2a509b..bbed640 100644 --- a/crates/alloc_buddy/src/lib.rs +++ b/crates/alloc_buddy/src/lib.rs @@ -14,6 +14,7 @@ use allocator_api2::alloc::{AllocError, Layout, LayoutError}; use contracts::{ensures, requires}; use core::{fmt, mem, ptr::NonNull}; use vernos_alloc_physmem_free_list::FreeListAllocator; +use vernos_utils::debug; /// A buddy allocator. pub struct BuddyAllocator< @@ -409,42 +410,75 @@ impl< > fmt::Debug for BuddyAllocator<'allocator, PAGE_SIZE, PAGE_SIZE_BITS, SIZE_CLASS_COUNT> { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - struct FreeLists(NonNull); - - impl fmt::Debug for FreeLists { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_list() - .entries((0..SIZE_CLASS_COUNT).map(|size_class| { - // SAFETY: The free lists are kept valid, and the range of size classes is - // necessarily in-bounds. - unsafe { FreeList::from_sentinel(self.0.add(size_class)) } - })) - .finish() - } - } - - struct Bitsets<'allocator, const PAGE_SIZE: usize, const PAGE_SIZE_BITS: usize>( - &'allocator [Tree], - &'allocator Bitset, - ); - - impl<'allocator, const PAGE_SIZE: usize, const PAGE_SIZE_BITS: usize> fmt::Debug - for Bitsets<'allocator, PAGE_SIZE, PAGE_SIZE_BITS> - { - fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { - fmt.debug_list() - .entries(self.0.iter().map(|tree| tree.debug_bitset(self.1))) - .finish() - } - } - fmt.debug_struct("BuddyAllocator") .field( "free_lists", - &FreeLists::(self.free_list_sentinels), + &debug(|fmt| { + fmt.debug_list() + .entries((0..SIZE_CLASS_COUNT).map(|size_class| { + // SAFETY: The free lists are kept valid, and the range of size classes is + // necessarily in-bounds. + unsafe { + FreeList::from_sentinel(self.free_list_sentinels.add(size_class)) + } + })) + .finish() + }), + ) + .field( + "trees", + &debug(|fmt| { + fmt.debug_list() + .entries(self.trees.iter().map(|tree| { + let ptr_lo = tree.base_ptr.unwrap().as_ptr(); + let ptr_hi = ptr_lo.wrapping_add(1 << tree.size_class); + debug(move |fmt| { + fmt.debug_tuple("Tree") + .field(&debug(|fmt| { + write!( + fmt, + "{:?} ({} pages)", + (ptr_lo..ptr_hi), + 1 << tree.size_class + ) + })) + .field(&debug(move |fmt| { + fmt.debug_list() + .entries((0..=tree.size_class).rev().map( + |size_class| { + debug(move |fmt| { + for i in + 0..(1 << (tree.size_class - size_class)) + { + let offset_bytes = + i << (PAGE_SIZE_BITS + size_class); + let bit = match tree.bitset_get( + self.bitset, + size_class, + offset_bytes, + ) { + SubregionStatus::NotInFreeList => { + '0' + } + SubregionStatus::InFreeList => '1', + }; + write!(fmt, "{}", bit)?; + for _ in 0..(1 << size_class) - 1 { + write!(fmt, " ")?; + } + } + Ok(()) + }) + }, + )) + .finish() + })) + .finish() + }) + })) + .finish() + }), ) - .field("trees", &self.trees) - .field("bitsets", &Bitsets(self.trees, self.bitset)) .finish() } } -- cgit v1.2.3