@@ -70,21 +70,43 @@ impl Heap {
7070 /// This function will panic if either of the following are true:
7171 ///
7272 /// - this function is called more than ONCE.
73- /// - `size == 0 `.
73+ /// - `size`, after aligning start and end to `rlsf::GRANULARITY`, is smaller than `rlsf::GRANULARITY * 2 `.
7474 pub unsafe fn init ( & self , start_addr : usize , size : usize ) {
7575 assert ! ( size > 0 ) ;
7676 critical_section:: with ( |cs| {
7777 let mut heap = self . heap . borrow_ref_mut ( cs) ;
7878 assert ! ( !heap. initialized) ;
79- heap. initialized = true ;
80- let block: NonNull < [ u8 ] > =
81- NonNull :: slice_from_raw_parts ( NonNull :: new_unchecked ( start_addr as * mut u8 ) , size) ;
82- heap. tlsf . insert_free_block_ptr ( block) ;
83- heap. raw_block = Some ( block) ;
84- heap. raw_block_size = size;
79+ // Work around https://github.com/yvt/rlsf/pull/21 by aligning block before passing
80+ // it to `Tlsf::insert_free_block_ptr`.
81+ if let Some ( ( aligned_start_addr, usable_size) ) = Self :: align ( start_addr, size) {
82+ let block: NonNull < [ u8 ] > = NonNull :: slice_from_raw_parts (
83+ NonNull :: new_unchecked ( aligned_start_addr as * mut u8 ) ,
84+ usable_size,
85+ ) ;
86+ if heap. tlsf . insert_free_block_ptr ( block) . is_some ( ) {
87+ heap. initialized = true ;
88+ heap. raw_block = Some ( block) ;
89+ heap. raw_block_size = size;
90+ }
91+ }
92+ if !heap. initialized {
93+ panic ! ( "Allocation too small for heap" ) ;
94+ }
8595 } ) ;
8696 }
8797
98+ /// Align `start_addr` to `rlsf::GRANULARITY` and make
99+ /// `size` a multiple of `2*rlsf::GRANULARITY`.
100+ fn align ( start_addr : usize , size : usize ) -> Option < ( usize , usize ) > {
101+ let align_offset: usize = ( start_addr as * const u8 ) . align_offset ( rlsf:: GRANULARITY ) ;
102+ if align_offset >= size {
103+ return None ;
104+ }
105+ let reduced_size: usize = size - align_offset;
106+ let usable_size: usize = reduced_size - ( reduced_size % ( rlsf:: GRANULARITY * 2 ) ) ;
107+ Some ( ( start_addr + align_offset, usable_size) )
108+ }
109+
88110 fn alloc ( & self , layout : Layout ) -> Option < NonNull < u8 > > {
89111 critical_section:: with ( |cs| self . heap . borrow_ref_mut ( cs) . tlsf . allocate ( layout) )
90112 }
0 commit comments