12 /* This function returns true if the interval [old,new]
13 * intersects the 'len'-sized interval below &libc.auxv
14 * (interpreted as the main-thread stack) or below &b
15 * (the current stack). It is used to defend against
16 * buggy brk implementations that can cross the stack. */
18 static int traverses_stack_p(uintptr_t old, uintptr_t new)
20 const uintptr_t len = 8<<20;
23 b = (uintptr_t)libc.auxv;
24 a = b > len ? b-len : 0;
25 if (new>a && old<b) return 1;
28 a = b > len ? b-len : 0;
29 if (new>a && old<b) return 1;
34 static void *__simple_malloc(size_t n)
36 static uintptr_t brk, cur, end;
37 static volatile int lock[1];
38 static unsigned mmap_step;
48 while (align<n && align<ALIGN)
53 cur += -cur & align-1;
56 size_t req = n - (end-cur) + PAGE_SIZE-1 & -PAGE_SIZE;
59 brk = __syscall(SYS_brk, 0);
60 brk += -brk & PAGE_SIZE-1;
64 if (brk == end && req < SIZE_MAX-brk
65 && !traverses_stack_p(brk, brk+req)
66 && __syscall(SYS_brk, brk+req)==brk+req) {
70 req = n + PAGE_SIZE-1 & -PAGE_SIZE;
71 /* Only make a new area rather than individual mmap
72 * if wasted space would be over 1/8 of the map. */
74 /* Geometric area size growth up to 64 pages,
75 * bounding waste by 1/8 of the area. */
76 size_t min = PAGE_SIZE<<(mmap_step/2);
77 if (min-n > end-cur) {
86 void *mem = __mmap(0, req, PROT_READ|PROT_WRITE,
87 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
88 if (mem == MAP_FAILED || !new_area) {
90 return mem==MAP_FAILED ? 0 : mem;
103 weak_alias(__simple_malloc, malloc);
105 static void *__simple_calloc(size_t m, size_t n)
107 if (n && m > (size_t)-1/n) {
111 return __simple_malloc(n * m);
114 weak_alias(__simple_calloc, calloc);