diff --git a/port/src/bitmapalloc.rs b/port/src/bitmapalloc.rs index 110a4f7..cc917e7 100644 --- a/port/src/bitmapalloc.rs +++ b/port/src/bitmapalloc.rs @@ -13,6 +13,7 @@ impl Bitmap { Self { bytes: [init_value; SIZE_BYTES] } } + /// Is bit `i` within the bitmap set? pub fn is_set(&self, i: usize) -> bool { let byteidx = i / 8; let bitidx = i % 8; @@ -20,6 +21,7 @@ impl Bitmap { byte & (1 << bitidx) > 0 } + /// Set bit `i` within the bitmap pub fn set(&mut self, i: usize, b: bool) { let byteidx = i / 8; let bitidx = i % 8; @@ -149,17 +151,13 @@ impl return Err(BitmapPageAllocError::OutOfBounds); } - let bytes_per_bitmap = self.bytes_per_bitmap(); - let bitmap_idx = pa.addr() as usize / bytes_per_bitmap; - - let offset_into_bitmap = pa.addr() as usize % bytes_per_bitmap; - let bitmap_byte_idx = offset_into_bitmap / self.alloc_page_size; + let (bitmap_idx, bit_idx) = self.physaddr_as_indices(pa); let bitmap = &mut self.bitmaps[bitmap_idx]; - if !bitmap.is_set(bitmap_byte_idx) { + if !bitmap.is_set(bit_idx) { return Err(BitmapPageAllocError::NotAllocated); } - bitmap.set(bitmap_byte_idx, false); + bitmap.set(bit_idx, false); Ok(()) } @@ -176,6 +174,20 @@ impl (total - free_bytes, total) } + /// For the given physaddr, returns a tuple of + /// (the bitmap containing pa, and the index of the bit within that bitmap). + fn physaddr_as_indices(&self, pa: PhysAddr) -> (usize, usize) { + // Get the index of the bitmap containing the pa + let bytes_per_bitmap = self.bytes_per_bitmap(); + let bitmap_idx = pa.addr() as usize / bytes_per_bitmap; + + // Get the bit within the bitmap representing the pa + let pa_offset_into_bitmap = pa.addr() as usize % bytes_per_bitmap; + let bit_idx = pa_offset_into_bitmap / self.alloc_page_size; + + (bitmap_idx, bit_idx) + } + fn mark_range( &mut self, range: &PhysRange, @@ -186,18 +198,14 @@ impl return Err(BitmapPageAllocError::OutOfBounds); } - let bytes_per_bitmap = self.bytes_per_bitmap(); for pa in range.step_by_rounded(self.alloc_page_size) { - let bitmap_idx = pa.addr() as usize / bytes_per_bitmap; + let (bitmap_idx, bit_idx) = self.physaddr_as_indices(pa); if bitmap_idx >= self.bitmaps.len() { return Err(BitmapPageAllocError::OutOfBounds); } - let offset_into_bitmap = pa.addr() as usize % bytes_per_bitmap; - let bitmap_byte_idx = offset_into_bitmap / self.alloc_page_size; - let bitmap = &mut self.bitmaps[bitmap_idx]; - bitmap.set(bitmap_byte_idx, mark_allocated); + bitmap.set(bit_idx, mark_allocated); } Ok(()) }