Skip to content

Commit 4bdfad5

Browse files
committed
feat(bitmap): 实现位图分配器并添加预分配版本
1 parent 0a25f40 commit 4bdfad5

File tree

1 file changed

+71
-1
lines changed

1 file changed

+71
-1
lines changed

kernel/src/libs/bitmap.rs

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,82 @@
22
//!
33
//! A simple bitset implementation for tracking allocation status of resources.
44
5+
use core::mem::MaybeUninit;
6+
57
/// A simple bitmap for tracking free/allocated slots.
68
pub struct BitMap<const N: usize> {
7-
bits: [u64; N],
9+
bits: MaybeUninit<[u64; N]>,
810
}
911

1012
impl<const N: usize> BitMap<N> {
13+
/// Create a new bitmap with all bits set to 0 (all slots free).
14+
pub const fn new() -> Self {
15+
let bits = MaybeUninit::new([0; N]);
16+
Self { bits }
17+
}
18+
19+
/// Mark a bit as allocated (1).
20+
pub fn set(&mut self, index: usize) {
21+
let word = index / 64;
22+
let bit = index % 64;
23+
if word < N {
24+
unsafe {
25+
self.bits.assume_init_mut()[word] |= 1 << bit;
26+
}
27+
}
28+
}
29+
30+
/// Mark a bit as free (0).
31+
pub fn clear(&mut self, index: usize) {
32+
let word = index / 64;
33+
let bit = index % 64;
34+
if word < N {
35+
unsafe {
36+
self.bits.assume_init_mut()[word] &= !(1 << bit);
37+
}
38+
}
39+
}
40+
41+
/// Check if a bit is set (allocated).
42+
pub fn test(&self, index: usize) -> bool {
43+
let word = index / 64;
44+
let bit = index % 64;
45+
if word < N {
46+
unsafe { (self.bits.assume_init_ref()[word] & (1 << bit)) != 0 }
47+
} else {
48+
true // Out of bounds is considered allocated
49+
}
50+
}
51+
52+
/// Find the first free slot (0 bit) and mark it as allocated (1).
53+
pub fn alloc(&mut self) -> Option<usize> {
54+
for i in 0..N {
55+
unsafe {
56+
// Safety: We know that the bitmap is initialized
57+
let bits_ref = self.bits.assume_init_mut();
58+
if bits_ref[i] != u64::MAX {
59+
// Find first trailing one bit in the inverted word
60+
// which is the first zero bit in the original word.
61+
let bit = (!bits_ref[i]).trailing_zeros() as usize;
62+
bits_ref[i] |= 1 << bit;
63+
return Some(i * 64 + bit);
64+
}
65+
}
66+
}
67+
None
68+
}
69+
70+
/// Get total capacity of the bitmap.
71+
pub const fn capacity(&self) -> usize {
72+
N * 64
73+
}
74+
}
75+
76+
pub struct PreAllocBitMap<const N: usize> {
77+
bits: [u64; N],
78+
}
79+
80+
impl<const N: usize> PreAllocBitMap<N> {
1181
/// Create a new bitmap with all bits set to 0 (all slots free).
1282
pub const fn new() -> Self {
1383
Self { bits: [0; N] }

0 commit comments

Comments
 (0)