Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libbsdmalloc libbsdmalloc: Provide all allocator front e...
details: https://anonhg.NetBSD.org/src/rev/ed701daeb618
branches: trunk
changeset: 377260:ed701daeb618
user: riastradh <riastradh%NetBSD.org@localhost>
date: Tue Jul 04 15:08:55 2023 +0000
description:
libbsdmalloc: Provide all allocator front ends and fork hooks.
Front ends:
- aligned_alloc
- calloc
- posix_memalign
Fork hooks:
- _malloc_prefork
- _malloc_postfork
- _malloc_postfork_child
Otherwise these will pull in the jemalloc definitions from libc,
which (a) defeats the purpose, and (b) won't work correctly with
fork and threads.
Thanks to kre@ and the thread on tech-userlevel for pointing me in
the right direction to making this actually work to override
jemalloc:
https://mail-index.netbsd.org/tech-userlevel/2023/06/30/msg013957.html
Note: libbsdmalloc doesn't set errno=ENOMEM on malloc failure, but
these front ends do (even aligned_alloc, which is from C11, which
doesn't define ENOMEM at all, but this pacifies our aligned_alloc
tests in t_posix_memalign.c). Might want to fix that.
XXX pullup-10
diffstat:
lib/libbsdmalloc/Makefile | 9 ++-
lib/libbsdmalloc/malloc.c | 124 ++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 129 insertions(+), 4 deletions(-)
diffs (185 lines):
diff -r 280760d67bad -r ed701daeb618 lib/libbsdmalloc/Makefile
--- a/lib/libbsdmalloc/Makefile Tue Jul 04 15:06:36 2023 +0000
+++ b/lib/libbsdmalloc/Makefile Tue Jul 04 15:08:55 2023 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.4 2012/03/21 10:08:30 matt Exp $
+# $NetBSD: Makefile,v 1.5 2023/07/04 15:08:55 riastradh Exp $
NOMAN=1
@@ -9,6 +9,13 @@ WARNS= 2
LIB= bsdmalloc
SRCS= malloc.c
+CFLAGS+= -fno-builtin-aligned_alloc
+CFLAGS+= -fno-builtin-calloc
+CFLAGS+= -fno-builtin-free
+CFLAGS+= -fno-builtin-malloc
+CFLAGS+= -fno-builtin-posix_memalign
+CFLAGS+= -fno-builtin-realloc
+
CPPFLAGS+= -D_REENT -D_REENTRANT -I${.CURDIR}/../libc/include/
.include <bsd.lib.mk>
diff -r 280760d67bad -r ed701daeb618 lib/libbsdmalloc/malloc.c
--- a/lib/libbsdmalloc/malloc.c Tue Jul 04 15:06:36 2023 +0000
+++ b/lib/libbsdmalloc/malloc.c Tue Jul 04 15:08:55 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: malloc.c,v 1.2 2003/08/07 16:42:01 agc Exp $ */
+/* $NetBSD: malloc.c,v 1.3 2023/07/04 15:08:55 riastradh Exp $ */
/*
* Copyright (c) 1983, 1993
@@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)malloc.c 8.1 (Berkeley) 6/4/93";
#else
-__RCSID("$NetBSD: malloc.c,v 1.2 2003/08/07 16:42:01 agc Exp $");
+__RCSID("$NetBSD: malloc.c,v 1.3 2023/07/04 15:08:55 riastradh Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -53,12 +53,18 @@ static char sccsid[] = "@(#)malloc.c 8.1
#if defined(DEBUG) || defined(RCHECK)
#include <sys/uio.h>
#endif
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdint.h>
#if defined(RCHECK) || defined(MSTATS)
#include <stdio.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+
#include "reentrant.h"
@@ -166,7 +172,7 @@ botch(s)
abort();
}
#else
-#define ASSERT(p)
+#define ASSERT(p) ((void)sizeof((long)(p)))
#endif
void *
@@ -493,3 +499,115 @@ mstats(s)
totused, totfree);
}
#endif
+
+/*
+ * Additional front ends:
+ * - aligned_alloc (C11)
+ * - calloc(n,m) = malloc(n*m) without overflow
+ * - posix_memalign (POSIX)
+ *
+ * These must all be in the same compilation unit as malloc, realloc,
+ * and free (or -lbsdmalloc must be surrounded by -Wl,--whole-archive
+ * -lbsdmalloc -Wl,--no-whole-archive) in order to override the libc
+ * built-in malloc implementation.
+ *
+ * Allocations of size n, up to and including the page size, are
+ * already aligned by malloc on multiples of n. Larger alignment is
+ * not supported.
+ */
+
+static long __constfunc
+cachedpagesize(void)
+{
+ long n;
+
+ /* XXX atomic_load_relaxed, but that's not defined in userland atm */
+ if (__predict_false((n = pagesz) == 0)) {
+ mutex_lock(&malloc_mutex);
+ if ((n = pagesz) == 0)
+ n = pagesz = getpagesize();
+ mutex_unlock(&malloc_mutex);
+ }
+
+ return n;
+}
+
+void *
+aligned_alloc(size_t alignment, size_t size)
+{
+ char *p;
+
+ if (alignment == 0 ||
+ (alignment & (alignment - 1)) != 0 ||
+ alignment > cachedpagesize() ||
+ (size & (alignment - 1)) != 0) {
+ errno = EINVAL;
+ return NULL;
+ }
+ p = malloc(size);
+ if (__predict_false(p == NULL))
+ ASSERT((uintptr_t)p % alignment == 0);
+ return p;
+}
+
+void *
+calloc(size_t nmemb, size_t size)
+{
+ void *p;
+ size_t n;
+
+ if (__builtin_mul_overflow_p(nmemb, size, (size_t)0)) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ n = nmemb * size;
+ p = malloc(n);
+ if (__predict_false(p == NULL))
+ return NULL;
+ memset(p, 0, n);
+ return p;
+}
+
+int
+posix_memalign(void **memptr, size_t alignment, size_t size)
+{
+ char *p;
+
+ if (alignment < sizeof(void *) ||
+ (alignment & (alignment - 1)) != 0 ||
+ alignment > cachedpagesize())
+ return EINVAL;
+ p = malloc(size < alignment ? alignment : size);
+ if (__predict_false(p == NULL))
+ return ENOMEM;
+ ASSERT((uintptr_t)p % alignment == 0);
+ *memptr = p;
+ return 0;
+}
+
+/*
+ * libc hooks required by fork
+ */
+
+#include "../libc/include/extern.h"
+
+void
+_malloc_prefork(void)
+{
+
+ mutex_lock(&malloc_mutex);
+}
+
+void
+_malloc_postfork(void)
+{
+
+ mutex_unlock(&malloc_mutex);
+}
+
+void
+_malloc_postfork_child(void)
+{
+
+ mutex_unlock(&malloc_mutex);
+}
Home |
Main Index |
Thread Index |
Old Index