Skip to content

Commit

Permalink
utils/bitmap: permit construction of empty bitmap allocators
Browse files Browse the repository at this point in the history
There are cases where it is useful to initialize a bitmap allocator with
all bits clear (signifying that the bitmap is empty) as well as
initializing the allocator with all bits set (signifying that the bitmap
is full).

Signed-off-by: Jon Lange <jlange@microsoft.com>
  • Loading branch information
msft-jlange committed Jan 2, 2025
1 parent 489d572 commit 7c58924
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 15 deletions.
4 changes: 2 additions & 2 deletions fuzz/fuzz_targets/bitmap_allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,8 @@ impl TestBitmapAllocator for BitmapAllocator1024 {
}

fuzz_target!(|actions: Vec<BmaAction>| {
let mut bma64 = BitmapAllocator64::new();
let mut bma1024 = BitmapAllocator1024::new();
let mut bma64 = BitmapAllocator64::new_full();
let mut bma1024 = BitmapAllocator1024::new_full();
for action in actions.iter() {
let bma64_before = bma64;
let bma1024_before = bma1024.clone();
Expand Down
2 changes: 1 addition & 1 deletion kernel/src/mm/virtualrange.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl VirtualRange {
start_virt: VirtAddr::null(),
page_count: 0,
page_shift: PAGE_SHIFT,
bits: BitmapAllocator1024::new(),
bits: BitmapAllocator1024::new_full(),
}
}

Expand Down
44 changes: 32 additions & 12 deletions kernel/src/utils/bitmap_allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,14 @@ pub struct BitmapAllocator64 {
}

impl BitmapAllocator64 {
pub const fn new() -> Self {
pub const fn new_full() -> Self {
Self { bits: u64::MAX }
}

pub const fn new_empty() -> Self {
Self { bits: 0 }
}

#[cfg(fuzzing)]
pub fn get_bits(&self) -> u64 {
self.bits
Expand Down Expand Up @@ -101,10 +105,17 @@ pub struct BitmapAllocatorTree<T: BitmapAllocator + Debug> {
}

impl BitmapAllocatorTree<BitmapAllocator64> {
pub const fn new() -> Self {
pub const fn new_full() -> Self {
Self {
bits: u16::MAX,
child: [BitmapAllocator64::new(); 16],
child: [BitmapAllocator64::new_full(); 16],
}
}

pub const fn new_empty() -> Self {
Self {
bits: 0,
child: [BitmapAllocator64::new_empty(); 16],
}
}

Expand Down Expand Up @@ -362,7 +373,7 @@ mod tests {

#[test]
fn tree_set_all() {
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new();
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new_full();
b.set(0, 64 * 16, false);
for i in 0..16 {
assert_eq!(b.child[i].bits, 0);
Expand All @@ -373,7 +384,7 @@ mod tests {

#[test]
fn tree_clear_all() {
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new();
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new_full();
b.set(0, 64 * 16, true);
for i in 0..16 {
assert_eq!(b.child[i].bits, u64::MAX);
Expand All @@ -384,7 +395,7 @@ mod tests {

#[test]
fn tree_set_some() {
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new();
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new_full();

// First child
b.set(0, BitmapAllocatorTree::<BitmapAllocator64>::CAPACITY, false);
Expand Down Expand Up @@ -430,17 +441,26 @@ mod tests {

#[test]
fn tree_alloc_simple() {
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new();
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new_full();
b.set(0, BitmapAllocatorTree::<BitmapAllocator64>::CAPACITY, false);
for i in 0..256 {
assert_eq!(b.alloc(1, 0), Some(i));
}
assert_eq!(b.used(), 256);
}

#[test]
fn tree_alloc_empty_simple() {
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new_empty();
for i in 0..256 {
assert_eq!(b.alloc(1, 0), Some(i));
}
assert_eq!(b.used(), 256);
}

#[test]
fn tree_alloc_aligned() {
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new();
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new_full();
b.set(0, BitmapAllocatorTree::<BitmapAllocator64>::CAPACITY, false);
// Alignment of 1 << 5 bits : 32 bit alignment
assert_eq!(b.alloc(1, 5), Some(0));
Expand All @@ -454,7 +474,7 @@ mod tests {

#[test]
fn tree_alloc_large_aligned() {
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new();
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new_full();
b.set(0, BitmapAllocatorTree::<BitmapAllocator64>::CAPACITY, false);
// Alignment of 1 << 4 bits : 16 bit alignment
assert_eq!(b.alloc(500, 4), Some(0));
Expand All @@ -464,7 +484,7 @@ mod tests {

#[test]
fn tree_alloc_out_of_space() {
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new();
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new_full();
b.set(0, BitmapAllocatorTree::<BitmapAllocator64>::CAPACITY, false);
// Alignment of 1 << 4 bits : 16 bit alignment
assert_eq!(b.alloc(1000, 4), Some(0));
Expand All @@ -477,7 +497,7 @@ mod tests {

#[test]
fn tree_free_space() {
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new();
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new_full();
b.set(0, BitmapAllocatorTree::<BitmapAllocator64>::CAPACITY, false);
// Alignment of 1 << 4 bits : 16 bit alignment
assert_eq!(
Expand All @@ -492,7 +512,7 @@ mod tests {

#[test]
fn tree_free_multiple() {
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new();
let mut b = BitmapAllocatorTree::<BitmapAllocator64>::new_full();
b.set(0, BitmapAllocatorTree::<BitmapAllocator64>::CAPACITY, true);
b.free(0, 16);
b.free(765, 16);
Expand Down

0 comments on commit 7c58924

Please sign in to comment.