stdlib.h: implement mkstemp()
[neatlibc.git] / malloc.c
blob0d08e530833adcf1f5306df5c9a118a5dfd9d8cb
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(int 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 (mem->mset) {
64 struct mset *mset = mem->mset;
65 mset->refs--;
66 if (!mset->refs && mset != pool)
67 munmap(mset, mset->size);
68 } else {
69 munmap(mem, mem->size);