summaryrefslogtreecommitdiff
path: root/src/malloc
diff options
context:
space:
mode:
Diffstat (limited to 'src/malloc')
-rw-r--r--src/malloc/free.c6
-rw-r--r--src/malloc/libc_calloc.c4
-rw-r--r--src/malloc/lite_malloc.c19
-rw-r--r--src/malloc/mallocng/aligned_alloc.c3
-rw-r--r--src/malloc/mallocng/free.c12
-rw-r--r--src/malloc/mallocng/glue.h20
-rw-r--r--src/malloc/mallocng/malloc_usable_size.c1
-rw-r--r--src/malloc/oldmalloc/malloc.c27
-rw-r--r--src/malloc/realloc.c6
-rw-r--r--src/malloc/reallocarray.c13
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);
+}