@@ -56,6 +56,14 @@ impl AtomicBitmap {
56
56
/// is for the page corresponding to `start_addr`, and the last bit that we set corresponds
57
57
/// to address `start_addr + len - 1`.
58
58
pub fn set_addr_range ( & self , start_addr : usize , len : usize ) {
59
+ self . set_reset_addr_range ( start_addr, len, true ) ;
60
+ }
61
+
62
+ // Set/Reset a range of `len` bytes starting at `start_addr`
63
+ // reset parameter determines whether bit will be set/reset
64
+ // if set is true then the range of bits will be set to one,
65
+ // otherwise zero
66
+ fn set_reset_addr_range ( & self , start_addr : usize , len : usize , set : bool ) {
59
67
// Return early in the unlikely event that `len == 0` so the `len - 1` computation
60
68
// below does not underflow.
61
69
if len == 0 {
@@ -71,8 +79,37 @@ impl AtomicBitmap {
71
79
// Attempts to set bits beyond the end of the bitmap are simply ignored.
72
80
break ;
73
81
}
74
- self . map [ n >> 6 ] . fetch_or ( 1 << ( n & 63 ) , Ordering :: SeqCst ) ;
82
+ if set {
83
+ self . map [ n >> 6 ] . fetch_or ( 1 << ( n & 63 ) , Ordering :: SeqCst ) ;
84
+ } else {
85
+ self . map [ n >> 6 ] . fetch_and ( !( 1 << ( n & 63 ) ) , Ordering :: SeqCst ) ;
86
+ }
87
+ }
88
+ }
89
+
90
+ /// Reset a range of `len` bytes starting at `start_addr`. The first bit set in the bitmap
91
+ /// is for the page corresponding to `start_addr`, and the last bit that we set corresponds
92
+ /// to address `start_addr + len - 1`.
93
+ pub fn reset_addr_range ( & self , start_addr : usize , len : usize ) {
94
+ self . set_reset_addr_range ( start_addr, len, false ) ;
95
+ }
96
+
97
+ /// Set bit to corresponding index
98
+ pub fn set_bit ( & self , index : usize ) {
99
+ if index >= self . size {
100
+ // Attempts to set bits beyond the end of the bitmap are simply ignored.
101
+ return ;
102
+ }
103
+ self . map [ index >> 6 ] . fetch_or ( 1 << ( index & 63 ) , Ordering :: SeqCst ) ;
104
+ }
105
+
106
+ /// Reset bit to corresponding index
107
+ pub fn reset_bit ( & self , index : usize ) {
108
+ if index >= self . size {
109
+ // Attempts to reset bits beyond the end of the bitmap are simply ignored.
110
+ return ;
75
111
}
112
+ self . map [ index >> 6 ] . fetch_and ( !( 1 << ( index & 63 ) ) , Ordering :: SeqCst ) ;
76
113
}
77
114
78
115
/// Get the length of the bitmap in bits (i.e. in how many pages it can represent).
@@ -208,6 +245,23 @@ mod tests {
208
245
assert_eq ! ( v[ 0 ] , 0b110 ) ;
209
246
}
210
247
248
+ #[ test]
249
+ fn test_bitmap_reset ( ) {
250
+ let b = AtomicBitmap :: new ( 1024 , DEFAULT_PAGE_SIZE ) ;
251
+ assert_eq ! ( b. len( ) , 8 ) ;
252
+ b. set_addr_range ( 128 , 129 ) ;
253
+ assert ! ( !b. is_addr_set( 0 ) ) ;
254
+ assert ! ( b. is_addr_set( 128 ) ) ;
255
+ assert ! ( b. is_addr_set( 256 ) ) ;
256
+ assert ! ( !b. is_addr_set( 384 ) ) ;
257
+
258
+ b. reset_addr_range ( 128 , 129 ) ;
259
+ assert ! ( !b. is_addr_set( 0 ) ) ;
260
+ assert ! ( !b. is_addr_set( 128 ) ) ;
261
+ assert ! ( !b. is_addr_set( 256 ) ) ;
262
+ assert ! ( !b. is_addr_set( 384 ) ) ;
263
+ }
264
+
211
265
#[ test]
212
266
fn test_bitmap_out_of_range ( ) {
213
267
let b = AtomicBitmap :: new ( 1024 , NonZeroUsize :: MIN ) ;
0 commit comments