stdlib: call __neatlibc_exit() in exit()
[neatlibc.git] / malloc.c
blobdb851d8b14bdece96d82f22b8e00afd4a4f49089
1 #include <stdlib.h>
2 #include <sys/mman.h>
4 #define MSET_SIZE (1 << 15)
5 #define MMAP_MIN (1 << 12)
7 struct mset {
8 int refs;
9 int size;
12 struct mem {
13 int size;
14 struct mset *mset;
17 static struct mset *pool;
19 static void mk_pool(void)
21 if (pool && !pool->refs) {
22 pool->size = sizeof(*pool);
23 return;
25 pool = mmap(NULL, MSET_SIZE, PROT_READ | PROT_WRITE,
26 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
27 if (pool == MAP_FAILED) {
28 pool = NULL;
29 return;
31 pool->size = sizeof(*pool);
32 pool->refs = 0;
35 void *malloc(long n)
37 struct mem *mem;
38 n += sizeof(*mem);
39 if (n >= MMAP_MIN) {
40 mem = mmap(NULL, n, PROT_READ | PROT_WRITE,
41 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
42 if (mem == MAP_FAILED)
43 return NULL;
44 mem->size = n;
45 mem->mset = NULL;
46 return (void *) mem + sizeof(*mem);
48 if (!pool || MSET_SIZE - pool->size < n)
49 mk_pool();
50 if (!pool)
51 return NULL;
52 mem = (void *) pool + pool->size;
53 mem->mset = pool;
54 mem->size = n;
55 pool->refs++;
56 pool->size += (n + 7) & ~7;
57 return (void *) mem + sizeof(*mem);
60 void free(void *v)
62 struct mem *mem = v - sizeof(struct mem);
63 if (!v)
64 return;
65 if (mem->mset) {
66 struct mset *mset = mem->mset;
67 mset->refs--;
68 if (!mset->refs && mset != pool)
69 munmap(mset, mset->size);
70 } else {
71 munmap(mem, mem->size);