Module Name: src
Committed By: ad
Date: Fri Oct 13 19:30:28 UTC 2023
Modified Files:
src/lib/libc/stdlib: jemalloc.c
Log Message:
Minor changes to jemalloc100 (the old one that only vax etc currently uses).
- Don't use TLS nor pretend to hash out arenas to reduce lock contention,
because NetBSD uses thr_curcpu() to choose arena (i.e. per-CPU arenas).
- In a single threaded process, don't prepare "ncpus" worth of arenas,
allocate only one.
- Use getpagesize() since it caches the return.
- Sprinkle branch hints.
- Make MALLOC_TRACE and MALLOC_DEBUG work again.
To generate a diff of this commit:
cvs rdiff -u -r1.56 -r1.57 src/lib/libc/stdlib/jemalloc.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/libc/stdlib/jemalloc.c
diff -u src/lib/libc/stdlib/jemalloc.c:1.56 src/lib/libc/stdlib/jemalloc.c:1.57
--- src/lib/libc/stdlib/jemalloc.c:1.56 Sun May 7 12:41:47 2023
+++ src/lib/libc/stdlib/jemalloc.c Fri Oct 13 19:30:28 2023
@@ -1,4 +1,4 @@
-/* $NetBSD: jemalloc.c,v 1.56 2023/05/07 12:41:47 skrll Exp $ */
+/* $NetBSD: jemalloc.c,v 1.57 2023/10/13 19:30:28 ad Exp $ */
/*-
* Copyright (C) 2006,2007 Jason Evans <[email protected]>.
@@ -97,13 +97,6 @@
/* LINTLIBRARY */
-#ifdef __NetBSD__
-# define xutrace(a, b) utrace("malloc", (a), (b))
-# define __DECONST(x, y) ((x)__UNCONST(y))
-#else
-# define xutrace(a, b) utrace((a), (b))
-#endif /* __NetBSD__ */
-
/*
* MALLOC_PRODUCTION disables assertions and statistics gathering. It also
* defaults the A and J runtime options to off. These settings are appropriate
@@ -117,21 +110,11 @@
#include <sys/cdefs.h>
/* __FBSDID("$FreeBSD: src/lib/libc/stdlib/malloc.c,v 1.147 2007/06/15 22:00:16 jasone Exp $"); */
-__RCSID("$NetBSD: jemalloc.c,v 1.56 2023/05/07 12:41:47 skrll Exp $");
+__RCSID("$NetBSD: jemalloc.c,v 1.57 2023/10/13 19:30:28 ad Exp $");
-#ifdef __FreeBSD__
-#include "libc_private.h"
-#ifdef MALLOC_DEBUG
-# define _LOCK_DEBUG
-#endif
-#include "spinlock.h"
-#endif
#include "namespace.h"
#include <sys/mman.h>
#include <sys/param.h>
-#ifdef __FreeBSD__
-#include <sys/stddef.h>
-#endif
#include <sys/time.h>
#include <sys/types.h>
#include <sys/sysctl.h>
@@ -139,12 +122,6 @@ __RCSID("$NetBSD: jemalloc.c,v 1.56 2023
#include <sys/uio.h>
#include <sys/ktrace.h> /* Must come after several other sys/ includes. */
-#ifdef __FreeBSD__
-#include <machine/atomic.h>
-#include <machine/cpufunc.h>
-#include <machine/vmparam.h>
-#endif
-
#include <errno.h>
#include <limits.h>
#include <pthread.h>
@@ -158,17 +135,10 @@ __RCSID("$NetBSD: jemalloc.c,v 1.56 2023
#include <strings.h>
#include <unistd.h>
-#ifdef __NetBSD__
-# include <reentrant.h>
-# include "extern.h"
+#include <reentrant.h>
+#include "extern.h"
#define STRERROR_R(a, b, c) strerror_r_ss(a, b, c);
-#endif
-
-#ifdef __FreeBSD__
-#define STRERROR_R(a, b, c) strerror_r(a, b, c);
-#include "un-namespace.h"
-#endif
/* MALLOC_STATS enables statistics calculation. */
#ifndef MALLOC_PRODUCTION
@@ -260,7 +230,6 @@ __RCSID("$NetBSD: jemalloc.c,v 1.56 2023
# define QUANTUM_2POW_MIN 4
# define SIZEOF_PTR_2POW 2
# define USE_BRK
-# define NO_TLS
#endif
#ifdef __sh__
# define QUANTUM_2POW_MIN 4
@@ -271,9 +240,6 @@ __RCSID("$NetBSD: jemalloc.c,v 1.56 2023
# define QUANTUM_2POW_MIN 4
# define SIZEOF_PTR_2POW 2
# define USE_BRK
-# ifdef __mc68010__
-# define NO_TLS
-# endif
#endif
#if defined(__mips__)
# ifdef _LP64
@@ -284,9 +250,6 @@ __RCSID("$NetBSD: jemalloc.c,v 1.56 2023
# endif
# define QUANTUM_2POW_MIN 4
# define USE_BRK
-# if defined(__mips__)
-# define NO_TLS
-# endif
#endif
#if defined(__riscv__)
# ifdef _LP64
@@ -297,7 +260,6 @@ __RCSID("$NetBSD: jemalloc.c,v 1.56 2023
# endif
# define QUANTUM_2POW_MIN 4
# define USE_BRK
-# define NO_TLS
#endif
#ifdef __hppa__
# define QUANTUM_2POW_MIN 4
@@ -367,21 +329,6 @@ __RCSID("$NetBSD: jemalloc.c,v 1.56 2023
/******************************************************************************/
-#ifdef __FreeBSD__
-/*
- * Mutexes based on spinlocks. We can't use normal pthread mutexes, because
- * they require malloc()ed memory.
- */
-typedef struct {
- spinlock_t lock;
-} malloc_mutex_t;
-
-/* Set to true once the allocator has been initialized. */
-static bool malloc_initialized = false;
-
-/* Used to avoid initialization races. */
-static malloc_mutex_t init_lock = {_SPINLOCK_INITIALIZER};
-#else
#define malloc_mutex_t mutex_t
/* Set to true once the allocator has been initialized. */
@@ -391,7 +338,6 @@ static bool malloc_initialized = false;
/* Used to avoid initialization races. */
static mutex_t init_lock = MUTEX_INITIALIZER;
#endif
-#endif
/******************************************************************************/
/*
@@ -774,71 +720,10 @@ static size_t base_mapped;
* arenas array are necessarily used; arenas are created lazily as needed.
*/
static arena_t **arenas;
-static unsigned narenas;
-static unsigned next_arena;
#ifdef _REENTRANT
static malloc_mutex_t arenas_mtx; /* Protects arenas initialization. */
#endif
-/*
- * Map of pthread_self() --> arenas[???], used for selecting an arena to use
- * for allocations.
- */
-#ifndef NO_TLS
-static __attribute__((tls_model("initial-exec")))
-__thread arena_t **arenas_map;
-#else
-static arena_t **arenas_map;
-#endif
-
-#if !defined(NO_TLS) || !defined(_REENTRANT)
-# define get_arenas_map() (arenas_map)
-# define set_arenas_map(x) (arenas_map = x)
-#else /* NO_TLS && _REENTRANT */
-
-static thread_key_t arenas_map_key = -1;
-
-static inline arena_t **
-get_arenas_map(void)
-{
- if (!__isthreaded)
- return arenas_map;
-
- if (arenas_map_key == -1) {
- (void)thr_keycreate(&arenas_map_key, NULL);
- if (arenas_map != NULL) {
- thr_setspecific(arenas_map_key, arenas_map);
- arenas_map = NULL;
- }
- }
-
- return thr_getspecific(arenas_map_key);
-}
-
-static __inline void
-set_arenas_map(arena_t **a)
-{
- if (!__isthreaded) {
- arenas_map = a;
- return;
- }
-
- if (arenas_map_key == -1) {
-#ifndef NO_TLS
- (void)thr_keycreate(&arenas_map_key, NULL);
-#endif
- if (arenas_map != NULL) {
- _DIAGASSERT(arenas_map == a);
- arenas_map = NULL;
- }
- }
-
-#ifndef NO_TLS
- thr_setspecific(arenas_map_key, a);
-#endif
-}
-#endif /* NO_TLS && _REENTRANT */
-
#ifdef MALLOC_STATS
/* Chunk statistics. */
static chunk_stats_t stats_chunks;
@@ -866,7 +751,6 @@ static bool opt_utrace = false;
static bool opt_sysv = false;
static bool opt_xmalloc = false;
static bool opt_zero = false;
-static int32_t opt_narenas_lshift = 0;
typedef struct {
void *p;
@@ -874,13 +758,18 @@ typedef struct {
void *r;
} malloc_utrace_t;
+/* Sprinkle branch hints for the compiler and CPU. */
+#define OPT(a) __predict_false(opt_##a)
+#define NOT_OPT(a) __predict_true(!opt_##a)
+
+/* Trace malloc/free for ktrace/kdump. */
#define UTRACE(a, b, c) \
- if (opt_utrace) { \
+ if (OPT(utrace)) { \
malloc_utrace_t ut; \
ut.p = a; \
ut.s = b; \
ut.r = c; \
- xutrace(&ut, sizeof(ut)); \
+ utrace("malloc", &ut, sizeof(ut)); \
}
/******************************************************************************/
@@ -920,8 +809,8 @@ static void *arena_palloc(arena_t *arena
static size_t arena_salloc(const void *ptr);
static void *arena_ralloc(void *ptr, size_t size, size_t oldsize);
static void arena_dalloc(arena_t *arena, arena_chunk_t *chunk, void *ptr);
-static bool arena_new(arena_t *arena);
-static arena_t *arenas_extend(unsigned ind);
+static void arena_new(arena_t *arena);
+static arena_t *arenas_extend(void);
static void *huge_malloc(size_t size);
static void *huge_palloc(size_t alignment, size_t size);
static void *huge_ralloc(void *ptr, size_t size, size_t oldsize);
@@ -1216,8 +1105,8 @@ base_chunk_node_dealloc(chunk_node_t *no
static void
stats_print(arena_t *arena)
{
- unsigned i;
- int gap_start;
+ const unsigned minusone = (unsigned)-1;
+ unsigned i, gap_start;
malloc_printf(
" allocated/mapped nmalloc ndalloc\n");
@@ -1236,12 +1125,12 @@ stats_print(arena_t *arena)
malloc_printf("bins: bin size regs pgs requests newruns"
" reruns maxruns curruns\n");
- for (i = 0, gap_start = -1; i < ntbins + nqbins + nsbins; i++) {
+ for (i = 0, gap_start = minusone; i < ntbins + nqbins + nsbins; i++) {
if (arena->bins[i].stats.nrequests == 0) {
- if (gap_start == -1)
+ if (gap_start == minusone)
gap_start = i;
} else {
- if (gap_start != -1) {
+ if (gap_start != minusone) {
if (i > gap_start + 1) {
/* Gap of more than one size class. */
malloc_printf("[%u..%u]\n",
@@ -1250,7 +1139,7 @@ stats_print(arena_t *arena)
/* Gap of one size class. */
malloc_printf("[%u]\n", gap_start);
}
- gap_start = -1;
+ gap_start = minusone;
}
malloc_printf(
"%13u %1s %4u %4u %3u %9llu %9llu"
@@ -1267,7 +1156,7 @@ stats_print(arena_t *arena)
arena->bins[i].stats.curruns);
}
}
- if (gap_start != -1) {
+ if (gap_start != minusone) {
if (i > gap_start + 1) {
/* Gap of more than one size class. */
malloc_printf("[%u..%u]\n", gap_start, i - 1);
@@ -1330,7 +1219,7 @@ pages_map_align(void *addr, size_t size,
STRERROR_R(errno, buf, sizeof(buf));
_malloc_message(getprogname(),
": (malloc) Error in munmap(): ", buf, "\n");
- if (opt_abort)
+ if (OPT(abort))
abort();
}
ret = NULL;
@@ -1358,7 +1247,7 @@ pages_unmap(void *addr, size_t size)
STRERROR_R(errno, buf, sizeof(buf));
_malloc_message(getprogname(),
": (malloc) Error in munmap(): ", buf, "\n");
- if (opt_abort)
+ if (OPT(abort))
abort();
}
}
@@ -1595,54 +1484,34 @@ chunk_dealloc(void *chunk, size_t size)
*/
/*
- * Choose an arena based on a per-thread and (optimistically) per-CPU value.
- *
- * We maintain at least one block of arenas. Usually there are more.
- * The blocks are $ncpu arenas in size. Whole blocks are 'hashed'
- * amongst threads. To accomplish this, next_arena advances only in
- * ncpu steps.
+ * Choose a per-CPU arena.
*/
static __noinline arena_t *
choose_arena_hard(void)
{
- unsigned i, curcpu;
- arena_t **map;
- /* Initialize the current block of arenas and advance to next. */
+ assert(arenas[0] != NULL);
+
malloc_mutex_lock(&arenas_mtx);
- assert(next_arena % ncpus == 0);
- assert(narenas % ncpus == 0);
- map = &arenas[next_arena];
- set_arenas_map(map);
- for (i = 0; i < ncpus; i++) {
- if (arenas[next_arena] == NULL)
- arenas_extend(next_arena);
- next_arena = (next_arena + 1) % narenas;
- }
+ for (unsigned i = 1; i < ncpus; i++)
+ if (arenas[i] == NULL)
+ arenas[i] = arenas_extend();
malloc_mutex_unlock(&arenas_mtx);
- /*
- * If we were unable to allocate an arena above, then default to
- * the first arena, which is always present.
- */
- curcpu = thr_curcpu();
- if (map[curcpu] != NULL)
- return map[curcpu];
- return arenas[0];
+ return arenas[thr_curcpu()];
}
static inline arena_t *
choose_arena(void)
{
- unsigned curcpu;
- arena_t **map;
+ arena_t *arena;
- map = get_arenas_map();
- curcpu = thr_curcpu();
- if (__predict_true(map != NULL && map[curcpu] != NULL))
- return map[curcpu];
+ /* NB: when libpthread is absent, thr_curcpu() always returns zero. */
+ arena = arenas[thr_curcpu()];
+ if (__predict_true(arena != NULL))
+ return arena;
- return choose_arena_hard();
+ return choose_arena_hard();
}
static inline int
@@ -1940,7 +1809,7 @@ arena_chunk_dealloc(arena_t *arena, aren
*/
RB_REMOVE(arena_chunk_tree_s, &chunk->arena->chunks, chunk);
- if (opt_hint == false) {
+ if (NOT_OPT(hint)) {
if (arena->spare != NULL) {
chunk_dealloc((void *)arena->spare, chunksize);
#ifdef MALLOC_STATS
@@ -2082,7 +1951,7 @@ arena_run_dalloc(arena_t *arena, arena_r
* Tell the kernel that we don't need the data in this run, but only if
* requested via runtime configuration.
*/
- if (opt_hint)
+ if (OPT(hint))
madvise(run, size, MADV_FREE);
/* Try to coalesce with neighboring runs. */
@@ -2373,9 +2242,9 @@ arena_malloc(arena_t *arena, size_t size
malloc_mutex_unlock(&arena->mtx);
- if (opt_junk)
+ if (OPT(junk))
memset(ret, 0xa5, size);
- else if (opt_zero)
+ else if (OPT(zero))
memset(ret, 0, size);
return (ret);
}
@@ -2473,9 +2342,9 @@ arena_palloc(arena_t *arena, size_t alig
#endif
malloc_mutex_unlock(&arena->mtx);
- if (opt_junk)
+ if (OPT(junk))
memset(ret, 0xa5, size);
- else if (opt_zero)
+ else if (OPT(zero))
memset(ret, 0, size);
return (ret);
}
@@ -2558,9 +2427,9 @@ arena_ralloc(void *ptr, size_t size, siz
idalloc(ptr);
return (ret);
IN_PLACE:
- if (opt_junk && size < oldsize)
+ if (OPT(junk) && size < oldsize)
memset((void *)((uintptr_t)ptr + size), 0x5a, oldsize - size);
- else if (opt_zero && size > oldsize)
+ else if (OPT(zero) && size > oldsize)
memset((void *)((uintptr_t)ptr + oldsize), 0, size - oldsize);
return (ptr);
}
@@ -2596,7 +2465,7 @@ arena_dalloc(arena_t *arena, arena_chunk
bin = run->bin;
size = bin->reg_size;
- if (opt_junk)
+ if (OPT(junk))
memset(ptr, 0x5a, size);
malloc_mutex_lock(&arena->mtx);
@@ -2652,7 +2521,7 @@ arena_dalloc(arena_t *arena, arena_chunk
size = mapelm->npages << pagesize_2pow;
assert((((uintptr_t)ptr) & pagesize_mask) == 0);
- if (opt_junk)
+ if (OPT(junk))
memset(ptr, 0x5a, size);
malloc_mutex_lock(&arena->mtx);
@@ -2666,7 +2535,7 @@ arena_dalloc(arena_t *arena, arena_chunk
malloc_mutex_unlock(&arena->mtx);
}
-static bool
+static void
arena_new(arena_t *arena)
{
unsigned i;
@@ -2735,21 +2604,19 @@ arena_new(arena_t *arena)
#ifdef MALLOC_DEBUG
arena->magic = ARENA_MAGIC;
#endif
-
- return (false);
}
/* Create a new arena and insert it into the arenas array at index ind. */
static arena_t *
-arenas_extend(unsigned ind)
+arenas_extend(void)
{
arena_t *ret;
/* Allocate enough space for trailing bins. */
ret = (arena_t *)base_alloc(sizeof(arena_t)
+ (sizeof(arena_bin_t) * (ntbins + nqbins + nsbins - 1)));
- if (ret != NULL && arena_new(ret) == false) {
- arenas[ind] = ret;
+ if (ret != NULL) {
+ arena_new(ret);
return (ret);
}
/* Only reached if there is an OOM error. */
@@ -2762,7 +2629,7 @@ arenas_extend(unsigned ind)
*/
_malloc_message(getprogname(),
": (malloc) Error initializing arena\n", "", "");
- if (opt_abort)
+ if (OPT(abort))
abort();
return (arenas[0]);
@@ -2814,9 +2681,9 @@ huge_malloc(size_t size)
#endif
malloc_mutex_unlock(&chunks_mtx);
- if (opt_junk)
+ if (OPT(junk))
memset(ret, 0xa5, csize);
- else if (opt_zero)
+ else if (OPT(zero))
memset(ret, 0, csize);
return (ret);
@@ -2894,9 +2761,9 @@ huge_palloc(size_t alignment, size_t siz
#endif
malloc_mutex_unlock(&chunks_mtx);
- if (opt_junk)
+ if (OPT(junk))
memset(ret, 0xa5, chunk_size);
- else if (opt_zero)
+ else if (OPT(zero))
memset(ret, 0, chunk_size);
return (ret);
@@ -2910,10 +2777,10 @@ huge_ralloc(void *ptr, size_t size, size
/* Avoid moving the allocation if the size class would not change. */
if (oldsize > arena_maxclass &&
CHUNK_CEILING(size) == CHUNK_CEILING(oldsize)) {
- if (opt_junk && size < oldsize) {
+ if (OPT(junk) && size < oldsize) {
memset((void *)((uintptr_t)ptr + size), 0x5a, oldsize
- size);
- } else if (opt_zero && size > oldsize) {
+ } else if (OPT(zero) && size > oldsize) {
memset((void *)((uintptr_t)ptr + oldsize), 0, size
- oldsize);
}
@@ -2946,7 +2813,7 @@ huge_ralloc(void *ptr, size_t size, size
* tree before we acquire the mutex lock again.
*/
malloc_mutex_lock(&chunks_mtx);
- key.chunk = __DECONST(void *, ptr);
+ key.chunk = __UNCONST(ptr);
node = RB_FIND(chunk_tree_s, &huge, &key);
assert(node != NULL);
assert(node->chunk == ptr);
@@ -2986,10 +2853,10 @@ huge_ralloc(void *ptr, size_t size, size
#endif
malloc_mutex_unlock(&chunks_mtx);
- if (opt_junk && size < oldsize) {
+ if (OPT(junk) && size < oldsize) {
memset((void *)((uintptr_t)newptr + size), 0x5a,
newcsize - size);
- } else if (opt_zero && size > oldsize) {
+ } else if (OPT(zero) && size > oldsize) {
memset((void *)((uintptr_t)newptr + oldsize), 0,
size - oldsize);
}
@@ -3045,7 +2912,7 @@ huge_dalloc(void *ptr)
/* Unmap chunk. */
#ifdef USE_BRK
- if (opt_junk)
+ if (OPT(junk))
memset(node->chunk, 0x5a, node->size);
#endif
chunk_dealloc(node->chunk, node->size);
@@ -3184,7 +3051,7 @@ icalloc(size_t size)
if (ret == NULL)
return (NULL);
- if (opt_junk)
+ if (OPT(junk))
memset(ret, 0, size);
#ifdef USE_BRK
else if ((uintptr_t)ret >= (uintptr_t)brk_base
@@ -3223,7 +3090,7 @@ isalloc(const void *ptr)
malloc_mutex_lock(&chunks_mtx);
/* Extract from tree of huge allocations. */
- key.chunk = __DECONST(void *, ptr);
+ key.chunk = __UNCONST(ptr);
node = RB_FIND(chunk_tree_s, &huge, &key);
assert(node != NULL);
@@ -3273,7 +3140,7 @@ static void
malloc_print_stats(void)
{
- if (opt_print_stats) {
+ if (OPT(print_stats)) {
char s[UMAX2S_BUFSIZE];
_malloc_message("___ Begin malloc statistics ___\n", "", "",
"");
@@ -3288,13 +3155,12 @@ malloc_print_stats(void)
opt_abort ? "A" : "a",
opt_junk ? "J" : "j",
opt_hint ? "H" : "h");
- _malloc_message(opt_utrace ? "PU" : "Pu",
+ _malloc_message(OPT(utrace) ? "PU" : "Pu",
opt_sysv ? "V" : "v",
opt_xmalloc ? "X" : "x",
opt_zero ? "Z\n" : "z\n");
_malloc_message("CPUs: ", size_t2s(ncpus, s), "\n", "");
- _malloc_message("Max arenas: ", size_t2s(narenas, s), "\n", "");
_malloc_message("Pointer size: ", size_t2s(sizeof(void *), s),
"\n", "");
_malloc_message("Quantum size: ", size_t2s(quantum, s), "\n", "");
@@ -3314,7 +3180,7 @@ malloc_print_stats(void)
/* Calculate and print allocated/mapped stats. */
/* arenas. */
- for (i = 0, allocated = 0; i < narenas; i++) {
+ for (i = 0, allocated = 0; i < ncpus; i++) {
if (arenas[i] != NULL) {
malloc_mutex_lock(&arenas[i]->mtx);
allocated +=
@@ -3363,7 +3229,7 @@ malloc_print_stats(void)
huge_allocated);
/* Print stats for each arena. */
- for (i = 0; i < narenas; i++) {
+ for (i = 0; i < ncpus; i++) {
arena = arenas[i];
if (arena != NULL) {
malloc_printf(
@@ -3380,15 +3246,14 @@ malloc_print_stats(void)
}
/*
- * FreeBSD's pthreads implementation calls malloc(3), so the malloc
- * implementation has to take pains to avoid infinite recursion during
- * initialization.
+ * libpthread might call malloc(3), so the malloc implementation has to take
+ * pains to avoid infinite recursion during initialization.
*/
static inline bool
malloc_init(void)
{
- if (malloc_initialized == false)
+ if (__predict_false(malloc_initialized == false))
return (malloc_init_hard());
return (false);
@@ -3432,7 +3297,7 @@ malloc_init_hard(void)
{
long result;
- result = sysconf(_SC_PAGESIZE);
+ result = getpagesize();
assert(result != -1);
pagesize = (unsigned) result;
@@ -3450,7 +3315,7 @@ malloc_init_hard(void)
switch (i) {
case 0:
if ((linklen = readlink("/etc/malloc.conf", buf,
- sizeof(buf) - 1)) != -1) {
+ sizeof(buf) - 1)) != -1) {
/*
* Use the contents of the "/etc/malloc.conf"
* symbolic link's name.
@@ -3479,10 +3344,10 @@ malloc_init_hard(void)
break;
case 2:
if (_malloc_options != NULL) {
- /*
- * Use options that were compiled into the program.
- */
- opts = _malloc_options;
+ /*
+ * Use options that were compiled into the program.
+ */
+ opts = _malloc_options;
} else {
/* No configuration specified. */
buf[0] = '\0';
@@ -3529,12 +3394,6 @@ malloc_init_hard(void)
(int)(sizeof(size_t) << 3))
opt_chunk_2pow++;
break;
- case 'n':
- opt_narenas_lshift--;
- break;
- case 'N':
- opt_narenas_lshift++;
- break;
case 'p':
opt_print_stats = false;
break;
@@ -3596,7 +3455,7 @@ malloc_init_hard(void)
errno = serrno;
/* Take care to call atexit() only once. */
- if (opt_print_stats) {
+ if (OPT(print_stats)) {
/* Print statistics at exit. */
atexit(malloc_print_stats);
}
@@ -3604,13 +3463,13 @@ malloc_init_hard(void)
/* Set variables according to the value of opt_small_max_2pow. */
if (opt_small_max_2pow < opt_quantum_2pow)
opt_small_max_2pow = opt_quantum_2pow;
- small_max = (1 << opt_small_max_2pow);
+ small_max = (1U << opt_small_max_2pow);
/* Set bin-related variables. */
bin_maxclass = (pagesize >> 1);
assert(opt_quantum_2pow >= TINY_MIN_2POW);
ntbins = (unsigned)(opt_quantum_2pow - TINY_MIN_2POW);
- assert(ntbins <= opt_quantum_2pow);
+ assert(ntbins <= (unsigned)opt_quantum_2pow);
nqbins = (unsigned)(small_max >> opt_quantum_2pow);
nsbins = (unsigned)(pagesize_2pow - opt_small_max_2pow - 1);
@@ -3684,37 +3543,8 @@ malloc_init_hard(void)
base_chunk_nodes = NULL;
malloc_mutex_init(&base_mtx);
- if (ncpus > 1) {
- /*
- * For SMP systems, create four times as many arenas as there
- * are CPUs by default.
- */
- opt_narenas_lshift += 2;
- }
-
- /* Determine how many arenas to use. */
- narenas = ncpus;
- if (opt_narenas_lshift > 0) {
- if ((narenas << opt_narenas_lshift) > narenas)
- narenas <<= opt_narenas_lshift;
- /*
- * Make sure not to exceed the limits of what base_malloc()
- * can handle.
- */
- if (narenas * sizeof(arena_t *) > chunksize)
- narenas = (unsigned)(chunksize / sizeof(arena_t *));
- } else if (opt_narenas_lshift < 0) {
- if ((narenas << opt_narenas_lshift) < narenas)
- narenas <<= opt_narenas_lshift;
- /* Make sure there is at least one arena. */
- if (narenas == 0)
- narenas = 1;
- }
-
- next_arena = 0;
-
/* Allocate and initialize arenas. */
- arenas = (arena_t **)base_alloc(sizeof(arena_t *) * narenas);
+ arenas = (arena_t **)base_alloc(sizeof(arena_t *) * ncpus);
if (arenas == NULL) {
malloc_mutex_unlock(&init_lock);
return (true);
@@ -3723,14 +3553,13 @@ malloc_init_hard(void)
* Zero the array. In practice, this should always be pre-zeroed,
* since it was just mmap()ed, but let's be sure.
*/
- memset(arenas, 0, sizeof(arena_t *) * narenas);
+ memset(arenas, 0, sizeof(arena_t *) * ncpus);
/*
* Initialize one arena here. The rest are lazily created in
* arena_choose_hard().
*/
- arenas_extend(0);
- if (arenas[0] == NULL) {
+ if ((arenas[0] = arenas_extend()) == NULL) {
malloc_mutex_unlock(&init_lock);
return (true);
}
@@ -3755,13 +3584,13 @@ malloc(size_t size)
{
void *ret;
- if (malloc_init()) {
+ if (__predict_false(malloc_init())) {
ret = NULL;
goto RETURN;
}
- if (size == 0) {
- if (opt_sysv == false)
+ if (__predict_false(size == 0)) {
+ if (NOT_OPT(sysv))
size = 1;
else {
ret = NULL;
@@ -3772,8 +3601,8 @@ malloc(size_t size)
ret = imalloc(size);
RETURN:
- if (ret == NULL) {
- if (opt_xmalloc) {
+ if (__predict_false(ret == NULL)) {
+ if (OPT(xmalloc)) {
_malloc_message(getprogname(),
": (malloc) Error in malloc(): out of memory\n", "",
"");
@@ -3792,13 +3621,13 @@ posix_memalign(void **memptr, size_t ali
int ret;
void *result;
- if (malloc_init())
+ if (__predict_false(malloc_init()))
result = NULL;
else {
/* Make sure that alignment is a large enough power of 2. */
if (((alignment - 1) & alignment) != 0
|| alignment < sizeof(void *)) {
- if (opt_xmalloc) {
+ if (OPT(xmalloc)) {
_malloc_message(getprogname(),
": (malloc) Error in posix_memalign(): "
"invalid alignment\n", "", "");
@@ -3812,8 +3641,8 @@ posix_memalign(void **memptr, size_t ali
result = ipalloc(alignment, size);
}
- if (result == NULL) {
- if (opt_xmalloc) {
+ if (__predict_false(result == NULL)) {
+ if (OPT(xmalloc)) {
_malloc_message(getprogname(),
": (malloc) Error in posix_memalign(): out of memory\n",
"", "");
@@ -3837,15 +3666,15 @@ calloc(size_t num, size_t size)
void *ret;
size_t num_size;
- if (malloc_init()) {
+ if (__predict_false(malloc_init())) {
num_size = 0;
ret = NULL;
goto RETURN;
}
num_size = num * size;
- if (num_size == 0) {
- if ((opt_sysv == false) && ((num == 0) || (size == 0)))
+ if (__predict_false(num_size == 0)) {
+ if (NOT_OPT(sysv) && ((num == 0) || (size == 0)))
num_size = 1;
else {
ret = NULL;
@@ -3868,7 +3697,7 @@ calloc(size_t num, size_t size)
RETURN:
if (ret == NULL) {
- if (opt_xmalloc) {
+ if (OPT(xmalloc)) {
_malloc_message(getprogname(),
": (malloc) Error in calloc(): out of memory\n", "",
"");
@@ -3886,8 +3715,8 @@ realloc(void *ptr, size_t size)
{
void *ret;
- if (size == 0) {
- if (opt_sysv == false)
+ if (__predict_false(size == 0)) {
+ if (NOT_OPT(sysv))
size = 1;
else {
if (ptr != NULL)
@@ -3897,13 +3726,13 @@ realloc(void *ptr, size_t size)
}
}
- if (ptr != NULL) {
+ if (__predict_true(ptr != NULL)) {
assert(malloc_initialized);
ret = iralloc(ptr, size);
if (ret == NULL) {
- if (opt_xmalloc) {
+ if (OPT(xmalloc)) {
_malloc_message(getprogname(),
": (malloc) Error in realloc(): out of "
"memory\n", "", "");
@@ -3912,13 +3741,13 @@ realloc(void *ptr, size_t size)
errno = ENOMEM;
}
} else {
- if (malloc_init())
+ if (__predict_false(malloc_init()))
ret = NULL;
else
ret = imalloc(size);
if (ret == NULL) {
- if (opt_xmalloc) {
+ if (OPT(xmalloc)) {
_malloc_message(getprogname(),
": (malloc) Error in realloc(): out of "
"memory\n", "", "");
@@ -3982,7 +3811,7 @@ _malloc_prefork(void)
/* Acquire all mutexes in a safe order. */
malloc_mutex_lock(&init_lock);
malloc_mutex_lock(&arenas_mtx);
- for (i = 0; i < narenas; i++) {
+ for (i = 0; i < ncpus; i++) {
if (arenas[i] != NULL)
malloc_mutex_lock(&arenas[i]->mtx);
}
@@ -4005,7 +3834,7 @@ _malloc_postfork(void)
malloc_mutex_unlock(&base_mtx);
malloc_mutex_unlock(&chunks_mtx);
- for (i = narenas; i-- > 0; ) {
+ for (i = ncpus; i-- > 0; ) {
if (arenas[i] != NULL)
malloc_mutex_unlock(&arenas[i]->mtx);
}
@@ -4025,7 +3854,7 @@ _malloc_postfork_child(void)
malloc_mutex_init(&base_mtx);
malloc_mutex_init(&chunks_mtx);
- for (i = narenas; i-- > 0; ) {
+ for (i = ncpus; i-- > 0; ) {
if (arenas[i] != NULL)
malloc_mutex_init(&arenas[i]->mtx);
}