@@ -350,3 +350,110 @@ impl FrameDeallocator<Size4KiB> for BitmapFrameAllocator {
350
350
) ;
351
351
}
352
352
}
353
+
354
+ #[ test_case]
355
+ fn bitmap_frame_allocator ( ) {
356
+ use bootloader:: bootinfo:: FrameRange ;
357
+ let regions = [
358
+ MemoryRegion {
359
+ range : FrameRange {
360
+ start_frame_number : 0u64 ,
361
+ end_frame_number : 1u64 ,
362
+ } ,
363
+ region_type : MemoryRegionType :: FrameZero ,
364
+ } ,
365
+ MemoryRegion {
366
+ range : FrameRange {
367
+ start_frame_number : 1u64 ,
368
+ end_frame_number : 4u64 ,
369
+ } ,
370
+ region_type : MemoryRegionType :: Reserved ,
371
+ } ,
372
+ MemoryRegion {
373
+ range : FrameRange {
374
+ start_frame_number : 4u64 ,
375
+ end_frame_number : 8u64 ,
376
+ } ,
377
+ region_type : MemoryRegionType :: Usable ,
378
+ } ,
379
+ MemoryRegion {
380
+ range : FrameRange {
381
+ start_frame_number : 8u64 ,
382
+ end_frame_number : 12u64 ,
383
+ } ,
384
+ region_type : MemoryRegionType :: Reserved ,
385
+ } ,
386
+ MemoryRegion {
387
+ range : FrameRange {
388
+ start_frame_number : 12u64 ,
389
+ end_frame_number : 14u64 ,
390
+ } ,
391
+ region_type : MemoryRegionType :: Usable ,
392
+ } ,
393
+ ] ;
394
+
395
+ let mut alloc = unsafe { BitmapFrameAllocator :: new ( regions. iter ( ) ) } ;
396
+ assert_eq ! ( alloc. num_frames, 6u64 ) ;
397
+ assert_eq ! ( alloc. free_frames, 6u64 ) ;
398
+
399
+ // Helper function to speed up making frames.
400
+ fn frame_for ( addr : u64 ) -> PhysFrame {
401
+ let start_addr = PhysAddr :: new ( addr) ;
402
+ let frame = PhysFrame :: from_start_address ( start_addr) . unwrap ( ) ;
403
+ frame
404
+ }
405
+
406
+ // Do some allocations.
407
+ assert_eq ! ( alloc. allocate_frame( ) , Some ( frame_for( 0x4000 ) ) ) ;
408
+ assert_eq ! ( alloc. num_frames, 6u64 ) ;
409
+ assert_eq ! ( alloc. free_frames, 5u64 ) ;
410
+ assert_eq ! ( alloc. allocate_frame( ) , Some ( frame_for( 0x5000 ) ) ) ;
411
+ assert_eq ! ( alloc. num_frames, 6u64 ) ;
412
+ assert_eq ! ( alloc. free_frames, 4u64 ) ;
413
+
414
+ // Do a free.
415
+ unsafe { alloc. deallocate_frame ( frame_for ( 0x4000 ) ) } ;
416
+ assert_eq ! ( alloc. num_frames, 6u64 ) ;
417
+ assert_eq ! ( alloc. free_frames, 5u64 ) ;
418
+
419
+ // Next allocation should return the address we just freed.
420
+ assert_eq ! ( alloc. allocate_frame( ) , Some ( frame_for( 0x4000 ) ) ) ;
421
+ assert_eq ! ( alloc. num_frames, 6u64 ) ;
422
+ assert_eq ! ( alloc. free_frames, 4u64 ) ;
423
+
424
+ // Check that all remaining allocations are as we expect.
425
+ assert_eq ! ( alloc. allocate_frame( ) , Some ( frame_for( 0x6000 ) ) ) ;
426
+ assert_eq ! ( alloc. allocate_frame( ) , Some ( frame_for( 0x7000 ) ) ) ;
427
+ assert_eq ! ( alloc. allocate_frame( ) , Some ( frame_for( 0xc000 ) ) ) ;
428
+ assert_eq ! ( alloc. allocate_frame( ) , Some ( frame_for( 0xd000 ) ) ) ;
429
+ assert_eq ! ( alloc. num_frames, 6u64 ) ;
430
+ assert_eq ! ( alloc. free_frames, 0u64 ) ;
431
+
432
+ // Check that we get nothing once we run out of frames.
433
+ assert_eq ! ( alloc. allocate_frame( ) , None ) ;
434
+ assert_eq ! ( alloc. num_frames, 6u64 ) ;
435
+ assert_eq ! ( alloc. free_frames, 0u64 ) ;
436
+
437
+ // Check that sequential allocations work correctly.
438
+
439
+ // Deallocate 2 non-sequential frames, expect None.
440
+ unsafe { alloc. deallocate_frame ( frame_for ( 0x5000 ) ) } ;
441
+ unsafe { alloc. deallocate_frame ( frame_for ( 0x7000 ) ) } ;
442
+ assert_eq ! ( alloc. allocate_n_frames( 2 ) , None ) ;
443
+
444
+ // Leave 2 sequential frames, check we get the right pair.
445
+ // Note: we use PhysFrameRange, not PhysFrameRangeInclusive.
446
+ assert_eq ! ( alloc. allocate_frame( ) , Some ( frame_for( 0x5000 ) ) ) ;
447
+ unsafe { alloc. deallocate_frame ( frame_for ( 0x6000 ) ) } ;
448
+ assert_eq ! (
449
+ alloc. allocate_n_frames( 2 ) ,
450
+ Some ( PhysFrameRange {
451
+ start: frame_for( 0x6000 ) ,
452
+ end: frame_for( 0x8000 ) // exclusive
453
+ } )
454
+ ) ;
455
+
456
+ // Check that we get nothing once we run out of frames.
457
+ assert_eq ! ( alloc. num_frames, 6u64 ) ;
458
+ assert_eq ! ( alloc. free_frames, 0u64 ) ;
459
+ }
0 commit comments