Skip to content

Commit 7161d26

Browse files
committed
Porting malloc() and __malloc0().
1 parent 6939fb3 commit 7161d26

2 files changed

Lines changed: 102 additions & 66 deletions

File tree

musl/src/malloc/malloc.c

Lines changed: 4 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ void unlock_bin(int i)
8484
unlock(mal.bins[i].lock);
8585
}
8686

87-
static int first_set(uint64_t x)
87+
int first_set(uint64_t x)
8888
{
8989
return a_ctz_64(x);
9090
}
@@ -97,7 +97,7 @@ int bin_index(size_t x)
9797
return ((union { float v; uint32_t r; }){(int)x}.r>>21) - 496;
9898
}
9999

100-
static int bin_index_up(size_t x)
100+
int bin_index_up(size_t x)
101101
{
102102
x = x / SIZE_ALIGN - 1;
103103
if (x <= 32) return x;
@@ -112,66 +112,8 @@ int alloc_fwd(struct chunk *c);
112112
int alloc_rev(struct chunk *c);
113113
int pretrim(struct chunk *self, size_t n, int i, int j);
114114
void trim(struct chunk *self, size_t n);
115-
116-
void *malloc(size_t n)
117-
{
118-
struct chunk *c;
119-
int i, j;
120-
121-
if (adjust_size(&n) < 0) return 0;
122-
123-
if (n > MMAP_THRESHOLD) {
124-
size_t len = n + OVERHEAD + PAGE_SIZE - 1 & -PAGE_SIZE;
125-
char *base = __mmap(0, len, PROT_READ|PROT_WRITE,
126-
MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
127-
if (base == (void *)-1) return 0;
128-
c = (void *)(base + SIZE_ALIGN - OVERHEAD);
129-
c->csize = len - (SIZE_ALIGN - OVERHEAD);
130-
c->psize = SIZE_ALIGN - OVERHEAD;
131-
return CHUNK_TO_MEM(c);
132-
}
133-
134-
i = bin_index_up(n);
135-
for (;;) {
136-
uint64_t mask = mal.binmap & -(1ULL<<i);
137-
if (!mask) {
138-
c = expand_heap(n);
139-
if (!c) return 0;
140-
if (alloc_rev(c)) {
141-
struct chunk *x = c;
142-
c = PREV_CHUNK(c);
143-
NEXT_CHUNK(x)->psize = c->csize =
144-
x->csize + CHUNK_SIZE(c);
145-
}
146-
break;
147-
}
148-
j = first_set(mask);
149-
lock_bin(j);
150-
c = mal.bins[j].head;
151-
if (c != BIN_TO_CHUNK(j)) {
152-
if (!pretrim(c, n, i, j)) unbin(c, j);
153-
unlock_bin(j);
154-
break;
155-
}
156-
unlock_bin(j);
157-
}
158-
159-
/* Now patch up in case we over-allocated */
160-
trim(c, n);
161-
162-
return CHUNK_TO_MEM(c);
163-
}
164-
165-
void *__malloc0(size_t n)
166-
{
167-
void *p = malloc(n);
168-
if (p && !IS_MMAPPED(MEM_TO_CHUNK(p))) {
169-
size_t *z;
170-
n = (n + sizeof *z - 1)/sizeof *z;
171-
for (z=p; n; n--, z++) if (*z) *z=0;
172-
}
173-
return p;
174-
}
115+
void *malloc(size_t n);
116+
void *__malloc0(size_t n);
175117

176118
void *realloc(void *p, size_t n)
177119
{

src/malloc/malloc.rs

Lines changed: 98 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
use core::isize;
2+
use core::mem::size_of;
23

34
use spin::Mutex;
45

56
use c_types::*;
67
use errno::{set_errno, ENOMEM};
78
use malloc::expand_heap::__expand_heap;
9+
use mmap::__mmap;
810
use platform::atomic::a_and_64;
911
use platform::malloc::*;
1012
use platform::mman::*;
@@ -13,19 +15,22 @@ pub const MMAP_THRESHOLD: usize = 0x1c00 * SIZE_ALIGN;
1315
pub const DONTCARE: usize = 16;
1416
pub const RECLAIM: usize = 163_840;
1517

18+
#[repr(C)]
1619
pub struct chunk {
1720
psize: usize,
1821
csize: usize,
1922
next: *mut chunk,
2023
prev: *mut chunk,
2124
}
2225

26+
#[repr(C)]
2327
pub struct bin {
2428
lock: [c_int; 2],
2529
head: *mut chunk,
2630
tail: *mut chunk,
2731
}
2832

33+
#[repr(C)]
2934
pub 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) ->
159243
pub 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+
229319
unsafe fn chunk_size(c: *mut chunk) -> usize { (*c).csize & ((-2i64) as usize) }
230320

231321
unsafe 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 {
237327
unsafe 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

Comments
 (0)