11use core:: isize;
2+ use core:: mem:: size_of;
23
34use spin:: Mutex ;
45
56use c_types:: * ;
67use errno:: { set_errno, ENOMEM } ;
78use malloc:: expand_heap:: __expand_heap;
9+ use mmap:: __mmap;
810use platform:: atomic:: a_and_64;
911use platform:: malloc:: * ;
1012use platform:: mman:: * ;
@@ -13,19 +15,22 @@ pub const MMAP_THRESHOLD: usize = 0x1c00 * SIZE_ALIGN;
1315pub const DONTCARE : usize = 16 ;
1416pub const RECLAIM : usize = 163_840 ;
1517
18+ #[ repr( C ) ]
1619pub struct chunk {
1720 psize : usize ,
1821 csize : usize ,
1922 next : * mut chunk ,
2023 prev : * mut chunk ,
2124}
2225
26+ #[ repr( C ) ]
2327pub struct bin {
2428 lock : [ c_int ; 2 ] ,
2529 head : * mut chunk ,
2630 tail : * mut chunk ,
2731}
2832
33+ #[ repr( C ) ]
2934pub struct mal {
3035 binmap : u64 ,
3136 bins : [ bin ; 64 ] ,
@@ -42,10 +47,87 @@ extern "C" {
4247 fn bin_index ( s : usize ) -> c_int ;
4348 fn bin_index_up ( x : usize ) -> c_int ;
4449
45- fn malloc ( n : usize ) -> * mut c_void ;
46- fn __malloc0 ( n : usize ) -> * mut c_void ;
4750 fn realloc ( p : * mut c_void , n : usize ) -> * mut c_void ;
4851 fn free ( p : * mut c_void ) ;
52+
53+ fn memset ( d : * mut c_void , c : c_int , n : usize ) -> * mut c_void ;
54+ }
55+
56+ #[ no_mangle]
57+ pub unsafe extern "C" fn malloc ( mut n : usize ) -> * mut c_void {
58+ let mut c: * mut chunk ;
59+
60+ if adjust_size ( & mut n as * mut usize ) < 0 {
61+ return 0 as * mut c_void ;
62+ }
63+
64+ if n > MMAP_THRESHOLD {
65+ let len = n + OVERHEAD + PAGE_SIZE as usize - 1 & ( -PAGE_SIZE ) as usize ;
66+ let base = __mmap ( 0 as * mut c_void ,
67+ len,
68+ PROT_READ | PROT_WRITE ,
69+ MAP_PRIVATE | MAP_ANONYMOUS ,
70+ -1 ,
71+ 0 ) as * mut u8 ;
72+
73+ if base == ( ( -1isize ) as usize ) as * mut u8 {
74+ return 0 as * mut c_void ;
75+ }
76+
77+ c = base. offset ( ( SIZE_ALIGN - OVERHEAD ) as isize ) as * mut chunk ;
78+ ( * c) . csize = len - ( SIZE_ALIGN - OVERHEAD ) ;
79+ ( * c) . psize = SIZE_ALIGN - OVERHEAD ;
80+ return chunk_to_mem ( c) ;
81+ }
82+
83+ let i = bin_index_up ( n) ;
84+ loop {
85+ let mask = mal. binmap & ( -( ( 1usize << i) as isize ) ) as u64 ;
86+ if mask == 0 {
87+ c = expand_heap ( n) ;
88+ if c == 0 as * mut chunk { return 0 as * mut c_void ; }
89+ if alloc_rev ( c) != 0 {
90+ let x = c;
91+ c = previous_chunk ( c) ;
92+
93+ let new = ( * x) . csize + chunk_size ( c) ;
94+ ( * c) . csize = new;
95+ ( * next_chunk ( x) ) . psize = new;
96+ }
97+ break ;
98+ }
99+
100+ let j = first_set ( mask) ;
101+ lock_bin ( j) ;
102+ c = mal. bins [ j as usize ] . head ;
103+
104+ if c != bin_to_chunk ( j as usize ) {
105+ if pretrim ( c, n, i, j) == 0 {
106+ unbin ( c, j) ;
107+ }
108+ unlock_bin ( j) ;
109+ break ;
110+ }
111+ unlock_bin ( j) ;
112+ }
113+
114+ // Now patch up in case we over-allocated
115+ trim ( c, n) ;
116+
117+ chunk_to_mem ( c)
118+ }
119+
120+ #[ no_mangle]
121+ pub unsafe extern "C" fn __malloc0 ( n : usize ) -> * mut c_void {
122+ let p = malloc ( n) ;
123+
124+ if p as usize != 0 && !is_mmapped ( mem_to_chunk ( p) ) {
125+ for i in 0 ..n {
126+ * ( p as * mut u8 ) . offset ( i as isize ) = 0 ;
127+ }
128+ }
129+
130+ p
49131}
50132
51133#[ no_mangle]
@@ -136,7 +218,9 @@ pub unsafe extern "C" fn pretrim(s: *mut chunk, n: usize, i: c_int, j: c_int) ->
136218 return 0 ;
137219 }
138220
139- if bin_index ( n1-n) != j { return 0 ; }
221+ if bin_index ( n1 - n) != j {
222+ return 0 ;
223+ }
140224
141225 let next = next_chunk ( s) ;
142226 let split = ( s as * mut u8 ) . offset ( n as isize ) as * mut chunk ;
@@ -159,7 +243,9 @@ pub unsafe extern "C" fn pretrim(s: *mut chunk, n: usize, i: c_int, j: c_int) ->
159243pub unsafe extern "C" fn trim ( s : * mut chunk , n : usize ) {
160244 let n1 = chunk_size ( s) ;
161245
162- if n >= n1 - DONTCARE { return ; }
246+ if n >= n1 - DONTCARE {
247+ return ;
248+ }
163249
164250 let next = next_chunk ( s) ;
165251 let split = ( s as * mut u8 ) . offset ( n as isize ) as * mut chunk ;
@@ -226,6 +312,10 @@ unsafe fn chunk_to_mem(c: *mut chunk) -> *mut c_void {
226312 ( c as * mut u8 ) . offset ( OVERHEAD as isize ) as * mut c_void
227313}
228314
315+ unsafe fn bin_to_chunk ( i : usize ) -> * mut chunk {
316+ mem_to_chunk ( mal. bins [ i] . head as * mut c_void )
317+ }
318+
229319unsafe fn chunk_size ( c : * mut chunk ) -> usize { ( * c) . csize & ( ( -2i64 ) as usize ) }
230320
231321unsafe fn chunk_psize ( c : * mut chunk ) -> usize { ( * c) . psize & ( ( -2i64 ) as usize ) }
@@ -237,3 +327,7 @@ unsafe fn previous_chunk(c: *mut chunk) -> *mut chunk {
237327unsafe fn next_chunk ( c : * mut chunk ) -> * mut chunk {
238328 ( c as * mut u8 ) . offset ( chunk_size ( c) as isize ) as * mut chunk
239329}
330+
331+ unsafe fn is_mmapped ( c : * mut chunk ) -> bool {
332+ ( ( * c) . csize & 1 ) == 0
333+ }
0 commit comments