@@ -35,12 +35,7 @@ impl MachineAlloc {
3535/// allow this function to be `const`; it is updated to its real value on 
3636/// the first call to `alloc()` or `alloc_zeroed()`. 
3737const  fn  empty ( )  -> Self  { 
38-         Self  { 
39-             pages :  Vec :: new ( ) , 
40-             huge_allocs :  Vec :: new ( ) , 
41-             allocated :  Vec :: new ( ) , 
42-             page_size :  0 , 
43-         } 
38+         Self  {  pages :  Vec :: new ( ) ,  huge_allocs :  Vec :: new ( ) ,  allocated :  Vec :: new ( ) ,  page_size :  0  } 
4439    } 
4540
4641    /// Expands the available memory pool by adding one page. 
@@ -68,9 +63,7 @@ impl MachineAlloc {
6863#[ inline]  
6964    pub  unsafe  fn  alloc ( layout :  Layout )  -> * mut  u8  { 
7065        let  mut  alloc = ALLOCATOR . lock ( ) . unwrap ( ) ; 
71-         unsafe  { 
72-             alloc. alloc_inner ( layout,  false ) 
73-         } 
66+         unsafe  {  alloc. alloc_inner ( layout,  false )  } 
7467    } 
7568
7669    /// Same as `alloc()`, but zeroes out data before allocating. 
@@ -199,3 +192,93 @@ impl MachineAlloc {
199192        } 
200193    } 
201194} 
195+ 
196+ #[ cfg( test) ]  
197+ mod  tests { 
198+     use  super :: * ; 
199+ 
200+     fn  assert_zeroes ( ptr :  * mut  u8 ,  layout :  Layout )  { 
201+         unsafe  { 
202+             for  ofs in  0 ..layout. size ( )  { 
203+                 assert_eq ! ( 0 ,  ptr. offset( ofs as  isize ) . read( ) ) ; 
204+             } 
205+         } 
206+     } 
207+ 
208+     #[ test]  
209+     fn  small_zeroes ( )  { 
210+         let  layout = Layout :: from_size_align ( 256 ,  32 ) . unwrap ( ) ; 
211+         let  ptr = unsafe  {  MachineAlloc :: alloc_zeroed ( layout)  } ; 
212+         assert_zeroes ( ptr,  layout) ; 
213+         unsafe  { 
214+             MachineAlloc :: dealloc ( ptr,  layout) ; 
215+         } 
216+     } 
217+ 
218+     #[ test]  
219+     fn  big_zeroes ( )  { 
220+         let  layout = Layout :: from_size_align ( 16  *  1024 ,  128 ) . unwrap ( ) ; 
221+         let  ptr = unsafe  {  MachineAlloc :: alloc_zeroed ( layout)  } ; 
222+         assert_zeroes ( ptr,  layout) ; 
223+         unsafe  { 
224+             MachineAlloc :: dealloc ( ptr,  layout) ; 
225+         } 
226+     } 
227+ 
228+     #[ test]  
229+     fn  repeated_allocs ( )  { 
230+         for  sz in  ( 1 ..=( 16  *  1024 ) ) . step_by ( 128 )  { 
231+             let  layout = Layout :: from_size_align ( sz,  1 ) . unwrap ( ) ; 
232+             let  ptr = unsafe  {  MachineAlloc :: alloc_zeroed ( layout)  } ; 
233+             assert_zeroes ( ptr,  layout) ; 
234+             unsafe  { 
235+                 ptr. write_bytes ( 255 ,  sz) ; 
236+                 MachineAlloc :: dealloc ( ptr,  layout) ; 
237+             } 
238+         } 
239+     } 
240+ 
241+     #[ test]  
242+     fn  no_overlaps ( )  { 
243+         // Some random sizes and aligns 
244+         let  mut  sizes = vec ! [ 32 ;  10 ] ; 
245+         sizes. append ( & mut  vec ! [ 15 ;  4 ] ) ; 
246+         sizes. append ( & mut  vec ! [ 256 ;  12 ] ) ; 
247+         // Give it some multi-page ones too 
248+         sizes. append ( & mut  vec ! [ 32 * 1024 ;  4 ] ) ; 
249+ 
250+         let  mut  aligns = vec ! [ 16 ;  12 ] ; 
251+         aligns. append ( & mut  vec ! [ 256 ;  2 ] ) ; 
252+         aligns. append ( & mut  vec ! [ 64 ;  12 ] ) ; 
253+         aligns. append ( & mut  vec ! [ 4096 ;  4 ] ) ; 
254+ 
255+         assert_eq ! ( sizes. len( ) ,  aligns. len( ) ) ; 
256+         let  layouts:  Vec < _ >  = std:: iter:: zip ( sizes,  aligns) 
257+             . map ( |( sz,  al) | Layout :: from_size_align ( sz,  al) . unwrap ( ) ) 
258+             . collect ( ) ; 
259+         let  ptrs:  Vec < _ >  = layouts. iter ( ) . map ( |layout| unsafe  {  MachineAlloc :: alloc_zeroed ( * layout)  } ) . collect ( ) ; 
260+ 
261+         for  ( & ptr,  & layout)  in  std:: iter:: zip ( & ptrs,  & layouts)  { 
262+             // Make sure we don't allocate overlapping ranges 
263+             unsafe  { 
264+                 assert_zeroes ( ptr,  layout) ; 
265+                 ptr. write_bytes ( 255 ,  layout. size ( ) ) ; 
266+                 MachineAlloc :: dealloc ( ptr,  layout) ; 
267+             } 
268+         } 
269+     } 
270+ 
271+     #[ test]  
272+     fn  check_leaks ( )  { 
273+         // In case this test gets run on its own, make sure to generate some 
274+         // noise in the allocator. 
275+         no_overlaps ( ) ; 
276+ 
277+         let  alloc = ALLOCATOR . lock ( ) . unwrap ( ) ; 
278+         for  pinfo in  & alloc. allocated  { 
279+             for  eight_bytes in  0 ..pinfo. len ( )  { 
280+                 assert_eq ! ( eight_bytes,  0 ) ; 
281+             } 
282+         } 
283+     } 
284+ } 
0 commit comments