Allocate a frame, returning the frame number in this allocation region.
(&mut self)
| 191 | /// Allocate a frame, returning the frame number in this |
| 192 | /// allocation region. |
| 193 | fn fetch_frame(&mut self) -> Option<u64> { |
| 194 | if self.frame_stack_number == 0 { |
| 195 | // Empty stack => Find more frames |
| 196 | |
| 197 | let mut chunk_number: u64 = 0; |
| 198 | for level in (1..self.nlevels).rev() { |
| 199 | let ptr = self.bitmap_virt_addr[level].as_ptr() as *const u32; |
| 200 | let bitmap = unsafe{*(ptr.offset(chunk_number as isize))}; |
| 201 | if bitmap == 0 { |
| 202 | return None; // Out of memory |
| 203 | } |
| 204 | chunk_number = chunk_number * 32 |
| 205 | + nonzero_bit_index(bitmap) as u64; |
| 206 | } |
| 207 | |
| 208 | // Get bitmap containing frame indices |
| 209 | let ptr = unsafe{(self.bitmap_virt_addr[0].as_mut_ptr() as *mut u32).offset(chunk_number as isize)}; |
| 210 | let mut bitmap = unsafe{*ptr}; |
| 211 | |
| 212 | // Take all frames and put them on the stack |
| 213 | while bitmap != 0 { |
| 214 | let index = nonzero_bit_index(bitmap); |
| 215 | let frame_number = chunk_number * 32 + index as u64; |
| 216 | bitmap ^= 1 << index; |
| 217 | self.frame_stack[self.frame_stack_number] = frame_number; |
| 218 | self.frame_stack_number += 1; |
| 219 | } |
| 220 | unsafe {core::ptr::write(ptr, 0)}; // Chunk now empty |
| 221 | |
| 222 | // Clear higher bitmaps if the chunk is empty |
| 223 | for level in 1..self.nlevels { |
| 224 | // Low 5 bits of the chunk at the lower level are the index at this level |
| 225 | let index = chunk_number & 31; |
| 226 | // High bits are the chunk at this level |
| 227 | chunk_number = chunk_number >> 5; |
| 228 | |
| 229 | let ptr = unsafe{(self.bitmap_virt_addr[level].as_mut_ptr() as *mut u32) |
| 230 | .offset(chunk_number as isize)}; |
| 231 | let mut bitmap = unsafe{*ptr}; |
| 232 | |
| 233 | bitmap &= !(1 << index); // clear bit |
| 234 | unsafe {core::ptr::write(ptr, bitmap)}; |
| 235 | |
| 236 | if bitmap != 0 { |
| 237 | // This chunk still has frames => stop clearing |
| 238 | break; |
| 239 | } |
| 240 | } |
| 241 | } |
| 242 | if self.frame_stack_number == 0 { |
| 243 | panic!("Stack still empty!") // bug! |
| 244 | } |
| 245 | // Stack now contains frames |
| 246 | self.frame_stack_number -= 1; |
| 247 | Some(self.frame_stack[self.frame_stack_number]) |
| 248 | } |
| 249 | |
| 250 | /// Put a frame back into the bitmap |