diff options
Diffstat (limited to 'src/malloc')
-rw-r--r-- | src/malloc/free.c | 6 | ||||
-rw-r--r-- | src/malloc/libc_calloc.c | 4 | ||||
-rw-r--r-- | src/malloc/lite_malloc.c | 19 | ||||
-rw-r--r-- | src/malloc/mallocng/aligned_alloc.c | 3 | ||||
-rw-r--r-- | src/malloc/mallocng/free.c | 12 | ||||
-rw-r--r-- | src/malloc/mallocng/glue.h | 20 | ||||
-rw-r--r-- | src/malloc/mallocng/malloc_usable_size.c | 1 | ||||
-rw-r--r-- | src/malloc/oldmalloc/malloc.c | 27 | ||||
-rw-r--r-- | src/malloc/realloc.c | 6 | ||||
-rw-r--r-- | src/malloc/reallocarray.c | 13 |
10 files changed, 106 insertions, 5 deletions
diff --git a/src/malloc/free.c b/src/malloc/free.c new file mode 100644 index 00000000..3944f7b2 --- /dev/null +++ b/src/malloc/free.c @@ -0,0 +1,6 @@ +#include <stdlib.h> + +void free(void *p) +{ + __libc_free(p); +} diff --git a/src/malloc/libc_calloc.c b/src/malloc/libc_calloc.c new file mode 100644 index 00000000..d25eabea --- /dev/null +++ b/src/malloc/libc_calloc.c @@ -0,0 +1,4 @@ +#define calloc __libc_calloc +#define malloc __libc_malloc + +#include "calloc.c" diff --git a/src/malloc/lite_malloc.c b/src/malloc/lite_malloc.c index f8931ba5..43a988fb 100644 --- a/src/malloc/lite_malloc.c +++ b/src/malloc/lite_malloc.c @@ -6,6 +6,7 @@ #include "libc.h" #include "lock.h" #include "syscall.h" +#include "fork_impl.h" #define ALIGN 16 @@ -31,10 +32,12 @@ static int traverses_stack_p(uintptr_t old, uintptr_t new) return 0; } +static volatile int lock[1]; +volatile int *const __bump_lockptr = lock; + static void *__simple_malloc(size_t n) { static uintptr_t brk, cur, end; - static volatile int lock[1]; static unsigned mmap_step; size_t align=1; void *p; @@ -100,4 +103,16 @@ static void *__simple_malloc(size_t n) return p; } -weak_alias(__simple_malloc, malloc); +weak_alias(__simple_malloc, __libc_malloc_impl); + +void *__libc_malloc(size_t n) +{ + return __libc_malloc_impl(n); +} + +static void *default_malloc(size_t n) +{ + return __libc_malloc_impl(n); +} + +weak_alias(default_malloc, malloc); diff --git a/src/malloc/mallocng/aligned_alloc.c b/src/malloc/mallocng/aligned_alloc.c index 34116896..e0862a83 100644 --- a/src/malloc/mallocng/aligned_alloc.c +++ b/src/malloc/mallocng/aligned_alloc.c @@ -22,6 +22,9 @@ void *aligned_alloc(size_t align, size_t len) if (align <= UNIT) align = UNIT; unsigned char *p = malloc(len + align - UNIT); + if (!p) + return 0; + struct meta *g = get_meta(p); int idx = get_slot_index(p); size_t stride = get_stride(g); diff --git a/src/malloc/mallocng/free.c b/src/malloc/mallocng/free.c index 40745f97..43f32aad 100644 --- a/src/malloc/mallocng/free.c +++ b/src/malloc/mallocng/free.c @@ -119,7 +119,11 @@ void free(void *p) if (((uintptr_t)(start-1) ^ (uintptr_t)end) >= 2*PGSZ && g->last_idx) { unsigned char *base = start + (-(uintptr_t)start & (PGSZ-1)); size_t len = (end-base) & -PGSZ; - if (len) madvise(base, len, MADV_FREE); + if (len && USE_MADV_FREE) { + int e = errno; + madvise(base, len, MADV_FREE); + errno = e; + } } // atomic free without locking if this is neither first or last slot @@ -139,5 +143,9 @@ void free(void *p) wrlock(); struct mapinfo mi = nontrivial_free(g, idx); unlock(); - if (mi.len) munmap(mi.base, mi.len); + if (mi.len) { + int e = errno; + munmap(mi.base, mi.len); + errno = e; + } } diff --git a/src/malloc/mallocng/glue.h b/src/malloc/mallocng/glue.h index 16acd1ea..77f4c812 100644 --- a/src/malloc/mallocng/glue.h +++ b/src/malloc/mallocng/glue.h @@ -20,6 +20,12 @@ #define is_allzero __malloc_allzerop #define dump_heap __dump_heap +#define malloc __libc_malloc_impl +#define realloc __libc_realloc +#define free __libc_free + +#define USE_MADV_FREE 0 + #if USE_REAL_ASSERT #include <assert.h> #else @@ -56,7 +62,8 @@ __attribute__((__visibility__("hidden"))) extern int __malloc_lock[1]; #define LOCK_OBJ_DEF \ -int __malloc_lock[1]; +int __malloc_lock[1]; \ +void __malloc_atfork(int who) { malloc_atfork(who); } static inline void rdlock() { @@ -73,5 +80,16 @@ static inline void unlock() static inline void upgradelock() { } +static inline void resetlock() +{ + __malloc_lock[0] = 0; +} + +static inline void malloc_atfork(int who) +{ + if (who<0) rdlock(); + else if (who>0) resetlock(); + else unlock(); +} #endif diff --git a/src/malloc/mallocng/malloc_usable_size.c b/src/malloc/mallocng/malloc_usable_size.c index a440a4ea..ce6a960c 100644 --- a/src/malloc/mallocng/malloc_usable_size.c +++ b/src/malloc/mallocng/malloc_usable_size.c @@ -3,6 +3,7 @@ size_t malloc_usable_size(void *p) { + if (!p) return 0; struct meta *g = get_meta(p); int idx = get_slot_index(p); size_t stride = get_stride(g); diff --git a/src/malloc/oldmalloc/malloc.c b/src/malloc/oldmalloc/malloc.c index c0997ad8..25d00d44 100644 --- a/src/malloc/oldmalloc/malloc.c +++ b/src/malloc/oldmalloc/malloc.c @@ -9,6 +9,11 @@ #include "atomic.h" #include "pthread_impl.h" #include "malloc_impl.h" +#include "fork_impl.h" + +#define malloc __libc_malloc_impl +#define realloc __libc_realloc +#define free __libc_free #if defined(__GNUC__) && defined(__PIC__) #define inline inline __attribute__((always_inline)) @@ -476,12 +481,14 @@ void __bin_chunk(struct chunk *self) if (size > RECLAIM && (size^(size-osize)) > size-osize) { uintptr_t a = (uintptr_t)self + SIZE_ALIGN+PAGE_SIZE-1 & -PAGE_SIZE; uintptr_t b = (uintptr_t)next - SIZE_ALIGN & -PAGE_SIZE; + int e = errno; #if 1 __madvise((void *)a, b-a, MADV_DONTNEED); #else __mmap((void *)a, b-a, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0); #endif + errno = e; } unlock_bin(i); @@ -494,7 +501,9 @@ static void unmap_chunk(struct chunk *self) size_t len = CHUNK_SIZE(self) + extra; /* Crash on double free */ if (extra & 1) a_crash(); + int e = errno; __munmap(base, len); + errno = e; } void free(void *p) @@ -527,3 +536,21 @@ void __malloc_donate(char *start, char *end) c->csize = n->psize = C_INUSE | (end-start); __bin_chunk(c); } + +void __malloc_atfork(int who) +{ + if (who<0) { + lock(mal.split_merge_lock); + for (int i=0; i<64; i++) + lock(mal.bins[i].lock); + } else if (!who) { + for (int i=0; i<64; i++) + unlock(mal.bins[i].lock); + unlock(mal.split_merge_lock); + } else { + for (int i=0; i<64; i++) + mal.bins[i].lock[0] = mal.bins[i].lock[1] = 0; + mal.split_merge_lock[1] = 0; + mal.split_merge_lock[0] = 0; + } +} diff --git a/src/malloc/realloc.c b/src/malloc/realloc.c new file mode 100644 index 00000000..fb0e8b7c --- /dev/null +++ b/src/malloc/realloc.c @@ -0,0 +1,6 @@ +#include <stdlib.h> + +void *realloc(void *p, size_t n) +{ + return __libc_realloc(p, n); +} diff --git a/src/malloc/reallocarray.c b/src/malloc/reallocarray.c new file mode 100644 index 00000000..4a6ebe46 --- /dev/null +++ b/src/malloc/reallocarray.c @@ -0,0 +1,13 @@ +#define _BSD_SOURCE +#include <errno.h> +#include <stdlib.h> + +void *reallocarray(void *ptr, size_t m, size_t n) +{ + if (n && m > -1 / n) { + errno = ENOMEM; + return 0; + } + + return realloc(ptr, m * n); +} |