diff options
Diffstat (limited to 'src/malloc/malloc.c')
| -rw-r--r-- | src/malloc/malloc.c | 24 | 
1 files changed, 23 insertions, 1 deletions
| diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c index d6ad9041..7932a975 100644 --- a/src/malloc/malloc.c +++ b/src/malloc/malloc.c @@ -37,6 +37,7 @@ static struct {  	struct bin bins[64];  	int brk_lock[2];  	int free_lock[2]; +	unsigned mmap_step;  } mal; @@ -162,7 +163,28 @@ static struct chunk *expand_heap(size_t n)  	new = mal.brk + n + SIZE_ALIGN + PAGE_SIZE - 1 & -PAGE_SIZE;  	n = new - mal.brk; -	if (__brk(new) != new) goto fail; +	if (__brk(new) != new) { +		size_t min = (size_t)PAGE_SIZE << mal.mmap_step/2; +		n += -n & PAGE_SIZE-1; +		if (n < min) n = min; +		void *area = __mmap(0, n, PROT_READ|PROT_WRITE, +			MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); +		if (area == MAP_FAILED) goto fail; + +		mal.mmap_step++; +		area = (char *)area + SIZE_ALIGN - OVERHEAD; +		w = area; +		n -= SIZE_ALIGN; +		w->psize = 0 | C_INUSE; +		w->csize = n | C_INUSE; +		w = NEXT_CHUNK(w); +		w->psize = n | C_INUSE; +		w->csize = 0 | C_INUSE; + +		unlock(mal.brk_lock); + +		return area; +	}  	w = MEM_TO_CHUNK(new);  	w->psize = n | C_INUSE; | 
