allow interposition/replacement of allocator (malloc)
[musl] / src / malloc / lite_malloc.c
1 #include <stdlib.h>
2 #include <stdint.h>
3 #include <limits.h>
4 #include <errno.h>
5 #include "libc.h"
6
7 #define ALIGN 16
8
9 void *__expand_heap(size_t *);
10
11 static void *__simple_malloc(size_t n)
12 {
13         static char *cur, *end;
14         static volatile int lock[1];
15         size_t align=1, pad;
16         void *p;
17
18         if (!n) n++;
19         while (align<n && align<ALIGN)
20                 align += align;
21
22         LOCK(lock);
23
24         pad = -(uintptr_t)cur & align-1;
25
26         if (n <= SIZE_MAX/2 + ALIGN) n += pad;
27
28         if (n > end-cur) {
29                 size_t m = n;
30                 char *new = __expand_heap(&m);
31                 if (!new) {
32                         UNLOCK(lock);
33                         return 0;
34                 }
35                 if (new != end) {
36                         cur = new;
37                         n -= pad;
38                         pad = 0;
39                 }
40                 end = new + m;
41         }
42
43         p = cur + pad;
44         cur += n;
45         UNLOCK(lock);
46         return p;
47 }
48
49 weak_alias(__simple_malloc, malloc);
50
51 static void *__simple_calloc(size_t m, size_t n)
52 {
53         if (n && m > (size_t)-1/n || malloc != __simple_malloc) {
54                 errno = ENOMEM;
55                 return 0;
56         }
57         return __simple_malloc(n * m);
58 }
59
60 weak_alias(__simple_calloc, calloc);