MCPcopy Create free account
hub / github.com/bendudson/EuraliOS / consecutive_frames

Method consecutive_frames

kernel/src/memory/frame_allocator.rs:302–368  ·  view source on GitHub ↗

Allocate a consecutive set of frames num_frames The number of frames required max_address The maximum physical address in the set e.g. for 32-bit addresses 0xFFFF_FFFF Returns the number of the first frame, or None if a set could not be found. Brute force search of lowest level bitmap. This is not very efficient, and is not intended to be called in performance-critical code.

(
        &mut self,
        needed_frames: u64,
        max_address: u64
    )

Source from the content-addressed store, hash-verified

300 /// very efficient, and is not intended to be called in
301 /// performance-critical code.
302 fn consecutive_frames(
303 &mut self,
304 needed_frames: u64,
305 max_address: u64
306 ) -> Option<u64> {
307 // Ensure that there is at least one frame in range
308 if max_address < (self.frame_phys_addr.as_u64() + 4095) {
309 return None;
310 }
311
312 // Restrict the number of frames to those under the address limit
313 let max_frames = (max_address + 1 - self.frame_phys_addr.as_u64()) >> 12;
314 let nframes = if max_frames < self.nframes {max_frames} else {self.nframes};
315
316 // Number of 32-bit chunks to search
317 let nchunks = (nframes >> 5) + if nframes & 31 != 0 {1} else {0};
318
319 // Pointer to lowest level frame bitmap
320 let ptr = self.bitmap_virt_addr[0].as_mut_ptr() as *mut u32;
321
322 let mut count = 0; // How many consecutive frames found so far?
323 for chunk in 0..nchunks {
324 let bitmap = unsafe{*ptr.offset(chunk as isize)};
325
326 for pos in 0..32 {
327 if bitmap & (1 << pos) == 0 {
328 // Not available
329 count = 0;
330 } else {
331 // Available frame
332 count += 1;
333 if count == needed_frames {
334 // Found a consecutive set of frames
335 let start_frame = (chunk << 5) + pos + 1 - count;
336
337 // Mark each frame as taken
338 for frame in start_frame..(start_frame + needed_frames) {
339 let mut chunk_number = frame;
340
341 // Clear higher bitmaps if the chunk is empty
342 for level in 0..self.nlevels {
343 // Low 5 bits of the chunk at the lower level are the index at this level
344 let index = chunk_number & 31;
345 // High bits are the chunk at this level
346 chunk_number = chunk_number >> 5;
347
348 let ptr = unsafe{(self.bitmap_virt_addr[level].as_mut_ptr() as *mut u32)
349 .offset(chunk_number as isize)};
350 let mut bitmap = unsafe{*ptr};
351
352 bitmap &= !(1 << index); // clear bit
353 unsafe {core::ptr::write(ptr, bitmap)};
354
355 if bitmap != 0 {
356 // This chunk still has frames => stop clearing
357 break;
358 }
359 }

Callers 1

Calls 2

as_mut_ptrMethod · 0.80
as_u64Method · 0.45

Tested by

no test coverage detected