xref: /netbsd-src/lib/libc/stdlib/jemalloc.c (revision 7d62b00eb9ad855ffcd7da46b41e23feb5476fac)
1 /*	$NetBSD: jemalloc.c,v 1.55 2022/11/30 04:35:53 skrll Exp $	*/
2 
3 /*-
4  * Copyright (C) 2006,2007 Jason Evans <jasone@FreeBSD.org>.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice(s), this list of conditions and the following disclaimer as
12  *    the first lines of this file unmodified other than the possible
13  *    addition of one or more copyright notices.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice(s), this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
20  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
26  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
29  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  *******************************************************************************
32  *
33  * This allocator implementation is designed to provide scalable performance
34  * for multi-threaded programs on multi-processor systems.  The following
35  * features are included for this purpose:
36  *
37  *   + Multiple arenas are used if there are multiple CPUs, which reduces lock
38  *     contention and cache sloshing.
39  *
40  *   + Cache line sharing between arenas is avoided for internal data
41  *     structures.
42  *
43  *   + Memory is managed in chunks and runs (chunks can be split into runs),
44  *     rather than as individual pages.  This provides a constant-time
45  *     mechanism for associating allocations with particular arenas.
46  *
47  * Allocation requests are rounded up to the nearest size class, and no record
48  * of the original request size is maintained.  Allocations are broken into
49  * categories according to size class.  Assuming runtime defaults, 4 kB pages
50  * and a 16 byte quantum, the size classes in each category are as follows:
51  *
52  *   |=====================================|
53  *   | Category | Subcategory    |    Size |
54  *   |=====================================|
55  *   | Small    | Tiny           |       2 |
56  *   |          |                |       4 |
57  *   |          |                |       8 |
58  *   |          |----------------+---------|
59  *   |          | Quantum-spaced |      16 |
60  *   |          |                |      32 |
61  *   |          |                |      48 |
62  *   |          |                |     ... |
63  *   |          |                |     480 |
64  *   |          |                |     496 |
65  *   |          |                |     512 |
66  *   |          |----------------+---------|
67  *   |          | Sub-page       |    1 kB |
68  *   |          |                |    2 kB |
69  *   |=====================================|
70  *   | Large                     |    4 kB |
71  *   |                           |    8 kB |
72  *   |                           |   12 kB |
73  *   |                           |     ... |
74  *   |                           | 1012 kB |
75  *   |                           | 1016 kB |
76  *   |                           | 1020 kB |
77  *   |=====================================|
78  *   | Huge                      |    1 MB |
79  *   |                           |    2 MB |
80  *   |                           |    3 MB |
81  *   |                           |     ... |
82  *   |=====================================|
83  *
84  * A different mechanism is used for each category:
85  *
86  *   Small : Each size class is segregated into its own set of runs.  Each run
87  *           maintains a bitmap of which regions are free/allocated.
88  *
89  *   Large : Each allocation is backed by a dedicated run.  Metadata are stored
90  *           in the associated arena chunk header maps.
91  *
92  *   Huge : Each allocation is backed by a dedicated contiguous set of chunks.
93  *          Metadata are stored in a separate red-black tree.
94  *
95  *******************************************************************************
96  */
97 
98 /* LINTLIBRARY */
99 
100 #ifdef __NetBSD__
101 #  define xutrace(a, b)		utrace("malloc", (a), (b))
102 #  define __DECONST(x, y)	((x)__UNCONST(y))
103 #else
104 #  define xutrace(a, b)		utrace((a), (b))
105 #endif	/* __NetBSD__ */
106 
107 /*
108  * MALLOC_PRODUCTION disables assertions and statistics gathering.  It also
109  * defaults the A and J runtime options to off.  These settings are appropriate
110  * for production systems.
111  */
112 #define MALLOC_PRODUCTION
113 
114 #ifndef MALLOC_PRODUCTION
115 #  define MALLOC_DEBUG
116 #endif
117 
118 #include <sys/cdefs.h>
119 /* __FBSDID("$FreeBSD: src/lib/libc/stdlib/malloc.c,v 1.147 2007/06/15 22:00:16 jasone Exp $"); */
120 __RCSID("$NetBSD: jemalloc.c,v 1.55 2022/11/30 04:35:53 skrll Exp $");
121 
122 #ifdef __FreeBSD__
123 #include "libc_private.h"
124 #ifdef MALLOC_DEBUG
125 #  define _LOCK_DEBUG
126 #endif
127 #include "spinlock.h"
128 #endif
129 #include "namespace.h"
130 #include <sys/mman.h>
131 #include <sys/param.h>
132 #ifdef __FreeBSD__
133 #include <sys/stddef.h>
134 #endif
135 #include <sys/time.h>
136 #include <sys/types.h>
137 #include <sys/sysctl.h>
138 #include <sys/tree.h>
139 #include <sys/uio.h>
140 #include <sys/ktrace.h> /* Must come after several other sys/ includes. */
141 
142 #ifdef __FreeBSD__
143 #include <machine/atomic.h>
144 #include <machine/cpufunc.h>
145 #include <machine/vmparam.h>
146 #endif
147 
148 #include <errno.h>
149 #include <limits.h>
150 #include <pthread.h>
151 #include <sched.h>
152 #include <stdarg.h>
153 #include <stdbool.h>
154 #include <stdio.h>
155 #include <stdint.h>
156 #include <stdlib.h>
157 #include <string.h>
158 #include <strings.h>
159 #include <unistd.h>
160 
161 #ifdef __NetBSD__
162 #  include <reentrant.h>
163 #  include "extern.h"
164 
165 #define STRERROR_R(a, b, c)	strerror_r_ss(a, b, c);
166 #endif
167 
168 #ifdef __FreeBSD__
169 #define STRERROR_R(a, b, c)	strerror_r(a, b, c);
170 #include "un-namespace.h"
171 #endif
172 
173 /* MALLOC_STATS enables statistics calculation. */
174 #ifndef MALLOC_PRODUCTION
175 #  define MALLOC_STATS
176 #endif
177 
178 #ifdef MALLOC_DEBUG
179 #  ifdef NDEBUG
180 #    undef NDEBUG
181 #  endif
182 #else
183 #  ifndef NDEBUG
184 #    define NDEBUG
185 #  endif
186 #endif
187 #include <assert.h>
188 
189 #ifdef MALLOC_DEBUG
190    /* Disable inlining to make debugging easier. */
191 #  define inline
192 #endif
193 
194 /* Size of stack-allocated buffer passed to strerror_r(). */
195 #define	STRERROR_BUF		64
196 
197 /* Minimum alignment of allocations is 2^QUANTUM_2POW_MIN bytes. */
198 
199 /*
200  * If you touch the TINY_MIN_2POW definition for any architecture, please
201  * make sure to adjust the corresponding definition for JEMALLOC_TINY_MIN_2POW
202  * in the gcc 4.8 tree in dist/gcc/tree-ssa-ccp.c and verify that a native
203  * gcc is still buildable!
204  */
205 
206 #ifdef __i386__
207 #  define QUANTUM_2POW_MIN	4
208 #  define SIZEOF_PTR_2POW	2
209 #  define USE_BRK
210 #endif
211 #ifdef __ia64__
212 #  define QUANTUM_2POW_MIN	4
213 #  define SIZEOF_PTR_2POW	3
214 #endif
215 #ifdef __aarch64__
216 #  define QUANTUM_2POW_MIN	4
217 #  define SIZEOF_PTR_2POW	3
218 #  define TINY_MIN_2POW		3
219 #endif
220 #ifdef __alpha__
221 #  define QUANTUM_2POW_MIN	4
222 #  define SIZEOF_PTR_2POW	3
223 #  define TINY_MIN_2POW		3
224 #endif
225 #ifdef __sparc64__
226 #  define QUANTUM_2POW_MIN	4
227 #  define SIZEOF_PTR_2POW	3
228 #  define TINY_MIN_2POW		3
229 #endif
230 #ifdef __amd64__
231 #  define QUANTUM_2POW_MIN	4
232 #  define SIZEOF_PTR_2POW	3
233 #  define TINY_MIN_2POW		3
234 #endif
235 #ifdef __arm__
236 #  define QUANTUM_2POW_MIN	3
237 #  define SIZEOF_PTR_2POW	2
238 #  define USE_BRK
239 #  ifdef __ARM_EABI__
240 #    define TINY_MIN_2POW	3
241 #  endif
242 #endif
243 #ifdef __powerpc__
244 #  define QUANTUM_2POW_MIN	4
245 #  define SIZEOF_PTR_2POW	2
246 #  define USE_BRK
247 #  define TINY_MIN_2POW		3
248 #endif
249 #if defined(__sparc__) && !defined(__sparc64__)
250 #  define QUANTUM_2POW_MIN	4
251 #  define SIZEOF_PTR_2POW	2
252 #  define USE_BRK
253 #endif
254 #ifdef __or1k__
255 #  define QUANTUM_2POW_MIN	4
256 #  define SIZEOF_PTR_2POW	2
257 #  define USE_BRK
258 #endif
259 #ifdef __vax__
260 #  define QUANTUM_2POW_MIN	4
261 #  define SIZEOF_PTR_2POW	2
262 #  define USE_BRK
263 #  define NO_TLS
264 #endif
265 #ifdef __sh__
266 #  define QUANTUM_2POW_MIN	4
267 #  define SIZEOF_PTR_2POW	2
268 #  define USE_BRK
269 #endif
270 #ifdef __m68k__
271 #  define QUANTUM_2POW_MIN	4
272 #  define SIZEOF_PTR_2POW	2
273 #  define USE_BRK
274 #  ifdef __mc68010__
275 #    define NO_TLS
276 #  endif
277 #endif
278 #if defined(__mips__) || defined(__riscv__)
279 #  ifdef _LP64
280 #    define SIZEOF_PTR_2POW	3
281 #    define TINY_MIN_2POW	3
282 #  else
283 #    define SIZEOF_PTR_2POW	2
284 #  endif
285 #  define QUANTUM_2POW_MIN	4
286 #  define USE_BRK
287 #  if defined(__mips__)
288 #    define NO_TLS
289 #  endif
290 #endif
291 #ifdef __hppa__
292 #  define QUANTUM_2POW_MIN	4
293 #  define TINY_MIN_2POW		4
294 #  define SIZEOF_PTR_2POW	2
295 #  define USE_BRK
296 #endif
297 
298 #define	SIZEOF_PTR		(1 << SIZEOF_PTR_2POW)
299 
300 /* sizeof(int) == (1 << SIZEOF_INT_2POW). */
301 #ifndef SIZEOF_INT_2POW
302 #  define SIZEOF_INT_2POW	2
303 #endif
304 
305 /*
306  * Size and alignment of memory chunks that are allocated by the OS's virtual
307  * memory system.
308  */
309 #define	CHUNK_2POW_DEFAULT	20
310 
311 /*
312  * Maximum size of L1 cache line.  This is used to avoid cache line aliasing,
313  * so over-estimates are okay (up to a point), but under-estimates will
314  * negatively affect performance.
315  */
316 #define	CACHELINE_2POW		6
317 #define	CACHELINE		((size_t)(1 << CACHELINE_2POW))
318 
319 /* Smallest size class to support. */
320 #ifndef TINY_MIN_2POW
321 #define	TINY_MIN_2POW		2
322 #endif
323 
324 /*
325  * Maximum size class that is a multiple of the quantum, but not (necessarily)
326  * a power of 2.  Above this size, allocations are rounded up to the nearest
327  * power of 2.
328  */
329 #define	SMALL_MAX_2POW_DEFAULT	9
330 #define	SMALL_MAX_DEFAULT	(1 << SMALL_MAX_2POW_DEFAULT)
331 
332 /*
333  * RUN_MAX_OVRHD indicates maximum desired run header overhead.  Runs are sized
334  * as small as possible such that this setting is still honored, without
335  * violating other constraints.  The goal is to make runs as small as possible
336  * without exceeding a per run external fragmentation threshold.
337  *
338  * We use binary fixed point math for overhead computations, where the binary
339  * point is implicitly RUN_BFP bits to the left.
340  *
341  * Note that it is possible to set RUN_MAX_OVRHD low enough that it cannot be
342  * honored for some/all object sizes, since there is one bit of header overhead
343  * per object (plus a constant).  This constraint is relaxed (ignored) for runs
344  * that are so small that the per-region overhead is greater than:
345  *
346  *   (RUN_MAX_OVRHD / (reg_size << (3+RUN_BFP))
347  */
348 #define RUN_BFP			12
349 /*                              \/   Implicit binary fixed point. */
350 #define RUN_MAX_OVRHD		0x0000003dU
351 #define RUN_MAX_OVRHD_RELAX	0x00001800U
352 
353 /* Put a cap on small object run size.  This overrides RUN_MAX_OVRHD. */
354 #define RUN_MAX_SMALL_2POW	15
355 #define RUN_MAX_SMALL		(1 << RUN_MAX_SMALL_2POW)
356 
357 /******************************************************************************/
358 
359 #ifdef __FreeBSD__
360 /*
361  * Mutexes based on spinlocks.  We can't use normal pthread mutexes, because
362  * they require malloc()ed memory.
363  */
364 typedef struct {
365 	spinlock_t	lock;
366 } malloc_mutex_t;
367 
368 /* Set to true once the allocator has been initialized. */
369 static bool malloc_initialized = false;
370 
371 /* Used to avoid initialization races. */
372 static malloc_mutex_t init_lock = {_SPINLOCK_INITIALIZER};
373 #else
374 #define	malloc_mutex_t	mutex_t
375 
376 /* Set to true once the allocator has been initialized. */
377 static bool malloc_initialized = false;
378 
379 #ifdef _REENTRANT
380 /* Used to avoid initialization races. */
381 static mutex_t init_lock = MUTEX_INITIALIZER;
382 #endif
383 #endif
384 
385 /******************************************************************************/
386 /*
387  * Statistics data structures.
388  */
389 
390 #ifdef MALLOC_STATS
391 
392 typedef struct malloc_bin_stats_s malloc_bin_stats_t;
393 struct malloc_bin_stats_s {
394 	/*
395 	 * Number of allocation requests that corresponded to the size of this
396 	 * bin.
397 	 */
398 	uint64_t	nrequests;
399 
400 	/* Total number of runs created for this bin's size class. */
401 	uint64_t	nruns;
402 
403 	/*
404 	 * Total number of runs reused by extracting them from the runs tree for
405 	 * this bin's size class.
406 	 */
407 	uint64_t	reruns;
408 
409 	/* High-water mark for this bin. */
410 	unsigned long	highruns;
411 
412 	/* Current number of runs in this bin. */
413 	unsigned long	curruns;
414 };
415 
416 typedef struct arena_stats_s arena_stats_t;
417 struct arena_stats_s {
418 	/* Number of bytes currently mapped. */
419 	size_t		mapped;
420 
421 	/* Per-size-category statistics. */
422 	size_t		allocated_small;
423 	uint64_t	nmalloc_small;
424 	uint64_t	ndalloc_small;
425 
426 	size_t		allocated_large;
427 	uint64_t	nmalloc_large;
428 	uint64_t	ndalloc_large;
429 };
430 
431 typedef struct chunk_stats_s chunk_stats_t;
432 struct chunk_stats_s {
433 	/* Number of chunks that were allocated. */
434 	uint64_t	nchunks;
435 
436 	/* High-water mark for number of chunks allocated. */
437 	unsigned long	highchunks;
438 
439 	/*
440 	 * Current number of chunks allocated.  This value isn't maintained for
441 	 * any other purpose, so keep track of it in order to be able to set
442 	 * highchunks.
443 	 */
444 	unsigned long	curchunks;
445 };
446 
447 #endif /* #ifdef MALLOC_STATS */
448 
449 /******************************************************************************/
450 /*
451  * Chunk data structures.
452  */
453 
454 /* Tree of chunks. */
455 typedef struct chunk_node_s chunk_node_t;
456 struct chunk_node_s {
457 	/* Linkage for the chunk tree. */
458 	RB_ENTRY(chunk_node_s) link;
459 
460 	/*
461 	 * Pointer to the chunk that this tree node is responsible for.  In some
462 	 * (but certainly not all) cases, this data structure is placed at the
463 	 * beginning of the corresponding chunk, so this field may point to this
464 	 * node.
465 	 */
466 	void	*chunk;
467 
468 	/* Total chunk size. */
469 	size_t	size;
470 };
471 typedef struct chunk_tree_s chunk_tree_t;
472 RB_HEAD(chunk_tree_s, chunk_node_s);
473 
474 /******************************************************************************/
475 /*
476  * Arena data structures.
477  */
478 
479 typedef struct arena_s arena_t;
480 typedef struct arena_bin_s arena_bin_t;
481 
482 typedef struct arena_chunk_map_s arena_chunk_map_t;
483 struct arena_chunk_map_s {
484 	/* Number of pages in run. */
485 	uint32_t	npages;
486 	/*
487 	 * Position within run.  For a free run, this is POS_FREE for the first
488 	 * and last pages.  The POS_FREE special value makes it possible to
489 	 * quickly coalesce free runs.
490 	 *
491 	 * This is the limiting factor for chunksize; there can be at most 2^31
492 	 * pages in a run.
493 	 */
494 #define POS_FREE ((uint32_t)0xffffffffU)
495 	uint32_t	pos;
496 };
497 
498 /* Arena chunk header. */
499 typedef struct arena_chunk_s arena_chunk_t;
500 struct arena_chunk_s {
501 	/* Arena that owns the chunk. */
502 	arena_t *arena;
503 
504 	/* Linkage for the arena's chunk tree. */
505 	RB_ENTRY(arena_chunk_s) link;
506 
507 	/*
508 	 * Number of pages in use.  This is maintained in order to make
509 	 * detection of empty chunks fast.
510 	 */
511 	uint32_t pages_used;
512 
513 	/*
514 	 * Every time a free run larger than this value is created/coalesced,
515 	 * this value is increased.  The only way that the value decreases is if
516 	 * arena_run_alloc() fails to find a free run as large as advertised by
517 	 * this value.
518 	 */
519 	uint32_t max_frun_npages;
520 
521 	/*
522 	 * Every time a free run that starts at an earlier page than this value
523 	 * is created/coalesced, this value is decreased.  It is reset in a
524 	 * similar fashion to max_frun_npages.
525 	 */
526 	uint32_t min_frun_ind;
527 
528 	/*
529 	 * Map of pages within chunk that keeps track of free/large/small.  For
530 	 * free runs, only the map entries for the first and last pages are
531 	 * kept up to date, so that free runs can be quickly coalesced.
532 	 */
533 	arena_chunk_map_t map[1]; /* Dynamically sized. */
534 };
535 typedef struct arena_chunk_tree_s arena_chunk_tree_t;
536 RB_HEAD(arena_chunk_tree_s, arena_chunk_s);
537 
538 typedef struct arena_run_s arena_run_t;
539 struct arena_run_s {
540 	/* Linkage for run trees. */
541 	RB_ENTRY(arena_run_s) link;
542 
543 #ifdef MALLOC_DEBUG
544 	uint32_t	magic;
545 #  define ARENA_RUN_MAGIC 0x384adf93
546 #endif
547 
548 	/* Bin this run is associated with. */
549 	arena_bin_t	*bin;
550 
551 	/* Index of first element that might have a free region. */
552 	unsigned	regs_minelm;
553 
554 	/* Number of free regions in run. */
555 	unsigned	nfree;
556 
557 	/* Bitmask of in-use regions (0: in use, 1: free). */
558 	unsigned	regs_mask[1]; /* Dynamically sized. */
559 };
560 typedef struct arena_run_tree_s arena_run_tree_t;
561 RB_HEAD(arena_run_tree_s, arena_run_s);
562 
563 struct arena_bin_s {
564 	/*
565 	 * Current run being used to service allocations of this bin's size
566 	 * class.
567 	 */
568 	arena_run_t	*runcur;
569 
570 	/*
571 	 * Tree of non-full runs.  This tree is used when looking for an
572 	 * existing run when runcur is no longer usable.  We choose the
573 	 * non-full run that is lowest in memory; this policy tends to keep
574 	 * objects packed well, and it can also help reduce the number of
575 	 * almost-empty chunks.
576 	 */
577 	arena_run_tree_t runs;
578 
579 	/* Size of regions in a run for this bin's size class. */
580 	size_t		reg_size;
581 
582 	/* Total size of a run for this bin's size class. */
583 	size_t		run_size;
584 
585 	/* Total number of regions in a run for this bin's size class. */
586 	uint32_t	nregs;
587 
588 	/* Number of elements in a run's regs_mask for this bin's size class. */
589 	uint32_t	regs_mask_nelms;
590 
591 	/* Offset of first region in a run for this bin's size class. */
592 	uint32_t	reg0_offset;
593 
594 #ifdef MALLOC_STATS
595 	/* Bin statistics. */
596 	malloc_bin_stats_t stats;
597 #endif
598 };
599 
600 struct arena_s {
601 #ifdef MALLOC_DEBUG
602 	uint32_t		magic;
603 #  define ARENA_MAGIC 0x947d3d24
604 #endif
605 
606 	/* All operations on this arena require that mtx be locked. */
607 	malloc_mutex_t		mtx;
608 
609 #ifdef MALLOC_STATS
610 	arena_stats_t		stats;
611 #endif
612 
613 	/*
614 	 * Tree of chunks this arena manages.
615 	 */
616 	arena_chunk_tree_t	chunks;
617 
618 	/*
619 	 * In order to avoid rapid chunk allocation/deallocation when an arena
620 	 * oscillates right on the cusp of needing a new chunk, cache the most
621 	 * recently freed chunk.  This caching is disabled by opt_hint.
622 	 *
623 	 * There is one spare chunk per arena, rather than one spare total, in
624 	 * order to avoid interactions between multiple threads that could make
625 	 * a single spare inadequate.
626 	 */
627 	arena_chunk_t *spare;
628 
629 	/*
630 	 * bins is used to store rings of free regions of the following sizes,
631 	 * assuming a 16-byte quantum, 4kB pagesize, and default MALLOC_OPTIONS.
632 	 *
633 	 *   bins[i] | size |
634 	 *   --------+------+
635 	 *        0  |    2 |
636 	 *        1  |    4 |
637 	 *        2  |    8 |
638 	 *   --------+------+
639 	 *        3  |   16 |
640 	 *        4  |   32 |
641 	 *        5  |   48 |
642 	 *        6  |   64 |
643 	 *           :      :
644 	 *           :      :
645 	 *       33  |  496 |
646 	 *       34  |  512 |
647 	 *   --------+------+
648 	 *       35  | 1024 |
649 	 *       36  | 2048 |
650 	 *   --------+------+
651 	 */
652 	arena_bin_t		bins[1]; /* Dynamically sized. */
653 };
654 
655 /******************************************************************************/
656 /*
657  * Data.
658  */
659 
660 /* Number of CPUs. */
661 static unsigned		ncpus;
662 
663 /* VM page size. */
664 static size_t		pagesize;
665 static size_t		pagesize_mask;
666 static int		pagesize_2pow;
667 
668 /* Various bin-related settings. */
669 static size_t		bin_maxclass; /* Max size class for bins. */
670 static unsigned		ntbins; /* Number of (2^n)-spaced tiny bins. */
671 static unsigned		nqbins; /* Number of quantum-spaced bins. */
672 static unsigned		nsbins; /* Number of (2^n)-spaced sub-page bins. */
673 static size_t		small_min;
674 static size_t		small_max;
675 
676 /* Various quantum-related settings. */
677 static size_t		quantum;
678 static size_t		quantum_mask; /* (quantum - 1). */
679 
680 /* Various chunk-related settings. */
681 static size_t		chunksize;
682 static size_t		chunksize_mask; /* (chunksize - 1). */
683 static int		chunksize_2pow;
684 static unsigned		chunk_npages;
685 static unsigned		arena_chunk_header_npages;
686 static size_t		arena_maxclass; /* Max size class for arenas. */
687 
688 /********/
689 /*
690  * Chunks.
691  */
692 
693 #ifdef _REENTRANT
694 /* Protects chunk-related data structures. */
695 static malloc_mutex_t	chunks_mtx;
696 #endif
697 
698 /* Tree of chunks that are stand-alone huge allocations. */
699 static chunk_tree_t	huge;
700 
701 #ifdef USE_BRK
702 /*
703  * Try to use brk for chunk-size allocations, due to address space constraints.
704  */
705 /*
706  * Protects sbrk() calls.  This must be separate from chunks_mtx, since
707  * base_pages_alloc() also uses sbrk(), but cannot lock chunks_mtx (doing so
708  * could cause recursive lock acquisition).
709  */
710 #ifdef _REENTRANT
711 static malloc_mutex_t	brk_mtx;
712 #endif
713 /* Result of first sbrk(0) call. */
714 static void		*brk_base;
715 /* Current end of brk, or ((void *)-1) if brk is exhausted. */
716 static void		*brk_prev;
717 /* Current upper limit on brk addresses. */
718 static void		*brk_max;
719 #endif
720 
721 #ifdef MALLOC_STATS
722 /* Huge allocation statistics. */
723 static uint64_t		huge_nmalloc;
724 static uint64_t		huge_ndalloc;
725 static uint64_t		huge_nralloc;
726 static size_t		huge_allocated;
727 #endif
728 
729 /*
730  * Tree of chunks that were previously allocated.  This is used when allocating
731  * chunks, in an attempt to re-use address space.
732  */
733 static chunk_tree_t	old_chunks;
734 
735 /****************************/
736 /*
737  * base (internal allocation).
738  */
739 
740 /*
741  * Current pages that are being used for internal memory allocations.  These
742  * pages are carved up in cacheline-size quanta, so that there is no chance of
743  * false cache line sharing.
744  */
745 static void		*base_pages;
746 static void		*base_next_addr;
747 static void		*base_past_addr; /* Addr immediately past base_pages. */
748 static chunk_node_t	*base_chunk_nodes; /* LIFO cache of chunk nodes. */
749 #ifdef _REENTRANT
750 static malloc_mutex_t	base_mtx;
751 #endif
752 #ifdef MALLOC_STATS
753 static size_t		base_mapped;
754 #endif
755 
756 /********/
757 /*
758  * Arenas.
759  */
760 
761 /*
762  * Arenas that are used to service external requests.  Not all elements of the
763  * arenas array are necessarily used; arenas are created lazily as needed.
764  */
765 static arena_t		**arenas;
766 static unsigned		narenas;
767 static unsigned		next_arena;
768 #ifdef _REENTRANT
769 static malloc_mutex_t	arenas_mtx; /* Protects arenas initialization. */
770 #endif
771 
772 /*
773  * Map of pthread_self() --> arenas[???], used for selecting an arena to use
774  * for allocations.
775  */
776 #ifndef NO_TLS
777 static __attribute__((tls_model("initial-exec")))
778 __thread arena_t	**arenas_map;
779 #else
780 static arena_t	**arenas_map;
781 #endif
782 
783 #if !defined(NO_TLS) || !defined(_REENTRANT)
784 # define	get_arenas_map()	(arenas_map)
785 # define	set_arenas_map(x)	(arenas_map = x)
786 #else /* NO_TLS && _REENTRANT */
787 
788 static thread_key_t arenas_map_key = -1;
789 
790 static inline arena_t **
791 get_arenas_map(void)
792 {
793 	if (!__isthreaded)
794 		return arenas_map;
795 
796 	if (arenas_map_key == -1) {
797 		(void)thr_keycreate(&arenas_map_key, NULL);
798 		if (arenas_map != NULL) {
799 			thr_setspecific(arenas_map_key, arenas_map);
800 			arenas_map = NULL;
801 		}
802 	}
803 
804 	return thr_getspecific(arenas_map_key);
805 }
806 
807 static __inline void
808 set_arenas_map(arena_t **a)
809 {
810 	if (!__isthreaded) {
811 		arenas_map = a;
812 		return;
813 	}
814 
815 	if (arenas_map_key == -1) {
816 #ifndef NO_TLS
817 		(void)thr_keycreate(&arenas_map_key, NULL);
818 #endif
819 		if (arenas_map != NULL) {
820 			_DIAGASSERT(arenas_map == a);
821 			arenas_map = NULL;
822 		}
823 	}
824 
825 #ifndef NO_TLS
826 	thr_setspecific(arenas_map_key, a);
827 #endif
828 }
829 #endif /* NO_TLS && _REENTRANT */
830 
831 #ifdef MALLOC_STATS
832 /* Chunk statistics. */
833 static chunk_stats_t	stats_chunks;
834 #endif
835 
836 /*******************************/
837 /*
838  * Runtime configuration options.
839  */
840 const char	*_malloc_options;
841 
842 #ifndef MALLOC_PRODUCTION
843 static bool	opt_abort = true;
844 static bool	opt_junk = true;
845 #else
846 static bool	opt_abort = false;
847 static bool	opt_junk = false;
848 #endif
849 static bool	opt_hint = false;
850 static bool	opt_print_stats = false;
851 static int	opt_quantum_2pow = QUANTUM_2POW_MIN;
852 static int	opt_small_max_2pow = SMALL_MAX_2POW_DEFAULT;
853 static int	opt_chunk_2pow = CHUNK_2POW_DEFAULT;
854 static bool	opt_utrace = false;
855 static bool	opt_sysv = false;
856 static bool	opt_xmalloc = false;
857 static bool	opt_zero = false;
858 static int32_t	opt_narenas_lshift = 0;
859 
860 typedef struct {
861 	void	*p;
862 	size_t	s;
863 	void	*r;
864 } malloc_utrace_t;
865 
866 #define	UTRACE(a, b, c)							\
867 	if (opt_utrace) {						\
868 		malloc_utrace_t ut;					\
869 		ut.p = a;						\
870 		ut.s = b;						\
871 		ut.r = c;						\
872 		xutrace(&ut, sizeof(ut));				\
873 	}
874 
875 /******************************************************************************/
876 /*
877  * Begin function prototypes for non-inline static functions.
878  */
879 
880 static void	wrtmessage(const char *p1, const char *p2, const char *p3,
881 		const char *p4);
882 #ifdef MALLOC_STATS
883 static void	malloc_printf(const char *format, ...);
884 #endif
885 static char	*size_t2s(size_t x, char *s);
886 static bool	base_pages_alloc(size_t minsize);
887 static void	*base_alloc(size_t size);
888 static chunk_node_t *base_chunk_node_alloc(void);
889 static void	base_chunk_node_dealloc(chunk_node_t *node);
890 #ifdef MALLOC_STATS
891 static void	stats_print(arena_t *arena);
892 #endif
893 static void	*pages_map(void *addr, size_t size);
894 static void	*pages_map_align(void *addr, size_t size, int align);
895 static void	pages_unmap(void *addr, size_t size);
896 static void	*chunk_alloc(size_t size);
897 static void	chunk_dealloc(void *chunk, size_t size);
898 static void	arena_run_split(arena_t *arena, arena_run_t *run, size_t size);
899 static arena_chunk_t *arena_chunk_alloc(arena_t *arena);
900 static void	arena_chunk_dealloc(arena_t *arena, arena_chunk_t *chunk);
901 static arena_run_t *arena_run_alloc(arena_t *arena, size_t size);
902 static void	arena_run_dalloc(arena_t *arena, arena_run_t *run, size_t size);
903 static arena_run_t *arena_bin_nonfull_run_get(arena_t *arena, arena_bin_t *bin);
904 static void *arena_bin_malloc_hard(arena_t *arena, arena_bin_t *bin);
905 static size_t arena_bin_run_size_calc(arena_bin_t *bin, size_t min_run_size);
906 static void	*arena_malloc(arena_t *arena, size_t size);
907 static void	*arena_palloc(arena_t *arena, size_t alignment, size_t size,
908     size_t alloc_size);
909 static size_t	arena_salloc(const void *ptr);
910 static void	*arena_ralloc(void *ptr, size_t size, size_t oldsize);
911 static void	arena_dalloc(arena_t *arena, arena_chunk_t *chunk, void *ptr);
912 static bool	arena_new(arena_t *arena);
913 static arena_t	*arenas_extend(unsigned ind);
914 static void	*huge_malloc(size_t size);
915 static void	*huge_palloc(size_t alignment, size_t size);
916 static void	*huge_ralloc(void *ptr, size_t size, size_t oldsize);
917 static void	huge_dalloc(void *ptr);
918 static void	*imalloc(size_t size);
919 static void	*ipalloc(size_t alignment, size_t size);
920 static void	*icalloc(size_t size);
921 static size_t	isalloc(const void *ptr);
922 static void	*iralloc(void *ptr, size_t size);
923 static void	idalloc(void *ptr);
924 static void	malloc_print_stats(void);
925 static bool	malloc_init_hard(void);
926 
927 /*
928  * End function prototypes.
929  */
930 /******************************************************************************/
931 /*
932  * Begin mutex.
933  */
934 
935 #ifdef __NetBSD__
936 #define	malloc_mutex_init(m)	mutex_init(m, NULL)
937 #define	malloc_mutex_lock(m)	mutex_lock(m)
938 #define	malloc_mutex_unlock(m)	mutex_unlock(m)
939 #else	/* __NetBSD__ */
940 static inline void
941 malloc_mutex_init(malloc_mutex_t *a_mutex)
942 {
943 	static const spinlock_t lock = _SPINLOCK_INITIALIZER;
944 
945 	a_mutex->lock = lock;
946 }
947 
948 static inline void
949 malloc_mutex_lock(malloc_mutex_t *a_mutex)
950 {
951 
952 	if (__isthreaded)
953 		_SPINLOCK(&a_mutex->lock);
954 }
955 
956 static inline void
957 malloc_mutex_unlock(malloc_mutex_t *a_mutex)
958 {
959 
960 	if (__isthreaded)
961 		_SPINUNLOCK(&a_mutex->lock);
962 }
963 #endif	/* __NetBSD__ */
964 
965 /*
966  * End mutex.
967  */
968 /******************************************************************************/
969 /*
970  * Begin Utility functions/macros.
971  */
972 
973 /* Return the chunk address for allocation address a. */
974 #define	CHUNK_ADDR2BASE(a)						\
975 	((void *)((uintptr_t)(a) & ~chunksize_mask))
976 
977 /* Return the chunk offset of address a. */
978 #define	CHUNK_ADDR2OFFSET(a)						\
979 	((size_t)((uintptr_t)(a) & chunksize_mask))
980 
981 /* Return the smallest chunk multiple that is >= s. */
982 #define	CHUNK_CEILING(s)						\
983 	(((s) + chunksize_mask) & ~chunksize_mask)
984 
985 /* Return the smallest cacheline multiple that is >= s. */
986 #define	CACHELINE_CEILING(s)						\
987 	(((s) + (CACHELINE - 1)) & ~(CACHELINE - 1))
988 
989 /* Return the smallest quantum multiple that is >= a. */
990 #define	QUANTUM_CEILING(a)						\
991 	(((a) + quantum_mask) & ~quantum_mask)
992 
993 /* Return the smallest pagesize multiple that is >= s. */
994 #define	PAGE_CEILING(s)							\
995 	(((s) + pagesize_mask) & ~pagesize_mask)
996 
997 /* Compute the smallest power of 2 that is >= x. */
998 static inline size_t
999 pow2_ceil(size_t x)
1000 {
1001 
1002 	x--;
1003 	x |= x >> 1;
1004 	x |= x >> 2;
1005 	x |= x >> 4;
1006 	x |= x >> 8;
1007 	x |= x >> 16;
1008 #if (SIZEOF_PTR == 8)
1009 	x |= x >> 32;
1010 #endif
1011 	x++;
1012 	return (x);
1013 }
1014 
1015 static void
1016 wrtmessage(const char *p1, const char *p2, const char *p3, const char *p4)
1017 {
1018 
1019 	write(STDERR_FILENO, p1, strlen(p1));
1020 	write(STDERR_FILENO, p2, strlen(p2));
1021 	write(STDERR_FILENO, p3, strlen(p3));
1022 	write(STDERR_FILENO, p4, strlen(p4));
1023 }
1024 
1025 void	(*_malloc_message)(const char *p1, const char *p2, const char *p3,
1026 	    const char *p4) = wrtmessage;
1027 
1028 #ifdef MALLOC_STATS
1029 /*
1030  * Print to stderr in such a way as to (hopefully) avoid memory allocation.
1031  */
1032 static void
1033 malloc_printf(const char *format, ...)
1034 {
1035 	char buf[4096];
1036 	va_list ap;
1037 
1038 	va_start(ap, format);
1039 	vsnprintf(buf, sizeof(buf), format, ap);
1040 	va_end(ap);
1041 	_malloc_message(buf, "", "", "");
1042 }
1043 #endif
1044 
1045 /*
1046  * We don't want to depend on vsnprintf() for production builds, since that can
1047  * cause unnecessary bloat for static binaries.  size_t2s() provides minimal
1048  * integer printing functionality, so that malloc_printf() use can be limited to
1049  * MALLOC_STATS code.
1050  */
1051 #define UMAX2S_BUFSIZE	21
1052 static char *
1053 size_t2s(size_t x, char *s)
1054 {
1055 	unsigned i;
1056 
1057 	/* Make sure UMAX2S_BUFSIZE is large enough. */
1058 	/* LINTED */
1059 	assert(sizeof(size_t) <= 8);
1060 
1061 	i = UMAX2S_BUFSIZE - 1;
1062 	s[i] = '\0';
1063 	do {
1064 		i--;
1065 		s[i] = "0123456789"[(int)x % 10];
1066 		x /= (uintmax_t)10LL;
1067 	} while (x > 0);
1068 
1069 	return (&s[i]);
1070 }
1071 
1072 /******************************************************************************/
1073 
1074 static bool
1075 base_pages_alloc(size_t minsize)
1076 {
1077 	size_t csize = 0;
1078 
1079 #ifdef USE_BRK
1080 	/*
1081 	 * Do special brk allocation here, since base allocations don't need to
1082 	 * be chunk-aligned.
1083 	 */
1084 	if (brk_prev != (void *)-1) {
1085 		void *brk_cur;
1086 		intptr_t incr;
1087 
1088 		if (minsize != 0)
1089 			csize = CHUNK_CEILING(minsize);
1090 
1091 		malloc_mutex_lock(&brk_mtx);
1092 		do {
1093 			/* Get the current end of brk. */
1094 			brk_cur = sbrk(0);
1095 
1096 			/*
1097 			 * Calculate how much padding is necessary to
1098 			 * chunk-align the end of brk.  Don't worry about
1099 			 * brk_cur not being chunk-aligned though.
1100 			 */
1101 			incr = (intptr_t)chunksize
1102 			    - (intptr_t)CHUNK_ADDR2OFFSET(brk_cur);
1103 			assert(incr >= 0);
1104 			if ((size_t)incr < minsize)
1105 				incr += csize;
1106 
1107 			brk_prev = sbrk(incr);
1108 			if (brk_prev == brk_cur) {
1109 				/* Success. */
1110 				malloc_mutex_unlock(&brk_mtx);
1111 				base_pages = brk_cur;
1112 				base_next_addr = base_pages;
1113 				base_past_addr = (void *)((uintptr_t)base_pages
1114 				    + incr);
1115 #ifdef MALLOC_STATS
1116 				base_mapped += incr;
1117 #endif
1118 				return (false);
1119 			}
1120 		} while (brk_prev != (void *)-1);
1121 		malloc_mutex_unlock(&brk_mtx);
1122 	}
1123 	if (minsize == 0) {
1124 		/*
1125 		 * Failure during initialization doesn't matter, so avoid
1126 		 * falling through to the mmap-based page mapping code.
1127 		 */
1128 		return (true);
1129 	}
1130 #endif
1131 	assert(minsize != 0);
1132 	csize = PAGE_CEILING(minsize);
1133 	base_pages = pages_map(NULL, csize);
1134 	if (base_pages == NULL)
1135 		return (true);
1136 	base_next_addr = base_pages;
1137 	base_past_addr = (void *)((uintptr_t)base_pages + csize);
1138 #ifdef MALLOC_STATS
1139 	base_mapped += csize;
1140 #endif
1141 	return (false);
1142 }
1143 
1144 static void *
1145 base_alloc(size_t size)
1146 {
1147 	void *ret;
1148 	size_t csize;
1149 
1150 	/* Round size up to nearest multiple of the cacheline size. */
1151 	csize = CACHELINE_CEILING(size);
1152 
1153 	malloc_mutex_lock(&base_mtx);
1154 
1155 	/* Make sure there's enough space for the allocation. */
1156 	if ((uintptr_t)base_next_addr + csize > (uintptr_t)base_past_addr) {
1157 		if (base_pages_alloc(csize)) {
1158 			ret = NULL;
1159 			goto RETURN;
1160 		}
1161 	}
1162 
1163 	/* Allocate. */
1164 	ret = base_next_addr;
1165 	base_next_addr = (void *)((uintptr_t)base_next_addr + csize);
1166 
1167 RETURN:
1168 	malloc_mutex_unlock(&base_mtx);
1169 	return (ret);
1170 }
1171 
1172 static chunk_node_t *
1173 base_chunk_node_alloc(void)
1174 {
1175 	chunk_node_t *ret;
1176 
1177 	malloc_mutex_lock(&base_mtx);
1178 	if (base_chunk_nodes != NULL) {
1179 		ret = base_chunk_nodes;
1180 		/* LINTED */
1181 		base_chunk_nodes = *(chunk_node_t **)ret;
1182 		malloc_mutex_unlock(&base_mtx);
1183 	} else {
1184 		malloc_mutex_unlock(&base_mtx);
1185 		ret = (chunk_node_t *)base_alloc(sizeof(chunk_node_t));
1186 	}
1187 
1188 	return (ret);
1189 }
1190 
1191 static void
1192 base_chunk_node_dealloc(chunk_node_t *node)
1193 {
1194 
1195 	malloc_mutex_lock(&base_mtx);
1196 	/* LINTED */
1197 	*(chunk_node_t **)node = base_chunk_nodes;
1198 	base_chunk_nodes = node;
1199 	malloc_mutex_unlock(&base_mtx);
1200 }
1201 
1202 /******************************************************************************/
1203 
1204 #ifdef MALLOC_STATS
1205 static void
1206 stats_print(arena_t *arena)
1207 {
1208 	unsigned i;
1209 	int gap_start;
1210 
1211 	malloc_printf(
1212 	    "          allocated/mapped            nmalloc      ndalloc\n");
1213 
1214 	malloc_printf("small: %12zu %-12s %12llu %12llu\n",
1215 	    arena->stats.allocated_small, "", arena->stats.nmalloc_small,
1216 	    arena->stats.ndalloc_small);
1217 	malloc_printf("large: %12zu %-12s %12llu %12llu\n",
1218 	    arena->stats.allocated_large, "", arena->stats.nmalloc_large,
1219 	    arena->stats.ndalloc_large);
1220 	malloc_printf("total: %12zu/%-12zu %12llu %12llu\n",
1221 	    arena->stats.allocated_small + arena->stats.allocated_large,
1222 	    arena->stats.mapped,
1223 	    arena->stats.nmalloc_small + arena->stats.nmalloc_large,
1224 	    arena->stats.ndalloc_small + arena->stats.ndalloc_large);
1225 
1226 	malloc_printf("bins:     bin   size regs pgs  requests   newruns"
1227 	    "    reruns maxruns curruns\n");
1228 	for (i = 0, gap_start = -1; i < ntbins + nqbins + nsbins; i++) {
1229 		if (arena->bins[i].stats.nrequests == 0) {
1230 			if (gap_start == -1)
1231 				gap_start = i;
1232 		} else {
1233 			if (gap_start != -1) {
1234 				if (i > gap_start + 1) {
1235 					/* Gap of more than one size class. */
1236 					malloc_printf("[%u..%u]\n",
1237 					    gap_start, i - 1);
1238 				} else {
1239 					/* Gap of one size class. */
1240 					malloc_printf("[%u]\n", gap_start);
1241 				}
1242 				gap_start = -1;
1243 			}
1244 			malloc_printf(
1245 			    "%13u %1s %4u %4u %3u %9llu %9llu"
1246 			    " %9llu %7lu %7lu\n",
1247 			    i,
1248 			    i < ntbins ? "T" : i < ntbins + nqbins ? "Q" : "S",
1249 			    arena->bins[i].reg_size,
1250 			    arena->bins[i].nregs,
1251 			    arena->bins[i].run_size >> pagesize_2pow,
1252 			    arena->bins[i].stats.nrequests,
1253 			    arena->bins[i].stats.nruns,
1254 			    arena->bins[i].stats.reruns,
1255 			    arena->bins[i].stats.highruns,
1256 			    arena->bins[i].stats.curruns);
1257 		}
1258 	}
1259 	if (gap_start != -1) {
1260 		if (i > gap_start + 1) {
1261 			/* Gap of more than one size class. */
1262 			malloc_printf("[%u..%u]\n", gap_start, i - 1);
1263 		} else {
1264 			/* Gap of one size class. */
1265 			malloc_printf("[%u]\n", gap_start);
1266 		}
1267 	}
1268 }
1269 #endif
1270 
1271 /*
1272  * End Utility functions/macros.
1273  */
1274 /******************************************************************************/
1275 /*
1276  * Begin chunk management functions.
1277  */
1278 
1279 static inline int
1280 chunk_comp(chunk_node_t *a, chunk_node_t *b)
1281 {
1282 
1283 	assert(a != NULL);
1284 	assert(b != NULL);
1285 
1286 	if ((uintptr_t)a->chunk < (uintptr_t)b->chunk)
1287 		return (-1);
1288 	else if (a->chunk == b->chunk)
1289 		return (0);
1290 	else
1291 		return (1);
1292 }
1293 
1294 /* Generate red-black tree code for chunks. */
1295 RB_GENERATE_STATIC(chunk_tree_s, chunk_node_s, link, chunk_comp)
1296 
1297 static void *
1298 pages_map_align(void *addr, size_t size, int align)
1299 {
1300 	void *ret;
1301 
1302 	/*
1303 	 * We don't use MAP_FIXED here, because it can cause the *replacement*
1304 	 * of existing mappings, and we only want to create new mappings.
1305 	 */
1306 	ret = mmap(addr, size, PROT_READ | PROT_WRITE,
1307 	    MAP_PRIVATE | MAP_ANON | MAP_ALIGNED(align), -1, 0);
1308 	assert(ret != NULL);
1309 
1310 	if (ret == MAP_FAILED)
1311 		ret = NULL;
1312 	else if (addr != NULL && ret != addr) {
1313 		/*
1314 		 * We succeeded in mapping memory, but not in the right place.
1315 		 */
1316 		if (munmap(ret, size) == -1) {
1317 			char buf[STRERROR_BUF];
1318 
1319 			STRERROR_R(errno, buf, sizeof(buf));
1320 			_malloc_message(getprogname(),
1321 			    ": (malloc) Error in munmap(): ", buf, "\n");
1322 			if (opt_abort)
1323 				abort();
1324 		}
1325 		ret = NULL;
1326 	}
1327 
1328 	assert(ret == NULL || (addr == NULL && ret != addr)
1329 	    || (addr != NULL && ret == addr));
1330 	return (ret);
1331 }
1332 
1333 static void *
1334 pages_map(void *addr, size_t size)
1335 {
1336 
1337 	return pages_map_align(addr, size, 0);
1338 }
1339 
1340 static void
1341 pages_unmap(void *addr, size_t size)
1342 {
1343 
1344 	if (munmap(addr, size) == -1) {
1345 		char buf[STRERROR_BUF];
1346 
1347 		STRERROR_R(errno, buf, sizeof(buf));
1348 		_malloc_message(getprogname(),
1349 		    ": (malloc) Error in munmap(): ", buf, "\n");
1350 		if (opt_abort)
1351 			abort();
1352 	}
1353 }
1354 
1355 static void *
1356 chunk_alloc(size_t size)
1357 {
1358 	void *ret, *chunk;
1359 	chunk_node_t *tchunk, *delchunk;
1360 
1361 	assert(size != 0);
1362 	assert((size & chunksize_mask) == 0);
1363 
1364 	malloc_mutex_lock(&chunks_mtx);
1365 
1366 	if (size == chunksize) {
1367 		/*
1368 		 * Check for address ranges that were previously chunks and try
1369 		 * to use them.
1370 		 */
1371 
1372 		tchunk = RB_MIN(chunk_tree_s, &old_chunks);
1373 		while (tchunk != NULL) {
1374 			/* Found an address range.  Try to recycle it. */
1375 
1376 			chunk = tchunk->chunk;
1377 			delchunk = tchunk;
1378 			tchunk = RB_NEXT(chunk_tree_s, &old_chunks, delchunk);
1379 
1380 			/* Remove delchunk from the tree. */
1381 			RB_REMOVE(chunk_tree_s, &old_chunks, delchunk);
1382 			base_chunk_node_dealloc(delchunk);
1383 
1384 #ifdef USE_BRK
1385 			if ((uintptr_t)chunk >= (uintptr_t)brk_base
1386 			    && (uintptr_t)chunk < (uintptr_t)brk_max) {
1387 				/* Re-use a previously freed brk chunk. */
1388 				ret = chunk;
1389 				goto RETURN;
1390 			}
1391 #endif
1392 			if ((ret = pages_map(chunk, size)) != NULL) {
1393 				/* Success. */
1394 				goto RETURN;
1395 			}
1396 		}
1397 	}
1398 
1399 	/*
1400 	 * Try to over-allocate, but allow the OS to place the allocation
1401 	 * anywhere.  Beware of size_t wrap-around.
1402 	 */
1403 	if (size + chunksize > size) {
1404 		if ((ret = pages_map_align(NULL, size, chunksize_2pow))
1405 		    != NULL) {
1406 			goto RETURN;
1407 		}
1408 	}
1409 
1410 #ifdef USE_BRK
1411 	/*
1412 	 * Try to create allocations in brk, in order to make full use of
1413 	 * limited address space.
1414 	 */
1415 	if (brk_prev != (void *)-1) {
1416 		void *brk_cur;
1417 		intptr_t incr;
1418 
1419 		/*
1420 		 * The loop is necessary to recover from races with other
1421 		 * threads that are using brk for something other than malloc.
1422 		 */
1423 		malloc_mutex_lock(&brk_mtx);
1424 		do {
1425 			/* Get the current end of brk. */
1426 			brk_cur = sbrk(0);
1427 
1428 			/*
1429 			 * Calculate how much padding is necessary to
1430 			 * chunk-align the end of brk.
1431 			 */
1432 			incr = (intptr_t)size
1433 			    - (intptr_t)CHUNK_ADDR2OFFSET(brk_cur);
1434 			if (incr == (intptr_t)size) {
1435 				ret = brk_cur;
1436 			} else {
1437 				ret = (void *)((intptr_t)brk_cur + incr);
1438 				incr += size;
1439 			}
1440 
1441 			brk_prev = sbrk(incr);
1442 			if (brk_prev == brk_cur) {
1443 				/* Success. */
1444 				malloc_mutex_unlock(&brk_mtx);
1445 				brk_max = (void *)((intptr_t)ret + size);
1446 				goto RETURN;
1447 			}
1448 		} while (brk_prev != (void *)-1);
1449 		malloc_mutex_unlock(&brk_mtx);
1450 	}
1451 #endif
1452 
1453 	/* All strategies for allocation failed. */
1454 	ret = NULL;
1455 RETURN:
1456 	if (ret != NULL) {
1457 		chunk_node_t key;
1458 		/*
1459 		 * Clean out any entries in old_chunks that overlap with the
1460 		 * memory we just allocated.
1461 		 */
1462 		key.chunk = ret;
1463 		tchunk = RB_NFIND(chunk_tree_s, &old_chunks, &key);
1464 		while (tchunk != NULL
1465 		    && (uintptr_t)tchunk->chunk >= (uintptr_t)ret
1466 		    && (uintptr_t)tchunk->chunk < (uintptr_t)ret + size) {
1467 			delchunk = tchunk;
1468 			tchunk = RB_NEXT(chunk_tree_s, &old_chunks, delchunk);
1469 			RB_REMOVE(chunk_tree_s, &old_chunks, delchunk);
1470 			base_chunk_node_dealloc(delchunk);
1471 		}
1472 
1473 	}
1474 #ifdef MALLOC_STATS
1475 	if (ret != NULL) {
1476 		stats_chunks.nchunks += (size / chunksize);
1477 		stats_chunks.curchunks += (size / chunksize);
1478 	}
1479 	if (stats_chunks.curchunks > stats_chunks.highchunks)
1480 		stats_chunks.highchunks = stats_chunks.curchunks;
1481 #endif
1482 	malloc_mutex_unlock(&chunks_mtx);
1483 
1484 	assert(CHUNK_ADDR2BASE(ret) == ret);
1485 	return (ret);
1486 }
1487 
1488 static void
1489 chunk_dealloc(void *chunk, size_t size)
1490 {
1491 	chunk_node_t *node;
1492 
1493 	assert(chunk != NULL);
1494 	assert(CHUNK_ADDR2BASE(chunk) == chunk);
1495 	assert(size != 0);
1496 	assert((size & chunksize_mask) == 0);
1497 
1498 	malloc_mutex_lock(&chunks_mtx);
1499 
1500 #ifdef USE_BRK
1501 	if ((uintptr_t)chunk >= (uintptr_t)brk_base
1502 	    && (uintptr_t)chunk < (uintptr_t)brk_max) {
1503 		void *brk_cur;
1504 
1505 		malloc_mutex_lock(&brk_mtx);
1506 		/* Get the current end of brk. */
1507 		brk_cur = sbrk(0);
1508 
1509 		/*
1510 		 * Try to shrink the data segment if this chunk is at the end
1511 		 * of the data segment.  The sbrk() call here is subject to a
1512 		 * race condition with threads that use brk(2) or sbrk(2)
1513 		 * directly, but the alternative would be to leak memory for
1514 		 * the sake of poorly designed multi-threaded programs.
1515 		 */
1516 		if (brk_cur == brk_max
1517 		    && (void *)((uintptr_t)chunk + size) == brk_max
1518 		    && sbrk(-(intptr_t)size) == brk_max) {
1519 			malloc_mutex_unlock(&brk_mtx);
1520 			if (brk_prev == brk_max) {
1521 				/* Success. */
1522 				brk_prev = (void *)((intptr_t)brk_max
1523 				    - (intptr_t)size);
1524 				brk_max = brk_prev;
1525 			}
1526 		} else {
1527 			size_t offset;
1528 
1529 			malloc_mutex_unlock(&brk_mtx);
1530 			madvise(chunk, size, MADV_FREE);
1531 
1532 			/*
1533 			 * Iteratively create records of each chunk-sized
1534 			 * memory region that 'chunk' is comprised of, so that
1535 			 * the address range can be recycled if memory usage
1536 			 * increases later on.
1537 			 */
1538 			for (offset = 0; offset < size; offset += chunksize) {
1539 				node = base_chunk_node_alloc();
1540 				if (node == NULL)
1541 					break;
1542 
1543 				node->chunk = (void *)((uintptr_t)chunk
1544 				    + (uintptr_t)offset);
1545 				node->size = chunksize;
1546 				RB_INSERT(chunk_tree_s, &old_chunks, node);
1547 			}
1548 		}
1549 	} else {
1550 #endif
1551 		pages_unmap(chunk, size);
1552 
1553 		/*
1554 		 * Make a record of the chunk's address, so that the address
1555 		 * range can be recycled if memory usage increases later on.
1556 		 * Don't bother to create entries if (size > chunksize), since
1557 		 * doing so could cause scalability issues for truly gargantuan
1558 		 * objects (many gigabytes or larger).
1559 		 */
1560 		if (size == chunksize) {
1561 			node = base_chunk_node_alloc();
1562 			if (node != NULL) {
1563 				node->chunk = (void *)(uintptr_t)chunk;
1564 				node->size = chunksize;
1565 				RB_INSERT(chunk_tree_s, &old_chunks, node);
1566 			}
1567 		}
1568 #ifdef USE_BRK
1569 	}
1570 #endif
1571 
1572 #ifdef MALLOC_STATS
1573 	stats_chunks.curchunks -= (size / chunksize);
1574 #endif
1575 	malloc_mutex_unlock(&chunks_mtx);
1576 }
1577 
1578 /*
1579  * End chunk management functions.
1580  */
1581 /******************************************************************************/
1582 /*
1583  * Begin arena.
1584  */
1585 
1586 /*
1587  * Choose an arena based on a per-thread and (optimistically) per-CPU value.
1588  *
1589  * We maintain at least one block of arenas.  Usually there are more.
1590  * The blocks are $ncpu arenas in size.  Whole blocks are 'hashed'
1591  * amongst threads.  To accomplish this, next_arena advances only in
1592  * ncpu steps.
1593  */
1594 static __noinline arena_t *
1595 choose_arena_hard(void)
1596 {
1597 	unsigned i, curcpu;
1598 	arena_t **map;
1599 
1600 	/* Initialize the current block of arenas and advance to next. */
1601 	malloc_mutex_lock(&arenas_mtx);
1602 	assert(next_arena % ncpus == 0);
1603 	assert(narenas % ncpus == 0);
1604 	map = &arenas[next_arena];
1605 	set_arenas_map(map);
1606 	for (i = 0; i < ncpus; i++) {
1607 		if (arenas[next_arena] == NULL)
1608 			arenas_extend(next_arena);
1609 		next_arena = (next_arena + 1) % narenas;
1610 	}
1611 	malloc_mutex_unlock(&arenas_mtx);
1612 
1613 	/*
1614 	 * If we were unable to allocate an arena above, then default to
1615 	 * the first arena, which is always present.
1616 	 */
1617 	curcpu = thr_curcpu();
1618 	if (map[curcpu] != NULL)
1619 		return map[curcpu];
1620 	return arenas[0];
1621 }
1622 
1623 static inline arena_t *
1624 choose_arena(void)
1625 {
1626 	unsigned curcpu;
1627 	arena_t **map;
1628 
1629 	map = get_arenas_map();
1630 	curcpu = thr_curcpu();
1631 	if (__predict_true(map != NULL && map[curcpu] != NULL))
1632 		return map[curcpu];
1633 
1634         return choose_arena_hard();
1635 }
1636 
1637 static inline int
1638 arena_chunk_comp(arena_chunk_t *a, arena_chunk_t *b)
1639 {
1640 
1641 	assert(a != NULL);
1642 	assert(b != NULL);
1643 
1644 	if (a->max_frun_npages < b->max_frun_npages)
1645 		return -1;
1646 	if (a->max_frun_npages > b->max_frun_npages)
1647 		return 1;
1648 
1649 	if ((uintptr_t)a < (uintptr_t)b)
1650 		return (-1);
1651 	else if (a == b)
1652 		return (0);
1653 	else
1654 		return (1);
1655 }
1656 
1657 /* Generate red-black tree code for arena chunks. */
1658 RB_GENERATE_STATIC(arena_chunk_tree_s, arena_chunk_s, link, arena_chunk_comp)
1659 
1660 static inline int
1661 arena_run_comp(arena_run_t *a, arena_run_t *b)
1662 {
1663 
1664 	assert(a != NULL);
1665 	assert(b != NULL);
1666 
1667 	if ((uintptr_t)a < (uintptr_t)b)
1668 		return (-1);
1669 	else if (a == b)
1670 		return (0);
1671 	else
1672 		return (1);
1673 }
1674 
1675 /* Generate red-black tree code for arena runs. */
1676 RB_GENERATE_STATIC(arena_run_tree_s, arena_run_s, link, arena_run_comp)
1677 
1678 static inline void *
1679 arena_run_reg_alloc(arena_run_t *run, arena_bin_t *bin)
1680 {
1681 	void *ret;
1682 	unsigned i, mask, bit, regind;
1683 
1684 	assert(run->magic == ARENA_RUN_MAGIC);
1685 	assert(run->regs_minelm < bin->regs_mask_nelms);
1686 
1687 	/*
1688 	 * Move the first check outside the loop, so that run->regs_minelm can
1689 	 * be updated unconditionally, without the possibility of updating it
1690 	 * multiple times.
1691 	 */
1692 	i = run->regs_minelm;
1693 	mask = run->regs_mask[i];
1694 	if (mask != 0) {
1695 		/* Usable allocation found. */
1696 		bit = ffs((int)mask) - 1;
1697 
1698 		regind = ((i << (SIZEOF_INT_2POW + 3)) + bit);
1699 		ret = (void *)(((uintptr_t)run) + bin->reg0_offset
1700 		    + (bin->reg_size * regind));
1701 
1702 		/* Clear bit. */
1703 		mask ^= (1U << bit);
1704 		run->regs_mask[i] = mask;
1705 
1706 		return (ret);
1707 	}
1708 
1709 	for (i++; i < bin->regs_mask_nelms; i++) {
1710 		mask = run->regs_mask[i];
1711 		if (mask != 0) {
1712 			/* Usable allocation found. */
1713 			bit = ffs((int)mask) - 1;
1714 
1715 			regind = ((i << (SIZEOF_INT_2POW + 3)) + bit);
1716 			ret = (void *)(((uintptr_t)run) + bin->reg0_offset
1717 			    + (bin->reg_size * regind));
1718 
1719 			/* Clear bit. */
1720 			mask ^= (1U << bit);
1721 			run->regs_mask[i] = mask;
1722 
1723 			/*
1724 			 * Make a note that nothing before this element
1725 			 * contains a free region.
1726 			 */
1727 			run->regs_minelm = i; /* Low payoff: + (mask == 0); */
1728 
1729 			return (ret);
1730 		}
1731 	}
1732 	/* Not reached. */
1733 	/* LINTED */
1734 	assert(0);
1735 	return (NULL);
1736 }
1737 
1738 static inline void
1739 arena_run_reg_dalloc(arena_run_t *run, arena_bin_t *bin, void *ptr, size_t size)
1740 {
1741 	/*
1742 	 * To divide by a number D that is not a power of two we multiply
1743 	 * by (2^21 / D) and then right shift by 21 positions.
1744 	 *
1745 	 *   X / D
1746 	 *
1747 	 * becomes
1748 	 *
1749 	 *   (X * size_invs[(D >> QUANTUM_2POW_MIN) - 3]) >> SIZE_INV_SHIFT
1750 	 */
1751 #define SIZE_INV_SHIFT 21
1752 #define SIZE_INV(s) (((1 << SIZE_INV_SHIFT) / (s << QUANTUM_2POW_MIN)) + 1)
1753 	static const unsigned size_invs[] = {
1754 	    SIZE_INV(3),
1755 	    SIZE_INV(4), SIZE_INV(5), SIZE_INV(6), SIZE_INV(7),
1756 	    SIZE_INV(8), SIZE_INV(9), SIZE_INV(10), SIZE_INV(11),
1757 	    SIZE_INV(12),SIZE_INV(13), SIZE_INV(14), SIZE_INV(15),
1758 	    SIZE_INV(16),SIZE_INV(17), SIZE_INV(18), SIZE_INV(19),
1759 	    SIZE_INV(20),SIZE_INV(21), SIZE_INV(22), SIZE_INV(23),
1760 	    SIZE_INV(24),SIZE_INV(25), SIZE_INV(26), SIZE_INV(27),
1761 	    SIZE_INV(28),SIZE_INV(29), SIZE_INV(30), SIZE_INV(31)
1762 #if (QUANTUM_2POW_MIN < 4)
1763 	    ,
1764 	    SIZE_INV(32), SIZE_INV(33), SIZE_INV(34), SIZE_INV(35),
1765 	    SIZE_INV(36), SIZE_INV(37), SIZE_INV(38), SIZE_INV(39),
1766 	    SIZE_INV(40), SIZE_INV(41), SIZE_INV(42), SIZE_INV(43),
1767 	    SIZE_INV(44), SIZE_INV(45), SIZE_INV(46), SIZE_INV(47),
1768 	    SIZE_INV(48), SIZE_INV(49), SIZE_INV(50), SIZE_INV(51),
1769 	    SIZE_INV(52), SIZE_INV(53), SIZE_INV(54), SIZE_INV(55),
1770 	    SIZE_INV(56), SIZE_INV(57), SIZE_INV(58), SIZE_INV(59),
1771 	    SIZE_INV(60), SIZE_INV(61), SIZE_INV(62), SIZE_INV(63)
1772 #endif
1773 	};
1774 	unsigned diff, regind, elm, bit;
1775 
1776 	/* LINTED */
1777 	assert(run->magic == ARENA_RUN_MAGIC);
1778 	assert(((sizeof(size_invs)) / sizeof(unsigned)) + 3
1779 	    >= (SMALL_MAX_DEFAULT >> QUANTUM_2POW_MIN));
1780 
1781 	/*
1782 	 * Avoid doing division with a variable divisor if possible.  Using
1783 	 * actual division here can reduce allocator throughput by over 20%!
1784 	 */
1785 	diff = (unsigned)((uintptr_t)ptr - (uintptr_t)run - bin->reg0_offset);
1786 	if ((size & (size - 1)) == 0) {
1787 		/*
1788 		 * log2_table allows fast division of a power of two in the
1789 		 * [1..128] range.
1790 		 *
1791 		 * (x / divisor) becomes (x >> log2_table[divisor - 1]).
1792 		 */
1793 		static const unsigned char log2_table[] = {
1794 		    0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4,
1795 		    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
1796 		    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1797 		    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
1798 		    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1799 		    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1800 		    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1801 		    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7
1802 		};
1803 
1804 		if (size <= 128)
1805 			regind = (diff >> log2_table[size - 1]);
1806 		else if (size <= 32768)
1807 			regind = diff >> (8 + log2_table[(size >> 8) - 1]);
1808 		else {
1809 			/*
1810 			 * The page size is too large for us to use the lookup
1811 			 * table.  Use real division.
1812 			 */
1813 			regind = (unsigned)(diff / size);
1814 		}
1815 	} else if (size <= ((sizeof(size_invs) / sizeof(unsigned))
1816 	    << QUANTUM_2POW_MIN) + 2) {
1817 		regind = size_invs[(size >> QUANTUM_2POW_MIN) - 3] * diff;
1818 		regind >>= SIZE_INV_SHIFT;
1819 	} else {
1820 		/*
1821 		 * size_invs isn't large enough to handle this size class, so
1822 		 * calculate regind using actual division.  This only happens
1823 		 * if the user increases small_max via the 'S' runtime
1824 		 * configuration option.
1825 		 */
1826 		regind = (unsigned)(diff / size);
1827 	};
1828 	assert(diff == regind * size);
1829 	assert(regind < bin->nregs);
1830 
1831 	elm = regind >> (SIZEOF_INT_2POW + 3);
1832 	if (elm < run->regs_minelm)
1833 		run->regs_minelm = elm;
1834 	bit = regind - (elm << (SIZEOF_INT_2POW + 3));
1835 	assert((run->regs_mask[elm] & (1U << bit)) == 0);
1836 	run->regs_mask[elm] |= (1U << bit);
1837 #undef SIZE_INV
1838 #undef SIZE_INV_SHIFT
1839 }
1840 
1841 static void
1842 arena_run_split(arena_t *arena, arena_run_t *run, size_t size)
1843 {
1844 	arena_chunk_t *chunk;
1845 	unsigned run_ind, map_offset, total_pages, need_pages, rem_pages;
1846 	unsigned i;
1847 
1848 	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);
1849 	run_ind = (unsigned)(((uintptr_t)run - (uintptr_t)chunk)
1850 	    >> pagesize_2pow);
1851 	total_pages = chunk->map[run_ind].npages;
1852 	need_pages = (unsigned)(size >> pagesize_2pow);
1853 	assert(need_pages <= total_pages);
1854 	rem_pages = total_pages - need_pages;
1855 
1856 	/* Split enough pages from the front of run to fit allocation size. */
1857 	map_offset = run_ind;
1858 	for (i = 0; i < need_pages; i++) {
1859 		chunk->map[map_offset + i].npages = need_pages;
1860 		chunk->map[map_offset + i].pos = i;
1861 	}
1862 
1863 	/* Keep track of trailing unused pages for later use. */
1864 	if (rem_pages > 0) {
1865 		/* Update map for trailing pages. */
1866 		map_offset += need_pages;
1867 		chunk->map[map_offset].npages = rem_pages;
1868 		chunk->map[map_offset].pos = POS_FREE;
1869 		chunk->map[map_offset + rem_pages - 1].npages = rem_pages;
1870 		chunk->map[map_offset + rem_pages - 1].pos = POS_FREE;
1871 	}
1872 
1873 	chunk->pages_used += need_pages;
1874 }
1875 
1876 static arena_chunk_t *
1877 arena_chunk_alloc(arena_t *arena)
1878 {
1879 	arena_chunk_t *chunk;
1880 
1881 	if (arena->spare != NULL) {
1882 		chunk = arena->spare;
1883 		arena->spare = NULL;
1884 
1885 		RB_INSERT(arena_chunk_tree_s, &arena->chunks, chunk);
1886 	} else {
1887 		chunk = (arena_chunk_t *)chunk_alloc(chunksize);
1888 		if (chunk == NULL)
1889 			return (NULL);
1890 #ifdef MALLOC_STATS
1891 		arena->stats.mapped += chunksize;
1892 #endif
1893 
1894 		chunk->arena = arena;
1895 
1896 		/*
1897 		 * Claim that no pages are in use, since the header is merely
1898 		 * overhead.
1899 		 */
1900 		chunk->pages_used = 0;
1901 
1902 		chunk->max_frun_npages = chunk_npages -
1903 		    arena_chunk_header_npages;
1904 		chunk->min_frun_ind = arena_chunk_header_npages;
1905 
1906 		/*
1907 		 * Initialize enough of the map to support one maximal free run.
1908 		 */
1909 		chunk->map[arena_chunk_header_npages].npages = chunk_npages -
1910 		    arena_chunk_header_npages;
1911 		chunk->map[arena_chunk_header_npages].pos = POS_FREE;
1912 		chunk->map[chunk_npages - 1].npages = chunk_npages -
1913 		    arena_chunk_header_npages;
1914 		chunk->map[chunk_npages - 1].pos = POS_FREE;
1915 
1916 		RB_INSERT(arena_chunk_tree_s, &arena->chunks, chunk);
1917 	}
1918 
1919 	return (chunk);
1920 }
1921 
1922 static void
1923 arena_chunk_dealloc(arena_t *arena, arena_chunk_t *chunk)
1924 {
1925 
1926 	/*
1927 	 * Remove chunk from the chunk tree, regardless of whether this chunk
1928 	 * will be cached, so that the arena does not use it.
1929 	 */
1930 	RB_REMOVE(arena_chunk_tree_s, &chunk->arena->chunks, chunk);
1931 
1932 	if (opt_hint == false) {
1933 		if (arena->spare != NULL) {
1934 			chunk_dealloc((void *)arena->spare, chunksize);
1935 #ifdef MALLOC_STATS
1936 			arena->stats.mapped -= chunksize;
1937 #endif
1938 		}
1939 		arena->spare = chunk;
1940 	} else {
1941 		assert(arena->spare == NULL);
1942 		chunk_dealloc((void *)chunk, chunksize);
1943 #ifdef MALLOC_STATS
1944 		arena->stats.mapped -= chunksize;
1945 #endif
1946 	}
1947 }
1948 
1949 static arena_run_t *
1950 arena_run_alloc(arena_t *arena, size_t size)
1951 {
1952 	arena_chunk_t *chunk, *chunk_tmp;
1953 	arena_run_t *run;
1954 	unsigned need_npages;
1955 
1956 	assert(size <= (chunksize - (arena_chunk_header_npages <<
1957 	    pagesize_2pow)));
1958 	assert((size & pagesize_mask) == 0);
1959 
1960 	/*
1961 	 * Search through the arena chunk tree for a large enough free run.
1962 	 * Tree order ensures that any exact fit is picked immediately or
1963 	 * otherwise the lowest address of the next size.
1964 	 */
1965 	need_npages = (unsigned)(size >> pagesize_2pow);
1966 	/* LINTED */
1967 	for (;;) {
1968 		chunk_tmp = RB_ROOT(&arena->chunks);
1969 		chunk = NULL;
1970 		while (chunk_tmp) {
1971 			if (chunk_tmp->max_frun_npages == need_npages) {
1972 				chunk = chunk_tmp;
1973 				break;
1974 			}
1975 			if (chunk_tmp->max_frun_npages < need_npages) {
1976 				chunk_tmp = RB_RIGHT(chunk_tmp, link);
1977 				continue;
1978 			}
1979 			chunk = chunk_tmp;
1980 			chunk_tmp = RB_LEFT(chunk, link);
1981 		}
1982 		if (chunk == NULL)
1983 			break;
1984 		/*
1985 		 * At this point, the chunk must have a cached run size large
1986 		 * enough to fit the allocation.
1987 		 */
1988 		assert(need_npages <= chunk->max_frun_npages);
1989 		{
1990 			arena_chunk_map_t *mapelm;
1991 			unsigned i;
1992 			unsigned max_frun_npages = 0;
1993 			unsigned min_frun_ind = chunk_npages;
1994 
1995 			assert(chunk->min_frun_ind >=
1996 			    arena_chunk_header_npages);
1997 			for (i = chunk->min_frun_ind; i < chunk_npages;) {
1998 				mapelm = &chunk->map[i];
1999 				if (mapelm->pos == POS_FREE) {
2000 					if (mapelm->npages >= need_npages) {
2001 						run = (arena_run_t *)
2002 						    ((uintptr_t)chunk + (i <<
2003 						    pagesize_2pow));
2004 						/* Update page map. */
2005 						arena_run_split(arena, run,
2006 						    size);
2007 						return (run);
2008 					}
2009 					if (mapelm->npages >
2010 					    max_frun_npages) {
2011 						max_frun_npages =
2012 						    mapelm->npages;
2013 					}
2014 					if (i < min_frun_ind) {
2015 						min_frun_ind = i;
2016 						if (i < chunk->min_frun_ind)
2017 							chunk->min_frun_ind = i;
2018 					}
2019 				}
2020 				i += mapelm->npages;
2021 			}
2022 			/*
2023 			 * Search failure.  Reset cached chunk->max_frun_npages.
2024 			 * chunk->min_frun_ind was already reset above (if
2025 			 * necessary).
2026 			 */
2027 			RB_REMOVE(arena_chunk_tree_s, &arena->chunks, chunk);
2028 			chunk->max_frun_npages = max_frun_npages;
2029 			RB_INSERT(arena_chunk_tree_s, &arena->chunks, chunk);
2030 		}
2031 	}
2032 
2033 	/*
2034 	 * No usable runs.  Create a new chunk from which to allocate the run.
2035 	 */
2036 	chunk = arena_chunk_alloc(arena);
2037 	if (chunk == NULL)
2038 		return (NULL);
2039 	run = (arena_run_t *)((uintptr_t)chunk + (arena_chunk_header_npages <<
2040 	    pagesize_2pow));
2041 	/* Update page map. */
2042 	arena_run_split(arena, run, size);
2043 	return (run);
2044 }
2045 
2046 static void
2047 arena_run_dalloc(arena_t *arena, arena_run_t *run, size_t size)
2048 {
2049 	arena_chunk_t *chunk;
2050 	unsigned run_ind, run_pages;
2051 
2052 	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);
2053 
2054 	run_ind = (unsigned)(((uintptr_t)run - (uintptr_t)chunk)
2055 	    >> pagesize_2pow);
2056 	assert(run_ind >= arena_chunk_header_npages);
2057 	assert(run_ind < (chunksize >> pagesize_2pow));
2058 	run_pages = (unsigned)(size >> pagesize_2pow);
2059 	assert(run_pages == chunk->map[run_ind].npages);
2060 
2061 	/* Subtract pages from count of pages used in chunk. */
2062 	chunk->pages_used -= run_pages;
2063 
2064 	/* Mark run as deallocated. */
2065 	assert(chunk->map[run_ind].npages == run_pages);
2066 	chunk->map[run_ind].pos = POS_FREE;
2067 	assert(chunk->map[run_ind + run_pages - 1].npages == run_pages);
2068 	chunk->map[run_ind + run_pages - 1].pos = POS_FREE;
2069 
2070 	/*
2071 	 * Tell the kernel that we don't need the data in this run, but only if
2072 	 * requested via runtime configuration.
2073 	 */
2074 	if (opt_hint)
2075 		madvise(run, size, MADV_FREE);
2076 
2077 	/* Try to coalesce with neighboring runs. */
2078 	if (run_ind > arena_chunk_header_npages &&
2079 	    chunk->map[run_ind - 1].pos == POS_FREE) {
2080 		unsigned prev_npages;
2081 
2082 		/* Coalesce with previous run. */
2083 		prev_npages = chunk->map[run_ind - 1].npages;
2084 		run_ind -= prev_npages;
2085 		assert(chunk->map[run_ind].npages == prev_npages);
2086 		assert(chunk->map[run_ind].pos == POS_FREE);
2087 		run_pages += prev_npages;
2088 
2089 		chunk->map[run_ind].npages = run_pages;
2090 		assert(chunk->map[run_ind].pos == POS_FREE);
2091 		chunk->map[run_ind + run_pages - 1].npages = run_pages;
2092 		assert(chunk->map[run_ind + run_pages - 1].pos == POS_FREE);
2093 	}
2094 
2095 	if (run_ind + run_pages < chunk_npages &&
2096 	    chunk->map[run_ind + run_pages].pos == POS_FREE) {
2097 		unsigned next_npages;
2098 
2099 		/* Coalesce with next run. */
2100 		next_npages = chunk->map[run_ind + run_pages].npages;
2101 		run_pages += next_npages;
2102 		assert(chunk->map[run_ind + run_pages - 1].npages ==
2103 		    next_npages);
2104 		assert(chunk->map[run_ind + run_pages - 1].pos == POS_FREE);
2105 
2106 		chunk->map[run_ind].npages = run_pages;
2107 		chunk->map[run_ind].pos = POS_FREE;
2108 		chunk->map[run_ind + run_pages - 1].npages = run_pages;
2109 		assert(chunk->map[run_ind + run_pages - 1].pos == POS_FREE);
2110 	}
2111 
2112 	if (chunk->map[run_ind].npages > chunk->max_frun_npages) {
2113 		RB_REMOVE(arena_chunk_tree_s, &arena->chunks, chunk);
2114 		chunk->max_frun_npages = chunk->map[run_ind].npages;
2115 		RB_INSERT(arena_chunk_tree_s, &arena->chunks, chunk);
2116 	}
2117 	if (run_ind < chunk->min_frun_ind)
2118 		chunk->min_frun_ind = run_ind;
2119 
2120 	/* Deallocate chunk if it is now completely unused. */
2121 	if (chunk->pages_used == 0)
2122 		arena_chunk_dealloc(arena, chunk);
2123 }
2124 
2125 static arena_run_t *
2126 arena_bin_nonfull_run_get(arena_t *arena, arena_bin_t *bin)
2127 {
2128 	arena_run_t *run;
2129 	unsigned i, remainder;
2130 
2131 	/* Look for a usable run. */
2132 	if ((run = RB_MIN(arena_run_tree_s, &bin->runs)) != NULL) {
2133 		/* run is guaranteed to have available space. */
2134 		RB_REMOVE(arena_run_tree_s, &bin->runs, run);
2135 #ifdef MALLOC_STATS
2136 		bin->stats.reruns++;
2137 #endif
2138 		return (run);
2139 	}
2140 	/* No existing runs have any space available. */
2141 
2142 	/* Allocate a new run. */
2143 	run = arena_run_alloc(arena, bin->run_size);
2144 	if (run == NULL)
2145 		return (NULL);
2146 
2147 	/* Initialize run internals. */
2148 	run->bin = bin;
2149 
2150 	for (i = 0; i < bin->regs_mask_nelms; i++)
2151 		run->regs_mask[i] = UINT_MAX;
2152 	remainder = bin->nregs & ((1 << (SIZEOF_INT_2POW + 3)) - 1);
2153 	if (remainder != 0) {
2154 		/* The last element has spare bits that need to be unset. */
2155 		run->regs_mask[i] = (UINT_MAX >> ((1 << (SIZEOF_INT_2POW + 3))
2156 		    - remainder));
2157 	}
2158 
2159 	run->regs_minelm = 0;
2160 
2161 	run->nfree = bin->nregs;
2162 #ifdef MALLOC_DEBUG
2163 	run->magic = ARENA_RUN_MAGIC;
2164 #endif
2165 
2166 #ifdef MALLOC_STATS
2167 	bin->stats.nruns++;
2168 	bin->stats.curruns++;
2169 	if (bin->stats.curruns > bin->stats.highruns)
2170 		bin->stats.highruns = bin->stats.curruns;
2171 #endif
2172 	return (run);
2173 }
2174 
2175 /* bin->runcur must have space available before this function is called. */
2176 static inline void *
2177 arena_bin_malloc_easy(arena_t *arena, arena_bin_t *bin, arena_run_t *run)
2178 {
2179 	void *ret;
2180 
2181 	assert(run->magic == ARENA_RUN_MAGIC);
2182 	assert(run->nfree > 0);
2183 
2184 	ret = arena_run_reg_alloc(run, bin);
2185 	assert(ret != NULL);
2186 	run->nfree--;
2187 
2188 	return (ret);
2189 }
2190 
2191 /* Re-fill bin->runcur, then call arena_bin_malloc_easy(). */
2192 static void *
2193 arena_bin_malloc_hard(arena_t *arena, arena_bin_t *bin)
2194 {
2195 
2196 	bin->runcur = arena_bin_nonfull_run_get(arena, bin);
2197 	if (bin->runcur == NULL)
2198 		return (NULL);
2199 	assert(bin->runcur->magic == ARENA_RUN_MAGIC);
2200 	assert(bin->runcur->nfree > 0);
2201 
2202 	return (arena_bin_malloc_easy(arena, bin, bin->runcur));
2203 }
2204 
2205 /*
2206  * Calculate bin->run_size such that it meets the following constraints:
2207  *
2208  *   *) bin->run_size >= min_run_size
2209  *   *) bin->run_size <= arena_maxclass
2210  *   *) bin->run_size <= RUN_MAX_SMALL
2211  *   *) run header overhead <= RUN_MAX_OVRHD (or header overhead relaxed).
2212  *
2213  * bin->nregs, bin->regs_mask_nelms, and bin->reg0_offset are
2214  * also calculated here, since these settings are all interdependent.
2215  */
2216 static size_t
2217 arena_bin_run_size_calc(arena_bin_t *bin, size_t min_run_size)
2218 {
2219 	size_t try_run_size, good_run_size;
2220 	unsigned good_nregs, good_mask_nelms, good_reg0_offset;
2221 	unsigned try_nregs, try_mask_nelms, try_reg0_offset;
2222 
2223 	assert(min_run_size >= pagesize);
2224 	assert(min_run_size <= arena_maxclass);
2225 	assert(min_run_size <= RUN_MAX_SMALL);
2226 
2227 	/*
2228 	 * Calculate known-valid settings before entering the run_size
2229 	 * expansion loop, so that the first part of the loop always copies
2230 	 * valid settings.
2231 	 *
2232 	 * The do..while loop iteratively reduces the number of regions until
2233 	 * the run header and the regions no longer overlap.  A closed formula
2234 	 * would be quite messy, since there is an interdependency between the
2235 	 * header's mask length and the number of regions.
2236 	 */
2237 	try_run_size = min_run_size;
2238 	try_nregs = (unsigned)(((try_run_size - sizeof(arena_run_t)) /
2239 	    bin->reg_size) + 1); /* Counter-act try_nregs-- in loop. */
2240 	do {
2241 		try_nregs--;
2242 		try_mask_nelms = (try_nregs >> (SIZEOF_INT_2POW + 3)) +
2243 		    ((try_nregs & ((1 << (SIZEOF_INT_2POW + 3)) - 1)) ? 1 : 0);
2244 		try_reg0_offset = (unsigned)(try_run_size -
2245 		    (try_nregs * bin->reg_size));
2246 	} while (sizeof(arena_run_t) + (sizeof(unsigned) * (try_mask_nelms - 1))
2247 	    > try_reg0_offset);
2248 
2249 	/* run_size expansion loop. */
2250 	do {
2251 		/*
2252 		 * Copy valid settings before trying more aggressive settings.
2253 		 */
2254 		good_run_size = try_run_size;
2255 		good_nregs = try_nregs;
2256 		good_mask_nelms = try_mask_nelms;
2257 		good_reg0_offset = try_reg0_offset;
2258 
2259 		/* Try more aggressive settings. */
2260 		try_run_size += pagesize;
2261 		try_nregs = (unsigned)(((try_run_size - sizeof(arena_run_t)) /
2262 		    bin->reg_size) + 1); /* Counter-act try_nregs-- in loop. */
2263 		do {
2264 			try_nregs--;
2265 			try_mask_nelms = (try_nregs >> (SIZEOF_INT_2POW + 3)) +
2266 			    ((try_nregs & ((1 << (SIZEOF_INT_2POW + 3)) - 1)) ?
2267 			    1 : 0);
2268 			try_reg0_offset = (unsigned)(try_run_size - (try_nregs *
2269 			    bin->reg_size));
2270 		} while (sizeof(arena_run_t) + (sizeof(unsigned) *
2271 		    (try_mask_nelms - 1)) > try_reg0_offset);
2272 	} while (try_run_size <= arena_maxclass && try_run_size <= RUN_MAX_SMALL
2273 	    && RUN_MAX_OVRHD * (bin->reg_size << 3) > RUN_MAX_OVRHD_RELAX
2274 	    && (try_reg0_offset << RUN_BFP) > RUN_MAX_OVRHD * try_run_size);
2275 
2276 	assert(sizeof(arena_run_t) + (sizeof(unsigned) * (good_mask_nelms - 1))
2277 	    <= good_reg0_offset);
2278 	assert((good_mask_nelms << (SIZEOF_INT_2POW + 3)) >= good_nregs);
2279 
2280 	/* Copy final settings. */
2281 	bin->run_size = good_run_size;
2282 	bin->nregs = good_nregs;
2283 	bin->regs_mask_nelms = good_mask_nelms;
2284 	bin->reg0_offset = good_reg0_offset;
2285 
2286 	return (good_run_size);
2287 }
2288 
2289 static void *
2290 arena_malloc(arena_t *arena, size_t size)
2291 {
2292 	void *ret;
2293 
2294 	assert(arena != NULL);
2295 	assert(arena->magic == ARENA_MAGIC);
2296 	assert(size != 0);
2297 	assert(QUANTUM_CEILING(size) <= arena_maxclass);
2298 
2299 	if (size <= bin_maxclass) {
2300 		arena_bin_t *bin;
2301 		arena_run_t *run;
2302 
2303 		/* Small allocation. */
2304 
2305 		if (size < small_min) {
2306 			/* Tiny. */
2307 			size = pow2_ceil(size);
2308 			bin = &arena->bins[ffs((int)(size >> (TINY_MIN_2POW +
2309 			    1)))];
2310 #if (!defined(NDEBUG) || defined(MALLOC_STATS))
2311 			/*
2312 			 * Bin calculation is always correct, but we may need
2313 			 * to fix size for the purposes of assertions and/or
2314 			 * stats accuracy.
2315 			 */
2316 			if (size < (1 << TINY_MIN_2POW))
2317 				size = (1 << TINY_MIN_2POW);
2318 #endif
2319 		} else if (size <= small_max) {
2320 			/* Quantum-spaced. */
2321 			size = QUANTUM_CEILING(size);
2322 			bin = &arena->bins[ntbins + (size >> opt_quantum_2pow)
2323 			    - 1];
2324 		} else {
2325 			/* Sub-page. */
2326 			size = pow2_ceil(size);
2327 			bin = &arena->bins[ntbins + nqbins
2328 			    + (ffs((int)(size >> opt_small_max_2pow)) - 2)];
2329 		}
2330 		assert(size == bin->reg_size);
2331 
2332 		malloc_mutex_lock(&arena->mtx);
2333 		if ((run = bin->runcur) != NULL && run->nfree > 0)
2334 			ret = arena_bin_malloc_easy(arena, bin, run);
2335 		else
2336 			ret = arena_bin_malloc_hard(arena, bin);
2337 
2338 		if (ret == NULL) {
2339 			malloc_mutex_unlock(&arena->mtx);
2340 			return (NULL);
2341 		}
2342 
2343 #ifdef MALLOC_STATS
2344 		bin->stats.nrequests++;
2345 		arena->stats.nmalloc_small++;
2346 		arena->stats.allocated_small += size;
2347 #endif
2348 	} else {
2349 		/* Large allocation. */
2350 		size = PAGE_CEILING(size);
2351 		malloc_mutex_lock(&arena->mtx);
2352 		ret = (void *)arena_run_alloc(arena, size);
2353 		if (ret == NULL) {
2354 			malloc_mutex_unlock(&arena->mtx);
2355 			return (NULL);
2356 		}
2357 #ifdef MALLOC_STATS
2358 		arena->stats.nmalloc_large++;
2359 		arena->stats.allocated_large += size;
2360 #endif
2361 	}
2362 
2363 	malloc_mutex_unlock(&arena->mtx);
2364 
2365 	if (opt_junk)
2366 		memset(ret, 0xa5, size);
2367 	else if (opt_zero)
2368 		memset(ret, 0, size);
2369 	return (ret);
2370 }
2371 
2372 static inline void
2373 arena_palloc_trim(arena_t *arena, arena_chunk_t *chunk, unsigned pageind,
2374     unsigned npages)
2375 {
2376 	unsigned i;
2377 
2378 	assert(npages > 0);
2379 
2380 	/*
2381 	 * Modifiy the map such that arena_run_dalloc() sees the run as
2382 	 * separately allocated.
2383 	 */
2384 	for (i = 0; i < npages; i++) {
2385 		chunk->map[pageind + i].npages = npages;
2386 		chunk->map[pageind + i].pos = i;
2387 	}
2388 	arena_run_dalloc(arena, (arena_run_t *)((uintptr_t)chunk + (pageind <<
2389 	    pagesize_2pow)), npages << pagesize_2pow);
2390 }
2391 
2392 /* Only handles large allocations that require more than page alignment. */
2393 static void *
2394 arena_palloc(arena_t *arena, size_t alignment, size_t size, size_t alloc_size)
2395 {
2396 	void *ret;
2397 	size_t offset;
2398 	arena_chunk_t *chunk;
2399 	unsigned pageind, i, npages;
2400 
2401 	assert((size & pagesize_mask) == 0);
2402 	assert((alignment & pagesize_mask) == 0);
2403 
2404 	npages = (unsigned)(size >> pagesize_2pow);
2405 
2406 	malloc_mutex_lock(&arena->mtx);
2407 	ret = (void *)arena_run_alloc(arena, alloc_size);
2408 	if (ret == NULL) {
2409 		malloc_mutex_unlock(&arena->mtx);
2410 		return (NULL);
2411 	}
2412 
2413 	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ret);
2414 
2415 	offset = (uintptr_t)ret & (alignment - 1);
2416 	assert((offset & pagesize_mask) == 0);
2417 	assert(offset < alloc_size);
2418 	if (offset == 0) {
2419 		pageind = (unsigned)(((uintptr_t)ret - (uintptr_t)chunk) >>
2420 		    pagesize_2pow);
2421 
2422 		/* Update the map for the run to be kept. */
2423 		for (i = 0; i < npages; i++) {
2424 			chunk->map[pageind + i].npages = npages;
2425 			assert(chunk->map[pageind + i].pos == i);
2426 		}
2427 
2428 		/* Trim trailing space. */
2429 		arena_palloc_trim(arena, chunk, pageind + npages,
2430 		    (unsigned)((alloc_size - size) >> pagesize_2pow));
2431 	} else {
2432 		size_t leadsize, trailsize;
2433 
2434 		leadsize = alignment - offset;
2435 		ret = (void *)((uintptr_t)ret + leadsize);
2436 		pageind = (unsigned)(((uintptr_t)ret - (uintptr_t)chunk) >>
2437 		    pagesize_2pow);
2438 
2439 		/* Update the map for the run to be kept. */
2440 		for (i = 0; i < npages; i++) {
2441 			chunk->map[pageind + i].npages = npages;
2442 			chunk->map[pageind + i].pos = i;
2443 		}
2444 
2445 		/* Trim leading space. */
2446 		arena_palloc_trim(arena, chunk,
2447 		    (unsigned)(pageind - (leadsize >> pagesize_2pow)),
2448 		    (unsigned)(leadsize >> pagesize_2pow));
2449 
2450 		trailsize = alloc_size - leadsize - size;
2451 		if (trailsize != 0) {
2452 			/* Trim trailing space. */
2453 			assert(trailsize < alloc_size);
2454 			arena_palloc_trim(arena, chunk, pageind + npages,
2455 			    (unsigned)(trailsize >> pagesize_2pow));
2456 		}
2457 	}
2458 
2459 #ifdef MALLOC_STATS
2460 	arena->stats.nmalloc_large++;
2461 	arena->stats.allocated_large += size;
2462 #endif
2463 	malloc_mutex_unlock(&arena->mtx);
2464 
2465 	if (opt_junk)
2466 		memset(ret, 0xa5, size);
2467 	else if (opt_zero)
2468 		memset(ret, 0, size);
2469 	return (ret);
2470 }
2471 
2472 /* Return the size of the allocation pointed to by ptr. */
2473 static size_t
2474 arena_salloc(const void *ptr)
2475 {
2476 	size_t ret;
2477 	arena_chunk_t *chunk;
2478 	arena_chunk_map_t *mapelm;
2479 	unsigned pageind;
2480 
2481 	assert(ptr != NULL);
2482 	assert(CHUNK_ADDR2BASE(ptr) != ptr);
2483 
2484 	/*
2485 	 * No arena data structures that we query here can change in a way that
2486 	 * affects this function, so we don't need to lock.
2487 	 */
2488 	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
2489 	pageind = (unsigned)(((uintptr_t)ptr - (uintptr_t)chunk) >>
2490 	    pagesize_2pow);
2491 	mapelm = &chunk->map[pageind];
2492 	if (mapelm->pos != 0 || ptr != (char *)((uintptr_t)chunk) + (pageind <<
2493 	    pagesize_2pow)) {
2494 		arena_run_t *run;
2495 
2496 		pageind -= mapelm->pos;
2497 
2498 		run = (arena_run_t *)((uintptr_t)chunk + (pageind <<
2499 		    pagesize_2pow));
2500 		assert(run->magic == ARENA_RUN_MAGIC);
2501 		ret = run->bin->reg_size;
2502 	} else
2503 		ret = mapelm->npages << pagesize_2pow;
2504 
2505 	return (ret);
2506 }
2507 
2508 static void *
2509 arena_ralloc(void *ptr, size_t size, size_t oldsize)
2510 {
2511 	void *ret;
2512 
2513 	/* Avoid moving the allocation if the size class would not change. */
2514 	if (size < small_min) {
2515 		if (oldsize < small_min &&
2516 		    ffs((int)(pow2_ceil(size) >> (TINY_MIN_2POW + 1)))
2517 		    == ffs((int)(pow2_ceil(oldsize) >> (TINY_MIN_2POW + 1))))
2518 			goto IN_PLACE;
2519 	} else if (size <= small_max) {
2520 		if (oldsize >= small_min && oldsize <= small_max &&
2521 		    (QUANTUM_CEILING(size) >> opt_quantum_2pow)
2522 		    == (QUANTUM_CEILING(oldsize) >> opt_quantum_2pow))
2523 			goto IN_PLACE;
2524 	} else {
2525 		/*
2526 		 * We make no attempt to resize runs here, though it would be
2527 		 * possible to do so.
2528 		 */
2529 		if (oldsize > small_max && PAGE_CEILING(size) == oldsize)
2530 			goto IN_PLACE;
2531 	}
2532 
2533 	/*
2534 	 * If we get here, then size and oldsize are different enough that we
2535 	 * need to use a different size class.  In that case, fall back to
2536 	 * allocating new space and copying.
2537 	 */
2538 	ret = arena_malloc(choose_arena(), size);
2539 	if (ret == NULL)
2540 		return (NULL);
2541 
2542 	/* Junk/zero-filling were already done by arena_malloc(). */
2543 	if (size < oldsize)
2544 		memcpy(ret, ptr, size);
2545 	else
2546 		memcpy(ret, ptr, oldsize);
2547 	idalloc(ptr);
2548 	return (ret);
2549 IN_PLACE:
2550 	if (opt_junk && size < oldsize)
2551 		memset((void *)((uintptr_t)ptr + size), 0x5a, oldsize - size);
2552 	else if (opt_zero && size > oldsize)
2553 		memset((void *)((uintptr_t)ptr + oldsize), 0, size - oldsize);
2554 	return (ptr);
2555 }
2556 
2557 static void
2558 arena_dalloc(arena_t *arena, arena_chunk_t *chunk, void *ptr)
2559 {
2560 	unsigned pageind;
2561 	arena_chunk_map_t *mapelm;
2562 	size_t size;
2563 
2564 	assert(arena != NULL);
2565 	assert(arena->magic == ARENA_MAGIC);
2566 	assert(chunk->arena == arena);
2567 	assert(ptr != NULL);
2568 	assert(CHUNK_ADDR2BASE(ptr) != ptr);
2569 
2570 	pageind = (unsigned)(((uintptr_t)ptr - (uintptr_t)chunk) >>
2571 	    pagesize_2pow);
2572 	mapelm = &chunk->map[pageind];
2573 	if (mapelm->pos != 0 || ptr != (char *)((uintptr_t)chunk) + (pageind <<
2574 	    pagesize_2pow)) {
2575 		arena_run_t *run;
2576 		arena_bin_t *bin;
2577 
2578 		/* Small allocation. */
2579 
2580 		pageind -= mapelm->pos;
2581 
2582 		run = (arena_run_t *)((uintptr_t)chunk + (pageind <<
2583 		    pagesize_2pow));
2584 		assert(run->magic == ARENA_RUN_MAGIC);
2585 		bin = run->bin;
2586 		size = bin->reg_size;
2587 
2588 		if (opt_junk)
2589 			memset(ptr, 0x5a, size);
2590 
2591 		malloc_mutex_lock(&arena->mtx);
2592 		arena_run_reg_dalloc(run, bin, ptr, size);
2593 		run->nfree++;
2594 
2595 		if (run->nfree == bin->nregs) {
2596 			/* Deallocate run. */
2597 			if (run == bin->runcur)
2598 				bin->runcur = NULL;
2599 			else if (bin->nregs != 1) {
2600 				/*
2601 				 * This block's conditional is necessary because
2602 				 * if the run only contains one region, then it
2603 				 * never gets inserted into the non-full runs
2604 				 * tree.
2605 				 */
2606 				RB_REMOVE(arena_run_tree_s, &bin->runs, run);
2607 			}
2608 #ifdef MALLOC_DEBUG
2609 			run->magic = 0;
2610 #endif
2611 			arena_run_dalloc(arena, run, bin->run_size);
2612 #ifdef MALLOC_STATS
2613 			bin->stats.curruns--;
2614 #endif
2615 		} else if (run->nfree == 1 && run != bin->runcur) {
2616 			/*
2617 			 * Make sure that bin->runcur always refers to the
2618 			 * lowest non-full run, if one exists.
2619 			 */
2620 			if (bin->runcur == NULL)
2621 				bin->runcur = run;
2622 			else if ((uintptr_t)run < (uintptr_t)bin->runcur) {
2623 				/* Switch runcur. */
2624 				if (bin->runcur->nfree > 0) {
2625 					/* Insert runcur. */
2626 					RB_INSERT(arena_run_tree_s, &bin->runs,
2627 					    bin->runcur);
2628 				}
2629 				bin->runcur = run;
2630 			} else {
2631 				RB_INSERT(arena_run_tree_s, &bin->runs, run);
2632 			}
2633 		}
2634 #ifdef MALLOC_STATS
2635 		arena->stats.allocated_small -= size;
2636 		arena->stats.ndalloc_small++;
2637 #endif
2638 	} else {
2639 		/* Large allocation. */
2640 
2641 		size = mapelm->npages << pagesize_2pow;
2642 		assert((((uintptr_t)ptr) & pagesize_mask) == 0);
2643 
2644 		if (opt_junk)
2645 			memset(ptr, 0x5a, size);
2646 
2647 		malloc_mutex_lock(&arena->mtx);
2648 		arena_run_dalloc(arena, (arena_run_t *)ptr, size);
2649 #ifdef MALLOC_STATS
2650 		arena->stats.allocated_large -= size;
2651 		arena->stats.ndalloc_large++;
2652 #endif
2653 	}
2654 
2655 	malloc_mutex_unlock(&arena->mtx);
2656 }
2657 
2658 static bool
2659 arena_new(arena_t *arena)
2660 {
2661 	unsigned i;
2662 	arena_bin_t *bin;
2663 	size_t prev_run_size;
2664 
2665 	malloc_mutex_init(&arena->mtx);
2666 
2667 #ifdef MALLOC_STATS
2668 	memset(&arena->stats, 0, sizeof(arena_stats_t));
2669 #endif
2670 
2671 	/* Initialize chunks. */
2672 	RB_INIT(&arena->chunks);
2673 	arena->spare = NULL;
2674 
2675 	/* Initialize bins. */
2676 	prev_run_size = pagesize;
2677 
2678 	/* (2^n)-spaced tiny bins. */
2679 	for (i = 0; i < ntbins; i++) {
2680 		bin = &arena->bins[i];
2681 		bin->runcur = NULL;
2682 		RB_INIT(&bin->runs);
2683 
2684 		bin->reg_size = (1 << (TINY_MIN_2POW + i));
2685 		prev_run_size = arena_bin_run_size_calc(bin, prev_run_size);
2686 
2687 #ifdef MALLOC_STATS
2688 		memset(&bin->stats, 0, sizeof(malloc_bin_stats_t));
2689 #endif
2690 	}
2691 
2692 	/* Quantum-spaced bins. */
2693 	for (; i < ntbins + nqbins; i++) {
2694 		bin = &arena->bins[i];
2695 		bin->runcur = NULL;
2696 		RB_INIT(&bin->runs);
2697 
2698 		bin->reg_size = quantum * (i - ntbins + 1);
2699 /*
2700 		pow2_size = pow2_ceil(quantum * (i - ntbins + 1));
2701 */
2702 		prev_run_size = arena_bin_run_size_calc(bin, prev_run_size);
2703 
2704 #ifdef MALLOC_STATS
2705 		memset(&bin->stats, 0, sizeof(malloc_bin_stats_t));
2706 #endif
2707 	}
2708 
2709 	/* (2^n)-spaced sub-page bins. */
2710 	for (; i < ntbins + nqbins + nsbins; i++) {
2711 		bin = &arena->bins[i];
2712 		bin->runcur = NULL;
2713 		RB_INIT(&bin->runs);
2714 
2715 		bin->reg_size = (small_max << (i - (ntbins + nqbins) + 1));
2716 
2717 		prev_run_size = arena_bin_run_size_calc(bin, prev_run_size);
2718 
2719 #ifdef MALLOC_STATS
2720 		memset(&bin->stats, 0, sizeof(malloc_bin_stats_t));
2721 #endif
2722 	}
2723 
2724 #ifdef MALLOC_DEBUG
2725 	arena->magic = ARENA_MAGIC;
2726 #endif
2727 
2728 	return (false);
2729 }
2730 
2731 /* Create a new arena and insert it into the arenas array at index ind. */
2732 static arena_t *
2733 arenas_extend(unsigned ind)
2734 {
2735 	arena_t *ret;
2736 
2737 	/* Allocate enough space for trailing bins. */
2738 	ret = (arena_t *)base_alloc(sizeof(arena_t)
2739 	    + (sizeof(arena_bin_t) * (ntbins + nqbins + nsbins - 1)));
2740 	if (ret != NULL && arena_new(ret) == false) {
2741 		arenas[ind] = ret;
2742 		return (ret);
2743 	}
2744 	/* Only reached if there is an OOM error. */
2745 
2746 	/*
2747 	 * OOM here is quite inconvenient to propagate, since dealing with it
2748 	 * would require a check for failure in the fast path.  Instead, punt
2749 	 * by using arenas[0].  In practice, this is an extremely unlikely
2750 	 * failure.
2751 	 */
2752 	_malloc_message(getprogname(),
2753 	    ": (malloc) Error initializing arena\n", "", "");
2754 	if (opt_abort)
2755 		abort();
2756 
2757 	return (arenas[0]);
2758 }
2759 
2760 /*
2761  * End arena.
2762  */
2763 /******************************************************************************/
2764 /*
2765  * Begin general internal functions.
2766  */
2767 
2768 static void *
2769 huge_malloc(size_t size)
2770 {
2771 	void *ret;
2772 	size_t csize;
2773 	chunk_node_t *node;
2774 
2775 	/* Allocate one or more contiguous chunks for this request. */
2776 
2777 	csize = CHUNK_CEILING(size);
2778 	if (csize == 0) {
2779 		/* size is large enough to cause size_t wrap-around. */
2780 		return (NULL);
2781 	}
2782 
2783 	/* Allocate a chunk node with which to track the chunk. */
2784 	node = base_chunk_node_alloc();
2785 	if (node == NULL)
2786 		return (NULL);
2787 
2788 	ret = chunk_alloc(csize);
2789 	if (ret == NULL) {
2790 		base_chunk_node_dealloc(node);
2791 		return (NULL);
2792 	}
2793 
2794 	/* Insert node into huge. */
2795 	node->chunk = ret;
2796 	node->size = csize;
2797 
2798 	malloc_mutex_lock(&chunks_mtx);
2799 	RB_INSERT(chunk_tree_s, &huge, node);
2800 #ifdef MALLOC_STATS
2801 	huge_nmalloc++;
2802 	huge_allocated += csize;
2803 #endif
2804 	malloc_mutex_unlock(&chunks_mtx);
2805 
2806 	if (opt_junk)
2807 		memset(ret, 0xa5, csize);
2808 	else if (opt_zero)
2809 		memset(ret, 0, csize);
2810 
2811 	return (ret);
2812 }
2813 
2814 /* Only handles large allocations that require more than chunk alignment. */
2815 static void *
2816 huge_palloc(size_t alignment, size_t size)
2817 {
2818 	void *ret;
2819 	size_t alloc_size, chunk_size, offset;
2820 	chunk_node_t *node;
2821 
2822 	/*
2823 	 * This allocation requires alignment that is even larger than chunk
2824 	 * alignment.  This means that huge_malloc() isn't good enough.
2825 	 *
2826 	 * Allocate almost twice as many chunks as are demanded by the size or
2827 	 * alignment, in order to assure the alignment can be achieved, then
2828 	 * unmap leading and trailing chunks.
2829 	 */
2830 	assert(alignment >= chunksize);
2831 
2832 	chunk_size = CHUNK_CEILING(size);
2833 
2834 	if (size >= alignment)
2835 		alloc_size = chunk_size + alignment - chunksize;
2836 	else
2837 		alloc_size = (alignment << 1) - chunksize;
2838 
2839 	/* Allocate a chunk node with which to track the chunk. */
2840 	node = base_chunk_node_alloc();
2841 	if (node == NULL)
2842 		return (NULL);
2843 
2844 	ret = chunk_alloc(alloc_size);
2845 	if (ret == NULL) {
2846 		base_chunk_node_dealloc(node);
2847 		return (NULL);
2848 	}
2849 
2850 	offset = (uintptr_t)ret & (alignment - 1);
2851 	assert((offset & chunksize_mask) == 0);
2852 	assert(offset < alloc_size);
2853 	if (offset == 0) {
2854 		/* Trim trailing space. */
2855 		chunk_dealloc((void *)((uintptr_t)ret + chunk_size), alloc_size
2856 		    - chunk_size);
2857 	} else {
2858 		size_t trailsize;
2859 
2860 		/* Trim leading space. */
2861 		chunk_dealloc(ret, alignment - offset);
2862 
2863 		ret = (void *)((uintptr_t)ret + (alignment - offset));
2864 
2865 		trailsize = alloc_size - (alignment - offset) - chunk_size;
2866 		if (trailsize != 0) {
2867 		    /* Trim trailing space. */
2868 		    assert(trailsize < alloc_size);
2869 		    chunk_dealloc((void *)((uintptr_t)ret + chunk_size),
2870 			trailsize);
2871 		}
2872 	}
2873 
2874 	/* Insert node into huge. */
2875 	node->chunk = ret;
2876 	node->size = chunk_size;
2877 
2878 	malloc_mutex_lock(&chunks_mtx);
2879 	RB_INSERT(chunk_tree_s, &huge, node);
2880 #ifdef MALLOC_STATS
2881 	huge_nmalloc++;
2882 	huge_allocated += chunk_size;
2883 #endif
2884 	malloc_mutex_unlock(&chunks_mtx);
2885 
2886 	if (opt_junk)
2887 		memset(ret, 0xa5, chunk_size);
2888 	else if (opt_zero)
2889 		memset(ret, 0, chunk_size);
2890 
2891 	return (ret);
2892 }
2893 
2894 static void *
2895 huge_ralloc(void *ptr, size_t size, size_t oldsize)
2896 {
2897 	void *ret;
2898 
2899 	/* Avoid moving the allocation if the size class would not change. */
2900 	if (oldsize > arena_maxclass &&
2901 	    CHUNK_CEILING(size) == CHUNK_CEILING(oldsize)) {
2902 		if (opt_junk && size < oldsize) {
2903 			memset((void *)((uintptr_t)ptr + size), 0x5a, oldsize
2904 			    - size);
2905 		} else if (opt_zero && size > oldsize) {
2906 			memset((void *)((uintptr_t)ptr + oldsize), 0, size
2907 			    - oldsize);
2908 		}
2909 		return (ptr);
2910 	}
2911 
2912 	if (CHUNK_ADDR2BASE(ptr) == ptr
2913 #ifdef USE_BRK
2914 	    && ((uintptr_t)ptr < (uintptr_t)brk_base
2915 	    || (uintptr_t)ptr >= (uintptr_t)brk_max)
2916 #endif
2917 	    ) {
2918 		chunk_node_t *node, key;
2919 		void *newptr;
2920 		size_t oldcsize;
2921 		size_t newcsize;
2922 
2923 		newcsize = CHUNK_CEILING(size);
2924 		oldcsize = CHUNK_CEILING(oldsize);
2925 		assert(oldcsize != newcsize);
2926 		if (newcsize == 0) {
2927 			/* size_t wrap-around */
2928 			return (NULL);
2929 		}
2930 
2931 		/*
2932 		 * Remove the old region from the tree now.  If mremap()
2933 		 * returns the region to the system, other thread may
2934 		 * map it for same huge allocation and insert it to the
2935 		 * tree before we acquire the mutex lock again.
2936 		 */
2937 		malloc_mutex_lock(&chunks_mtx);
2938 		key.chunk = __DECONST(void *, ptr);
2939 		node = RB_FIND(chunk_tree_s, &huge, &key);
2940 		assert(node != NULL);
2941 		assert(node->chunk == ptr);
2942 		assert(node->size == oldcsize);
2943 		RB_REMOVE(chunk_tree_s, &huge, node);
2944 		malloc_mutex_unlock(&chunks_mtx);
2945 
2946 		newptr = mremap(ptr, oldcsize, NULL, newcsize,
2947 		    MAP_ALIGNED(chunksize_2pow));
2948 		if (newptr == MAP_FAILED) {
2949 			/* We still own the old region. */
2950 			malloc_mutex_lock(&chunks_mtx);
2951 			RB_INSERT(chunk_tree_s, &huge, node);
2952 			malloc_mutex_unlock(&chunks_mtx);
2953 		} else {
2954 			assert(CHUNK_ADDR2BASE(newptr) == newptr);
2955 
2956 			/* Insert new or resized old region. */
2957 			malloc_mutex_lock(&chunks_mtx);
2958 			node->size = newcsize;
2959 			node->chunk = newptr;
2960 			RB_INSERT(chunk_tree_s, &huge, node);
2961 #ifdef MALLOC_STATS
2962 			huge_nralloc++;
2963 			huge_allocated += newcsize - oldcsize;
2964 			if (newcsize > oldcsize) {
2965 				stats_chunks.curchunks +=
2966 				    (newcsize - oldcsize) / chunksize;
2967 				if (stats_chunks.curchunks >
2968 				    stats_chunks.highchunks)
2969 					stats_chunks.highchunks =
2970 					    stats_chunks.curchunks;
2971 			} else {
2972 				stats_chunks.curchunks -=
2973 				    (oldcsize - newcsize) / chunksize;
2974 			}
2975 #endif
2976 			malloc_mutex_unlock(&chunks_mtx);
2977 
2978 			if (opt_junk && size < oldsize) {
2979 				memset((void *)((uintptr_t)newptr + size), 0x5a,
2980 				    newcsize - size);
2981 			} else if (opt_zero && size > oldsize) {
2982 				memset((void *)((uintptr_t)newptr + oldsize), 0,
2983 				    size - oldsize);
2984 			}
2985 			return (newptr);
2986 		}
2987 	}
2988 
2989 	/*
2990 	 * If we get here, then size and oldsize are different enough that we
2991 	 * need to use a different size class.  In that case, fall back to
2992 	 * allocating new space and copying.
2993 	 */
2994 	ret = huge_malloc(size);
2995 	if (ret == NULL)
2996 		return (NULL);
2997 
2998 	if (CHUNK_ADDR2BASE(ptr) == ptr) {
2999 		/* The old allocation is a chunk. */
3000 		if (size < oldsize)
3001 			memcpy(ret, ptr, size);
3002 		else
3003 			memcpy(ret, ptr, oldsize);
3004 	} else {
3005 		/* The old allocation is a region. */
3006 		assert(oldsize < size);
3007 		memcpy(ret, ptr, oldsize);
3008 	}
3009 	idalloc(ptr);
3010 	return (ret);
3011 }
3012 
3013 static void
3014 huge_dalloc(void *ptr)
3015 {
3016 	chunk_node_t key;
3017 	chunk_node_t *node;
3018 
3019 	malloc_mutex_lock(&chunks_mtx);
3020 
3021 	/* Extract from tree of huge allocations. */
3022 	key.chunk = ptr;
3023 	node = RB_FIND(chunk_tree_s, &huge, &key);
3024 	assert(node != NULL);
3025 	assert(node->chunk == ptr);
3026 	RB_REMOVE(chunk_tree_s, &huge, node);
3027 
3028 #ifdef MALLOC_STATS
3029 	huge_ndalloc++;
3030 	huge_allocated -= node->size;
3031 #endif
3032 
3033 	malloc_mutex_unlock(&chunks_mtx);
3034 
3035 	/* Unmap chunk. */
3036 #ifdef USE_BRK
3037 	if (opt_junk)
3038 		memset(node->chunk, 0x5a, node->size);
3039 #endif
3040 	chunk_dealloc(node->chunk, node->size);
3041 
3042 	base_chunk_node_dealloc(node);
3043 }
3044 
3045 static void *
3046 imalloc(size_t size)
3047 {
3048 	void *ret;
3049 
3050 	assert(size != 0);
3051 
3052 	if (size <= arena_maxclass)
3053 		ret = arena_malloc(choose_arena(), size);
3054 	else
3055 		ret = huge_malloc(size);
3056 
3057 	return (ret);
3058 }
3059 
3060 static void *
3061 ipalloc(size_t alignment, size_t size)
3062 {
3063 	void *ret;
3064 	size_t ceil_size;
3065 
3066 	/*
3067 	 * Round size up to the nearest multiple of alignment.
3068 	 *
3069 	 * This done, we can take advantage of the fact that for each small
3070 	 * size class, every object is aligned at the smallest power of two
3071 	 * that is non-zero in the base two representation of the size.  For
3072 	 * example:
3073 	 *
3074 	 *   Size |   Base 2 | Minimum alignment
3075 	 *   -----+----------+------------------
3076 	 *     96 |  1100000 |  32
3077 	 *    144 | 10100000 |  32
3078 	 *    192 | 11000000 |  64
3079 	 *
3080 	 * Depending on runtime settings, it is possible that arena_malloc()
3081 	 * will further round up to a power of two, but that never causes
3082 	 * correctness issues.
3083 	 */
3084 	ceil_size = (size + (alignment - 1)) & (-alignment);
3085 	/*
3086 	 * (ceil_size < size) protects against the combination of maximal
3087 	 * alignment and size greater than maximal alignment.
3088 	 */
3089 	if (ceil_size < size) {
3090 		/* size_t overflow. */
3091 		return (NULL);
3092 	}
3093 
3094 	if (ceil_size <= pagesize || (alignment <= pagesize
3095 	    && ceil_size <= arena_maxclass))
3096 		ret = arena_malloc(choose_arena(), ceil_size);
3097 	else {
3098 		size_t run_size;
3099 
3100 		/*
3101 		 * We can't achieve sub-page alignment, so round up alignment
3102 		 * permanently; it makes later calculations simpler.
3103 		 */
3104 		alignment = PAGE_CEILING(alignment);
3105 		ceil_size = PAGE_CEILING(size);
3106 		/*
3107 		 * (ceil_size < size) protects against very large sizes within
3108 		 * pagesize of SIZE_T_MAX.
3109 		 *
3110 		 * (ceil_size + alignment < ceil_size) protects against the
3111 		 * combination of maximal alignment and ceil_size large enough
3112 		 * to cause overflow.  This is similar to the first overflow
3113 		 * check above, but it needs to be repeated due to the new
3114 		 * ceil_size value, which may now be *equal* to maximal
3115 		 * alignment, whereas before we only detected overflow if the
3116 		 * original size was *greater* than maximal alignment.
3117 		 */
3118 		if (ceil_size < size || ceil_size + alignment < ceil_size) {
3119 			/* size_t overflow. */
3120 			return (NULL);
3121 		}
3122 
3123 		/*
3124 		 * Calculate the size of the over-size run that arena_palloc()
3125 		 * would need to allocate in order to guarantee the alignment.
3126 		 */
3127 		if (ceil_size >= alignment)
3128 			run_size = ceil_size + alignment - pagesize;
3129 		else {
3130 			/*
3131 			 * It is possible that (alignment << 1) will cause
3132 			 * overflow, but it doesn't matter because we also
3133 			 * subtract pagesize, which in the case of overflow
3134 			 * leaves us with a very large run_size.  That causes
3135 			 * the first conditional below to fail, which means
3136 			 * that the bogus run_size value never gets used for
3137 			 * anything important.
3138 			 */
3139 			run_size = (alignment << 1) - pagesize;
3140 		}
3141 
3142 		if (run_size <= arena_maxclass) {
3143 			ret = arena_palloc(choose_arena(), alignment, ceil_size,
3144 			    run_size);
3145 		} else if (alignment <= chunksize)
3146 			ret = huge_malloc(ceil_size);
3147 		else
3148 			ret = huge_palloc(alignment, ceil_size);
3149 	}
3150 
3151 	assert(((uintptr_t)ret & (alignment - 1)) == 0);
3152 	return (ret);
3153 }
3154 
3155 static void *
3156 icalloc(size_t size)
3157 {
3158 	void *ret;
3159 
3160 	if (size <= arena_maxclass) {
3161 		ret = arena_malloc(choose_arena(), size);
3162 		if (ret == NULL)
3163 			return (NULL);
3164 		memset(ret, 0, size);
3165 	} else {
3166 		/*
3167 		 * The virtual memory system provides zero-filled pages, so
3168 		 * there is no need to do so manually, unless opt_junk is
3169 		 * enabled, in which case huge_malloc() fills huge allocations
3170 		 * with junk.
3171 		 */
3172 		ret = huge_malloc(size);
3173 		if (ret == NULL)
3174 			return (NULL);
3175 
3176 		if (opt_junk)
3177 			memset(ret, 0, size);
3178 #ifdef USE_BRK
3179 		else if ((uintptr_t)ret >= (uintptr_t)brk_base
3180 		    && (uintptr_t)ret < (uintptr_t)brk_max) {
3181 			/*
3182 			 * This may be a re-used brk chunk.  Therefore, zero
3183 			 * the memory.
3184 			 */
3185 			memset(ret, 0, size);
3186 		}
3187 #endif
3188 	}
3189 
3190 	return (ret);
3191 }
3192 
3193 static size_t
3194 isalloc(const void *ptr)
3195 {
3196 	size_t ret;
3197 	arena_chunk_t *chunk;
3198 
3199 	assert(ptr != NULL);
3200 
3201 	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
3202 	if (chunk != ptr) {
3203 		/* Region. */
3204 		assert(chunk->arena->magic == ARENA_MAGIC);
3205 
3206 		ret = arena_salloc(ptr);
3207 	} else {
3208 		chunk_node_t *node, key;
3209 
3210 		/* Chunk (huge allocation). */
3211 
3212 		malloc_mutex_lock(&chunks_mtx);
3213 
3214 		/* Extract from tree of huge allocations. */
3215 		key.chunk = __DECONST(void *, ptr);
3216 		node = RB_FIND(chunk_tree_s, &huge, &key);
3217 		assert(node != NULL);
3218 
3219 		ret = node->size;
3220 
3221 		malloc_mutex_unlock(&chunks_mtx);
3222 	}
3223 
3224 	return (ret);
3225 }
3226 
3227 static void *
3228 iralloc(void *ptr, size_t size)
3229 {
3230 	void *ret;
3231 	size_t oldsize;
3232 
3233 	assert(ptr != NULL);
3234 	assert(size != 0);
3235 
3236 	oldsize = isalloc(ptr);
3237 
3238 	if (size <= arena_maxclass)
3239 		ret = arena_ralloc(ptr, size, oldsize);
3240 	else
3241 		ret = huge_ralloc(ptr, size, oldsize);
3242 
3243 	return (ret);
3244 }
3245 
3246 static void
3247 idalloc(void *ptr)
3248 {
3249 	arena_chunk_t *chunk;
3250 
3251 	assert(ptr != NULL);
3252 
3253 	chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
3254 	if (chunk != ptr) {
3255 		/* Region. */
3256 		arena_dalloc(chunk->arena, chunk, ptr);
3257 	} else
3258 		huge_dalloc(ptr);
3259 }
3260 
3261 static void
3262 malloc_print_stats(void)
3263 {
3264 
3265 	if (opt_print_stats) {
3266 		char s[UMAX2S_BUFSIZE];
3267 		_malloc_message("___ Begin malloc statistics ___\n", "", "",
3268 		    "");
3269 		_malloc_message("Assertions ",
3270 #ifdef NDEBUG
3271 		    "disabled",
3272 #else
3273 		    "enabled",
3274 #endif
3275 		    "\n", "");
3276 		_malloc_message("Boolean MALLOC_OPTIONS: ",
3277 		    opt_abort ? "A" : "a",
3278 		    opt_junk ? "J" : "j",
3279 		    opt_hint ? "H" : "h");
3280 		_malloc_message(opt_utrace ? "PU" : "Pu",
3281 		    opt_sysv ? "V" : "v",
3282 		    opt_xmalloc ? "X" : "x",
3283 		    opt_zero ? "Z\n" : "z\n");
3284 
3285 		_malloc_message("CPUs: ", size_t2s(ncpus, s), "\n", "");
3286 		_malloc_message("Max arenas: ", size_t2s(narenas, s), "\n", "");
3287 		_malloc_message("Pointer size: ", size_t2s(sizeof(void *), s),
3288 		    "\n", "");
3289 		_malloc_message("Quantum size: ", size_t2s(quantum, s), "\n", "");
3290 		_malloc_message("Max small size: ", size_t2s(small_max, s), "\n",
3291 		    "");
3292 
3293 		_malloc_message("Chunk size: ", size_t2s(chunksize, s), "", "");
3294 		_malloc_message(" (2^", size_t2s((size_t)opt_chunk_2pow, s),
3295 		    ")\n", "");
3296 
3297 #ifdef MALLOC_STATS
3298 		{
3299 			size_t allocated, mapped;
3300 			unsigned i;
3301 			arena_t *arena;
3302 
3303 			/* Calculate and print allocated/mapped stats. */
3304 
3305 			/* arenas. */
3306 			for (i = 0, allocated = 0; i < narenas; i++) {
3307 				if (arenas[i] != NULL) {
3308 					malloc_mutex_lock(&arenas[i]->mtx);
3309 					allocated +=
3310 					    arenas[i]->stats.allocated_small;
3311 					allocated +=
3312 					    arenas[i]->stats.allocated_large;
3313 					malloc_mutex_unlock(&arenas[i]->mtx);
3314 				}
3315 			}
3316 
3317 			/* huge/base. */
3318 			malloc_mutex_lock(&chunks_mtx);
3319 			allocated += huge_allocated;
3320 			mapped = stats_chunks.curchunks * chunksize;
3321 			malloc_mutex_unlock(&chunks_mtx);
3322 
3323 			malloc_mutex_lock(&base_mtx);
3324 			mapped += base_mapped;
3325 			malloc_mutex_unlock(&base_mtx);
3326 
3327 			malloc_printf("Allocated: %zu, mapped: %zu\n",
3328 			    allocated, mapped);
3329 
3330 			/* Print chunk stats. */
3331 			{
3332 				chunk_stats_t chunks_stats;
3333 
3334 				malloc_mutex_lock(&chunks_mtx);
3335 				chunks_stats = stats_chunks;
3336 				malloc_mutex_unlock(&chunks_mtx);
3337 
3338 				malloc_printf("chunks: nchunks   "
3339 				    "highchunks    curchunks\n");
3340 				malloc_printf("  %13llu%13lu%13lu\n",
3341 				    chunks_stats.nchunks,
3342 				    chunks_stats.highchunks,
3343 				    chunks_stats.curchunks);
3344 			}
3345 
3346 			/* Print chunk stats. */
3347 			malloc_printf(
3348 			    "huge: nmalloc      ndalloc      "
3349 			    "nralloc    allocated\n");
3350 			malloc_printf(" %12llu %12llu %12llu %12zu\n",
3351 			    huge_nmalloc, huge_ndalloc, huge_nralloc,
3352 			    huge_allocated);
3353 
3354 			/* Print stats for each arena. */
3355 			for (i = 0; i < narenas; i++) {
3356 				arena = arenas[i];
3357 				if (arena != NULL) {
3358 					malloc_printf(
3359 					    "\narenas[%u] @ %p\n", i, arena);
3360 					malloc_mutex_lock(&arena->mtx);
3361 					stats_print(arena);
3362 					malloc_mutex_unlock(&arena->mtx);
3363 				}
3364 			}
3365 		}
3366 #endif /* #ifdef MALLOC_STATS */
3367 		_malloc_message("--- End malloc statistics ---\n", "", "", "");
3368 	}
3369 }
3370 
3371 /*
3372  * FreeBSD's pthreads implementation calls malloc(3), so the malloc
3373  * implementation has to take pains to avoid infinite recursion during
3374  * initialization.
3375  */
3376 static inline bool
3377 malloc_init(void)
3378 {
3379 
3380 	if (malloc_initialized == false)
3381 		return (malloc_init_hard());
3382 
3383 	return (false);
3384 }
3385 
3386 static bool
3387 malloc_init_hard(void)
3388 {
3389 	unsigned i, j;
3390 	ssize_t linklen;
3391 	char buf[PATH_MAX + 1];
3392 	const char *opts = "";
3393 	int serrno;
3394 
3395 	malloc_mutex_lock(&init_lock);
3396 	if (malloc_initialized) {
3397 		/*
3398 		 * Another thread initialized the allocator before this one
3399 		 * acquired init_lock.
3400 		 */
3401 		malloc_mutex_unlock(&init_lock);
3402 		return (false);
3403 	}
3404 
3405 	serrno = errno;
3406 	/* Get number of CPUs. */
3407 	{
3408 		int mib[2];
3409 		size_t len;
3410 
3411 		mib[0] = CTL_HW;
3412 		mib[1] = HW_NCPU;
3413 		len = sizeof(ncpus);
3414 		if (sysctl(mib, 2, &ncpus, &len, (void *) 0, 0) == -1) {
3415 			/* Error. */
3416 			ncpus = 1;
3417 		}
3418 	}
3419 
3420 	/* Get page size. */
3421 	{
3422 		long result;
3423 
3424 		result = sysconf(_SC_PAGESIZE);
3425 		assert(result != -1);
3426 		pagesize = (unsigned) result;
3427 
3428 		/*
3429 		 * We assume that pagesize is a power of 2 when calculating
3430 		 * pagesize_mask and pagesize_2pow.
3431 		 */
3432 		assert(((result - 1) & result) == 0);
3433 		pagesize_mask = result - 1;
3434 		pagesize_2pow = ffs((int)result) - 1;
3435 	}
3436 
3437 	for (i = 0; i < 3; i++) {
3438 		/* Get runtime configuration. */
3439 		switch (i) {
3440 		case 0:
3441 			if ((linklen = readlink("/etc/malloc.conf", buf,
3442 						sizeof(buf) - 1)) != -1) {
3443 				/*
3444 				 * Use the contents of the "/etc/malloc.conf"
3445 				 * symbolic link's name.
3446 				 */
3447 				buf[linklen] = '\0';
3448 				opts = buf;
3449 			} else {
3450 				/* No configuration specified. */
3451 				buf[0] = '\0';
3452 				opts = buf;
3453 			}
3454 			break;
3455 		case 1:
3456 			if ((opts = getenv("MALLOC_OPTIONS")) != NULL &&
3457 			    issetugid() == 0) {
3458 				/*
3459 				 * Do nothing; opts is already initialized to
3460 				 * the value of the MALLOC_OPTIONS environment
3461 				 * variable.
3462 				 */
3463 			} else {
3464 				/* No configuration specified. */
3465 				buf[0] = '\0';
3466 				opts = buf;
3467 			}
3468 			break;
3469 		case 2:
3470 			if (_malloc_options != NULL) {
3471 			    /*
3472 			     * Use options that were compiled into the program.
3473 			     */
3474 			    opts = _malloc_options;
3475 			} else {
3476 				/* No configuration specified. */
3477 				buf[0] = '\0';
3478 				opts = buf;
3479 			}
3480 			break;
3481 		default:
3482 			/* NOTREACHED */
3483 			/* LINTED */
3484 			assert(false);
3485 		}
3486 
3487 		for (j = 0; opts[j] != '\0'; j++) {
3488 			switch (opts[j]) {
3489 			case 'a':
3490 				opt_abort = false;
3491 				break;
3492 			case 'A':
3493 				opt_abort = true;
3494 				break;
3495 			case 'h':
3496 				opt_hint = false;
3497 				break;
3498 			case 'H':
3499 				opt_hint = true;
3500 				break;
3501 			case 'j':
3502 				opt_junk = false;
3503 				break;
3504 			case 'J':
3505 				opt_junk = true;
3506 				break;
3507 			case 'k':
3508 				/*
3509 				 * Chunks always require at least one header
3510 				 * page, so chunks can never be smaller than
3511 				 * two pages.
3512 				 */
3513 				if (opt_chunk_2pow > pagesize_2pow + 1)
3514 					opt_chunk_2pow--;
3515 				break;
3516 			case 'K':
3517 				if (opt_chunk_2pow + 1 <
3518 				    (int)(sizeof(size_t) << 3))
3519 					opt_chunk_2pow++;
3520 				break;
3521 			case 'n':
3522 				opt_narenas_lshift--;
3523 				break;
3524 			case 'N':
3525 				opt_narenas_lshift++;
3526 				break;
3527 			case 'p':
3528 				opt_print_stats = false;
3529 				break;
3530 			case 'P':
3531 				opt_print_stats = true;
3532 				break;
3533 			case 'q':
3534 				if (opt_quantum_2pow > QUANTUM_2POW_MIN)
3535 					opt_quantum_2pow--;
3536 				break;
3537 			case 'Q':
3538 				if (opt_quantum_2pow < pagesize_2pow - 1)
3539 					opt_quantum_2pow++;
3540 				break;
3541 			case 's':
3542 				if (opt_small_max_2pow > QUANTUM_2POW_MIN)
3543 					opt_small_max_2pow--;
3544 				break;
3545 			case 'S':
3546 				if (opt_small_max_2pow < pagesize_2pow - 1)
3547 					opt_small_max_2pow++;
3548 				break;
3549 			case 'u':
3550 				opt_utrace = false;
3551 				break;
3552 			case 'U':
3553 				opt_utrace = true;
3554 				break;
3555 			case 'v':
3556 				opt_sysv = false;
3557 				break;
3558 			case 'V':
3559 				opt_sysv = true;
3560 				break;
3561 			case 'x':
3562 				opt_xmalloc = false;
3563 				break;
3564 			case 'X':
3565 				opt_xmalloc = true;
3566 				break;
3567 			case 'z':
3568 				opt_zero = false;
3569 				break;
3570 			case 'Z':
3571 				opt_zero = true;
3572 				break;
3573 			default: {
3574 				char cbuf[2];
3575 
3576 				cbuf[0] = opts[j];
3577 				cbuf[1] = '\0';
3578 				_malloc_message(getprogname(),
3579 				    ": (malloc) Unsupported character in "
3580 				    "malloc options: '", cbuf, "'\n");
3581 			}
3582 			}
3583 		}
3584 	}
3585 	errno = serrno;
3586 
3587 	/* Take care to call atexit() only once. */
3588 	if (opt_print_stats) {
3589 		/* Print statistics at exit. */
3590 		atexit(malloc_print_stats);
3591 	}
3592 
3593 	/* Set variables according to the value of opt_small_max_2pow. */
3594 	if (opt_small_max_2pow < opt_quantum_2pow)
3595 		opt_small_max_2pow = opt_quantum_2pow;
3596 	small_max = (1 << opt_small_max_2pow);
3597 
3598 	/* Set bin-related variables. */
3599 	bin_maxclass = (pagesize >> 1);
3600 	assert(opt_quantum_2pow >= TINY_MIN_2POW);
3601 	ntbins = (unsigned)(opt_quantum_2pow - TINY_MIN_2POW);
3602 	assert(ntbins <= opt_quantum_2pow);
3603 	nqbins = (unsigned)(small_max >> opt_quantum_2pow);
3604 	nsbins = (unsigned)(pagesize_2pow - opt_small_max_2pow - 1);
3605 
3606 	/* Set variables according to the value of opt_quantum_2pow. */
3607 	quantum = (1 << opt_quantum_2pow);
3608 	quantum_mask = quantum - 1;
3609 	if (ntbins > 0)
3610 		small_min = (quantum >> 1) + 1;
3611 	else
3612 		small_min = 1;
3613 	assert(small_min <= quantum);
3614 
3615 	/* Set variables according to the value of opt_chunk_2pow. */
3616 	chunksize = (1LU << opt_chunk_2pow);
3617 	chunksize_mask = chunksize - 1;
3618 	chunksize_2pow = (unsigned)opt_chunk_2pow;
3619 	chunk_npages = (unsigned)(chunksize >> pagesize_2pow);
3620 	{
3621 		unsigned header_size;
3622 
3623 		header_size = (unsigned)(sizeof(arena_chunk_t) +
3624 		    (sizeof(arena_chunk_map_t) * (chunk_npages - 1)));
3625 		arena_chunk_header_npages = (header_size >> pagesize_2pow);
3626 		if ((header_size & pagesize_mask) != 0)
3627 			arena_chunk_header_npages++;
3628 	}
3629 	arena_maxclass = chunksize - (arena_chunk_header_npages <<
3630 	    pagesize_2pow);
3631 
3632 	UTRACE(0, 0, 0);
3633 
3634 #ifdef MALLOC_STATS
3635 	memset(&stats_chunks, 0, sizeof(chunk_stats_t));
3636 #endif
3637 
3638 	/* Various sanity checks that regard configuration. */
3639 	assert(quantum >= sizeof(void *));
3640 	assert(quantum <= pagesize);
3641 	assert(chunksize >= pagesize);
3642 	assert(quantum * 4 <= chunksize);
3643 
3644 	/* Initialize chunks data. */
3645 	malloc_mutex_init(&chunks_mtx);
3646 	RB_INIT(&huge);
3647 #ifdef USE_BRK
3648 	malloc_mutex_init(&brk_mtx);
3649 	brk_base = sbrk(0);
3650 	brk_prev = brk_base;
3651 	brk_max = brk_base;
3652 #endif
3653 #ifdef MALLOC_STATS
3654 	huge_nmalloc = 0;
3655 	huge_ndalloc = 0;
3656 	huge_nralloc = 0;
3657 	huge_allocated = 0;
3658 #endif
3659 	RB_INIT(&old_chunks);
3660 
3661 	/* Initialize base allocation data structures. */
3662 #ifdef MALLOC_STATS
3663 	base_mapped = 0;
3664 #endif
3665 #ifdef USE_BRK
3666 	/*
3667 	 * Allocate a base chunk here, since it doesn't actually have to be
3668 	 * chunk-aligned.  Doing this before allocating any other chunks allows
3669 	 * the use of space that would otherwise be wasted.
3670 	 */
3671 	base_pages_alloc(0);
3672 #endif
3673 	base_chunk_nodes = NULL;
3674 	malloc_mutex_init(&base_mtx);
3675 
3676 	if (ncpus > 1) {
3677 		/*
3678 		 * For SMP systems, create four times as many arenas as there
3679 		 * are CPUs by default.
3680 		 */
3681 		opt_narenas_lshift += 2;
3682 	}
3683 
3684 	/* Determine how many arenas to use. */
3685 	narenas = ncpus;
3686 	if (opt_narenas_lshift > 0) {
3687 		if ((narenas << opt_narenas_lshift) > narenas)
3688 			narenas <<= opt_narenas_lshift;
3689 		/*
3690 		 * Make sure not to exceed the limits of what base_malloc()
3691 		 * can handle.
3692 		 */
3693 		if (narenas * sizeof(arena_t *) > chunksize)
3694 			narenas = (unsigned)(chunksize / sizeof(arena_t *));
3695 	} else if (opt_narenas_lshift < 0) {
3696 		if ((narenas << opt_narenas_lshift) < narenas)
3697 			narenas <<= opt_narenas_lshift;
3698 		/* Make sure there is at least one arena. */
3699 		if (narenas == 0)
3700 			narenas = 1;
3701 	}
3702 
3703 	next_arena = 0;
3704 
3705 	/* Allocate and initialize arenas. */
3706 	arenas = (arena_t **)base_alloc(sizeof(arena_t *) * narenas);
3707 	if (arenas == NULL) {
3708 		malloc_mutex_unlock(&init_lock);
3709 		return (true);
3710 	}
3711 	/*
3712 	 * Zero the array.  In practice, this should always be pre-zeroed,
3713 	 * since it was just mmap()ed, but let's be sure.
3714 	 */
3715 	memset(arenas, 0, sizeof(arena_t *) * narenas);
3716 
3717 	/*
3718 	 * Initialize one arena here.  The rest are lazily created in
3719 	 * arena_choose_hard().
3720 	 */
3721 	arenas_extend(0);
3722 	if (arenas[0] == NULL) {
3723 		malloc_mutex_unlock(&init_lock);
3724 		return (true);
3725 	}
3726 
3727 	malloc_mutex_init(&arenas_mtx);
3728 
3729 	malloc_initialized = true;
3730 	malloc_mutex_unlock(&init_lock);
3731 	return (false);
3732 }
3733 
3734 /*
3735  * End general internal functions.
3736  */
3737 /******************************************************************************/
3738 /*
3739  * Begin malloc(3)-compatible functions.
3740  */
3741 
3742 void *
3743 malloc(size_t size)
3744 {
3745 	void *ret;
3746 
3747 	if (malloc_init()) {
3748 		ret = NULL;
3749 		goto RETURN;
3750 	}
3751 
3752 	if (size == 0) {
3753 		if (opt_sysv == false)
3754 			size = 1;
3755 		else {
3756 			ret = NULL;
3757 			goto RETURN;
3758 		}
3759 	}
3760 
3761 	ret = imalloc(size);
3762 
3763 RETURN:
3764 	if (ret == NULL) {
3765 		if (opt_xmalloc) {
3766 			_malloc_message(getprogname(),
3767 			    ": (malloc) Error in malloc(): out of memory\n", "",
3768 			    "");
3769 			abort();
3770 		}
3771 		errno = ENOMEM;
3772 	}
3773 
3774 	UTRACE(0, size, ret);
3775 	return (ret);
3776 }
3777 
3778 int
3779 posix_memalign(void **memptr, size_t alignment, size_t size)
3780 {
3781 	int ret;
3782 	void *result;
3783 
3784 	if (malloc_init())
3785 		result = NULL;
3786 	else {
3787 		/* Make sure that alignment is a large enough power of 2. */
3788 		if (((alignment - 1) & alignment) != 0
3789 		    || alignment < sizeof(void *)) {
3790 			if (opt_xmalloc) {
3791 				_malloc_message(getprogname(),
3792 				    ": (malloc) Error in posix_memalign(): "
3793 				    "invalid alignment\n", "", "");
3794 				abort();
3795 			}
3796 			result = NULL;
3797 			ret = EINVAL;
3798 			goto RETURN;
3799 		}
3800 
3801 		result = ipalloc(alignment, size);
3802 	}
3803 
3804 	if (result == NULL) {
3805 		if (opt_xmalloc) {
3806 			_malloc_message(getprogname(),
3807 			": (malloc) Error in posix_memalign(): out of memory\n",
3808 			"", "");
3809 			abort();
3810 		}
3811 		ret = ENOMEM;
3812 		goto RETURN;
3813 	}
3814 
3815 	*memptr = result;
3816 	ret = 0;
3817 
3818 RETURN:
3819 	UTRACE(0, size, result);
3820 	return (ret);
3821 }
3822 
3823 void *
3824 calloc(size_t num, size_t size)
3825 {
3826 	void *ret;
3827 	size_t num_size;
3828 
3829 	if (malloc_init()) {
3830 		num_size = 0;
3831 		ret = NULL;
3832 		goto RETURN;
3833 	}
3834 
3835 	num_size = num * size;
3836 	if (num_size == 0) {
3837 		if ((opt_sysv == false) && ((num == 0) || (size == 0)))
3838 			num_size = 1;
3839 		else {
3840 			ret = NULL;
3841 			goto RETURN;
3842 		}
3843 	/*
3844 	 * Try to avoid division here.  We know that it isn't possible to
3845 	 * overflow during multiplication if neither operand uses any of the
3846 	 * most significant half of the bits in a size_t.
3847 	 */
3848 	} else if ((unsigned long long)((num | size) &
3849 	   ((unsigned long long)SIZE_T_MAX << (sizeof(size_t) << 2))) &&
3850 	   (num_size / size != num)) {
3851 		/* size_t overflow. */
3852 		ret = NULL;
3853 		goto RETURN;
3854 	}
3855 
3856 	ret = icalloc(num_size);
3857 
3858 RETURN:
3859 	if (ret == NULL) {
3860 		if (opt_xmalloc) {
3861 			_malloc_message(getprogname(),
3862 			    ": (malloc) Error in calloc(): out of memory\n", "",
3863 			    "");
3864 			abort();
3865 		}
3866 		errno = ENOMEM;
3867 	}
3868 
3869 	UTRACE(0, num_size, ret);
3870 	return (ret);
3871 }
3872 
3873 void *
3874 realloc(void *ptr, size_t size)
3875 {
3876 	void *ret;
3877 
3878 	if (size == 0) {
3879 		if (opt_sysv == false)
3880 			size = 1;
3881 		else {
3882 			if (ptr != NULL)
3883 				idalloc(ptr);
3884 			ret = NULL;
3885 			goto RETURN;
3886 		}
3887 	}
3888 
3889 	if (ptr != NULL) {
3890 		assert(malloc_initialized);
3891 
3892 		ret = iralloc(ptr, size);
3893 
3894 		if (ret == NULL) {
3895 			if (opt_xmalloc) {
3896 				_malloc_message(getprogname(),
3897 				    ": (malloc) Error in realloc(): out of "
3898 				    "memory\n", "", "");
3899 				abort();
3900 			}
3901 			errno = ENOMEM;
3902 		}
3903 	} else {
3904 		if (malloc_init())
3905 			ret = NULL;
3906 		else
3907 			ret = imalloc(size);
3908 
3909 		if (ret == NULL) {
3910 			if (opt_xmalloc) {
3911 				_malloc_message(getprogname(),
3912 				    ": (malloc) Error in realloc(): out of "
3913 				    "memory\n", "", "");
3914 				abort();
3915 			}
3916 			errno = ENOMEM;
3917 		}
3918 	}
3919 
3920 RETURN:
3921 	UTRACE(ptr, size, ret);
3922 	return (ret);
3923 }
3924 
3925 void
3926 free(void *ptr)
3927 {
3928 
3929 	UTRACE(ptr, 0, 0);
3930 	if (ptr != NULL) {
3931 		assert(malloc_initialized);
3932 
3933 		idalloc(ptr);
3934 	}
3935 }
3936 
3937 /*
3938  * End malloc(3)-compatible functions.
3939  */
3940 /******************************************************************************/
3941 /*
3942  * Begin non-standard functions.
3943  */
3944 #ifndef __NetBSD__
3945 size_t
3946 malloc_usable_size(const void *ptr)
3947 {
3948 
3949 	assert(ptr != NULL);
3950 
3951 	return (isalloc(ptr));
3952 }
3953 #endif
3954 
3955 /*
3956  * End non-standard functions.
3957  */
3958 /******************************************************************************/
3959 /*
3960  * Begin library-private functions, used by threading libraries for protection
3961  * of malloc during fork().  These functions are only called if the program is
3962  * running in threaded mode, so there is no need to check whether the program
3963  * is threaded here.
3964  */
3965 
3966 void
3967 _malloc_prefork(void)
3968 {
3969 	unsigned i;
3970 
3971 	/* Acquire all mutexes in a safe order. */
3972 	malloc_mutex_lock(&init_lock);
3973 	malloc_mutex_lock(&arenas_mtx);
3974 	for (i = 0; i < narenas; i++) {
3975 		if (arenas[i] != NULL)
3976 			malloc_mutex_lock(&arenas[i]->mtx);
3977 	}
3978 	malloc_mutex_lock(&chunks_mtx);
3979 	malloc_mutex_lock(&base_mtx);
3980 #ifdef USE_BRK
3981 	malloc_mutex_lock(&brk_mtx);
3982 #endif
3983 }
3984 
3985 void
3986 _malloc_postfork(void)
3987 {
3988 	unsigned i;
3989 
3990 	/* Release all mutexes, now that fork() has completed. */
3991 #ifdef USE_BRK
3992 	malloc_mutex_unlock(&brk_mtx);
3993 #endif
3994 	malloc_mutex_unlock(&base_mtx);
3995 	malloc_mutex_unlock(&chunks_mtx);
3996 
3997 	for (i = narenas; i-- > 0; ) {
3998 		if (arenas[i] != NULL)
3999 			malloc_mutex_unlock(&arenas[i]->mtx);
4000 	}
4001 	malloc_mutex_unlock(&arenas_mtx);
4002 	malloc_mutex_unlock(&init_lock);
4003 }
4004 
4005 void
4006 _malloc_postfork_child(void)
4007 {
4008 	unsigned i;
4009 
4010 	/* Release all mutexes, now that fork() has completed. */
4011 #ifdef USE_BRK
4012 	malloc_mutex_init(&brk_mtx);
4013 #endif
4014 	malloc_mutex_init(&base_mtx);
4015 	malloc_mutex_init(&chunks_mtx);
4016 
4017 	for (i = narenas; i-- > 0; ) {
4018 		if (arenas[i] != NULL)
4019 			malloc_mutex_init(&arenas[i]->mtx);
4020 	}
4021 	malloc_mutex_init(&arenas_mtx);
4022 	malloc_mutex_init(&init_lock);
4023 }
4024 
4025 /*
4026  * End library-private functions.
4027  */
4028 /******************************************************************************/
4029