@@ -656,10 +656,9 @@ fn deallocate(list: &mut HoleList, addr: *mut u8, size: usize) {
656656
657657#[ cfg( test) ]
658658pub mod test {
659+ use super :: HoleList ;
659660 use crate :: Heap ;
660- use core:: alloc:: Layout ;
661- use std:: mem:: MaybeUninit ;
662- use std:: prelude:: v1:: * ;
661+ use std:: { alloc:: Layout , convert:: TryInto , mem:: MaybeUninit , prelude:: v1:: * , ptr:: NonNull } ;
663662
664663 #[ repr( align( 128 ) ) ]
665664 struct Chonk < const N : usize > {
@@ -704,4 +703,70 @@ pub mod test {
704703 let reqd = Layout :: from_size_align ( 256 , 1 ) . unwrap ( ) ;
705704 let _ = heap. allocate_first_fit ( reqd) . unwrap ( ) ;
706705 }
706+
707+ /// Tests `HoleList::new` with the minimal allowed `hole_size`.
708+ #[ test]
709+ fn hole_list_new_min_size ( ) {
710+ // define an array of `u64` instead of `u8` for alignment
711+ static mut HEAP : [ u64 ; 2 ] = [ 0 ; 2 ] ;
712+ let heap =
713+ unsafe { HoleList :: new ( HEAP . as_mut_ptr ( ) . cast ( ) , 2 * core:: mem:: size_of :: < usize > ( ) ) } ;
714+ assert_eq ! ( heap. bottom. cast( ) , unsafe { HEAP . as_mut_ptr( ) } ) ;
715+ assert_eq ! ( heap. top. cast( ) , unsafe { HEAP . as_mut_ptr( ) . add( 2 ) } ) ;
716+ assert_eq ! ( heap. first. size, 0 ) ; // dummy
717+ assert_eq ! (
718+ heap. first. next,
719+ Some ( NonNull :: new( heap. bottom. cast( ) ) ) . unwrap( )
720+ ) ;
721+ assert_eq ! (
722+ unsafe { & * ( heap. first. next. unwrap( ) . as_ptr( ) ) } . size,
723+ 2 * core:: mem:: size_of:: <usize >( )
724+ ) ;
725+ assert_eq ! ( unsafe { & * ( heap. first. next. unwrap( ) . as_ptr( ) ) } . next, None ) ;
726+ }
727+
728+ /// Tests that `HoleList::new` aligns the `hole_addr` correctly and adjusts the size
729+ /// accordingly.
730+ #[ test]
731+ fn hole_list_new_align ( ) {
732+ // define an array of `u64` instead of `u8` for alignment
733+ static mut HEAP : [ u64 ; 3 ] = [ 0 ; 3 ] ;
734+
735+ let heap_start: * mut u8 = unsafe { HEAP . as_mut_ptr ( ) . add ( 1 ) } . cast ( ) ;
736+ // initialize the HoleList with a hole_addr one byte before `heap_start`
737+ // -> the function should align it up to `heap_start`
738+ let heap =
739+ unsafe { HoleList :: new ( heap_start. sub ( 1 ) , 2 * core:: mem:: size_of :: < usize > ( ) + 1 ) } ;
740+ assert_eq ! ( heap. bottom, heap_start) ;
741+ assert_eq ! ( heap. top. cast( ) , unsafe {
742+ // one byte less than the `hole_size` given to `new` because of alignment
743+ heap_start. add( 2 * core:: mem:: size_of:: <usize >( ) )
744+ } ) ;
745+
746+ assert_eq ! ( heap. first. size, 0 ) ; // dummy
747+ assert_eq ! (
748+ heap. first. next,
749+ Some ( NonNull :: new( heap. bottom. cast( ) ) ) . unwrap( )
750+ ) ;
751+ assert_eq ! (
752+ unsafe { & * ( heap. first. next. unwrap( ) . as_ptr( ) ) } . size,
753+ unsafe { heap. top. offset_from( heap. bottom) }
754+ . try_into( )
755+ . unwrap( )
756+ ) ;
757+ assert_eq ! ( unsafe { & * ( heap. first. next. unwrap( ) . as_ptr( ) ) } . next, None ) ;
758+ }
759+
760+ #[ test]
761+ #[ should_panic]
762+ fn hole_list_new_too_small ( ) {
763+ // define an array of `u64` instead of `u8` for alignment
764+ static mut HEAP : [ u64 ; 3 ] = [ 0 ; 3 ] ;
765+
766+ let heap_start: * mut u8 = unsafe { HEAP . as_mut_ptr ( ) . add ( 1 ) } . cast ( ) ;
767+ // initialize the HoleList with a hole_addr one byte before `heap_start`
768+ // -> the function should align it up to `heap_start`, but then the
769+ // available size is too small to store a hole -> it should panic
770+ unsafe { HoleList :: new ( heap_start. sub ( 1 ) , 2 * core:: mem:: size_of :: < usize > ( ) ) } ;
771+ }
707772}
0 commit comments