@@ -44,15 +44,15 @@ impl HoleList {
4444 println ! ( "allocate {} bytes (align {})" , size, align) ;
4545 assert ! ( size >= Self :: min_size( ) ) ;
4646
47- if let Some ( ( start_addr , front_padding , back_padding ) ) =
48- allocate_first_fit ( & mut self . first , size , align ) {
49- if let Some ( ( padding_addr, padding_size) ) = front_padding {
50- self . deallocate ( padding_addr as * mut u8 , padding_size)
47+ if let Some ( result ) = allocate_first_fit ( & mut self . first , size , align ) {
48+ println ! ( "allocated address: {:#x}" , result . hole . addr ) ;
49+ if let Some ( HoleInfo { addr : padding_addr, size : padding_size} ) = result . front_padding {
50+ self . deallocate ( padding_addr as * mut u8 , padding_size) ;
5151 }
52- if let Some ( ( padding_addr, padding_size) ) = back_padding {
53- self . deallocate ( padding_addr as * mut u8 , padding_size)
52+ if let Some ( HoleInfo { addr : padding_addr, size : padding_size} ) = result . back_padding {
53+ self . deallocate ( padding_addr as * mut u8 , padding_size) ;
5454 }
55- Some ( start_addr as * mut u8 )
55+ Some ( result . hole . addr as * mut u8 )
5656 } else {
5757 None
5858 }
@@ -84,56 +84,92 @@ pub struct Hole {
8484 pub next : Option < Unique < Hole > > ,
8585}
8686
87- fn allocate_first_fit ( previous : & mut Hole ,
88- size : usize ,
89- align : usize )
90- -> Option < ( usize , Option < ( usize , usize ) > , Option < ( usize , usize ) > ) > {
91- let mut front_padding = None ;
92- let mut back_padding = None ;
93-
94- if previous. next . is_some ( ) {
95- let hole_addr = * * previous. next . as_ref ( ) . unwrap ( ) as usize ;
96- let aligned_hole_addr = align_up ( hole_addr, align) ;
97-
98- if aligned_hole_addr > hole_addr {
99- if aligned_hole_addr < hole_addr + HoleList :: min_size ( ) {
100- // hole would cause a new, too small hole. try next hole
101- return allocate_first_fit ( unsafe { previous. next . as_mut ( ) . unwrap ( ) . get_mut ( ) } ,
102- size,
103- align) ;
104- } else {
105- let padding_hole_size = aligned_hole_addr - hole_addr;
106- front_padding = Some ( ( hole_addr, padding_hole_size) ) ;
107- }
87+ impl Hole {
88+ fn info ( & self ) -> HoleInfo {
89+ HoleInfo {
90+ addr : self as * const _ as usize ,
91+ size : self . size ,
10892 }
93+ }
94+ }
10995
110- let aligned_hole_size = unsafe { previous. next . as_ref ( ) . unwrap ( ) . get ( ) . size } -
111- ( aligned_hole_addr - hole_addr) ;
112-
113- if aligned_hole_size > size {
114- if aligned_hole_size - size < HoleList :: min_size ( ) {
115- // hole would cause a new, too small hole. try next hole
116- return allocate_first_fit ( unsafe { previous. next . as_mut ( ) . unwrap ( ) . get_mut ( ) } ,
117- size,
118- align) ;
119- } else {
120- let padding_hole_size = aligned_hole_size - size;
121- back_padding = Some ( ( aligned_hole_addr + size, padding_hole_size) ) ;
122- }
96+ struct HoleInfo {
97+ addr : usize ,
98+ size : usize ,
99+ }
100+
101+ struct HoleResult {
102+ hole : HoleInfo ,
103+ front_padding : Option < HoleInfo > ,
104+ back_padding : Option < HoleInfo > ,
105+ }
106+
107+ fn split_hole ( hole : HoleInfo , required_size : usize , required_align : usize ) -> Option < HoleResult > {
108+ let aligned_hole = {
109+ let aligned_hole_addr = align_up ( hole. addr , required_align) ;
110+ if aligned_hole_addr + required_size > hole. addr + hole. size {
111+ // hole is too small
112+ return None ;
113+ }
114+ HoleInfo {
115+ addr : aligned_hole_addr,
116+ size : hole. size - ( aligned_hole_addr - hole. addr ) ,
123117 }
118+ } ;
124119
125- if aligned_hole_size >= size {
126- previous. next = unsafe { previous. next . as_mut ( ) . unwrap ( ) . get_mut ( ) . next . take ( ) } ;
127- Some ( ( aligned_hole_addr, front_padding, back_padding) )
120+ let front_padding = if aligned_hole. addr > hole. addr {
121+ if aligned_hole. addr < hole. addr + HoleList :: min_size ( ) {
122+ // hole would cause a new, too small hole
123+ return None ;
128124 } else {
129- // hole is too small, try next hole
130- return allocate_first_fit ( unsafe { previous . next . as_mut ( ) . unwrap ( ) . get_mut ( ) } ,
131- size ,
132- align ) ;
125+ Some ( HoleInfo {
126+ addr : hole . addr ,
127+ size : aligned_hole . addr - hole . addr ,
128+ } )
133129 }
134130 } else {
135131 None
136- }
132+ } ;
133+
134+ let back_padding = if aligned_hole. size > required_size {
135+ if aligned_hole. size - required_size < HoleList :: min_size ( ) {
136+ // hole would cause a new, too small hole
137+ return None ;
138+ } else {
139+ Some ( HoleInfo {
140+ addr : aligned_hole. addr + required_size,
141+ size : aligned_hole. size - required_size,
142+ } )
143+ }
144+ } else {
145+ None
146+ } ;
147+
148+ Some ( HoleResult {
149+ hole : HoleInfo {
150+ addr : aligned_hole. addr ,
151+ size : required_size,
152+ } ,
153+ front_padding : front_padding,
154+ back_padding : back_padding,
155+ } )
156+ }
157+
158+ fn allocate_first_fit ( previous : & mut Hole , size : usize , align : usize ) -> Option < HoleResult > {
159+
160+ previous. next
161+ . as_mut ( )
162+ . and_then ( |current| split_hole ( unsafe { current. get ( ) } . info ( ) , size, align) )
163+ . map ( |result| {
164+ previous. next = unsafe { previous. next . as_mut ( ) . unwrap ( ) . get_mut ( ) . next . take ( ) } ;
165+ result
166+ } )
167+ . or_else ( || {
168+ // hole is too small, try next hole
169+ allocate_first_fit ( unsafe { previous. next . as_mut ( ) . unwrap ( ) . get_mut ( ) } ,
170+ size,
171+ align)
172+ } )
137173}
138174
139175fn deallocate ( hole : & mut Hole , addr : usize , size : usize ) {
0 commit comments