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