]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - lib/libc/stdlib/malloc.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / lib / libc / stdlib / malloc.c
1 /*-
2  * Copyright (C) 2006-2008 Jason Evans <jasone@FreeBSD.org>.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice(s), this list of conditions and the following disclaimer as
10  *    the first lines of this file unmodified other than the possible
11  *    addition of one or more copyright notices.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice(s), this list of conditions and the following disclaimer in
14  *    the documentation and/or other materials provided with the
15  *    distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
18  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  *
29  *******************************************************************************
30  *
31  * This allocator implementation is designed to provide scalable performance
32  * for multi-threaded programs on multi-processor systems.  The following
33  * features are included for this purpose:
34  *
35  *   + Multiple arenas are used if there are multiple CPUs, which reduces lock
36  *     contention and cache sloshing.
37  *
38  *   + Cache line sharing between arenas is avoided for internal data
39  *     structures.
40  *
41  *   + Memory is managed in chunks and runs (chunks can be split into runs),
42  *     rather than as individual pages.  This provides a constant-time
43  *     mechanism for associating allocations with particular arenas.
44  *
45  * Allocation requests are rounded up to the nearest size class, and no record
46  * of the original request size is maintained.  Allocations are broken into
47  * categories according to size class.  Assuming runtime defaults, 4 kB pages
48  * and a 16 byte quantum on a 32-bit system, the size classes in each category
49  * are as follows:
50  *
51  *   |=====================================|
52  *   | Category | Subcategory    |    Size |
53  *   |=====================================|
54  *   | Small    | Tiny           |       2 |
55  *   |          |                |       4 |
56  *   |          |                |       8 |
57  *   |          |----------------+---------|
58  *   |          | Quantum-spaced |      16 |
59  *   |          |                |      32 |
60  *   |          |                |      48 |
61  *   |          |                |     ... |
62  *   |          |                |     480 |
63  *   |          |                |     496 |
64  *   |          |                |     512 |
65  *   |          |----------------+---------|
66  *   |          | Sub-page       |    1 kB |
67  *   |          |                |    2 kB |
68  *   |=====================================|
69  *   | Large                     |    4 kB |
70  *   |                           |    8 kB |
71  *   |                           |   12 kB |
72  *   |                           |     ... |
73  *   |                           | 1012 kB |
74  *   |                           | 1016 kB |
75  *   |                           | 1020 kB |
76  *   |=====================================|
77  *   | Huge                      |    1 MB |
78  *   |                           |    2 MB |
79  *   |                           |    3 MB |
80  *   |                           |     ... |
81  *   |=====================================|
82  *
83  * A different mechanism is used for each category:
84  *
85  *   Small : Each size class is segregated into its own set of runs.  Each run
86  *           maintains a bitmap of which regions are free/allocated.
87  *
88  *   Large : Each allocation is backed by a dedicated run.  Metadata are stored
89  *           in the associated arena chunk header maps.
90  *
91  *   Huge : Each allocation is backed by a dedicated contiguous set of chunks.
92  *          Metadata are stored in a separate red-black tree.
93  *
94  *******************************************************************************
95  */
96
97 /*
98  * MALLOC_PRODUCTION disables assertions and statistics gathering.  It also
99  * defaults the A and J runtime options to off.  These settings are appropriate
100  * for production systems.
101  */
102 #define MALLOC_PRODUCTION
103
104 #ifndef MALLOC_PRODUCTION
105    /*
106     * MALLOC_DEBUG enables assertions and other sanity checks, and disables
107     * inline functions.
108     */
109 #  define MALLOC_DEBUG
110
111    /* MALLOC_STATS enables statistics calculation. */
112 #  define MALLOC_STATS
113 #endif
114
115 /*
116  * MALLOC_BALANCE enables monitoring of arena lock contention and dynamically
117  * re-balances arena load if exponentially averaged contention exceeds a
118  * certain threshold.
119  */
120 #define MALLOC_BALANCE
121
122 /*
123  * MALLOC_DSS enables use of sbrk(2) to allocate chunks from the data storage
124  * segment (DSS).  In an ideal world, this functionality would be completely
125  * unnecessary, but we are burdened by history and the lack of resource limits
126  * for anonymous mapped memory.
127  */
128 #define MALLOC_DSS
129
130 #include <sys/cdefs.h>
131 __FBSDID("$FreeBSD$");
132
133 #include "libc_private.h"
134 #ifdef MALLOC_DEBUG
135 #  define _LOCK_DEBUG
136 #endif
137 #include "spinlock.h"
138 #include "namespace.h"
139 #include <sys/mman.h>
140 #include <sys/param.h>
141 #include <sys/stddef.h>
142 #include <sys/time.h>
143 #include <sys/types.h>
144 #include <sys/sysctl.h>
145 #include <sys/uio.h>
146 #include <sys/ktrace.h> /* Must come after several other sys/ includes. */
147
148 #include <machine/cpufunc.h>
149 #include <machine/vmparam.h>
150
151 #include <errno.h>
152 #include <limits.h>
153 #include <pthread.h>
154 #include <sched.h>
155 #include <stdarg.h>
156 #include <stdbool.h>
157 #include <stdio.h>
158 #include <stdint.h>
159 #include <stdlib.h>
160 #include <string.h>
161 #include <strings.h>
162 #include <unistd.h>
163
164 #include "un-namespace.h"
165
166 #ifdef MALLOC_DEBUG
167 #  ifdef NDEBUG
168 #    undef NDEBUG
169 #  endif
170 #else
171 #  ifndef NDEBUG
172 #    define NDEBUG
173 #  endif
174 #endif
175 #include <assert.h>
176
177 #include "rb.h"
178
179 #ifdef MALLOC_DEBUG
180    /* Disable inlining to make debugging easier. */
181 #  define inline
182 #endif
183
184 /* Size of stack-allocated buffer passed to strerror_r(). */
185 #define STRERROR_BUF            64
186
187 /* Minimum alignment of allocations is 2^QUANTUM_2POW_MIN bytes. */
188 #ifdef __i386__
189 #  define QUANTUM_2POW_MIN      4
190 #  define SIZEOF_PTR_2POW       2
191 #  define CPU_SPINWAIT          __asm__ volatile("pause")
192 #endif
193 #ifdef __ia64__
194 #  define QUANTUM_2POW_MIN      4
195 #  define SIZEOF_PTR_2POW       3
196 #endif
197 #ifdef __alpha__
198 #  define QUANTUM_2POW_MIN      4
199 #  define SIZEOF_PTR_2POW       3
200 #  define NO_TLS
201 #endif
202 #ifdef __sparc64__
203 #  define QUANTUM_2POW_MIN      4
204 #  define SIZEOF_PTR_2POW       3
205 #  define NO_TLS
206 #endif
207 #ifdef __amd64__
208 #  define QUANTUM_2POW_MIN      4
209 #  define SIZEOF_PTR_2POW       3
210 #  define CPU_SPINWAIT          __asm__ volatile("pause")
211 #endif
212 #ifdef __arm__
213 #  define QUANTUM_2POW_MIN      3
214 #  define SIZEOF_PTR_2POW       2
215 #  define NO_TLS
216 #endif
217 #ifdef __mips__
218 #  define QUANTUM_2POW_MIN      3
219 #  define SIZEOF_PTR_2POW       2
220 #  define NO_TLS
221 #endif
222 #ifdef __powerpc__
223 #  define QUANTUM_2POW_MIN      4
224 #  define SIZEOF_PTR_2POW       2
225 #endif
226
227 #define SIZEOF_PTR              (1U << SIZEOF_PTR_2POW)
228
229 /* sizeof(int) == (1U << SIZEOF_INT_2POW). */
230 #ifndef SIZEOF_INT_2POW
231 #  define SIZEOF_INT_2POW       2
232 #endif
233
234 /* We can't use TLS in non-PIC programs, since TLS relies on loader magic. */
235 #if (!defined(PIC) && !defined(NO_TLS))
236 #  define NO_TLS
237 #endif
238
239 #ifdef NO_TLS
240    /* MALLOC_BALANCE requires TLS. */
241 #  ifdef MALLOC_BALANCE
242 #    undef MALLOC_BALANCE
243 #  endif
244 #endif
245
246 /*
247  * Size and alignment of memory chunks that are allocated by the OS's virtual
248  * memory system.
249  */
250 #define CHUNK_2POW_DEFAULT      20
251
252 /* Maximum number of dirty pages per arena. */
253 #define DIRTY_MAX_DEFAULT       (1U << 9)
254
255 /*
256  * Maximum size of L1 cache line.  This is used to avoid cache line aliasing,
257  * so over-estimates are okay (up to a point), but under-estimates will
258  * negatively affect performance.
259  */
260 #define CACHELINE_2POW          6
261 #define CACHELINE               ((size_t)(1U << CACHELINE_2POW))
262
263 /* Smallest size class to support. */
264 #define TINY_MIN_2POW           1
265
266 /*
267  * Maximum size class that is a multiple of the quantum, but not (necessarily)
268  * a power of 2.  Above this size, allocations are rounded up to the nearest
269  * power of 2.
270  */
271 #define SMALL_MAX_2POW_DEFAULT  9
272 #define SMALL_MAX_DEFAULT       (1U << SMALL_MAX_2POW_DEFAULT)
273
274 /*
275  * RUN_MAX_OVRHD indicates maximum desired run header overhead.  Runs are sized
276  * as small as possible such that this setting is still honored, without
277  * violating other constraints.  The goal is to make runs as small as possible
278  * without exceeding a per run external fragmentation threshold.
279  *
280  * We use binary fixed point math for overhead computations, where the binary
281  * point is implicitly RUN_BFP bits to the left.
282  *
283  * Note that it is possible to set RUN_MAX_OVRHD low enough that it cannot be
284  * honored for some/all object sizes, since there is one bit of header overhead
285  * per object (plus a constant).  This constraint is relaxed (ignored) for runs
286  * that are so small that the per-region overhead is greater than:
287  *
288  *   (RUN_MAX_OVRHD / (reg_size << (3+RUN_BFP))
289  */
290 #define RUN_BFP                 12
291 /*                                    \/   Implicit binary fixed point. */
292 #define RUN_MAX_OVRHD           0x0000003dU
293 #define RUN_MAX_OVRHD_RELAX     0x00001800U
294
295 /* Put a cap on small object run size.  This overrides RUN_MAX_OVRHD. */
296 #define RUN_MAX_SMALL_2POW      15
297 #define RUN_MAX_SMALL           (1U << RUN_MAX_SMALL_2POW)
298
299 /*
300  * Hyper-threaded CPUs may need a special instruction inside spin loops in
301  * order to yield to another virtual CPU.  If no such instruction is defined
302  * above, make CPU_SPINWAIT a no-op.
303  */
304 #ifndef CPU_SPINWAIT
305 #  define CPU_SPINWAIT
306 #endif
307
308 /*
309  * Adaptive spinning must eventually switch to blocking, in order to avoid the
310  * potential for priority inversion deadlock.  Backing off past a certain point
311  * can actually waste time.
312  */
313 #define SPIN_LIMIT_2POW         11
314
315 /*
316  * Conversion from spinning to blocking is expensive; we use (1U <<
317  * BLOCK_COST_2POW) to estimate how many more times costly blocking is than
318  * worst-case spinning.
319  */
320 #define BLOCK_COST_2POW         4
321
322 #ifdef MALLOC_BALANCE
323    /*
324     * We use an exponential moving average to track recent lock contention,
325     * where the size of the history window is N, and alpha=2/(N+1).
326     *
327     * Due to integer math rounding, very small values here can cause
328     * substantial degradation in accuracy, thus making the moving average decay
329     * faster than it would with precise calculation.
330     */
331 #  define BALANCE_ALPHA_INV_2POW        9
332
333    /*
334     * Threshold value for the exponential moving contention average at which to
335     * re-assign a thread.
336     */
337 #  define BALANCE_THRESHOLD_DEFAULT     (1U << (SPIN_LIMIT_2POW-4))
338 #endif
339
340 /******************************************************************************/
341
342 /*
343  * Mutexes based on spinlocks.  We can't use normal pthread spinlocks in all
344  * places, because they require malloc()ed memory, which causes bootstrapping
345  * issues in some cases.
346  */
347 typedef struct {
348         spinlock_t      lock;
349 } malloc_mutex_t;
350
351 /* Set to true once the allocator has been initialized. */
352 static bool malloc_initialized = false;
353
354 /* Used to avoid initialization races. */
355 static malloc_mutex_t init_lock = {_SPINLOCK_INITIALIZER};
356
357 /******************************************************************************/
358 /*
359  * Statistics data structures.
360  */
361
362 #ifdef MALLOC_STATS
363
364 typedef struct malloc_bin_stats_s malloc_bin_stats_t;
365 struct malloc_bin_stats_s {
366         /*
367          * Number of allocation requests that corresponded to the size of this
368          * bin.
369          */
370         uint64_t        nrequests;
371
372         /* Total number of runs created for this bin's size class. */
373         uint64_t        nruns;
374
375         /*
376          * Total number of runs reused by extracting them from the runs tree for
377          * this bin's size class.
378          */
379         uint64_t        reruns;
380
381         /* High-water mark for this bin. */
382         unsigned long   highruns;
383
384         /* Current number of runs in this bin. */
385         unsigned long   curruns;
386 };
387
388 typedef struct arena_stats_s arena_stats_t;
389 struct arena_stats_s {
390         /* Number of bytes currently mapped. */
391         size_t          mapped;
392
393         /*
394          * Total number of purge sweeps, total number of madvise calls made,
395          * and total pages purged in order to keep dirty unused memory under
396          * control.
397          */
398         uint64_t        npurge;
399         uint64_t        nmadvise;
400         uint64_t        purged;
401
402         /* Per-size-category statistics. */
403         size_t          allocated_small;
404         uint64_t        nmalloc_small;
405         uint64_t        ndalloc_small;
406
407         size_t          allocated_large;
408         uint64_t        nmalloc_large;
409         uint64_t        ndalloc_large;
410
411 #ifdef MALLOC_BALANCE
412         /* Number of times this arena reassigned a thread due to contention. */
413         uint64_t        nbalance;
414 #endif
415 };
416
417 typedef struct chunk_stats_s chunk_stats_t;
418 struct chunk_stats_s {
419         /* Number of chunks that were allocated. */
420         uint64_t        nchunks;
421
422         /* High-water mark for number of chunks allocated. */
423         unsigned long   highchunks;
424
425         /*
426          * Current number of chunks allocated.  This value isn't maintained for
427          * any other purpose, so keep track of it in order to be able to set
428          * highchunks.
429          */
430         unsigned long   curchunks;
431 };
432
433 #endif /* #ifdef MALLOC_STATS */
434
435 /******************************************************************************/
436 /*
437  * Extent data structures.
438  */
439
440 /* Tree of extents. */
441 typedef struct extent_node_s extent_node_t;
442 struct extent_node_s {
443 #ifdef MALLOC_DSS
444         /* Linkage for the size/address-ordered tree. */
445         rb_node(extent_node_t) link_szad;
446 #endif
447
448         /* Linkage for the address-ordered tree. */
449         rb_node(extent_node_t) link_ad;
450
451         /* Pointer to the extent that this tree node is responsible for. */
452         void    *addr;
453
454         /* Total region size. */
455         size_t  size;
456 };
457 typedef rb_tree(extent_node_t) extent_tree_t;
458
459 /******************************************************************************/
460 /*
461  * Arena data structures.
462  */
463
464 typedef struct arena_s arena_t;
465 typedef struct arena_bin_s arena_bin_t;
466
467 /* Each element of the chunk map corresponds to one page within the chunk. */
468 typedef struct arena_chunk_map_s arena_chunk_map_t;
469 struct arena_chunk_map_s {
470         /*
471          * Linkage for run trees.  There are two disjoint uses:
472          *
473          * 1) arena_t's runs_avail tree.
474          * 2) arena_run_t conceptually uses this linkage for in-use non-full
475          *    runs, rather than directly embedding linkage.
476          */
477         rb_node(arena_chunk_map_t)      link;
478
479         /*
480          * Run address (or size) and various flags are stored together.  The bit
481          * layout looks like (assuming 32-bit system):
482          *
483          *   ???????? ???????? ????---- ---kdzla
484          *
485          * ? : Unallocated: Run address for first/last pages, unset for internal
486          *                  pages.
487          *     Small: Run address.
488          *     Large: Run size for first page, unset for trailing pages.
489          * - : Unused.
490          * k : key?
491          * d : dirty?
492          * z : zeroed?
493          * l : large?
494          * a : allocated?
495          *
496          * Following are example bit patterns for the three types of runs.
497          *
498          * r : run address
499          * s : run size
500          * x : don't care
501          * - : 0
502          * [dzla] : bit set
503          *
504          *   Unallocated:
505          *     ssssssss ssssssss ssss---- --------
506          *     xxxxxxxx xxxxxxxx xxxx---- ----d---
507          *     ssssssss ssssssss ssss---- -----z--
508          *
509          *   Small:
510          *     rrrrrrrr rrrrrrrr rrrr---- -------a
511          *     rrrrrrrr rrrrrrrr rrrr---- -------a
512          *     rrrrrrrr rrrrrrrr rrrr---- -------a
513          *
514          *   Large:
515          *     ssssssss ssssssss ssss---- ------la
516          *     -------- -------- -------- ------la
517          *     -------- -------- -------- ------la
518          */
519         size_t                          bits;
520 #define CHUNK_MAP_KEY           ((size_t)0x10U)
521 #define CHUNK_MAP_DIRTY         ((size_t)0x08U)
522 #define CHUNK_MAP_ZEROED        ((size_t)0x04U)
523 #define CHUNK_MAP_LARGE         ((size_t)0x02U)
524 #define CHUNK_MAP_ALLOCATED     ((size_t)0x01U)
525 };
526 typedef rb_tree(arena_chunk_map_t) arena_avail_tree_t;
527 typedef rb_tree(arena_chunk_map_t) arena_run_tree_t;
528
529 /* Arena chunk header. */
530 typedef struct arena_chunk_s arena_chunk_t;
531 struct arena_chunk_s {
532         /* Arena that owns the chunk. */
533         arena_t         *arena;
534
535         /* Linkage for the arena's chunks_dirty tree. */
536         rb_node(arena_chunk_t) link_dirty;
537
538         /* Number of dirty pages. */
539         size_t          ndirty;
540
541         /* Map of pages within chunk that keeps track of free/large/small. */
542         arena_chunk_map_t map[1]; /* Dynamically sized. */
543 };
544 typedef rb_tree(arena_chunk_t) arena_chunk_tree_t;
545
546 typedef struct arena_run_s arena_run_t;
547 struct arena_run_s {
548 #ifdef MALLOC_DEBUG
549         uint32_t        magic;
550 #  define ARENA_RUN_MAGIC 0x384adf93
551 #endif
552
553         /* Bin this run is associated with. */
554         arena_bin_t     *bin;
555
556         /* Index of first element that might have a free region. */
557         unsigned        regs_minelm;
558
559         /* Number of free regions in run. */
560         unsigned        nfree;
561
562         /* Bitmask of in-use regions (0: in use, 1: free). */
563         unsigned        regs_mask[1]; /* Dynamically sized. */
564 };
565
566 struct arena_bin_s {
567         /*
568          * Current run being used to service allocations of this bin's size
569          * class.
570          */
571         arena_run_t     *runcur;
572
573         /*
574          * Tree of non-full runs.  This tree is used when looking for an
575          * existing run when runcur is no longer usable.  We choose the
576          * non-full run that is lowest in memory; this policy tends to keep
577          * objects packed well, and it can also help reduce the number of
578          * almost-empty chunks.
579          */
580         arena_run_tree_t runs;
581
582         /* Size of regions in a run for this bin's size class. */
583         size_t          reg_size;
584
585         /* Total size of a run for this bin's size class. */
586         size_t          run_size;
587
588         /* Total number of regions in a run for this bin's size class. */
589         uint32_t        nregs;
590
591         /* Number of elements in a run's regs_mask for this bin's size class. */
592         uint32_t        regs_mask_nelms;
593
594         /* Offset of first region in a run for this bin's size class. */
595         uint32_t        reg0_offset;
596
597 #ifdef MALLOC_STATS
598         /* Bin statistics. */
599         malloc_bin_stats_t stats;
600 #endif
601 };
602
603 struct arena_s {
604 #ifdef MALLOC_DEBUG
605         uint32_t                magic;
606 #  define ARENA_MAGIC 0x947d3d24
607 #endif
608
609         /* All operations on this arena require that lock be locked. */
610         pthread_mutex_t         lock;
611
612 #ifdef MALLOC_STATS
613         arena_stats_t           stats;
614 #endif
615
616         /* Tree of dirty-page-containing chunks this arena manages. */
617         arena_chunk_tree_t      chunks_dirty;
618
619         /*
620          * In order to avoid rapid chunk allocation/deallocation when an arena
621          * oscillates right on the cusp of needing a new chunk, cache the most
622          * recently freed chunk.  The spare is left in the arena's chunk trees
623          * until it is deleted.
624          *
625          * There is one spare chunk per arena, rather than one spare total, in
626          * order to avoid interactions between multiple threads that could make
627          * a single spare inadequate.
628          */
629         arena_chunk_t           *spare;
630
631         /*
632          * Current count of pages within unused runs that are potentially
633          * dirty, and for which madvise(... MADV_FREE) has not been called.  By
634          * tracking this, we can institute a limit on how much dirty unused
635          * memory is mapped for each arena.
636          */
637         size_t                  ndirty;
638
639         /*
640          * Size/address-ordered tree of this arena's available runs.  This tree
641          * is used for first-best-fit run allocation.
642          */
643         arena_avail_tree_t      runs_avail;
644
645 #ifdef MALLOC_BALANCE
646         /*
647          * The arena load balancing machinery needs to keep track of how much
648          * lock contention there is.  This value is exponentially averaged.
649          */
650         uint32_t                contention;
651 #endif
652
653         /*
654          * bins is used to store rings of free regions of the following sizes,
655          * assuming a 16-byte quantum, 4kB pagesize, and default MALLOC_OPTIONS.
656          *
657          *   bins[i] | size |
658          *   --------+------+
659          *        0  |    2 |
660          *        1  |    4 |
661          *        2  |    8 |
662          *   --------+------+
663          *        3  |   16 |
664          *        4  |   32 |
665          *        5  |   48 |
666          *        6  |   64 |
667          *           :      :
668          *           :      :
669          *       33  |  496 |
670          *       34  |  512 |
671          *   --------+------+
672          *       35  | 1024 |
673          *       36  | 2048 |
674          *   --------+------+
675          */
676         arena_bin_t             bins[1]; /* Dynamically sized. */
677 };
678
679 /******************************************************************************/
680 /*
681  * Data.
682  */
683
684 /* Number of CPUs. */
685 static unsigned         ncpus;
686
687 /* VM page size. */
688 static size_t           pagesize;
689 static size_t           pagesize_mask;
690 static size_t           pagesize_2pow;
691
692 /* Various bin-related settings. */
693 static size_t           bin_maxclass; /* Max size class for bins. */
694 static unsigned         ntbins; /* Number of (2^n)-spaced tiny bins. */
695 static unsigned         nqbins; /* Number of quantum-spaced bins. */
696 static unsigned         nsbins; /* Number of (2^n)-spaced sub-page bins. */
697 static size_t           small_min;
698 static size_t           small_max;
699
700 /* Various quantum-related settings. */
701 static size_t           quantum;
702 static size_t           quantum_mask; /* (quantum - 1). */
703
704 /* Various chunk-related settings. */
705 static size_t           chunksize;
706 static size_t           chunksize_mask; /* (chunksize - 1). */
707 static size_t           chunk_npages;
708 static size_t           arena_chunk_header_npages;
709 static size_t           arena_maxclass; /* Max size class for arenas. */
710
711 /********/
712 /*
713  * Chunks.
714  */
715
716 /* Protects chunk-related data structures. */
717 static malloc_mutex_t   huge_mtx;
718
719 /* Tree of chunks that are stand-alone huge allocations. */
720 static extent_tree_t    huge;
721
722 #ifdef MALLOC_DSS
723 /*
724  * Protects sbrk() calls.  This avoids malloc races among threads, though it
725  * does not protect against races with threads that call sbrk() directly.
726  */
727 static malloc_mutex_t   dss_mtx;
728 /* Base address of the DSS. */
729 static void             *dss_base;
730 /* Current end of the DSS, or ((void *)-1) if the DSS is exhausted. */
731 static void             *dss_prev;
732 /* Current upper limit on DSS addresses. */
733 static void             *dss_max;
734
735 /*
736  * Trees of chunks that were previously allocated (trees differ only in node
737  * ordering).  These are used when allocating chunks, in an attempt to re-use
738  * address space.  Depending on function, different tree orderings are needed,
739  * which is why there are two trees with the same contents.
740  */
741 static extent_tree_t    dss_chunks_szad;
742 static extent_tree_t    dss_chunks_ad;
743 #endif
744
745 #ifdef MALLOC_STATS
746 /* Huge allocation statistics. */
747 static uint64_t         huge_nmalloc;
748 static uint64_t         huge_ndalloc;
749 static size_t           huge_allocated;
750 #endif
751
752 /****************************/
753 /*
754  * base (internal allocation).
755  */
756
757 /*
758  * Current pages that are being used for internal memory allocations.  These
759  * pages are carved up in cacheline-size quanta, so that there is no chance of
760  * false cache line sharing.
761  */
762 static void             *base_pages;
763 static void             *base_next_addr;
764 static void             *base_past_addr; /* Addr immediately past base_pages. */
765 static extent_node_t    *base_nodes;
766 static malloc_mutex_t   base_mtx;
767 #ifdef MALLOC_STATS
768 static size_t           base_mapped;
769 #endif
770
771 /********/
772 /*
773  * Arenas.
774  */
775
776 /*
777  * Arenas that are used to service external requests.  Not all elements of the
778  * arenas array are necessarily used; arenas are created lazily as needed.
779  */
780 static arena_t          **arenas;
781 static unsigned         narenas;
782 #ifndef NO_TLS
783 #  ifdef MALLOC_BALANCE
784 static unsigned         narenas_2pow;
785 #  else
786 static unsigned         next_arena;
787 #  endif
788 #endif
789 static pthread_mutex_t  arenas_lock; /* Protects arenas initialization. */
790
791 #ifndef NO_TLS
792 /*
793  * Map of pthread_self() --> arenas[???], used for selecting an arena to use
794  * for allocations.
795  */
796 static __thread arena_t *arenas_map;
797 #endif
798
799 #ifdef MALLOC_STATS
800 /* Chunk statistics. */
801 static chunk_stats_t    stats_chunks;
802 #endif
803
804 /*******************************/
805 /*
806  * Runtime configuration options.
807  */
808 const char      *_malloc_options;
809
810 #ifndef MALLOC_PRODUCTION
811 static bool     opt_abort = true;
812 static bool     opt_junk = true;
813 #else
814 static bool     opt_abort = false;
815 static bool     opt_junk = false;
816 #endif
817 #ifdef MALLOC_DSS
818 static bool     opt_dss = true;
819 static bool     opt_mmap = true;
820 #endif
821 static size_t   opt_dirty_max = DIRTY_MAX_DEFAULT;
822 #ifdef MALLOC_BALANCE
823 static uint64_t opt_balance_threshold = BALANCE_THRESHOLD_DEFAULT;
824 #endif
825 static bool     opt_print_stats = false;
826 static size_t   opt_quantum_2pow = QUANTUM_2POW_MIN;
827 static size_t   opt_small_max_2pow = SMALL_MAX_2POW_DEFAULT;
828 static size_t   opt_chunk_2pow = CHUNK_2POW_DEFAULT;
829 static bool     opt_utrace = false;
830 static bool     opt_sysv = false;
831 static bool     opt_xmalloc = false;
832 static bool     opt_zero = false;
833 static int      opt_narenas_lshift = 0;
834
835 typedef struct {
836         void    *p;
837         size_t  s;
838         void    *r;
839 } malloc_utrace_t;
840
841 #define UTRACE(a, b, c)                                                 \
842         if (opt_utrace) {                                               \
843                 malloc_utrace_t ut;                                     \
844                 ut.p = (a);                                             \
845                 ut.s = (b);                                             \
846                 ut.r = (c);                                             \
847                 utrace(&ut, sizeof(ut));                                \
848         }
849
850 /******************************************************************************/
851 /*
852  * Begin function prototypes for non-inline static functions.
853  */
854
855 static void     malloc_mutex_init(malloc_mutex_t *mutex);
856 static bool     malloc_spin_init(pthread_mutex_t *lock);
857 static void     wrtmessage(const char *p1, const char *p2, const char *p3,
858                 const char *p4);
859 #ifdef MALLOC_STATS
860 static void     malloc_printf(const char *format, ...);
861 #endif
862 static char     *umax2s(uintmax_t x, char *s);
863 #ifdef MALLOC_DSS
864 static bool     base_pages_alloc_dss(size_t minsize);
865 #endif
866 static bool     base_pages_alloc_mmap(size_t minsize);
867 static bool     base_pages_alloc(size_t minsize);
868 static void     *base_alloc(size_t size);
869 static void     *base_calloc(size_t number, size_t size);
870 static extent_node_t *base_node_alloc(void);
871 static void     base_node_dealloc(extent_node_t *node);
872 #ifdef MALLOC_STATS
873 static void     stats_print(arena_t *arena);
874 #endif
875 static void     *pages_map(void *addr, size_t size);
876 static void     pages_unmap(void *addr, size_t size);
877 #ifdef MALLOC_DSS
878 static void     *chunk_alloc_dss(size_t size);
879 static void     *chunk_recycle_dss(size_t size, bool zero);
880 #endif
881 static void     *chunk_alloc_mmap(size_t size);
882 static void     *chunk_alloc(size_t size, bool zero);
883 #ifdef MALLOC_DSS
884 static extent_node_t *chunk_dealloc_dss_record(void *chunk, size_t size);
885 static bool     chunk_dealloc_dss(void *chunk, size_t size);
886 #endif
887 static void     chunk_dealloc_mmap(void *chunk, size_t size);
888 static void     chunk_dealloc(void *chunk, size_t size);
889 #ifndef NO_TLS
890 static arena_t  *choose_arena_hard(void);
891 #endif
892 static void     arena_run_split(arena_t *arena, arena_run_t *run, size_t size,
893     bool large, bool zero);
894 static arena_chunk_t *arena_chunk_alloc(arena_t *arena);
895 static void     arena_chunk_dealloc(arena_t *arena, arena_chunk_t *chunk);
896 static arena_run_t *arena_run_alloc(arena_t *arena, size_t size, bool large,
897     bool zero);
898 static void     arena_purge(arena_t *arena);
899 static void     arena_run_dalloc(arena_t *arena, arena_run_t *run, bool dirty);
900 static void     arena_run_trim_head(arena_t *arena, arena_chunk_t *chunk,
901     arena_run_t *run, size_t oldsize, size_t newsize);
902 static void     arena_run_trim_tail(arena_t *arena, arena_chunk_t *chunk,
903     arena_run_t *run, size_t oldsize, size_t newsize, bool dirty);
904 static arena_run_t *arena_bin_nonfull_run_get(arena_t *arena, arena_bin_t *bin);
905 static void *arena_bin_malloc_hard(arena_t *arena, arena_bin_t *bin);
906 static size_t arena_bin_run_size_calc(arena_bin_t *bin, size_t min_run_size);
907 #ifdef MALLOC_BALANCE
908 static void     arena_lock_balance_hard(arena_t *arena);
909 #endif
910 static void     *arena_malloc_large(arena_t *arena, size_t size, bool zero);
911 static void     *arena_palloc(arena_t *arena, size_t alignment, size_t size,
912     size_t alloc_size);
913 static size_t   arena_salloc(const void *ptr);
914 static void     arena_dalloc_large(arena_t *arena, arena_chunk_t *chunk,
915     void *ptr);
916 static void     arena_ralloc_large_shrink(arena_t *arena, arena_chunk_t *chunk,
917     void *ptr, size_t size, size_t oldsize);
918 static bool     arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk,
919     void *ptr, size_t size, size_t oldsize);
920 static bool     arena_ralloc_large(void *ptr, size_t size, size_t oldsize);
921 static void     *arena_ralloc(void *ptr, size_t size, size_t oldsize);
922 static bool     arena_new(arena_t *arena);
923 static arena_t  *arenas_extend(unsigned ind);
924 static void     *huge_malloc(size_t size, bool zero);
925 static void     *huge_palloc(size_t alignment, size_t size);
926 static void     *huge_ralloc(void *ptr, size_t size, size_t oldsize);
927 static void     huge_dalloc(void *ptr);
928 static void     malloc_print_stats(void);
929 static bool     malloc_init_hard(void);
930
931 /*
932  * End function prototypes.
933  */
934 /******************************************************************************/
935 /*
936  * Begin mutex.  We can't use normal pthread mutexes in all places, because
937  * they require malloc()ed memory, which causes bootstrapping issues in some
938  * cases.
939  */
940
941 static void
942 malloc_mutex_init(malloc_mutex_t *mutex)
943 {
944         static const spinlock_t lock = _SPINLOCK_INITIALIZER;
945
946         mutex->lock = lock;
947 }
948
949 static inline void
950 malloc_mutex_lock(malloc_mutex_t *mutex)
951 {
952
953         if (__isthreaded)
954                 _SPINLOCK(&mutex->lock);
955 }
956
957 static inline void
958 malloc_mutex_unlock(malloc_mutex_t *mutex)
959 {
960
961         if (__isthreaded)
962                 _SPINUNLOCK(&mutex->lock);
963 }
964
965 /*
966  * End mutex.
967  */
968 /******************************************************************************/
969 /*
970  * Begin spin lock.  Spin locks here are actually adaptive mutexes that block
971  * after a period of spinning, because unbounded spinning would allow for
972  * priority inversion.
973  */
974
975 /*
976  * We use an unpublished interface to initialize pthread mutexes with an
977  * allocation callback, in order to avoid infinite recursion.
978  */
979 int     _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex,
980     void *(calloc_cb)(size_t, size_t));
981
982 __weak_reference(_pthread_mutex_init_calloc_cb_stub,
983     _pthread_mutex_init_calloc_cb);
984
985 int
986 _pthread_mutex_init_calloc_cb_stub(pthread_mutex_t *mutex,
987     void *(calloc_cb)(size_t, size_t))
988 {
989
990         return (0);
991 }
992
993 static bool
994 malloc_spin_init(pthread_mutex_t *lock)
995 {
996
997         if (_pthread_mutex_init_calloc_cb(lock, base_calloc) != 0)
998                 return (true);
999
1000         return (false);
1001 }
1002
1003 static inline unsigned
1004 malloc_spin_lock(pthread_mutex_t *lock)
1005 {
1006         unsigned ret = 0;
1007
1008         if (__isthreaded) {
1009                 if (_pthread_mutex_trylock(lock) != 0) {
1010                         unsigned i;
1011                         volatile unsigned j;
1012
1013                         /* Exponentially back off. */
1014                         for (i = 1; i <= SPIN_LIMIT_2POW; i++) {
1015                                 for (j = 0; j < (1U << i); j++) {
1016                                         ret++;
1017                                         CPU_SPINWAIT;
1018                                 }
1019
1020                                 if (_pthread_mutex_trylock(lock) == 0)
1021                                         return (ret);
1022                         }
1023
1024                         /*
1025                          * Spinning failed.  Block until the lock becomes
1026                          * available, in order to avoid indefinite priority
1027                          * inversion.
1028                          */
1029                         _pthread_mutex_lock(lock);
1030                         assert((ret << BLOCK_COST_2POW) != 0);
1031                         return (ret << BLOCK_COST_2POW);
1032                 }
1033         }
1034
1035         return (ret);
1036 }
1037
1038 static inline void
1039 malloc_spin_unlock(pthread_mutex_t *lock)
1040 {
1041
1042         if (__isthreaded)
1043                 _pthread_mutex_unlock(lock);
1044 }
1045
1046 /*
1047  * End spin lock.
1048  */
1049 /******************************************************************************/
1050 /*
1051  * Begin Utility functions/macros.
1052  */
1053
1054 /* Return the chunk address for allocation address a. */
1055 #define CHUNK_ADDR2BASE(a)                                              \
1056         ((void *)((uintptr_t)(a) & ~chunksize_mask))
1057
1058 /* Return the chunk offset of address a. */
1059 #define CHUNK_ADDR2OFFSET(a)                                            \
1060         ((size_t)((uintptr_t)(a) & chunksize_mask))
1061
1062 /* Return the smallest chunk multiple that is >= s. */
1063 #define CHUNK_CEILING(s)                                                \
1064         (((s) + chunksize_mask) & ~chunksize_mask)
1065
1066 /* Return the smallest cacheline multiple that is >= s. */
1067 #define CACHELINE_CEILING(s)                                            \
1068         (((s) + (CACHELINE - 1)) & ~(CACHELINE - 1))
1069
1070 /* Return the smallest quantum multiple that is >= a. */
1071 #define QUANTUM_CEILING(a)                                              \
1072         (((a) + quantum_mask) & ~quantum_mask)
1073
1074 /* Return the smallest pagesize multiple that is >= s. */
1075 #define PAGE_CEILING(s)                                                 \
1076         (((s) + pagesize_mask) & ~pagesize_mask)
1077
1078 /* Compute the smallest power of 2 that is >= x. */
1079 static inline size_t
1080 pow2_ceil(size_t x)
1081 {
1082
1083         x--;
1084         x |= x >> 1;
1085         x |= x >> 2;
1086         x |= x >> 4;
1087         x |= x >> 8;
1088         x |= x >> 16;
1089 #if (SIZEOF_PTR == 8)
1090         x |= x >> 32;
1091 #endif
1092         x++;
1093         return (x);
1094 }
1095
1096 #ifdef MALLOC_BALANCE
1097 /*
1098  * Use a simple linear congruential pseudo-random number generator:
1099  *
1100  *   prn(y) = (a*x + c) % m
1101  *
1102  * where the following constants ensure maximal period:
1103  *
1104  *   a == Odd number (relatively prime to 2^n), and (a-1) is a multiple of 4.
1105  *   c == Odd number (relatively prime to 2^n).
1106  *   m == 2^32
1107  *
1108  * See Knuth's TAOCP 3rd Ed., Vol. 2, pg. 17 for details on these constraints.
1109  *
1110  * This choice of m has the disadvantage that the quality of the bits is
1111  * proportional to bit position.  For example. the lowest bit has a cycle of 2,
1112  * the next has a cycle of 4, etc.  For this reason, we prefer to use the upper
1113  * bits.
1114  */
1115 #  define PRN_DEFINE(suffix, var, a, c)                                 \
1116 static inline void                                                      \
1117 sprn_##suffix(uint32_t seed)                                            \
1118 {                                                                       \
1119         var = seed;                                                     \
1120 }                                                                       \
1121                                                                         \
1122 static inline uint32_t                                                  \
1123 prn_##suffix(uint32_t lg_range)                                         \
1124 {                                                                       \
1125         uint32_t ret, x;                                                \
1126                                                                         \
1127         assert(lg_range > 0);                                           \
1128         assert(lg_range <= 32);                                         \
1129                                                                         \
1130         x = (var * (a)) + (c);                                          \
1131         var = x;                                                        \
1132         ret = x >> (32 - lg_range);                                     \
1133                                                                         \
1134         return (ret);                                                   \
1135 }
1136 #  define SPRN(suffix, seed)    sprn_##suffix(seed)
1137 #  define PRN(suffix, lg_range) prn_##suffix(lg_range)
1138 #endif
1139
1140 #ifdef MALLOC_BALANCE
1141 /* Define the PRNG used for arena assignment. */
1142 static __thread uint32_t balance_x;
1143 PRN_DEFINE(balance, balance_x, 1297, 1301)
1144 #endif
1145
1146 static void
1147 wrtmessage(const char *p1, const char *p2, const char *p3, const char *p4)
1148 {
1149
1150         _write(STDERR_FILENO, p1, strlen(p1));
1151         _write(STDERR_FILENO, p2, strlen(p2));
1152         _write(STDERR_FILENO, p3, strlen(p3));
1153         _write(STDERR_FILENO, p4, strlen(p4));
1154 }
1155
1156 void    (*_malloc_message)(const char *p1, const char *p2, const char *p3,
1157             const char *p4) = wrtmessage;
1158
1159 #ifdef MALLOC_STATS
1160 /*
1161  * Print to stderr in such a way as to (hopefully) avoid memory allocation.
1162  */
1163 static void
1164 malloc_printf(const char *format, ...)
1165 {
1166         char buf[4096];
1167         va_list ap;
1168
1169         va_start(ap, format);
1170         vsnprintf(buf, sizeof(buf), format, ap);
1171         va_end(ap);
1172         _malloc_message(buf, "", "", "");
1173 }
1174 #endif
1175
1176 /*
1177  * We don't want to depend on vsnprintf() for production builds, since that can
1178  * cause unnecessary bloat for static binaries.  umax2s() provides minimal
1179  * integer printing functionality, so that malloc_printf() use can be limited to
1180  * MALLOC_STATS code.
1181  */
1182 #define UMAX2S_BUFSIZE  21
1183 static char *
1184 umax2s(uintmax_t x, char *s)
1185 {
1186         unsigned i;
1187
1188         /* Make sure UMAX2S_BUFSIZE is large enough. */
1189         assert(sizeof(uintmax_t) <= 8);
1190
1191         i = UMAX2S_BUFSIZE - 1;
1192         s[i] = '\0';
1193         do {
1194                 i--;
1195                 s[i] = "0123456789"[x % 10];
1196                 x /= 10;
1197         } while (x > 0);
1198
1199         return (&s[i]);
1200 }
1201
1202 /******************************************************************************/
1203
1204 #ifdef MALLOC_DSS
1205 static bool
1206 base_pages_alloc_dss(size_t minsize)
1207 {
1208
1209         /*
1210          * Do special DSS allocation here, since base allocations don't need to
1211          * be chunk-aligned.
1212          */
1213         malloc_mutex_lock(&dss_mtx);
1214         if (dss_prev != (void *)-1) {
1215                 intptr_t incr;
1216                 size_t csize = CHUNK_CEILING(minsize);
1217
1218                 do {
1219                         /* Get the current end of the DSS. */
1220                         dss_max = sbrk(0);
1221
1222                         /*
1223                          * Calculate how much padding is necessary to
1224                          * chunk-align the end of the DSS.  Don't worry about
1225                          * dss_max not being chunk-aligned though.
1226                          */
1227                         incr = (intptr_t)chunksize
1228                             - (intptr_t)CHUNK_ADDR2OFFSET(dss_max);
1229                         assert(incr >= 0);
1230                         if ((size_t)incr < minsize)
1231                                 incr += csize;
1232
1233                         dss_prev = sbrk(incr);
1234                         if (dss_prev == dss_max) {
1235                                 /* Success. */
1236                                 dss_max = (void *)((intptr_t)dss_prev + incr);
1237                                 base_pages = dss_prev;
1238                                 base_next_addr = base_pages;
1239                                 base_past_addr = dss_max;
1240 #ifdef MALLOC_STATS
1241                                 base_mapped += incr;
1242 #endif
1243                                 malloc_mutex_unlock(&dss_mtx);
1244                                 return (false);
1245                         }
1246                 } while (dss_prev != (void *)-1);
1247         }
1248         malloc_mutex_unlock(&dss_mtx);
1249
1250         return (true);
1251 }
1252 #endif
1253
1254 static bool
1255 base_pages_alloc_mmap(size_t minsize)
1256 {
1257         size_t csize;
1258
1259         assert(minsize != 0);
1260         csize = PAGE_CEILING(minsize);
1261         base_pages = pages_map(NULL, csize);
1262         if (base_pages == NULL)
1263                 return (true);
1264         base_next_addr = base_pages;
1265         base_past_addr = (void *)((uintptr_t)base_pages + csize);
1266 #ifdef MALLOC_STATS
1267         base_mapped += csize;
1268 #endif
1269
1270         return (false);
1271 }
1272
1273 static bool
1274 base_pages_alloc(size_t minsize)
1275 {
1276
1277 #ifdef MALLOC_DSS
1278         if (opt_mmap && minsize != 0)
1279 #endif
1280         {
1281                 if (base_pages_alloc_mmap(minsize) == false)
1282                         return (false);
1283         }
1284
1285 #ifdef MALLOC_DSS
1286         if (opt_dss) {
1287                 if (base_pages_alloc_dss(minsize) == false)
1288                         return (false);
1289         }
1290
1291 #endif
1292
1293         return (true);
1294 }
1295
1296 static void *
1297 base_alloc(size_t size)
1298 {
1299         void *ret;
1300         size_t csize;
1301
1302         /* Round size up to nearest multiple of the cacheline size. */
1303         csize = CACHELINE_CEILING(size);
1304
1305         malloc_mutex_lock(&base_mtx);
1306         /* Make sure there's enough space for the allocation. */
1307         if ((uintptr_t)base_next_addr + csize > (uintptr_t)base_past_addr) {
1308                 if (base_pages_alloc(csize)) {
1309                         malloc_mutex_unlock(&base_mtx);
1310                         return (NULL);
1311                 }
1312         }
1313         /* Allocate. */
1314         ret = base_next_addr;
1315         base_next_addr = (void *)((uintptr_t)base_next_addr + csize);
1316         malloc_mutex_unlock(&base_mtx);
1317
1318         return (ret);
1319 }
1320
1321 static void *
1322 base_calloc(size_t number, size_t size)
1323 {
1324         void *ret;
1325
1326         ret = base_alloc(number * size);
1327         memset(ret, 0, number * size);
1328
1329         return (ret);
1330 }
1331
1332 static extent_node_t *
1333 base_node_alloc(void)
1334 {
1335         extent_node_t *ret;
1336
1337         malloc_mutex_lock(&base_mtx);
1338         if (base_nodes != NULL) {
1339                 ret = base_nodes;
1340                 base_nodes = *(extent_node_t **)ret;
1341                 malloc_mutex_unlock(&base_mtx);
1342         } else {
1343                 malloc_mutex_unlock(&base_mtx);
1344                 ret = (extent_node_t *)base_alloc(sizeof(extent_node_t));
1345         }
1346
1347         return (ret);
1348 }
1349
1350 static void
1351 base_node_dealloc(extent_node_t *node)
1352 {
1353
1354         malloc_mutex_lock(&base_mtx);
1355         *(extent_node_t **)node = base_nodes;
1356         base_nodes = node;
1357         malloc_mutex_unlock(&base_mtx);
1358 }
1359
1360 /******************************************************************************/
1361
1362 #ifdef MALLOC_STATS
1363 static void
1364 stats_print(arena_t *arena)
1365 {
1366         unsigned i, gap_start;
1367
1368         malloc_printf("dirty: %zu page%s dirty, %llu sweep%s,"
1369             " %llu madvise%s, %llu page%s purged\n",
1370             arena->ndirty, arena->ndirty == 1 ? "" : "s",
1371             arena->stats.npurge, arena->stats.npurge == 1 ? "" : "s",
1372             arena->stats.nmadvise, arena->stats.nmadvise == 1 ? "" : "s",
1373             arena->stats.purged, arena->stats.purged == 1 ? "" : "s");
1374
1375         malloc_printf("            allocated      nmalloc      ndalloc\n");
1376         malloc_printf("small:   %12zu %12llu %12llu\n",
1377             arena->stats.allocated_small, arena->stats.nmalloc_small,
1378             arena->stats.ndalloc_small);
1379         malloc_printf("large:   %12zu %12llu %12llu\n",
1380             arena->stats.allocated_large, arena->stats.nmalloc_large,
1381             arena->stats.ndalloc_large);
1382         malloc_printf("total:   %12zu %12llu %12llu\n",
1383             arena->stats.allocated_small + arena->stats.allocated_large,
1384             arena->stats.nmalloc_small + arena->stats.nmalloc_large,
1385             arena->stats.ndalloc_small + arena->stats.ndalloc_large);
1386         malloc_printf("mapped:  %12zu\n", arena->stats.mapped);
1387
1388         malloc_printf("bins:     bin   size regs pgs  requests   newruns"
1389             "    reruns maxruns curruns\n");
1390         for (i = 0, gap_start = UINT_MAX; i < ntbins + nqbins + nsbins; i++) {
1391                 if (arena->bins[i].stats.nrequests == 0) {
1392                         if (gap_start == UINT_MAX)
1393                                 gap_start = i;
1394                 } else {
1395                         if (gap_start != UINT_MAX) {
1396                                 if (i > gap_start + 1) {
1397                                         /* Gap of more than one size class. */
1398                                         malloc_printf("[%u..%u]\n",
1399                                             gap_start, i - 1);
1400                                 } else {
1401                                         /* Gap of one size class. */
1402                                         malloc_printf("[%u]\n", gap_start);
1403                                 }
1404                                 gap_start = UINT_MAX;
1405                         }
1406                         malloc_printf(
1407                             "%13u %1s %4u %4u %3u %9llu %9llu"
1408                             " %9llu %7lu %7lu\n",
1409                             i,
1410                             i < ntbins ? "T" : i < ntbins + nqbins ? "Q" : "S",
1411                             arena->bins[i].reg_size,
1412                             arena->bins[i].nregs,
1413                             arena->bins[i].run_size >> pagesize_2pow,
1414                             arena->bins[i].stats.nrequests,
1415                             arena->bins[i].stats.nruns,
1416                             arena->bins[i].stats.reruns,
1417                             arena->bins[i].stats.highruns,
1418                             arena->bins[i].stats.curruns);
1419                 }
1420         }
1421         if (gap_start != UINT_MAX) {
1422                 if (i > gap_start + 1) {
1423                         /* Gap of more than one size class. */
1424                         malloc_printf("[%u..%u]\n", gap_start, i - 1);
1425                 } else {
1426                         /* Gap of one size class. */
1427                         malloc_printf("[%u]\n", gap_start);
1428                 }
1429         }
1430 }
1431 #endif
1432
1433 /*
1434  * End Utility functions/macros.
1435  */
1436 /******************************************************************************/
1437 /*
1438  * Begin extent tree code.
1439  */
1440
1441 #ifdef MALLOC_DSS
1442 static inline int
1443 extent_szad_comp(extent_node_t *a, extent_node_t *b)
1444 {
1445         int ret;
1446         size_t a_size = a->size;
1447         size_t b_size = b->size;
1448
1449         ret = (a_size > b_size) - (a_size < b_size);
1450         if (ret == 0) {
1451                 uintptr_t a_addr = (uintptr_t)a->addr;
1452                 uintptr_t b_addr = (uintptr_t)b->addr;
1453
1454                 ret = (a_addr > b_addr) - (a_addr < b_addr);
1455         }
1456
1457         return (ret);
1458 }
1459
1460 /* Wrap red-black tree macros in functions. */
1461 rb_wrap(__unused static, extent_tree_szad_, extent_tree_t, extent_node_t,
1462     link_szad, extent_szad_comp)
1463 #endif
1464
1465 static inline int
1466 extent_ad_comp(extent_node_t *a, extent_node_t *b)
1467 {
1468         uintptr_t a_addr = (uintptr_t)a->addr;
1469         uintptr_t b_addr = (uintptr_t)b->addr;
1470
1471         return ((a_addr > b_addr) - (a_addr < b_addr));
1472 }
1473
1474 /* Wrap red-black tree macros in functions. */
1475 rb_wrap(__unused static, extent_tree_ad_, extent_tree_t, extent_node_t, link_ad,
1476     extent_ad_comp)
1477
1478 /*
1479  * End extent tree code.
1480  */
1481 /******************************************************************************/
1482 /*
1483  * Begin chunk management functions.
1484  */
1485
1486 static void *
1487 pages_map(void *addr, size_t size)
1488 {
1489         void *ret;
1490
1491         /*
1492          * We don't use MAP_FIXED here, because it can cause the *replacement*
1493          * of existing mappings, and we only want to create new mappings.
1494          */
1495         ret = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON,
1496             -1, 0);
1497         assert(ret != NULL);
1498
1499         if (ret == MAP_FAILED)
1500                 ret = NULL;
1501         else if (addr != NULL && ret != addr) {
1502                 /*
1503                  * We succeeded in mapping memory, but not in the right place.
1504                  */
1505                 if (munmap(ret, size) == -1) {
1506                         char buf[STRERROR_BUF];
1507
1508                         strerror_r(errno, buf, sizeof(buf));
1509                         _malloc_message(_getprogname(),
1510                             ": (malloc) Error in munmap(): ", buf, "\n");
1511                         if (opt_abort)
1512                                 abort();
1513                 }
1514                 ret = NULL;
1515         }
1516
1517         assert(ret == NULL || (addr == NULL && ret != addr)
1518             || (addr != NULL && ret == addr));
1519         return (ret);
1520 }
1521
1522 static void
1523 pages_unmap(void *addr, size_t size)
1524 {
1525
1526         if (munmap(addr, size) == -1) {
1527                 char buf[STRERROR_BUF];
1528
1529                 strerror_r(errno, buf, sizeof(buf));
1530                 _malloc_message(_getprogname(),
1531                     ": (malloc) Error in munmap(): ", buf, "\n");
1532                 if (opt_abort)
1533                         abort();
1534         }
1535 }
1536
1537 #ifdef MALLOC_DSS
1538 static void *
1539 chunk_alloc_dss(size_t size)
1540 {
1541
1542         /*
1543          * sbrk() uses a signed increment argument, so take care not to
1544          * interpret a huge allocation request as a negative increment.
1545          */
1546         if ((intptr_t)size < 0)
1547                 return (NULL);
1548
1549         malloc_mutex_lock(&dss_mtx);
1550         if (dss_prev != (void *)-1) {
1551                 intptr_t incr;
1552
1553                 /*
1554                  * The loop is necessary to recover from races with other
1555                  * threads that are using the DSS for something other than
1556                  * malloc.
1557                  */
1558                 do {
1559                         void *ret;
1560
1561                         /* Get the current end of the DSS. */
1562                         dss_max = sbrk(0);
1563
1564                         /*
1565                          * Calculate how much padding is necessary to
1566                          * chunk-align the end of the DSS.
1567                          */
1568                         incr = (intptr_t)size
1569                             - (intptr_t)CHUNK_ADDR2OFFSET(dss_max);
1570                         if (incr == (intptr_t)size)
1571                                 ret = dss_max;
1572                         else {
1573                                 ret = (void *)((intptr_t)dss_max + incr);
1574                                 incr += size;
1575                         }
1576
1577                         dss_prev = sbrk(incr);
1578                         if (dss_prev == dss_max) {
1579                                 /* Success. */
1580                                 dss_max = (void *)((intptr_t)dss_prev + incr);
1581                                 malloc_mutex_unlock(&dss_mtx);
1582                                 return (ret);
1583                         }
1584                 } while (dss_prev != (void *)-1);
1585         }
1586         malloc_mutex_unlock(&dss_mtx);
1587
1588         return (NULL);
1589 }
1590
1591 static void *
1592 chunk_recycle_dss(size_t size, bool zero)
1593 {
1594         extent_node_t *node, key;
1595
1596         key.addr = NULL;
1597         key.size = size;
1598         malloc_mutex_lock(&dss_mtx);
1599         node = extent_tree_szad_nsearch(&dss_chunks_szad, &key);
1600         if (node != NULL) {
1601                 void *ret = node->addr;
1602
1603                 /* Remove node from the tree. */
1604                 extent_tree_szad_remove(&dss_chunks_szad, node);
1605                 if (node->size == size) {
1606                         extent_tree_ad_remove(&dss_chunks_ad, node);
1607                         base_node_dealloc(node);
1608                 } else {
1609                         /*
1610                          * Insert the remainder of node's address range as a
1611                          * smaller chunk.  Its position within dss_chunks_ad
1612                          * does not change.
1613                          */
1614                         assert(node->size > size);
1615                         node->addr = (void *)((uintptr_t)node->addr + size);
1616                         node->size -= size;
1617                         extent_tree_szad_insert(&dss_chunks_szad, node);
1618                 }
1619                 malloc_mutex_unlock(&dss_mtx);
1620
1621                 if (zero)
1622                         memset(ret, 0, size);
1623                 return (ret);
1624         }
1625         malloc_mutex_unlock(&dss_mtx);
1626
1627         return (NULL);
1628 }
1629 #endif
1630
1631 static void *
1632 chunk_alloc_mmap(size_t size)
1633 {
1634         void *ret;
1635         size_t offset;
1636
1637         /*
1638          * Ideally, there would be a way to specify alignment to mmap() (like
1639          * NetBSD has), but in the absence of such a feature, we have to work
1640          * hard to efficiently create aligned mappings.  The reliable, but
1641          * expensive method is to create a mapping that is over-sized, then
1642          * trim the excess.  However, that always results in at least one call
1643          * to pages_unmap().
1644          *
1645          * A more optimistic approach is to try mapping precisely the right
1646          * amount, then try to append another mapping if alignment is off.  In
1647          * practice, this works out well as long as the application is not
1648          * interleaving mappings via direct mmap() calls.  If we do run into a
1649          * situation where there is an interleaved mapping and we are unable to
1650          * extend an unaligned mapping, our best option is to momentarily
1651          * revert to the reliable-but-expensive method.  This will tend to
1652          * leave a gap in the memory map that is too small to cause later
1653          * problems for the optimistic method.
1654          */
1655
1656         ret = pages_map(NULL, size);
1657         if (ret == NULL)
1658                 return (NULL);
1659
1660         offset = CHUNK_ADDR2OFFSET(ret);
1661         if (offset != 0) {
1662                 /* Try to extend chunk boundary. */
1663                 if (pages_map((void *)((uintptr_t)ret + size),
1664                     chunksize - offset) == NULL) {
1665                         /*
1666                          * Extension failed.  Clean up, then revert to the
1667                          * reliable-but-expensive method.
1668                          */
1669                         pages_unmap(ret, size);
1670
1671                         /* Beware size_t wrap-around. */
1672                         if (size + chunksize <= size)
1673                                 return NULL;
1674
1675                         ret = pages_map(NULL, size + chunksize);
1676                         if (ret == NULL)
1677                                 return (NULL);
1678
1679                         /* Clean up unneeded leading/trailing space. */
1680                         offset = CHUNK_ADDR2OFFSET(ret);
1681                         if (offset != 0) {
1682                                 /* Leading space. */
1683                                 pages_unmap(ret, chunksize - offset);
1684
1685                                 ret = (void *)((uintptr_t)ret +
1686                                     (chunksize - offset));
1687
1688                                 /* Trailing space. */
1689                                 pages_unmap((void *)((uintptr_t)ret + size),
1690                                     offset);
1691                         } else {
1692                                 /* Trailing space only. */
1693                                 pages_unmap((void *)((uintptr_t)ret + size),
1694                                     chunksize);
1695                         }
1696                 } else {
1697                         /* Clean up unneeded leading space. */
1698                         pages_unmap(ret, chunksize - offset);
1699                         ret = (void *)((uintptr_t)ret + (chunksize - offset));
1700                 }
1701         }
1702
1703         return (ret);
1704 }
1705
1706 static void *
1707 chunk_alloc(size_t size, bool zero)
1708 {
1709         void *ret;
1710
1711         assert(size != 0);
1712         assert((size & chunksize_mask) == 0);
1713
1714 #ifdef MALLOC_DSS
1715         if (opt_mmap)
1716 #endif
1717         {
1718                 ret = chunk_alloc_mmap(size);
1719                 if (ret != NULL)
1720                         goto RETURN;
1721         }
1722
1723 #ifdef MALLOC_DSS
1724         if (opt_dss) {
1725                 ret = chunk_recycle_dss(size, zero);
1726                 if (ret != NULL) {
1727                         goto RETURN;
1728                 }
1729
1730                 ret = chunk_alloc_dss(size);
1731                 if (ret != NULL)
1732                         goto RETURN;
1733         }
1734 #endif
1735
1736         /* All strategies for allocation failed. */
1737         ret = NULL;
1738 RETURN:
1739 #ifdef MALLOC_STATS
1740         if (ret != NULL) {
1741                 stats_chunks.nchunks += (size / chunksize);
1742                 stats_chunks.curchunks += (size / chunksize);
1743         }
1744         if (stats_chunks.curchunks > stats_chunks.highchunks)
1745                 stats_chunks.highchunks = stats_chunks.curchunks;
1746 #endif
1747
1748         assert(CHUNK_ADDR2BASE(ret) == ret);
1749         return (ret);
1750 }
1751
1752 #ifdef MALLOC_DSS
1753 static extent_node_t *
1754 chunk_dealloc_dss_record(void *chunk, size_t size)
1755 {
1756         extent_node_t *node, *prev, key;
1757
1758         key.addr = (void *)((uintptr_t)chunk + size);
1759         node = extent_tree_ad_nsearch(&dss_chunks_ad, &key);
1760         /* Try to coalesce forward. */
1761         if (node != NULL && node->addr == key.addr) {
1762                 /*
1763                  * Coalesce chunk with the following address range.  This does
1764                  * not change the position within dss_chunks_ad, so only
1765                  * remove/insert from/into dss_chunks_szad.
1766                  */
1767                 extent_tree_szad_remove(&dss_chunks_szad, node);
1768                 node->addr = chunk;
1769                 node->size += size;
1770                 extent_tree_szad_insert(&dss_chunks_szad, node);
1771         } else {
1772                 /*
1773                  * Coalescing forward failed, so insert a new node.  Drop
1774                  * dss_mtx during node allocation, since it is possible that a
1775                  * new base chunk will be allocated.
1776                  */
1777                 malloc_mutex_unlock(&dss_mtx);
1778                 node = base_node_alloc();
1779                 malloc_mutex_lock(&dss_mtx);
1780                 if (node == NULL)
1781                         return (NULL);
1782                 node->addr = chunk;
1783                 node->size = size;
1784                 extent_tree_ad_insert(&dss_chunks_ad, node);
1785                 extent_tree_szad_insert(&dss_chunks_szad, node);
1786         }
1787
1788         /* Try to coalesce backward. */
1789         prev = extent_tree_ad_prev(&dss_chunks_ad, node);
1790         if (prev != NULL && (void *)((uintptr_t)prev->addr + prev->size) ==
1791             chunk) {
1792                 /*
1793                  * Coalesce chunk with the previous address range.  This does
1794                  * not change the position within dss_chunks_ad, so only
1795                  * remove/insert node from/into dss_chunks_szad.
1796                  */
1797                 extent_tree_szad_remove(&dss_chunks_szad, prev);
1798                 extent_tree_ad_remove(&dss_chunks_ad, prev);
1799
1800                 extent_tree_szad_remove(&dss_chunks_szad, node);
1801                 node->addr = prev->addr;
1802                 node->size += prev->size;
1803                 extent_tree_szad_insert(&dss_chunks_szad, node);
1804
1805                 base_node_dealloc(prev);
1806         }
1807
1808         return (node);
1809 }
1810
1811 static bool
1812 chunk_dealloc_dss(void *chunk, size_t size)
1813 {
1814
1815         malloc_mutex_lock(&dss_mtx);
1816         if ((uintptr_t)chunk >= (uintptr_t)dss_base
1817             && (uintptr_t)chunk < (uintptr_t)dss_max) {
1818                 extent_node_t *node;
1819
1820                 /* Try to coalesce with other unused chunks. */
1821                 node = chunk_dealloc_dss_record(chunk, size);
1822                 if (node != NULL) {
1823                         chunk = node->addr;
1824                         size = node->size;
1825                 }
1826
1827                 /* Get the current end of the DSS. */
1828                 dss_max = sbrk(0);
1829
1830                 /*
1831                  * Try to shrink the DSS if this chunk is at the end of the
1832                  * DSS.  The sbrk() call here is subject to a race condition
1833                  * with threads that use brk(2) or sbrk(2) directly, but the
1834                  * alternative would be to leak memory for the sake of poorly
1835                  * designed multi-threaded programs.
1836                  */
1837                 if ((void *)((uintptr_t)chunk + size) == dss_max
1838                     && (dss_prev = sbrk(-(intptr_t)size)) == dss_max) {
1839                         /* Success. */
1840                         dss_max = (void *)((intptr_t)dss_prev - (intptr_t)size);
1841
1842                         if (node != NULL) {
1843                                 extent_tree_szad_remove(&dss_chunks_szad, node);
1844                                 extent_tree_ad_remove(&dss_chunks_ad, node);
1845                                 base_node_dealloc(node);
1846                         }
1847                         malloc_mutex_unlock(&dss_mtx);
1848                 } else {
1849                         malloc_mutex_unlock(&dss_mtx);
1850                         madvise(chunk, size, MADV_FREE);
1851                 }
1852
1853                 return (false);
1854         }
1855         malloc_mutex_unlock(&dss_mtx);
1856
1857         return (true);
1858 }
1859 #endif
1860
1861 static void
1862 chunk_dealloc_mmap(void *chunk, size_t size)
1863 {
1864
1865         pages_unmap(chunk, size);
1866 }
1867
1868 static void
1869 chunk_dealloc(void *chunk, size_t size)
1870 {
1871
1872         assert(chunk != NULL);
1873         assert(CHUNK_ADDR2BASE(chunk) == chunk);
1874         assert(size != 0);
1875         assert((size & chunksize_mask) == 0);
1876
1877 #ifdef MALLOC_STATS
1878         stats_chunks.curchunks -= (size / chunksize);
1879 #endif
1880
1881 #ifdef MALLOC_DSS
1882         if (opt_dss) {
1883                 if (chunk_dealloc_dss(chunk, size) == false)
1884                         return;
1885         }
1886
1887         if (opt_mmap)
1888 #endif
1889                 chunk_dealloc_mmap(chunk, size);
1890 }
1891
1892 /*
1893  * End chunk management functions.
1894  */
1895 /******************************************************************************/
1896 /*
1897  * Begin arena.
1898  */
1899
1900 /*
1901  * Choose an arena based on a per-thread value (fast-path code, calls slow-path
1902  * code if necessary).
1903  */
1904 static inline arena_t *
1905 choose_arena(void)
1906 {
1907         arena_t *ret;
1908
1909         /*
1910          * We can only use TLS if this is a PIC library, since for the static
1911          * library version, libc's malloc is used by TLS allocation, which
1912          * introduces a bootstrapping issue.
1913          */
1914 #ifndef NO_TLS
1915         if (__isthreaded == false) {
1916             /* Avoid the overhead of TLS for single-threaded operation. */
1917             return (arenas[0]);
1918         }
1919
1920         ret = arenas_map;
1921         if (ret == NULL) {
1922                 ret = choose_arena_hard();
1923                 assert(ret != NULL);
1924         }
1925 #else
1926         if (__isthreaded && narenas > 1) {
1927                 unsigned long ind;
1928
1929                 /*
1930                  * Hash _pthread_self() to one of the arenas.  There is a prime
1931                  * number of arenas, so this has a reasonable chance of
1932                  * working.  Even so, the hashing can be easily thwarted by
1933                  * inconvenient _pthread_self() values.  Without specific
1934                  * knowledge of how _pthread_self() calculates values, we can't
1935                  * easily do much better than this.
1936                  */
1937                 ind = (unsigned long) _pthread_self() % narenas;
1938
1939                 /*
1940                  * Optimistially assume that arenas[ind] has been initialized.
1941                  * At worst, we find out that some other thread has already
1942                  * done so, after acquiring the lock in preparation.  Note that
1943                  * this lazy locking also has the effect of lazily forcing
1944                  * cache coherency; without the lock acquisition, there's no
1945                  * guarantee that modification of arenas[ind] by another thread
1946                  * would be seen on this CPU for an arbitrary amount of time.
1947                  *
1948                  * In general, this approach to modifying a synchronized value
1949                  * isn't a good idea, but in this case we only ever modify the
1950                  * value once, so things work out well.
1951                  */
1952                 ret = arenas[ind];
1953                 if (ret == NULL) {
1954                         /*
1955                          * Avoid races with another thread that may have already
1956                          * initialized arenas[ind].
1957                          */
1958                         malloc_spin_lock(&arenas_lock);
1959                         if (arenas[ind] == NULL)
1960                                 ret = arenas_extend((unsigned)ind);
1961                         else
1962                                 ret = arenas[ind];
1963                         malloc_spin_unlock(&arenas_lock);
1964                 }
1965         } else
1966                 ret = arenas[0];
1967 #endif
1968
1969         assert(ret != NULL);
1970         return (ret);
1971 }
1972
1973 #ifndef NO_TLS
1974 /*
1975  * Choose an arena based on a per-thread value (slow-path code only, called
1976  * only by choose_arena()).
1977  */
1978 static arena_t *
1979 choose_arena_hard(void)
1980 {
1981         arena_t *ret;
1982
1983         assert(__isthreaded);
1984
1985 #ifdef MALLOC_BALANCE
1986         /* Seed the PRNG used for arena load balancing. */
1987         SPRN(balance, (uint32_t)(uintptr_t)(_pthread_self()));
1988 #endif
1989
1990         if (narenas > 1) {
1991 #ifdef MALLOC_BALANCE
1992                 unsigned ind;
1993
1994                 ind = PRN(balance, narenas_2pow);
1995                 if ((ret = arenas[ind]) == NULL) {
1996                         malloc_spin_lock(&arenas_lock);
1997                         if ((ret = arenas[ind]) == NULL)
1998                                 ret = arenas_extend(ind);
1999                         malloc_spin_unlock(&arenas_lock);
2000                 }
2001 #else
2002                 malloc_spin_lock(&arenas_lock);
2003                 if ((ret = arenas[next_arena]) == NULL)
2004                         ret = arenas_extend(next_arena);
2005                 next_arena = (next_arena + 1) % narenas;
2006                 malloc_spin_unlock(&arenas_lock);
2007 #endif
2008         } else
2009                 ret = arenas[0];
2010
2011         arenas_map = ret;
2012
2013         return (ret);
2014 }
2015 #endif
2016
2017 static inline int
2018 arena_chunk_comp(arena_chunk_t *a, arena_chunk_t *b)
2019 {
2020         uintptr_t a_chunk = (uintptr_t)a;
2021         uintptr_t b_chunk = (uintptr_t)b;
2022
2023         assert(a != NULL);
2024         assert(b != NULL);
2025
2026         return ((a_chunk > b_chunk) - (a_chunk < b_chunk));
2027 }
2028
2029 /* Wrap red-black tree macros in functions. */
2030 rb_wrap(__unused static, arena_chunk_tree_dirty_, arena_chunk_tree_t,
2031     arena_chunk_t, link_dirty, arena_chunk_comp)
2032
2033 static inline int
2034 arena_run_comp(arena_chunk_map_t *a, arena_chunk_map_t *b)
2035 {
2036         uintptr_t a_mapelm = (uintptr_t)a;
2037         uintptr_t b_mapelm = (uintptr_t)b;
2038
2039         assert(a != NULL);
2040         assert(b != NULL);
2041
2042         return ((a_mapelm > b_mapelm) - (a_mapelm < b_mapelm));
2043 }
2044
2045 /* Wrap red-black tree macros in functions. */
2046 rb_wrap(__unused static, arena_run_tree_, arena_run_tree_t, arena_chunk_map_t,
2047     link, arena_run_comp)
2048
2049 static inline int
2050 arena_avail_comp(arena_chunk_map_t *a, arena_chunk_map_t *b)
2051 {
2052         int ret;
2053         size_t a_size = a->bits & ~pagesize_mask;
2054         size_t b_size = b->bits & ~pagesize_mask;
2055
2056         ret = (a_size > b_size) - (a_size < b_size);
2057         if (ret == 0) {
2058                 uintptr_t a_mapelm, b_mapelm;
2059
2060                 if ((a->bits & CHUNK_MAP_KEY) == 0)
2061                         a_mapelm = (uintptr_t)a;
2062                 else {
2063                         /*
2064                          * Treat keys as though they are lower than anything
2065                          * else.
2066                          */
2067                         a_mapelm = 0;
2068                 }
2069                 b_mapelm = (uintptr_t)b;
2070
2071                 ret = (a_mapelm > b_mapelm) - (a_mapelm < b_mapelm);
2072         }
2073
2074         return (ret);
2075 }
2076
2077 /* Wrap red-black tree macros in functions. */
2078 rb_wrap(__unused static, arena_avail_tree_, arena_avail_tree_t,
2079     arena_chunk_map_t, link, arena_avail_comp)
2080
2081 static inline void *
2082 arena_run_reg_alloc(arena_run_t *run, arena_bin_t *bin)
2083 {
2084         void *ret;
2085         unsigned i, mask, bit, regind;
2086
2087         assert(run->magic == ARENA_RUN_MAGIC);
2088         assert(run->regs_minelm < bin->regs_mask_nelms);
2089
2090         /*
2091          * Move the first check outside the loop, so that run->regs_minelm can
2092          * be updated unconditionally, without the possibility of updating it
2093          * multiple times.
2094          */
2095         i = run->regs_minelm;
2096         mask = run->regs_mask[i];
2097         if (mask != 0) {
2098                 /* Usable allocation found. */
2099                 bit = ffs((int)mask) - 1;
2100
2101                 regind = ((i << (SIZEOF_INT_2POW + 3)) + bit);
2102                 assert(regind < bin->nregs);
2103                 ret = (void *)(((uintptr_t)run) + bin->reg0_offset
2104                     + (bin->reg_size * regind));
2105
2106                 /* Clear bit. */
2107                 mask ^= (1U << bit);
2108                 run->regs_mask[i] = mask;
2109
2110                 return (ret);
2111         }
2112
2113         for (i++; i < bin->regs_mask_nelms; i++) {
2114                 mask = run->regs_mask[i];
2115                 if (mask != 0) {
2116                         /* Usable allocation found. */
2117                         bit = ffs((int)mask) - 1;
2118
2119                         regind = ((i << (SIZEOF_INT_2POW + 3)) + bit);
2120                         assert(regind < bin->nregs);
2121                         ret = (void *)(((uintptr_t)run) + bin->reg0_offset
2122                             + (bin->reg_size * regind));
2123
2124                         /* Clear bit. */
2125                         mask ^= (1U << bit);
2126                         run->regs_mask[i] = mask;
2127
2128                         /*
2129                          * Make a note that nothing before this element
2130                          * contains a free region.
2131                          */
2132                         run->regs_minelm = i; /* Low payoff: + (mask == 0); */
2133
2134                         return (ret);
2135                 }
2136         }
2137         /* Not reached. */
2138         assert(0);
2139         return (NULL);
2140 }
2141
2142 static inline void
2143 arena_run_reg_dalloc(arena_run_t *run, arena_bin_t *bin, void *ptr, size_t size)
2144 {
2145         /*
2146          * To divide by a number D that is not a power of two we multiply
2147          * by (2^21 / D) and then right shift by 21 positions.
2148          *
2149          *   X / D
2150          *
2151          * becomes
2152          *
2153          *   (X * size_invs[(D >> QUANTUM_2POW_MIN) - 3]) >> SIZE_INV_SHIFT
2154          */
2155 #define SIZE_INV_SHIFT 21
2156 #define SIZE_INV(s) (((1U << SIZE_INV_SHIFT) / (s << QUANTUM_2POW_MIN)) + 1)
2157         static const unsigned size_invs[] = {
2158             SIZE_INV(3),
2159             SIZE_INV(4), SIZE_INV(5), SIZE_INV(6), SIZE_INV(7),
2160             SIZE_INV(8), SIZE_INV(9), SIZE_INV(10), SIZE_INV(11),
2161             SIZE_INV(12),SIZE_INV(13), SIZE_INV(14), SIZE_INV(15),
2162             SIZE_INV(16),SIZE_INV(17), SIZE_INV(18), SIZE_INV(19),
2163             SIZE_INV(20),SIZE_INV(21), SIZE_INV(22), SIZE_INV(23),
2164             SIZE_INV(24),SIZE_INV(25), SIZE_INV(26), SIZE_INV(27),
2165             SIZE_INV(28),SIZE_INV(29), SIZE_INV(30), SIZE_INV(31)
2166 #if (QUANTUM_2POW_MIN < 4)
2167             ,
2168             SIZE_INV(32), SIZE_INV(33), SIZE_INV(34), SIZE_INV(35),
2169             SIZE_INV(36), SIZE_INV(37), SIZE_INV(38), SIZE_INV(39),
2170             SIZE_INV(40), SIZE_INV(41), SIZE_INV(42), SIZE_INV(43),
2171             SIZE_INV(44), SIZE_INV(45), SIZE_INV(46), SIZE_INV(47),
2172             SIZE_INV(48), SIZE_INV(49), SIZE_INV(50), SIZE_INV(51),
2173             SIZE_INV(52), SIZE_INV(53), SIZE_INV(54), SIZE_INV(55),
2174             SIZE_INV(56), SIZE_INV(57), SIZE_INV(58), SIZE_INV(59),
2175             SIZE_INV(60), SIZE_INV(61), SIZE_INV(62), SIZE_INV(63)
2176 #endif
2177         };
2178         unsigned diff, regind, elm, bit;
2179
2180         assert(run->magic == ARENA_RUN_MAGIC);
2181         assert(((sizeof(size_invs)) / sizeof(unsigned)) + 3
2182             >= (SMALL_MAX_DEFAULT >> QUANTUM_2POW_MIN));
2183
2184         /*
2185          * Avoid doing division with a variable divisor if possible.  Using
2186          * actual division here can reduce allocator throughput by over 20%!
2187          */
2188         diff = (unsigned)((uintptr_t)ptr - (uintptr_t)run - bin->reg0_offset);
2189         if ((size & (size - 1)) == 0) {
2190                 /*
2191                  * log2_table allows fast division of a power of two in the
2192                  * [1..128] range.
2193                  *
2194                  * (x / divisor) becomes (x >> log2_table[divisor - 1]).
2195                  */
2196                 static const unsigned char log2_table[] = {
2197                     0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4,
2198                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
2199                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2200                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6,
2201                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2202                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2203                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2204                     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7
2205                 };
2206
2207                 if (size <= 128)
2208                         regind = (diff >> log2_table[size - 1]);
2209                 else if (size <= 32768)
2210                         regind = diff >> (8 + log2_table[(size >> 8) - 1]);
2211                 else {
2212                         /*
2213                          * The run size is too large for us to use the lookup
2214                          * table.  Use real division.
2215                          */
2216                         regind = diff / size;
2217                 }
2218         } else if (size <= (((sizeof(size_invs) / sizeof(unsigned)) + 2)
2219             << QUANTUM_2POW_MIN)) {
2220                 regind = size_invs[(size >> QUANTUM_2POW_MIN) - 3] * diff;
2221                 regind >>= SIZE_INV_SHIFT;
2222         } else {
2223                 /*
2224                  * size_invs isn't large enough to handle this size class, so
2225                  * calculate regind using actual division.  This only happens
2226                  * if the user increases small_max via the 'S' runtime
2227                  * configuration option.
2228                  */
2229                 regind = diff / size;
2230         };
2231         assert(diff == regind * size);
2232         assert(regind < bin->nregs);
2233
2234         elm = regind >> (SIZEOF_INT_2POW + 3);
2235         if (elm < run->regs_minelm)
2236                 run->regs_minelm = elm;
2237         bit = regind - (elm << (SIZEOF_INT_2POW + 3));
2238         assert((run->regs_mask[elm] & (1U << bit)) == 0);
2239         run->regs_mask[elm] |= (1U << bit);
2240 #undef SIZE_INV
2241 #undef SIZE_INV_SHIFT
2242 }
2243
2244 static void
2245 arena_run_split(arena_t *arena, arena_run_t *run, size_t size, bool large,
2246     bool zero)
2247 {
2248         arena_chunk_t *chunk;
2249         size_t old_ndirty, run_ind, total_pages, need_pages, rem_pages, i;
2250
2251         chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);
2252         old_ndirty = chunk->ndirty;
2253         run_ind = (unsigned)(((uintptr_t)run - (uintptr_t)chunk)
2254             >> pagesize_2pow);
2255         total_pages = (chunk->map[run_ind].bits & ~pagesize_mask) >>
2256             pagesize_2pow;
2257         need_pages = (size >> pagesize_2pow);
2258         assert(need_pages > 0);
2259         assert(need_pages <= total_pages);
2260         rem_pages = total_pages - need_pages;
2261
2262         arena_avail_tree_remove(&arena->runs_avail, &chunk->map[run_ind]);
2263
2264         /* Keep track of trailing unused pages for later use. */
2265         if (rem_pages > 0) {
2266                 chunk->map[run_ind+need_pages].bits = (rem_pages <<
2267                     pagesize_2pow) | (chunk->map[run_ind+need_pages].bits &
2268                     pagesize_mask);
2269                 chunk->map[run_ind+total_pages-1].bits = (rem_pages <<
2270                     pagesize_2pow) | (chunk->map[run_ind+total_pages-1].bits &
2271                     pagesize_mask);
2272                 arena_avail_tree_insert(&arena->runs_avail,
2273                     &chunk->map[run_ind+need_pages]);
2274         }
2275
2276         for (i = 0; i < need_pages; i++) {
2277                 /* Zero if necessary. */
2278                 if (zero) {
2279                         if ((chunk->map[run_ind + i].bits & CHUNK_MAP_ZEROED)
2280                             == 0) {
2281                                 memset((void *)((uintptr_t)chunk + ((run_ind
2282                                     + i) << pagesize_2pow)), 0, pagesize);
2283                                 /* CHUNK_MAP_ZEROED is cleared below. */
2284                         }
2285                 }
2286
2287                 /* Update dirty page accounting. */
2288                 if (chunk->map[run_ind + i].bits & CHUNK_MAP_DIRTY) {
2289                         chunk->ndirty--;
2290                         arena->ndirty--;
2291                         /* CHUNK_MAP_DIRTY is cleared below. */
2292                 }
2293
2294                 /* Initialize the chunk map. */
2295                 if (large) {
2296                         chunk->map[run_ind + i].bits = CHUNK_MAP_LARGE
2297                             | CHUNK_MAP_ALLOCATED;
2298                 } else {
2299                         chunk->map[run_ind + i].bits = (size_t)run
2300                             | CHUNK_MAP_ALLOCATED;
2301                 }
2302         }
2303
2304         /*
2305          * Set the run size only in the first element for large runs.  This is
2306          * primarily a debugging aid, since the lack of size info for trailing
2307          * pages only matters if the application tries to operate on an
2308          * interior pointer.
2309          */
2310         if (large)
2311                 chunk->map[run_ind].bits |= size;
2312
2313         if (chunk->ndirty == 0 && old_ndirty > 0)
2314                 arena_chunk_tree_dirty_remove(&arena->chunks_dirty, chunk);
2315 }
2316
2317 static arena_chunk_t *
2318 arena_chunk_alloc(arena_t *arena)
2319 {
2320         arena_chunk_t *chunk;
2321         size_t i;
2322
2323         if (arena->spare != NULL) {
2324                 chunk = arena->spare;
2325                 arena->spare = NULL;
2326         } else {
2327                 chunk = (arena_chunk_t *)chunk_alloc(chunksize, true);
2328                 if (chunk == NULL)
2329                         return (NULL);
2330 #ifdef MALLOC_STATS
2331                 arena->stats.mapped += chunksize;
2332 #endif
2333
2334                 chunk->arena = arena;
2335
2336                 /*
2337                  * Claim that no pages are in use, since the header is merely
2338                  * overhead.
2339                  */
2340                 chunk->ndirty = 0;
2341
2342                 /*
2343                  * Initialize the map to contain one maximal free untouched run.
2344                  */
2345                 for (i = 0; i < arena_chunk_header_npages; i++)
2346                         chunk->map[i].bits = 0;
2347                 chunk->map[i].bits = arena_maxclass | CHUNK_MAP_ZEROED;
2348                 for (i++; i < chunk_npages-1; i++) {
2349                         chunk->map[i].bits = CHUNK_MAP_ZEROED;
2350                 }
2351                 chunk->map[chunk_npages-1].bits = arena_maxclass |
2352                     CHUNK_MAP_ZEROED;
2353         }
2354
2355         /* Insert the run into the runs_avail tree. */
2356         arena_avail_tree_insert(&arena->runs_avail,
2357             &chunk->map[arena_chunk_header_npages]);
2358
2359         return (chunk);
2360 }
2361
2362 static void
2363 arena_chunk_dealloc(arena_t *arena, arena_chunk_t *chunk)
2364 {
2365
2366         if (arena->spare != NULL) {
2367                 if (arena->spare->ndirty > 0) {
2368                         arena_chunk_tree_dirty_remove(
2369                             &chunk->arena->chunks_dirty, arena->spare);
2370                         arena->ndirty -= arena->spare->ndirty;
2371                 }
2372                 chunk_dealloc((void *)arena->spare, chunksize);
2373 #ifdef MALLOC_STATS
2374                 arena->stats.mapped -= chunksize;
2375 #endif
2376         }
2377
2378         /*
2379          * Remove run from runs_avail, regardless of whether this chunk
2380          * will be cached, so that the arena does not use it.  Dirty page
2381          * flushing only uses the chunks_dirty tree, so leaving this chunk in
2382          * the chunks_* trees is sufficient for that purpose.
2383          */
2384         arena_avail_tree_remove(&arena->runs_avail,
2385             &chunk->map[arena_chunk_header_npages]);
2386
2387         arena->spare = chunk;
2388 }
2389
2390 static arena_run_t *
2391 arena_run_alloc(arena_t *arena, size_t size, bool large, bool zero)
2392 {
2393         arena_chunk_t *chunk;
2394         arena_run_t *run;
2395         arena_chunk_map_t *mapelm, key;
2396
2397         assert(size <= arena_maxclass);
2398         assert((size & pagesize_mask) == 0);
2399
2400         /* Search the arena's chunks for the lowest best fit. */
2401         key.bits = size | CHUNK_MAP_KEY;
2402         mapelm = arena_avail_tree_nsearch(&arena->runs_avail, &key);
2403         if (mapelm != NULL) {
2404                 arena_chunk_t *run_chunk = CHUNK_ADDR2BASE(mapelm);
2405                 size_t pageind = ((uintptr_t)mapelm - (uintptr_t)run_chunk->map)
2406                     / sizeof(arena_chunk_map_t);
2407
2408                 run = (arena_run_t *)((uintptr_t)run_chunk + (pageind
2409                     << pagesize_2pow));
2410                 arena_run_split(arena, run, size, large, zero);
2411                 return (run);
2412         }
2413
2414         /*
2415          * No usable runs.  Create a new chunk from which to allocate the run.
2416          */
2417         chunk = arena_chunk_alloc(arena);
2418         if (chunk == NULL)
2419                 return (NULL);
2420         run = (arena_run_t *)((uintptr_t)chunk + (arena_chunk_header_npages <<
2421             pagesize_2pow));
2422         /* Update page map. */
2423         arena_run_split(arena, run, size, large, zero);
2424         return (run);
2425 }
2426
2427 static void
2428 arena_purge(arena_t *arena)
2429 {
2430         arena_chunk_t *chunk;
2431         size_t i, npages;
2432 #ifdef MALLOC_DEBUG
2433         size_t ndirty = 0;
2434
2435         rb_foreach_begin(arena_chunk_t, link_dirty, &arena->chunks_dirty,
2436             chunk) {
2437                 ndirty += chunk->ndirty;
2438         } rb_foreach_end(arena_chunk_t, link_dirty, &arena->chunks_dirty, chunk)
2439         assert(ndirty == arena->ndirty);
2440 #endif
2441         assert(arena->ndirty > opt_dirty_max);
2442
2443 #ifdef MALLOC_STATS
2444         arena->stats.npurge++;
2445 #endif
2446
2447         /*
2448          * Iterate downward through chunks until enough dirty memory has been
2449          * purged.  Terminate as soon as possible in order to minimize the
2450          * number of system calls, even if a chunk has only been partially
2451          * purged.
2452          */
2453         while (arena->ndirty > (opt_dirty_max >> 1)) {
2454                 chunk = arena_chunk_tree_dirty_last(&arena->chunks_dirty);
2455                 assert(chunk != NULL);
2456
2457                 for (i = chunk_npages - 1; chunk->ndirty > 0; i--) {
2458                         assert(i >= arena_chunk_header_npages);
2459
2460                         if (chunk->map[i].bits & CHUNK_MAP_DIRTY) {
2461                                 chunk->map[i].bits ^= CHUNK_MAP_DIRTY;
2462                                 /* Find adjacent dirty run(s). */
2463                                 for (npages = 1; i > arena_chunk_header_npages
2464                                     && (chunk->map[i - 1].bits &
2465                                     CHUNK_MAP_DIRTY); npages++) {
2466                                         i--;
2467                                         chunk->map[i].bits ^= CHUNK_MAP_DIRTY;
2468                                 }
2469                                 chunk->ndirty -= npages;
2470                                 arena->ndirty -= npages;
2471
2472                                 madvise((void *)((uintptr_t)chunk + (i <<
2473                                     pagesize_2pow)), (npages << pagesize_2pow),
2474                                     MADV_FREE);
2475 #ifdef MALLOC_STATS
2476                                 arena->stats.nmadvise++;
2477                                 arena->stats.purged += npages;
2478 #endif
2479                                 if (arena->ndirty <= (opt_dirty_max >> 1))
2480                                         break;
2481                         }
2482                 }
2483
2484                 if (chunk->ndirty == 0) {
2485                         arena_chunk_tree_dirty_remove(&arena->chunks_dirty,
2486                             chunk);
2487                 }
2488         }
2489 }
2490
2491 static void
2492 arena_run_dalloc(arena_t *arena, arena_run_t *run, bool dirty)
2493 {
2494         arena_chunk_t *chunk;
2495         size_t size, run_ind, run_pages;
2496
2497         chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(run);
2498         run_ind = (size_t)(((uintptr_t)run - (uintptr_t)chunk)
2499             >> pagesize_2pow);
2500         assert(run_ind >= arena_chunk_header_npages);
2501         assert(run_ind < chunk_npages);
2502         if ((chunk->map[run_ind].bits & CHUNK_MAP_LARGE) != 0)
2503                 size = chunk->map[run_ind].bits & ~pagesize_mask;
2504         else
2505                 size = run->bin->run_size;
2506         run_pages = (size >> pagesize_2pow);
2507
2508         /* Mark pages as unallocated in the chunk map. */
2509         if (dirty) {
2510                 size_t i;
2511
2512                 for (i = 0; i < run_pages; i++) {
2513                         assert((chunk->map[run_ind + i].bits & CHUNK_MAP_DIRTY)
2514                             == 0);
2515                         chunk->map[run_ind + i].bits = CHUNK_MAP_DIRTY;
2516                 }
2517
2518                 if (chunk->ndirty == 0) {
2519                         arena_chunk_tree_dirty_insert(&arena->chunks_dirty,
2520                             chunk);
2521                 }
2522                 chunk->ndirty += run_pages;
2523                 arena->ndirty += run_pages;
2524         } else {
2525                 size_t i;
2526
2527                 for (i = 0; i < run_pages; i++) {
2528                         chunk->map[run_ind + i].bits &= ~(CHUNK_MAP_LARGE |
2529                             CHUNK_MAP_ALLOCATED);
2530                 }
2531         }
2532         chunk->map[run_ind].bits = size | (chunk->map[run_ind].bits &
2533             pagesize_mask);
2534         chunk->map[run_ind+run_pages-1].bits = size |
2535             (chunk->map[run_ind+run_pages-1].bits & pagesize_mask);
2536
2537         /* Try to coalesce forward. */
2538         if (run_ind + run_pages < chunk_npages &&
2539             (chunk->map[run_ind+run_pages].bits & CHUNK_MAP_ALLOCATED) == 0) {
2540                 size_t nrun_size = chunk->map[run_ind+run_pages].bits &
2541                     ~pagesize_mask;
2542
2543                 /*
2544                  * Remove successor from runs_avail; the coalesced run is
2545                  * inserted later.
2546                  */
2547                 arena_avail_tree_remove(&arena->runs_avail,
2548                     &chunk->map[run_ind+run_pages]);
2549
2550                 size += nrun_size;
2551                 run_pages = size >> pagesize_2pow;
2552
2553                 assert((chunk->map[run_ind+run_pages-1].bits & ~pagesize_mask)
2554                     == nrun_size);
2555                 chunk->map[run_ind].bits = size | (chunk->map[run_ind].bits &
2556                     pagesize_mask);
2557                 chunk->map[run_ind+run_pages-1].bits = size |
2558                     (chunk->map[run_ind+run_pages-1].bits & pagesize_mask);
2559         }
2560
2561         /* Try to coalesce backward. */
2562         if (run_ind > arena_chunk_header_npages && (chunk->map[run_ind-1].bits &
2563             CHUNK_MAP_ALLOCATED) == 0) {
2564                 size_t prun_size = chunk->map[run_ind-1].bits & ~pagesize_mask;
2565
2566                 run_ind -= prun_size >> pagesize_2pow;
2567
2568                 /*
2569                  * Remove predecessor from runs_avail; the coalesced run is
2570                  * inserted later.
2571                  */
2572                 arena_avail_tree_remove(&arena->runs_avail,
2573                     &chunk->map[run_ind]);
2574
2575                 size += prun_size;
2576                 run_pages = size >> pagesize_2pow;
2577
2578                 assert((chunk->map[run_ind].bits & ~pagesize_mask) ==
2579                     prun_size);
2580                 chunk->map[run_ind].bits = size | (chunk->map[run_ind].bits &
2581                     pagesize_mask);
2582                 chunk->map[run_ind+run_pages-1].bits = size |
2583                     (chunk->map[run_ind+run_pages-1].bits & pagesize_mask);
2584         }
2585
2586         /* Insert into runs_avail, now that coalescing is complete. */
2587         arena_avail_tree_insert(&arena->runs_avail, &chunk->map[run_ind]);
2588
2589         /* Deallocate chunk if it is now completely unused. */
2590         if ((chunk->map[arena_chunk_header_npages].bits & (~pagesize_mask |
2591             CHUNK_MAP_ALLOCATED)) == arena_maxclass)
2592                 arena_chunk_dealloc(arena, chunk);
2593
2594         /* Enforce opt_dirty_max. */
2595         if (arena->ndirty > opt_dirty_max)
2596                 arena_purge(arena);
2597 }
2598
2599 static void
2600 arena_run_trim_head(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run,
2601     size_t oldsize, size_t newsize)
2602 {
2603         size_t pageind = ((uintptr_t)run - (uintptr_t)chunk) >> pagesize_2pow;
2604         size_t head_npages = (oldsize - newsize) >> pagesize_2pow;
2605
2606         assert(oldsize > newsize);
2607
2608         /*
2609          * Update the chunk map so that arena_run_dalloc() can treat the
2610          * leading run as separately allocated.
2611          */
2612         chunk->map[pageind].bits = (oldsize - newsize) | CHUNK_MAP_LARGE |
2613             CHUNK_MAP_ALLOCATED;
2614         chunk->map[pageind+head_npages].bits = newsize | CHUNK_MAP_LARGE |
2615             CHUNK_MAP_ALLOCATED;
2616
2617         arena_run_dalloc(arena, run, false);
2618 }
2619
2620 static void
2621 arena_run_trim_tail(arena_t *arena, arena_chunk_t *chunk, arena_run_t *run,
2622     size_t oldsize, size_t newsize, bool dirty)
2623 {
2624         size_t pageind = ((uintptr_t)run - (uintptr_t)chunk) >> pagesize_2pow;
2625         size_t npages = newsize >> pagesize_2pow;
2626
2627         assert(oldsize > newsize);
2628
2629         /*
2630          * Update the chunk map so that arena_run_dalloc() can treat the
2631          * trailing run as separately allocated.
2632          */
2633         chunk->map[pageind].bits = newsize | CHUNK_MAP_LARGE |
2634             CHUNK_MAP_ALLOCATED;
2635         chunk->map[pageind+npages].bits = (oldsize - newsize) | CHUNK_MAP_LARGE
2636             | CHUNK_MAP_ALLOCATED;
2637
2638         arena_run_dalloc(arena, (arena_run_t *)((uintptr_t)run + newsize),
2639             dirty);
2640 }
2641
2642 static arena_run_t *
2643 arena_bin_nonfull_run_get(arena_t *arena, arena_bin_t *bin)
2644 {
2645         arena_chunk_map_t *mapelm;
2646         arena_run_t *run;
2647         unsigned i, remainder;
2648
2649         /* Look for a usable run. */
2650         mapelm = arena_run_tree_first(&bin->runs);
2651         if (mapelm != NULL) {
2652                 /* run is guaranteed to have available space. */
2653                 arena_run_tree_remove(&bin->runs, mapelm);
2654                 run = (arena_run_t *)(mapelm->bits & ~pagesize_mask);
2655 #ifdef MALLOC_STATS
2656                 bin->stats.reruns++;
2657 #endif
2658                 return (run);
2659         }
2660         /* No existing runs have any space available. */
2661
2662         /* Allocate a new run. */
2663         run = arena_run_alloc(arena, bin->run_size, false, false);
2664         if (run == NULL)
2665                 return (NULL);
2666
2667         /* Initialize run internals. */
2668         run->bin = bin;
2669
2670         for (i = 0; i < bin->regs_mask_nelms - 1; i++)
2671                 run->regs_mask[i] = UINT_MAX;
2672         remainder = bin->nregs & ((1U << (SIZEOF_INT_2POW + 3)) - 1);
2673         if (remainder == 0)
2674                 run->regs_mask[i] = UINT_MAX;
2675         else {
2676                 /* The last element has spare bits that need to be unset. */
2677                 run->regs_mask[i] = (UINT_MAX >> ((1U << (SIZEOF_INT_2POW + 3))
2678                     - remainder));
2679         }
2680
2681         run->regs_minelm = 0;
2682
2683         run->nfree = bin->nregs;
2684 #ifdef MALLOC_DEBUG
2685         run->magic = ARENA_RUN_MAGIC;
2686 #endif
2687
2688 #ifdef MALLOC_STATS
2689         bin->stats.nruns++;
2690         bin->stats.curruns++;
2691         if (bin->stats.curruns > bin->stats.highruns)
2692                 bin->stats.highruns = bin->stats.curruns;
2693 #endif
2694         return (run);
2695 }
2696
2697 /* bin->runcur must have space available before this function is called. */
2698 static inline void *
2699 arena_bin_malloc_easy(arena_t *arena, arena_bin_t *bin, arena_run_t *run)
2700 {
2701         void *ret;
2702
2703         assert(run->magic == ARENA_RUN_MAGIC);
2704         assert(run->nfree > 0);
2705
2706         ret = arena_run_reg_alloc(run, bin);
2707         assert(ret != NULL);
2708         run->nfree--;
2709
2710         return (ret);
2711 }
2712
2713 /* Re-fill bin->runcur, then call arena_bin_malloc_easy(). */
2714 static void *
2715 arena_bin_malloc_hard(arena_t *arena, arena_bin_t *bin)
2716 {
2717
2718         bin->runcur = arena_bin_nonfull_run_get(arena, bin);
2719         if (bin->runcur == NULL)
2720                 return (NULL);
2721         assert(bin->runcur->magic == ARENA_RUN_MAGIC);
2722         assert(bin->runcur->nfree > 0);
2723
2724         return (arena_bin_malloc_easy(arena, bin, bin->runcur));
2725 }
2726
2727 /*
2728  * Calculate bin->run_size such that it meets the following constraints:
2729  *
2730  *   *) bin->run_size >= min_run_size
2731  *   *) bin->run_size <= arena_maxclass
2732  *   *) bin->run_size <= RUN_MAX_SMALL
2733  *   *) run header overhead <= RUN_MAX_OVRHD (or header overhead relaxed).
2734  *
2735  * bin->nregs, bin->regs_mask_nelms, and bin->reg0_offset are
2736  * also calculated here, since these settings are all interdependent.
2737  */
2738 static size_t
2739 arena_bin_run_size_calc(arena_bin_t *bin, size_t min_run_size)
2740 {
2741         size_t try_run_size, good_run_size;
2742         unsigned good_nregs, good_mask_nelms, good_reg0_offset;
2743         unsigned try_nregs, try_mask_nelms, try_reg0_offset;
2744
2745         assert(min_run_size >= pagesize);
2746         assert(min_run_size <= arena_maxclass);
2747         assert(min_run_size <= RUN_MAX_SMALL);
2748
2749         /*
2750          * Calculate known-valid settings before entering the run_size
2751          * expansion loop, so that the first part of the loop always copies
2752          * valid settings.
2753          *
2754          * The do..while loop iteratively reduces the number of regions until
2755          * the run header and the regions no longer overlap.  A closed formula
2756          * would be quite messy, since there is an interdependency between the
2757          * header's mask length and the number of regions.
2758          */
2759         try_run_size = min_run_size;
2760         try_nregs = ((try_run_size - sizeof(arena_run_t)) / bin->reg_size)
2761             + 1; /* Counter-act try_nregs-- in loop. */
2762         do {
2763                 try_nregs--;
2764                 try_mask_nelms = (try_nregs >> (SIZEOF_INT_2POW + 3)) +
2765                     ((try_nregs & ((1U << (SIZEOF_INT_2POW + 3)) - 1)) ? 1 : 0);
2766                 try_reg0_offset = try_run_size - (try_nregs * bin->reg_size);
2767         } while (sizeof(arena_run_t) + (sizeof(unsigned) * (try_mask_nelms - 1))
2768             > try_reg0_offset);
2769
2770         /* run_size expansion loop. */
2771         do {
2772                 /*
2773                  * Copy valid settings before trying more aggressive settings.
2774                  */
2775                 good_run_size = try_run_size;
2776                 good_nregs = try_nregs;
2777                 good_mask_nelms = try_mask_nelms;
2778                 good_reg0_offset = try_reg0_offset;
2779
2780                 /* Try more aggressive settings. */
2781                 try_run_size += pagesize;
2782                 try_nregs = ((try_run_size - sizeof(arena_run_t)) /
2783                     bin->reg_size) + 1; /* Counter-act try_nregs-- in loop. */
2784                 do {
2785                         try_nregs--;
2786                         try_mask_nelms = (try_nregs >> (SIZEOF_INT_2POW + 3)) +
2787                             ((try_nregs & ((1U << (SIZEOF_INT_2POW + 3)) - 1)) ?
2788                             1 : 0);
2789                         try_reg0_offset = try_run_size - (try_nregs *
2790                             bin->reg_size);
2791                 } while (sizeof(arena_run_t) + (sizeof(unsigned) *
2792                     (try_mask_nelms - 1)) > try_reg0_offset);
2793         } while (try_run_size <= arena_maxclass && try_run_size <= RUN_MAX_SMALL
2794             && RUN_MAX_OVRHD * (bin->reg_size << 3) > RUN_MAX_OVRHD_RELAX
2795             && (try_reg0_offset << RUN_BFP) > RUN_MAX_OVRHD * try_run_size);
2796
2797         assert(sizeof(arena_run_t) + (sizeof(unsigned) * (good_mask_nelms - 1))
2798             <= good_reg0_offset);
2799         assert((good_mask_nelms << (SIZEOF_INT_2POW + 3)) >= good_nregs);
2800
2801         /* Copy final settings. */
2802         bin->run_size = good_run_size;
2803         bin->nregs = good_nregs;
2804         bin->regs_mask_nelms = good_mask_nelms;
2805         bin->reg0_offset = good_reg0_offset;
2806
2807         return (good_run_size);
2808 }
2809
2810 #ifdef MALLOC_BALANCE
2811 static inline void
2812 arena_lock_balance(arena_t *arena)
2813 {
2814         unsigned contention;
2815
2816         contention = malloc_spin_lock(&arena->lock);
2817         if (narenas > 1) {
2818                 /*
2819                  * Calculate the exponentially averaged contention for this
2820                  * arena.  Due to integer math always rounding down, this value
2821                  * decays somewhat faster then normal.
2822                  */
2823                 arena->contention = (((uint64_t)arena->contention
2824                     * (uint64_t)((1U << BALANCE_ALPHA_INV_2POW)-1))
2825                     + (uint64_t)contention) >> BALANCE_ALPHA_INV_2POW;
2826                 if (arena->contention >= opt_balance_threshold)
2827                         arena_lock_balance_hard(arena);
2828         }
2829 }
2830
2831 static void
2832 arena_lock_balance_hard(arena_t *arena)
2833 {
2834         uint32_t ind;
2835
2836         arena->contention = 0;
2837 #ifdef MALLOC_STATS
2838         arena->stats.nbalance++;
2839 #endif
2840         ind = PRN(balance, narenas_2pow);
2841         if (arenas[ind] != NULL)
2842                 arenas_map = arenas[ind];
2843         else {
2844                 malloc_spin_lock(&arenas_lock);
2845                 if (arenas[ind] != NULL)
2846                         arenas_map = arenas[ind];
2847                 else
2848                         arenas_map = arenas_extend(ind);
2849                 malloc_spin_unlock(&arenas_lock);
2850         }
2851 }
2852 #endif
2853
2854 static inline void *
2855 arena_malloc_small(arena_t *arena, size_t size, bool zero)
2856 {
2857         void *ret;
2858         arena_bin_t *bin;
2859         arena_run_t *run;
2860
2861         if (size < small_min) {
2862                 /* Tiny. */
2863                 size = pow2_ceil(size);
2864                 bin = &arena->bins[ffs((int)(size >> (TINY_MIN_2POW +
2865                     1)))];
2866 #if (!defined(NDEBUG) || defined(MALLOC_STATS))
2867                 /*
2868                  * Bin calculation is always correct, but we may need
2869                  * to fix size for the purposes of assertions and/or
2870                  * stats accuracy.
2871                  */
2872                 if (size < (1U << TINY_MIN_2POW))
2873                         size = (1U << TINY_MIN_2POW);
2874 #endif
2875         } else if (size <= small_max) {
2876                 /* Quantum-spaced. */
2877                 size = QUANTUM_CEILING(size);
2878                 bin = &arena->bins[ntbins + (size >> opt_quantum_2pow)
2879                     - 1];
2880         } else {
2881                 /* Sub-page. */
2882                 size = pow2_ceil(size);
2883                 bin = &arena->bins[ntbins + nqbins
2884                     + (ffs((int)(size >> opt_small_max_2pow)) - 2)];
2885         }
2886         assert(size == bin->reg_size);
2887
2888 #ifdef MALLOC_BALANCE
2889         arena_lock_balance(arena);
2890 #else
2891         malloc_spin_lock(&arena->lock);
2892 #endif
2893         if ((run = bin->runcur) != NULL && run->nfree > 0)
2894                 ret = arena_bin_malloc_easy(arena, bin, run);
2895         else
2896                 ret = arena_bin_malloc_hard(arena, bin);
2897
2898         if (ret == NULL) {
2899                 malloc_spin_unlock(&arena->lock);
2900                 return (NULL);
2901         }
2902
2903 #ifdef MALLOC_STATS
2904         bin->stats.nrequests++;
2905         arena->stats.nmalloc_small++;
2906         arena->stats.allocated_small += size;
2907 #endif
2908         malloc_spin_unlock(&arena->lock);
2909
2910         if (zero == false) {
2911                 if (opt_junk)
2912                         memset(ret, 0xa5, size);
2913                 else if (opt_zero)
2914                         memset(ret, 0, size);
2915         } else
2916                 memset(ret, 0, size);
2917
2918         return (ret);
2919 }
2920
2921 static void *
2922 arena_malloc_large(arena_t *arena, size_t size, bool zero)
2923 {
2924         void *ret;
2925
2926         /* Large allocation. */
2927         size = PAGE_CEILING(size);
2928 #ifdef MALLOC_BALANCE
2929         arena_lock_balance(arena);
2930 #else
2931         malloc_spin_lock(&arena->lock);
2932 #endif
2933         ret = (void *)arena_run_alloc(arena, size, true, zero);
2934         if (ret == NULL) {
2935                 malloc_spin_unlock(&arena->lock);
2936                 return (NULL);
2937         }
2938 #ifdef MALLOC_STATS
2939         arena->stats.nmalloc_large++;
2940         arena->stats.allocated_large += size;
2941 #endif
2942         malloc_spin_unlock(&arena->lock);
2943
2944         if (zero == false) {
2945                 if (opt_junk)
2946                         memset(ret, 0xa5, size);
2947                 else if (opt_zero)
2948                         memset(ret, 0, size);
2949         }
2950
2951         return (ret);
2952 }
2953
2954 static inline void *
2955 arena_malloc(arena_t *arena, size_t size, bool zero)
2956 {
2957
2958         assert(arena != NULL);
2959         assert(arena->magic == ARENA_MAGIC);
2960         assert(size != 0);
2961         assert(QUANTUM_CEILING(size) <= arena_maxclass);
2962
2963         if (size <= bin_maxclass) {
2964                 return (arena_malloc_small(arena, size, zero));
2965         } else
2966                 return (arena_malloc_large(arena, size, zero));
2967 }
2968
2969 static inline void *
2970 imalloc(size_t size)
2971 {
2972
2973         assert(size != 0);
2974
2975         if (size <= arena_maxclass)
2976                 return (arena_malloc(choose_arena(), size, false));
2977         else
2978                 return (huge_malloc(size, false));
2979 }
2980
2981 static inline void *
2982 icalloc(size_t size)
2983 {
2984
2985         if (size <= arena_maxclass)
2986                 return (arena_malloc(choose_arena(), size, true));
2987         else
2988                 return (huge_malloc(size, true));
2989 }
2990
2991 /* Only handles large allocations that require more than page alignment. */
2992 static void *
2993 arena_palloc(arena_t *arena, size_t alignment, size_t size, size_t alloc_size)
2994 {
2995         void *ret;
2996         size_t offset;
2997         arena_chunk_t *chunk;
2998
2999         assert((size & pagesize_mask) == 0);
3000         assert((alignment & pagesize_mask) == 0);
3001
3002 #ifdef MALLOC_BALANCE
3003         arena_lock_balance(arena);
3004 #else
3005         malloc_spin_lock(&arena->lock);
3006 #endif
3007         ret = (void *)arena_run_alloc(arena, alloc_size, true, false);
3008         if (ret == NULL) {
3009                 malloc_spin_unlock(&arena->lock);
3010                 return (NULL);
3011         }
3012
3013         chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ret);
3014
3015         offset = (uintptr_t)ret & (alignment - 1);
3016         assert((offset & pagesize_mask) == 0);
3017         assert(offset < alloc_size);
3018         if (offset == 0)
3019                 arena_run_trim_tail(arena, chunk, ret, alloc_size, size, false);
3020         else {
3021                 size_t leadsize, trailsize;
3022
3023                 leadsize = alignment - offset;
3024                 if (leadsize > 0) {
3025                         arena_run_trim_head(arena, chunk, ret, alloc_size,
3026                             alloc_size - leadsize);
3027                         ret = (void *)((uintptr_t)ret + leadsize);
3028                 }
3029
3030                 trailsize = alloc_size - leadsize - size;
3031                 if (trailsize != 0) {
3032                         /* Trim trailing space. */
3033                         assert(trailsize < alloc_size);
3034                         arena_run_trim_tail(arena, chunk, ret, size + trailsize,
3035                             size, false);
3036                 }
3037         }
3038
3039 #ifdef MALLOC_STATS
3040         arena->stats.nmalloc_large++;
3041         arena->stats.allocated_large += size;
3042 #endif
3043         malloc_spin_unlock(&arena->lock);
3044
3045         if (opt_junk)
3046                 memset(ret, 0xa5, size);
3047         else if (opt_zero)
3048                 memset(ret, 0, size);
3049         return (ret);
3050 }
3051
3052 static inline void *
3053 ipalloc(size_t alignment, size_t size)
3054 {
3055         void *ret;
3056         size_t ceil_size;
3057
3058         /*
3059          * Round size up to the nearest multiple of alignment.
3060          *
3061          * This done, we can take advantage of the fact that for each small
3062          * size class, every object is aligned at the smallest power of two
3063          * that is non-zero in the base two representation of the size.  For
3064          * example:
3065          *
3066          *   Size |   Base 2 | Minimum alignment
3067          *   -----+----------+------------------
3068          *     96 |  1100000 |  32
3069          *    144 | 10100000 |  32
3070          *    192 | 11000000 |  64
3071          *
3072          * Depending on runtime settings, it is possible that arena_malloc()
3073          * will further round up to a power of two, but that never causes
3074          * correctness issues.
3075          */
3076         ceil_size = (size + (alignment - 1)) & (-alignment);
3077         /*
3078          * (ceil_size < size) protects against the combination of maximal
3079          * alignment and size greater than maximal alignment.
3080          */
3081         if (ceil_size < size) {
3082                 /* size_t overflow. */
3083                 return (NULL);
3084         }
3085
3086         if (ceil_size <= pagesize || (alignment <= pagesize
3087             && ceil_size <= arena_maxclass))
3088                 ret = arena_malloc(choose_arena(), ceil_size, false);
3089         else {
3090                 size_t run_size;
3091
3092                 /*
3093                  * We can't achieve sub-page alignment, so round up alignment
3094                  * permanently; it makes later calculations simpler.
3095                  */
3096                 alignment = PAGE_CEILING(alignment);
3097                 ceil_size = PAGE_CEILING(size);
3098                 /*
3099                  * (ceil_size < size) protects against very large sizes within
3100                  * pagesize of SIZE_T_MAX.
3101                  *
3102                  * (ceil_size + alignment < ceil_size) protects against the
3103                  * combination of maximal alignment and ceil_size large enough
3104                  * to cause overflow.  This is similar to the first overflow
3105                  * check above, but it needs to be repeated due to the new
3106                  * ceil_size value, which may now be *equal* to maximal
3107                  * alignment, whereas before we only detected overflow if the
3108                  * original size was *greater* than maximal alignment.
3109                  */
3110                 if (ceil_size < size || ceil_size + alignment < ceil_size) {
3111                         /* size_t overflow. */
3112                         return (NULL);
3113                 }
3114
3115                 /*
3116                  * Calculate the size of the over-size run that arena_palloc()
3117                  * would need to allocate in order to guarantee the alignment.
3118                  */
3119                 if (ceil_size >= alignment)
3120                         run_size = ceil_size + alignment - pagesize;
3121                 else {
3122                         /*
3123                          * It is possible that (alignment << 1) will cause
3124                          * overflow, but it doesn't matter because we also
3125                          * subtract pagesize, which in the case of overflow
3126                          * leaves us with a very large run_size.  That causes
3127                          * the first conditional below to fail, which means
3128                          * that the bogus run_size value never gets used for
3129                          * anything important.
3130                          */
3131                         run_size = (alignment << 1) - pagesize;
3132                 }
3133
3134                 if (run_size <= arena_maxclass) {
3135                         ret = arena_palloc(choose_arena(), alignment, ceil_size,
3136                             run_size);
3137                 } else if (alignment <= chunksize)
3138                         ret = huge_malloc(ceil_size, false);
3139                 else
3140                         ret = huge_palloc(alignment, ceil_size);
3141         }
3142
3143         assert(((uintptr_t)ret & (alignment - 1)) == 0);
3144         return (ret);
3145 }
3146
3147 /* Return the size of the allocation pointed to by ptr. */
3148 static size_t
3149 arena_salloc(const void *ptr)
3150 {
3151         size_t ret;
3152         arena_chunk_t *chunk;
3153         size_t pageind, mapbits;
3154
3155         assert(ptr != NULL);
3156         assert(CHUNK_ADDR2BASE(ptr) != ptr);
3157
3158         chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
3159         pageind = (((uintptr_t)ptr - (uintptr_t)chunk) >> pagesize_2pow);
3160         mapbits = chunk->map[pageind].bits;
3161         assert((mapbits & CHUNK_MAP_ALLOCATED) != 0);
3162         if ((mapbits & CHUNK_MAP_LARGE) == 0) {
3163                 arena_run_t *run = (arena_run_t *)(mapbits & ~pagesize_mask);
3164                 assert(run->magic == ARENA_RUN_MAGIC);
3165                 ret = run->bin->reg_size;
3166         } else {
3167                 ret = mapbits & ~pagesize_mask;
3168                 assert(ret != 0);
3169         }
3170
3171         return (ret);
3172 }
3173
3174 static inline size_t
3175 isalloc(const void *ptr)
3176 {
3177         size_t ret;
3178         arena_chunk_t *chunk;
3179
3180         assert(ptr != NULL);
3181
3182         chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
3183         if (chunk != ptr) {
3184                 /* Region. */
3185                 assert(chunk->arena->magic == ARENA_MAGIC);
3186
3187                 ret = arena_salloc(ptr);
3188         } else {
3189                 extent_node_t *node, key;
3190
3191                 /* Chunk (huge allocation). */
3192
3193                 malloc_mutex_lock(&huge_mtx);
3194
3195                 /* Extract from tree of huge allocations. */
3196                 key.addr = __DECONST(void *, ptr);
3197                 node = extent_tree_ad_search(&huge, &key);
3198                 assert(node != NULL);
3199
3200                 ret = node->size;
3201
3202                 malloc_mutex_unlock(&huge_mtx);
3203         }
3204
3205         return (ret);
3206 }
3207
3208 static inline void
3209 arena_dalloc_small(arena_t *arena, arena_chunk_t *chunk, void *ptr,
3210     arena_chunk_map_t *mapelm)
3211 {
3212         arena_run_t *run;
3213         arena_bin_t *bin;
3214         size_t size;
3215
3216         run = (arena_run_t *)(mapelm->bits & ~pagesize_mask);
3217         assert(run->magic == ARENA_RUN_MAGIC);
3218         bin = run->bin;
3219         size = bin->reg_size;
3220
3221         if (opt_junk)
3222                 memset(ptr, 0x5a, size);
3223
3224         arena_run_reg_dalloc(run, bin, ptr, size);
3225         run->nfree++;
3226
3227         if (run->nfree == bin->nregs) {
3228                 /* Deallocate run. */
3229                 if (run == bin->runcur)
3230                         bin->runcur = NULL;
3231                 else if (bin->nregs != 1) {
3232                         size_t run_pageind = (((uintptr_t)run -
3233                             (uintptr_t)chunk)) >> pagesize_2pow;
3234                         arena_chunk_map_t *run_mapelm =
3235                             &chunk->map[run_pageind];
3236                         /*
3237                          * This block's conditional is necessary because if the
3238                          * run only contains one region, then it never gets
3239                          * inserted into the non-full runs tree.
3240                          */
3241                         arena_run_tree_remove(&bin->runs, run_mapelm);
3242                 }
3243 #ifdef MALLOC_DEBUG
3244                 run->magic = 0;
3245 #endif
3246                 arena_run_dalloc(arena, run, true);
3247 #ifdef MALLOC_STATS
3248                 bin->stats.curruns--;
3249 #endif
3250         } else if (run->nfree == 1 && run != bin->runcur) {
3251                 /*
3252                  * Make sure that bin->runcur always refers to the lowest
3253                  * non-full run, if one exists.
3254                  */
3255                 if (bin->runcur == NULL)
3256                         bin->runcur = run;
3257                 else if ((uintptr_t)run < (uintptr_t)bin->runcur) {
3258                         /* Switch runcur. */
3259                         if (bin->runcur->nfree > 0) {
3260                                 arena_chunk_t *runcur_chunk =
3261                                     CHUNK_ADDR2BASE(bin->runcur);
3262                                 size_t runcur_pageind =
3263                                     (((uintptr_t)bin->runcur -
3264                                     (uintptr_t)runcur_chunk)) >> pagesize_2pow;
3265                                 arena_chunk_map_t *runcur_mapelm =
3266                                     &runcur_chunk->map[runcur_pageind];
3267
3268                                 /* Insert runcur. */
3269                                 arena_run_tree_insert(&bin->runs,
3270                                     runcur_mapelm);
3271                         }
3272                         bin->runcur = run;
3273                 } else {
3274                         size_t run_pageind = (((uintptr_t)run -
3275                             (uintptr_t)chunk)) >> pagesize_2pow;
3276                         arena_chunk_map_t *run_mapelm =
3277                             &chunk->map[run_pageind];
3278
3279                         assert(arena_run_tree_search(&bin->runs, run_mapelm) ==
3280                             NULL);
3281                         arena_run_tree_insert(&bin->runs, run_mapelm);
3282                 }
3283         }
3284 #ifdef MALLOC_STATS
3285         arena->stats.allocated_small -= size;
3286         arena->stats.ndalloc_small++;
3287 #endif
3288 }
3289
3290 static void
3291 arena_dalloc_large(arena_t *arena, arena_chunk_t *chunk, void *ptr)
3292 {
3293         /* Large allocation. */
3294         malloc_spin_lock(&arena->lock);
3295
3296 #ifndef MALLOC_STATS
3297         if (opt_junk)
3298 #endif
3299         {
3300                 size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >>
3301                     pagesize_2pow;
3302                 size_t size = chunk->map[pageind].bits & ~pagesize_mask;
3303
3304 #ifdef MALLOC_STATS
3305                 if (opt_junk)
3306 #endif
3307                         memset(ptr, 0x5a, size);
3308 #ifdef MALLOC_STATS
3309                 arena->stats.allocated_large -= size;
3310 #endif
3311         }
3312 #ifdef MALLOC_STATS
3313         arena->stats.ndalloc_large++;
3314 #endif
3315
3316         arena_run_dalloc(arena, (arena_run_t *)ptr, true);
3317         malloc_spin_unlock(&arena->lock);
3318 }
3319
3320 static inline void
3321 arena_dalloc(arena_t *arena, arena_chunk_t *chunk, void *ptr)
3322 {
3323         size_t pageind;
3324         arena_chunk_map_t *mapelm;
3325
3326         assert(arena != NULL);
3327         assert(arena->magic == ARENA_MAGIC);
3328         assert(chunk->arena == arena);
3329         assert(ptr != NULL);
3330         assert(CHUNK_ADDR2BASE(ptr) != ptr);
3331
3332         pageind = (((uintptr_t)ptr - (uintptr_t)chunk) >> pagesize_2pow);
3333         mapelm = &chunk->map[pageind];
3334         assert((mapelm->bits & CHUNK_MAP_ALLOCATED) != 0);
3335         if ((mapelm->bits & CHUNK_MAP_LARGE) == 0) {
3336                 /* Small allocation. */
3337                 malloc_spin_lock(&arena->lock);
3338                 arena_dalloc_small(arena, chunk, ptr, mapelm);
3339                 malloc_spin_unlock(&arena->lock);
3340         } else
3341                 arena_dalloc_large(arena, chunk, ptr);
3342 }
3343
3344 static inline void
3345 idalloc(void *ptr)
3346 {
3347         arena_chunk_t *chunk;
3348
3349         assert(ptr != NULL);
3350
3351         chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
3352         if (chunk != ptr)
3353                 arena_dalloc(chunk->arena, chunk, ptr);
3354         else
3355                 huge_dalloc(ptr);
3356 }
3357
3358 static void
3359 arena_ralloc_large_shrink(arena_t *arena, arena_chunk_t *chunk, void *ptr,
3360     size_t size, size_t oldsize)
3361 {
3362
3363         assert(size < oldsize);
3364
3365         /*
3366          * Shrink the run, and make trailing pages available for other
3367          * allocations.
3368          */
3369 #ifdef MALLOC_BALANCE
3370         arena_lock_balance(arena);
3371 #else
3372         malloc_spin_lock(&arena->lock);
3373 #endif
3374         arena_run_trim_tail(arena, chunk, (arena_run_t *)ptr, oldsize, size,
3375             true);
3376 #ifdef MALLOC_STATS
3377         arena->stats.allocated_large -= oldsize - size;
3378 #endif
3379         malloc_spin_unlock(&arena->lock);
3380 }
3381
3382 static bool
3383 arena_ralloc_large_grow(arena_t *arena, arena_chunk_t *chunk, void *ptr,
3384     size_t size, size_t oldsize)
3385 {
3386         size_t pageind = ((uintptr_t)ptr - (uintptr_t)chunk) >> pagesize_2pow;
3387         size_t npages = oldsize >> pagesize_2pow;
3388
3389         assert(oldsize == (chunk->map[pageind].bits & ~pagesize_mask));
3390
3391         /* Try to extend the run. */
3392         assert(size > oldsize);
3393 #ifdef MALLOC_BALANCE
3394         arena_lock_balance(arena);
3395 #else
3396         malloc_spin_lock(&arena->lock);
3397 #endif
3398         if (pageind + npages < chunk_npages && (chunk->map[pageind+npages].bits
3399             & CHUNK_MAP_ALLOCATED) == 0 && (chunk->map[pageind+npages].bits &
3400             ~pagesize_mask) >= size - oldsize) {
3401                 /*
3402                  * The next run is available and sufficiently large.  Split the
3403                  * following run, then merge the first part with the existing
3404                  * allocation.
3405                  */
3406                 arena_run_split(arena, (arena_run_t *)((uintptr_t)chunk +
3407                     ((pageind+npages) << pagesize_2pow)), size - oldsize, true,
3408                     false);
3409
3410                 chunk->map[pageind].bits = size | CHUNK_MAP_LARGE |
3411                     CHUNK_MAP_ALLOCATED;
3412                 chunk->map[pageind+npages].bits = CHUNK_MAP_LARGE |
3413                     CHUNK_MAP_ALLOCATED;
3414
3415 #ifdef MALLOC_STATS
3416                 arena->stats.allocated_large += size - oldsize;
3417 #endif
3418                 malloc_spin_unlock(&arena->lock);
3419                 return (false);
3420         }
3421         malloc_spin_unlock(&arena->lock);
3422
3423         return (true);
3424 }
3425
3426 /*
3427  * Try to resize a large allocation, in order to avoid copying.  This will
3428  * always fail if growing an object, and the following run is already in use.
3429  */
3430 static bool
3431 arena_ralloc_large(void *ptr, size_t size, size_t oldsize)
3432 {
3433         size_t psize;
3434
3435         psize = PAGE_CEILING(size);
3436         if (psize == oldsize) {
3437                 /* Same size class. */
3438                 if (opt_junk && size < oldsize) {
3439                         memset((void *)((uintptr_t)ptr + size), 0x5a, oldsize -
3440                             size);
3441                 }
3442                 return (false);
3443         } else {
3444                 arena_chunk_t *chunk;
3445                 arena_t *arena;
3446
3447                 chunk = (arena_chunk_t *)CHUNK_ADDR2BASE(ptr);
3448                 arena = chunk->arena;
3449                 assert(arena->magic == ARENA_MAGIC);
3450
3451                 if (psize < oldsize) {
3452                         /* Fill before shrinking in order avoid a race. */
3453                         if (opt_junk) {
3454                                 memset((void *)((uintptr_t)ptr + size), 0x5a,
3455                                     oldsize - size);
3456                         }
3457                         arena_ralloc_large_shrink(arena, chunk, ptr, psize,
3458                             oldsize);
3459                         return (false);
3460                 } else {
3461                         bool ret = arena_ralloc_large_grow(arena, chunk, ptr,
3462                             psize, oldsize);
3463                         if (ret == false && opt_zero) {
3464                                 memset((void *)((uintptr_t)ptr + oldsize), 0,
3465                                     size - oldsize);
3466                         }
3467                         return (ret);
3468                 }
3469         }
3470 }
3471
3472 static void *
3473 arena_ralloc(void *ptr, size_t size, size_t oldsize)
3474 {
3475         void *ret;
3476         size_t copysize;
3477
3478         /* Try to avoid moving the allocation. */
3479         if (size < small_min) {
3480                 if (oldsize < small_min &&
3481                     ffs((int)(pow2_ceil(size) >> (TINY_MIN_2POW + 1)))
3482                     == ffs((int)(pow2_ceil(oldsize) >> (TINY_MIN_2POW + 1))))
3483                         goto IN_PLACE; /* Same size class. */
3484         } else if (size <= small_max) {
3485                 if (oldsize >= small_min && oldsize <= small_max &&
3486                     (QUANTUM_CEILING(size) >> opt_quantum_2pow)
3487                     == (QUANTUM_CEILING(oldsize) >> opt_quantum_2pow))
3488                         goto IN_PLACE; /* Same size class. */
3489         } else if (size <= bin_maxclass) {
3490                 if (oldsize > small_max && oldsize <= bin_maxclass &&
3491                     pow2_ceil(size) == pow2_ceil(oldsize))
3492                         goto IN_PLACE; /* Same size class. */
3493         } else if (oldsize > bin_maxclass && oldsize <= arena_maxclass) {
3494                 assert(size > bin_maxclass);
3495                 if (arena_ralloc_large(ptr, size, oldsize) == false)
3496                         return (ptr);
3497         }
3498
3499         /*
3500          * If we get here, then size and oldsize are different enough that we
3501          * need to move the object.  In that case, fall back to allocating new
3502          * space and copying.
3503          */
3504         ret = arena_malloc(choose_arena(), size, false);
3505         if (ret == NULL)
3506                 return (NULL);
3507
3508         /* Junk/zero-filling were already done by arena_malloc(). */
3509         copysize = (size < oldsize) ? size : oldsize;
3510         memcpy(ret, ptr, copysize);
3511         idalloc(ptr);
3512         return (ret);
3513 IN_PLACE:
3514         if (opt_junk && size < oldsize)
3515                 memset((void *)((uintptr_t)ptr + size), 0x5a, oldsize - size);
3516         else if (opt_zero && size > oldsize)
3517                 memset((void *)((uintptr_t)ptr + oldsize), 0, size - oldsize);
3518         return (ptr);
3519 }
3520
3521 static inline void *
3522 iralloc(void *ptr, size_t size)
3523 {
3524         size_t oldsize;
3525
3526         assert(ptr != NULL);
3527         assert(size != 0);
3528
3529         oldsize = isalloc(ptr);
3530
3531         if (size <= arena_maxclass)
3532                 return (arena_ralloc(ptr, size, oldsize));
3533         else
3534                 return (huge_ralloc(ptr, size, oldsize));
3535 }
3536
3537 static bool
3538 arena_new(arena_t *arena)
3539 {
3540         unsigned i;
3541         arena_bin_t *bin;
3542         size_t prev_run_size;
3543
3544         if (malloc_spin_init(&arena->lock))
3545                 return (true);
3546
3547 #ifdef MALLOC_STATS
3548         memset(&arena->stats, 0, sizeof(arena_stats_t));
3549 #endif
3550
3551         /* Initialize chunks. */
3552         arena_chunk_tree_dirty_new(&arena->chunks_dirty);
3553         arena->spare = NULL;
3554
3555         arena->ndirty = 0;
3556
3557         arena_avail_tree_new(&arena->runs_avail);
3558
3559 #ifdef MALLOC_BALANCE
3560         arena->contention = 0;
3561 #endif
3562
3563         /* Initialize bins. */
3564         prev_run_size = pagesize;
3565
3566         /* (2^n)-spaced tiny bins. */
3567         for (i = 0; i < ntbins; i++) {
3568                 bin = &arena->bins[i];
3569                 bin->runcur = NULL;
3570                 arena_run_tree_new(&bin->runs);
3571
3572                 bin->reg_size = (1U << (TINY_MIN_2POW + i));
3573
3574                 prev_run_size = arena_bin_run_size_calc(bin, prev_run_size);
3575
3576 #ifdef MALLOC_STATS
3577                 memset(&bin->stats, 0, sizeof(malloc_bin_stats_t));
3578 #endif
3579         }
3580
3581         /* Quantum-spaced bins. */
3582         for (; i < ntbins + nqbins; i++) {
3583                 bin = &arena->bins[i];
3584                 bin->runcur = NULL;
3585                 arena_run_tree_new(&bin->runs);
3586
3587                 bin->reg_size = quantum * (i - ntbins + 1);
3588
3589                 prev_run_size = arena_bin_run_size_calc(bin, prev_run_size);
3590
3591 #ifdef MALLOC_STATS
3592                 memset(&bin->stats, 0, sizeof(malloc_bin_stats_t));
3593 #endif
3594         }
3595
3596         /* (2^n)-spaced sub-page bins. */
3597         for (; i < ntbins + nqbins + nsbins; i++) {
3598                 bin = &arena->bins[i];
3599                 bin->runcur = NULL;
3600                 arena_run_tree_new(&bin->runs);
3601
3602                 bin->reg_size = (small_max << (i - (ntbins + nqbins) + 1));
3603
3604                 prev_run_size = arena_bin_run_size_calc(bin, prev_run_size);
3605
3606 #ifdef MALLOC_STATS
3607                 memset(&bin->stats, 0, sizeof(malloc_bin_stats_t));
3608 #endif
3609         }
3610
3611 #ifdef MALLOC_DEBUG
3612         arena->magic = ARENA_MAGIC;
3613 #endif
3614
3615         return (false);
3616 }
3617
3618 /* Create a new arena and insert it into the arenas array at index ind. */
3619 static arena_t *
3620 arenas_extend(unsigned ind)
3621 {
3622         arena_t *ret;
3623
3624         /* Allocate enough space for trailing bins. */
3625         ret = (arena_t *)base_alloc(sizeof(arena_t)
3626             + (sizeof(arena_bin_t) * (ntbins + nqbins + nsbins - 1)));
3627         if (ret != NULL && arena_new(ret) == false) {
3628                 arenas[ind] = ret;
3629                 return (ret);
3630         }
3631         /* Only reached if there is an OOM error. */
3632
3633         /*
3634          * OOM here is quite inconvenient to propagate, since dealing with it
3635          * would require a check for failure in the fast path.  Instead, punt
3636          * by using arenas[0].  In practice, this is an extremely unlikely
3637          * failure.
3638          */
3639         _malloc_message(_getprogname(),
3640             ": (malloc) Error initializing arena\n", "", "");
3641         if (opt_abort)
3642                 abort();
3643
3644         return (arenas[0]);
3645 }
3646
3647 /*
3648  * End arena.
3649  */
3650 /******************************************************************************/
3651 /*
3652  * Begin general internal functions.
3653  */
3654
3655 static void *
3656 huge_malloc(size_t size, bool zero)
3657 {
3658         void *ret;
3659         size_t csize;
3660         extent_node_t *node;
3661
3662         /* Allocate one or more contiguous chunks for this request. */
3663
3664         csize = CHUNK_CEILING(size);
3665         if (csize == 0) {
3666                 /* size is large enough to cause size_t wrap-around. */
3667                 return (NULL);
3668         }
3669
3670         /* Allocate an extent node with which to track the chunk. */
3671         node = base_node_alloc();
3672         if (node == NULL)
3673                 return (NULL);
3674
3675         ret = chunk_alloc(csize, zero);
3676         if (ret == NULL) {
3677                 base_node_dealloc(node);
3678                 return (NULL);
3679         }
3680
3681         /* Insert node into huge. */
3682         node->addr = ret;
3683         node->size = csize;
3684
3685         malloc_mutex_lock(&huge_mtx);
3686         extent_tree_ad_insert(&huge, node);
3687 #ifdef MALLOC_STATS
3688         huge_nmalloc++;
3689         huge_allocated += csize;
3690 #endif
3691         malloc_mutex_unlock(&huge_mtx);
3692
3693         if (zero == false) {
3694                 if (opt_junk)
3695                         memset(ret, 0xa5, csize);
3696                 else if (opt_zero)
3697                         memset(ret, 0, csize);
3698         }
3699
3700         return (ret);
3701 }
3702
3703 /* Only handles large allocations that require more than chunk alignment. */
3704 static void *
3705 huge_palloc(size_t alignment, size_t size)
3706 {
3707         void *ret;
3708         size_t alloc_size, chunk_size, offset;
3709         extent_node_t *node;
3710
3711         /*
3712          * This allocation requires alignment that is even larger than chunk
3713          * alignment.  This means that huge_malloc() isn't good enough.
3714          *
3715          * Allocate almost twice as many chunks as are demanded by the size or
3716          * alignment, in order to assure the alignment can be achieved, then
3717          * unmap leading and trailing chunks.
3718          */
3719         assert(alignment >= chunksize);
3720
3721         chunk_size = CHUNK_CEILING(size);
3722
3723         if (size >= alignment)
3724                 alloc_size = chunk_size + alignment - chunksize;
3725         else
3726                 alloc_size = (alignment << 1) - chunksize;
3727
3728         /* Allocate an extent node with which to track the chunk. */
3729         node = base_node_alloc();
3730         if (node == NULL)
3731                 return (NULL);
3732
3733         ret = chunk_alloc(alloc_size, false);
3734         if (ret == NULL) {
3735                 base_node_dealloc(node);
3736                 return (NULL);
3737         }
3738
3739         offset = (uintptr_t)ret & (alignment - 1);
3740         assert((offset & chunksize_mask) == 0);
3741         assert(offset < alloc_size);
3742         if (offset == 0) {
3743                 /* Trim trailing space. */
3744                 chunk_dealloc((void *)((uintptr_t)ret + chunk_size), alloc_size
3745                     - chunk_size);
3746         } else {
3747                 size_t trailsize;
3748
3749                 /* Trim leading space. */
3750                 chunk_dealloc(ret, alignment - offset);
3751
3752                 ret = (void *)((uintptr_t)ret + (alignment - offset));
3753
3754                 trailsize = alloc_size - (alignment - offset) - chunk_size;
3755                 if (trailsize != 0) {
3756                     /* Trim trailing space. */
3757                     assert(trailsize < alloc_size);
3758                     chunk_dealloc((void *)((uintptr_t)ret + chunk_size),
3759                         trailsize);
3760                 }
3761         }
3762
3763         /* Insert node into huge. */
3764         node->addr = ret;
3765         node->size = chunk_size;
3766
3767         malloc_mutex_lock(&huge_mtx);
3768         extent_tree_ad_insert(&huge, node);
3769 #ifdef MALLOC_STATS
3770         huge_nmalloc++;
3771         huge_allocated += chunk_size;
3772 #endif
3773         malloc_mutex_unlock(&huge_mtx);
3774
3775         if (opt_junk)
3776                 memset(ret, 0xa5, chunk_size);
3777         else if (opt_zero)
3778                 memset(ret, 0, chunk_size);
3779
3780         return (ret);
3781 }
3782
3783 static void *
3784 huge_ralloc(void *ptr, size_t size, size_t oldsize)
3785 {
3786         void *ret;
3787         size_t copysize;
3788
3789         /* Avoid moving the allocation if the size class would not change. */
3790         if (oldsize > arena_maxclass &&
3791             CHUNK_CEILING(size) == CHUNK_CEILING(oldsize)) {
3792                 if (opt_junk && size < oldsize) {
3793                         memset((void *)((uintptr_t)ptr + size), 0x5a, oldsize
3794                             - size);
3795                 } else if (opt_zero && size > oldsize) {
3796                         memset((void *)((uintptr_t)ptr + oldsize), 0, size
3797                             - oldsize);
3798                 }
3799                 return (ptr);
3800         }
3801
3802         /*
3803          * If we get here, then size and oldsize are different enough that we
3804          * need to use a different size class.  In that case, fall back to
3805          * allocating new space and copying.
3806          */
3807         ret = huge_malloc(size, false);
3808         if (ret == NULL)
3809                 return (NULL);
3810
3811         copysize = (size < oldsize) ? size : oldsize;
3812         memcpy(ret, ptr, copysize);
3813         idalloc(ptr);
3814         return (ret);
3815 }
3816
3817 static void
3818 huge_dalloc(void *ptr)
3819 {
3820         extent_node_t *node, key;
3821
3822         malloc_mutex_lock(&huge_mtx);
3823
3824         /* Extract from tree of huge allocations. */
3825         key.addr = ptr;
3826         node = extent_tree_ad_search(&huge, &key);
3827         assert(node != NULL);
3828         assert(node->addr == ptr);
3829         extent_tree_ad_remove(&huge, node);
3830
3831 #ifdef MALLOC_STATS
3832         huge_ndalloc++;
3833         huge_allocated -= node->size;
3834 #endif
3835
3836         malloc_mutex_unlock(&huge_mtx);
3837
3838         /* Unmap chunk. */
3839 #ifdef MALLOC_DSS
3840         if (opt_dss && opt_junk)
3841                 memset(node->addr, 0x5a, node->size);
3842 #endif
3843         chunk_dealloc(node->addr, node->size);
3844
3845         base_node_dealloc(node);
3846 }
3847
3848 static void
3849 malloc_print_stats(void)
3850 {
3851
3852         if (opt_print_stats) {
3853                 char s[UMAX2S_BUFSIZE];
3854                 _malloc_message("___ Begin malloc statistics ___\n", "", "",
3855                     "");
3856                 _malloc_message("Assertions ",
3857 #ifdef NDEBUG
3858                     "disabled",
3859 #else
3860                     "enabled",
3861 #endif
3862                     "\n", "");
3863                 _malloc_message("Boolean MALLOC_OPTIONS: ",
3864                     opt_abort ? "A" : "a", "", "");
3865 #ifdef MALLOC_DSS
3866                 _malloc_message(opt_dss ? "D" : "d", "", "", "");
3867 #endif
3868                 _malloc_message(opt_junk ? "J" : "j", "", "", "");
3869 #ifdef MALLOC_DSS
3870                 _malloc_message(opt_mmap ? "M" : "m", "", "", "");
3871 #endif
3872                 _malloc_message(opt_utrace ? "PU" : "Pu",
3873                     opt_sysv ? "V" : "v",
3874                     opt_xmalloc ? "X" : "x",
3875                     opt_zero ? "Z\n" : "z\n");
3876
3877                 _malloc_message("CPUs: ", umax2s(ncpus, s), "\n", "");
3878                 _malloc_message("Max arenas: ", umax2s(narenas, s), "\n", "");
3879 #ifdef MALLOC_BALANCE
3880                 _malloc_message("Arena balance threshold: ",
3881                     umax2s(opt_balance_threshold, s), "\n", "");
3882 #endif
3883                 _malloc_message("Pointer size: ", umax2s(sizeof(void *), s),
3884                     "\n", "");
3885                 _malloc_message("Quantum size: ", umax2s(quantum, s), "\n", "");
3886                 _malloc_message("Max small size: ", umax2s(small_max, s), "\n",
3887                     "");
3888                 _malloc_message("Max dirty pages per arena: ",
3889                     umax2s(opt_dirty_max, s), "\n", "");
3890
3891                 _malloc_message("Chunk size: ", umax2s(chunksize, s), "", "");
3892                 _malloc_message(" (2^", umax2s(opt_chunk_2pow, s), ")\n", "");
3893
3894 #ifdef MALLOC_STATS
3895                 {
3896                         size_t allocated, mapped;
3897 #ifdef MALLOC_BALANCE
3898                         uint64_t nbalance = 0;
3899 #endif
3900                         unsigned i;
3901                         arena_t *arena;
3902
3903                         /* Calculate and print allocated/mapped stats. */
3904
3905                         /* arenas. */
3906                         for (i = 0, allocated = 0; i < narenas; i++) {
3907                                 if (arenas[i] != NULL) {
3908                                         malloc_spin_lock(&arenas[i]->lock);
3909                                         allocated +=
3910                                             arenas[i]->stats.allocated_small;
3911                                         allocated +=
3912                                             arenas[i]->stats.allocated_large;
3913 #ifdef MALLOC_BALANCE
3914                                         nbalance += arenas[i]->stats.nbalance;
3915 #endif
3916                                         malloc_spin_unlock(&arenas[i]->lock);
3917                                 }
3918                         }
3919
3920                         /* huge/base. */
3921                         malloc_mutex_lock(&huge_mtx);
3922                         allocated += huge_allocated;
3923                         mapped = stats_chunks.curchunks * chunksize;
3924                         malloc_mutex_unlock(&huge_mtx);
3925
3926                         malloc_mutex_lock(&base_mtx);
3927                         mapped += base_mapped;
3928                         malloc_mutex_unlock(&base_mtx);
3929
3930                         malloc_printf("Allocated: %zu, mapped: %zu\n",
3931                             allocated, mapped);
3932
3933 #ifdef MALLOC_BALANCE
3934                         malloc_printf("Arena balance reassignments: %llu\n",
3935                             nbalance);
3936 #endif
3937
3938                         /* Print chunk stats. */
3939                         {
3940                                 chunk_stats_t chunks_stats;
3941
3942                                 malloc_mutex_lock(&huge_mtx);
3943                                 chunks_stats = stats_chunks;
3944                                 malloc_mutex_unlock(&huge_mtx);
3945
3946                                 malloc_printf("chunks: nchunks   "
3947                                     "highchunks    curchunks\n");
3948                                 malloc_printf("  %13llu%13lu%13lu\n",
3949                                     chunks_stats.nchunks,
3950                                     chunks_stats.highchunks,
3951                                     chunks_stats.curchunks);
3952                         }
3953
3954                         /* Print chunk stats. */
3955                         malloc_printf(
3956                             "huge: nmalloc      ndalloc    allocated\n");
3957                         malloc_printf(" %12llu %12llu %12zu\n",
3958                             huge_nmalloc, huge_ndalloc, huge_allocated);
3959
3960                         /* Print stats for each arena. */
3961                         for (i = 0; i < narenas; i++) {
3962                                 arena = arenas[i];
3963                                 if (arena != NULL) {
3964                                         malloc_printf(
3965                                             "\narenas[%u]:\n", i);
3966                                         malloc_spin_lock(&arena->lock);
3967                                         stats_print(arena);
3968                                         malloc_spin_unlock(&arena->lock);
3969                                 }
3970                         }
3971                 }
3972 #endif /* #ifdef MALLOC_STATS */
3973                 _malloc_message("--- End malloc statistics ---\n", "", "", "");
3974         }
3975 }
3976
3977 /*
3978  * FreeBSD's pthreads implementation calls malloc(3), so the malloc
3979  * implementation has to take pains to avoid infinite recursion during
3980  * initialization.
3981  */
3982 static inline bool
3983 malloc_init(void)
3984 {
3985
3986         if (malloc_initialized == false)
3987                 return (malloc_init_hard());
3988
3989         return (false);
3990 }
3991
3992 static bool
3993 malloc_init_hard(void)
3994 {
3995         unsigned i;
3996         int linklen;
3997         char buf[PATH_MAX + 1];
3998         const char *opts;
3999
4000         malloc_mutex_lock(&init_lock);
4001         if (malloc_initialized) {
4002                 /*
4003                  * Another thread initialized the allocator before this one
4004                  * acquired init_lock.
4005                  */
4006                 malloc_mutex_unlock(&init_lock);
4007                 return (false);
4008         }
4009
4010         /* Get number of CPUs. */
4011         {
4012                 int mib[2];
4013                 size_t len;
4014
4015                 mib[0] = CTL_HW;
4016                 mib[1] = HW_NCPU;
4017                 len = sizeof(ncpus);
4018                 if (sysctl(mib, 2, &ncpus, &len, (void *) 0, 0) == -1) {
4019                         /* Error. */
4020                         ncpus = 1;
4021                 }
4022         }
4023
4024         /* Get page size. */
4025         {
4026                 long result;
4027
4028                 result = sysconf(_SC_PAGESIZE);
4029                 assert(result != -1);
4030                 pagesize = (unsigned)result;
4031
4032                 /*
4033                  * We assume that pagesize is a power of 2 when calculating
4034                  * pagesize_mask and pagesize_2pow.
4035                  */
4036                 assert(((result - 1) & result) == 0);
4037                 pagesize_mask = result - 1;
4038                 pagesize_2pow = ffs((int)result) - 1;
4039         }
4040
4041         for (i = 0; i < 3; i++) {
4042                 unsigned j;
4043
4044                 /* Get runtime configuration. */
4045                 switch (i) {
4046                 case 0:
4047                         if ((linklen = readlink("/etc/malloc.conf", buf,
4048                                                 sizeof(buf) - 1)) != -1) {
4049                                 /*
4050                                  * Use the contents of the "/etc/malloc.conf"
4051                                  * symbolic link's name.
4052                                  */
4053                                 buf[linklen] = '\0';
4054                                 opts = buf;
4055                         } else {
4056                                 /* No configuration specified. */
4057                                 buf[0] = '\0';
4058                                 opts = buf;
4059                         }
4060                         break;
4061                 case 1:
4062                         if (issetugid() == 0 && (opts =
4063                             getenv("MALLOC_OPTIONS")) != NULL) {
4064                                 /*
4065                                  * Do nothing; opts is already initialized to
4066                                  * the value of the MALLOC_OPTIONS environment
4067                                  * variable.
4068                                  */
4069                         } else {
4070                                 /* No configuration specified. */
4071                                 buf[0] = '\0';
4072                                 opts = buf;
4073                         }
4074                         break;
4075                 case 2:
4076                         if (_malloc_options != NULL) {
4077                                 /*
4078                                  * Use options that were compiled into the
4079                                  * program.
4080                                  */
4081                                 opts = _malloc_options;
4082                         } else {
4083                                 /* No configuration specified. */
4084                                 buf[0] = '\0';
4085                                 opts = buf;
4086                         }
4087                         break;
4088                 default:
4089                         /* NOTREACHED */
4090                         assert(false);
4091                 }
4092
4093                 for (j = 0; opts[j] != '\0'; j++) {
4094                         unsigned k, nreps;
4095                         bool nseen;
4096
4097                         /* Parse repetition count, if any. */
4098                         for (nreps = 0, nseen = false;; j++, nseen = true) {
4099                                 switch (opts[j]) {
4100                                         case '0': case '1': case '2': case '3':
4101                                         case '4': case '5': case '6': case '7':
4102                                         case '8': case '9':
4103                                                 nreps *= 10;
4104                                                 nreps += opts[j] - '0';
4105                                                 break;
4106                                         default:
4107                                                 goto MALLOC_OUT;
4108                                 }
4109                         }
4110 MALLOC_OUT:
4111                         if (nseen == false)
4112                                 nreps = 1;
4113
4114                         for (k = 0; k < nreps; k++) {
4115                                 switch (opts[j]) {
4116                                 case 'a':
4117                                         opt_abort = false;
4118                                         break;
4119                                 case 'A':
4120                                         opt_abort = true;
4121                                         break;
4122                                 case 'b':
4123 #ifdef MALLOC_BALANCE
4124                                         opt_balance_threshold >>= 1;
4125 #endif
4126                                         break;
4127                                 case 'B':
4128 #ifdef MALLOC_BALANCE
4129                                         if (opt_balance_threshold == 0)
4130                                                 opt_balance_threshold = 1;
4131                                         else if ((opt_balance_threshold << 1)
4132                                             > opt_balance_threshold)
4133                                                 opt_balance_threshold <<= 1;
4134 #endif
4135                                         break;
4136                                 case 'd':
4137 #ifdef MALLOC_DSS
4138                                         opt_dss = false;
4139 #endif
4140                                         break;
4141                                 case 'D':
4142 #ifdef MALLOC_DSS
4143                                         opt_dss = true;
4144 #endif
4145                                         break;
4146                                 case 'f':
4147                                         opt_dirty_max >>= 1;
4148                                         break;
4149                                 case 'F':
4150                                         if (opt_dirty_max == 0)
4151                                                 opt_dirty_max = 1;
4152                                         else if ((opt_dirty_max << 1) != 0)
4153                                                 opt_dirty_max <<= 1;
4154                                         break;
4155                                 case 'h':
4156                                         /* Compatibility hack for RELENG_7. */
4157                                         opt_dirty_max = DIRTY_MAX_DEFAULT;
4158                                         break;
4159                                 case 'H':
4160                                         /* Compatibility hack for RELENG_7. */
4161                                         opt_dirty_max = 0;
4162                                         break;
4163                                 case 'j':
4164                                         opt_junk = false;
4165                                         break;
4166                                 case 'J':
4167                                         opt_junk = true;
4168                                         break;
4169                                 case 'k':
4170                                         /*
4171                                          * Chunks always require at least one
4172                                          * header page, so chunks can never be
4173                                          * smaller than two pages.
4174                                          */
4175                                         if (opt_chunk_2pow > pagesize_2pow + 1)
4176                                                 opt_chunk_2pow--;
4177                                         break;
4178                                 case 'K':
4179                                         if (opt_chunk_2pow + 1 <
4180                                             (sizeof(size_t) << 3))
4181                                                 opt_chunk_2pow++;
4182                                         break;
4183                                 case 'm':
4184 #ifdef MALLOC_DSS
4185                                         opt_mmap = false;
4186 #endif
4187                                         break;
4188                                 case 'M':
4189 #ifdef MALLOC_DSS
4190                                         opt_mmap = true;
4191 #endif
4192                                         break;
4193                                 case 'n':
4194                                         opt_narenas_lshift--;
4195                                         break;
4196                                 case 'N':
4197                                         opt_narenas_lshift++;
4198                                         break;
4199                                 case 'p':
4200                                         opt_print_stats = false;
4201                                         break;
4202                                 case 'P':
4203                                         opt_print_stats = true;
4204                                         break;
4205                                 case 'q':
4206                                         if (opt_quantum_2pow > QUANTUM_2POW_MIN)
4207                                                 opt_quantum_2pow--;
4208                                         break;
4209                                 case 'Q':
4210                                         if (opt_quantum_2pow < pagesize_2pow -
4211                                             1)
4212                                                 opt_quantum_2pow++;
4213                                         break;
4214                                 case 's':
4215                                         if (opt_small_max_2pow >
4216                                             QUANTUM_2POW_MIN)
4217                                                 opt_small_max_2pow--;
4218                                         break;
4219                                 case 'S':
4220                                         if (opt_small_max_2pow < pagesize_2pow
4221                                             - 1)
4222                                                 opt_small_max_2pow++;
4223                                         break;
4224                                 case 'u':
4225                                         opt_utrace = false;
4226                                         break;
4227                                 case 'U':
4228                                         opt_utrace = true;
4229                                         break;
4230                                 case 'v':
4231                                         opt_sysv = false;
4232                                         break;
4233                                 case 'V':
4234                                         opt_sysv = true;
4235                                         break;
4236                                 case 'x':
4237                                         opt_xmalloc = false;
4238                                         break;
4239                                 case 'X':
4240                                         opt_xmalloc = true;
4241                                         break;
4242                                 case 'z':
4243                                         opt_zero = false;
4244                                         break;
4245                                 case 'Z':
4246                                         opt_zero = true;
4247                                         break;
4248                                 default: {
4249                                         char cbuf[2];
4250
4251                                         cbuf[0] = opts[j];
4252                                         cbuf[1] = '\0';
4253                                         _malloc_message(_getprogname(),
4254                                             ": (malloc) Unsupported character "
4255                                             "in malloc options: '", cbuf,
4256                                             "'\n");
4257                                 }
4258                                 }
4259                         }
4260                 }
4261         }
4262
4263 #ifdef MALLOC_DSS
4264         /* Make sure that there is some method for acquiring memory. */
4265         if (opt_dss == false && opt_mmap == false)
4266                 opt_mmap = true;
4267 #endif
4268
4269         /* Take care to call atexit() only once. */
4270         if (opt_print_stats) {
4271                 /* Print statistics at exit. */
4272                 atexit(malloc_print_stats);
4273         }
4274
4275         /* Set variables according to the value of opt_small_max_2pow. */
4276         if (opt_small_max_2pow < opt_quantum_2pow)
4277                 opt_small_max_2pow = opt_quantum_2pow;
4278         small_max = (1U << opt_small_max_2pow);
4279
4280         /* Set bin-related variables. */
4281         bin_maxclass = (pagesize >> 1);
4282         assert(opt_quantum_2pow >= TINY_MIN_2POW);
4283         ntbins = opt_quantum_2pow - TINY_MIN_2POW;
4284         assert(ntbins <= opt_quantum_2pow);
4285         nqbins = (small_max >> opt_quantum_2pow);
4286         nsbins = pagesize_2pow - opt_small_max_2pow - 1;
4287
4288         /* Set variables according to the value of opt_quantum_2pow. */
4289         quantum = (1U << opt_quantum_2pow);
4290         quantum_mask = quantum - 1;
4291         if (ntbins > 0)
4292                 small_min = (quantum >> 1) + 1;
4293         else
4294                 small_min = 1;
4295         assert(small_min <= quantum);
4296
4297         /* Set variables according to the value of opt_chunk_2pow. */
4298         chunksize = (1LU << opt_chunk_2pow);
4299         chunksize_mask = chunksize - 1;
4300         chunk_npages = (chunksize >> pagesize_2pow);
4301         {
4302                 size_t header_size;
4303
4304                 /*
4305                  * Compute the header size such that it is large
4306                  * enough to contain the page map and enough nodes for the
4307                  * worst case: one node per non-header page plus one extra for
4308                  * situations where we briefly have one more node allocated
4309                  * than we will need.
4310                  */
4311                 header_size = sizeof(arena_chunk_t) +
4312                     (sizeof(arena_chunk_map_t) * (chunk_npages - 1));
4313                 arena_chunk_header_npages = (header_size >> pagesize_2pow) +
4314                     ((header_size & pagesize_mask) != 0);
4315         }
4316         arena_maxclass = chunksize - (arena_chunk_header_npages <<
4317             pagesize_2pow);
4318
4319         UTRACE(0, 0, 0);
4320
4321 #ifdef MALLOC_STATS
4322         memset(&stats_chunks, 0, sizeof(chunk_stats_t));
4323 #endif
4324
4325         /* Various sanity checks that regard configuration. */
4326         assert(quantum >= sizeof(void *));
4327         assert(quantum <= pagesize);
4328         assert(chunksize >= pagesize);
4329         assert(quantum * 4 <= chunksize);
4330
4331         /* Initialize chunks data. */
4332         malloc_mutex_init(&huge_mtx);
4333         extent_tree_ad_new(&huge);
4334 #ifdef MALLOC_DSS
4335         malloc_mutex_init(&dss_mtx);
4336         dss_base = sbrk(0);
4337         dss_prev = dss_base;
4338         dss_max = dss_base;
4339         extent_tree_szad_new(&dss_chunks_szad);
4340         extent_tree_ad_new(&dss_chunks_ad);
4341 #endif
4342 #ifdef MALLOC_STATS
4343         huge_nmalloc = 0;
4344         huge_ndalloc = 0;
4345         huge_allocated = 0;
4346 #endif
4347
4348         /* Initialize base allocation data structures. */
4349 #ifdef MALLOC_STATS
4350         base_mapped = 0;
4351 #endif
4352 #ifdef MALLOC_DSS
4353         /*
4354          * Allocate a base chunk here, since it doesn't actually have to be
4355          * chunk-aligned.  Doing this before allocating any other chunks allows
4356          * the use of space that would otherwise be wasted.
4357          */
4358         if (opt_dss)
4359                 base_pages_alloc(0);
4360 #endif
4361         base_nodes = NULL;
4362         malloc_mutex_init(&base_mtx);
4363
4364         if (ncpus > 1) {
4365                 /*
4366                  * For SMP systems, create four times as many arenas as there
4367                  * are CPUs by default.
4368                  */
4369                 opt_narenas_lshift += 2;
4370         }
4371
4372         /* Determine how many arenas to use. */
4373         narenas = ncpus;
4374         if (opt_narenas_lshift > 0) {
4375                 if ((narenas << opt_narenas_lshift) > narenas)
4376                         narenas <<= opt_narenas_lshift;
4377                 /*
4378                  * Make sure not to exceed the limits of what base_alloc() can
4379                  * handle.
4380                  */
4381                 if (narenas * sizeof(arena_t *) > chunksize)
4382                         narenas = chunksize / sizeof(arena_t *);
4383         } else if (opt_narenas_lshift < 0) {
4384                 if ((narenas >> -opt_narenas_lshift) < narenas)
4385                         narenas >>= -opt_narenas_lshift;
4386                 /* Make sure there is at least one arena. */
4387                 if (narenas == 0)
4388                         narenas = 1;
4389         }
4390 #ifdef MALLOC_BALANCE
4391         assert(narenas != 0);
4392         for (narenas_2pow = 0;
4393              (narenas >> (narenas_2pow + 1)) != 0;
4394              narenas_2pow++);
4395 #endif
4396
4397 #ifdef NO_TLS
4398         if (narenas > 1) {
4399                 static const unsigned primes[] = {1, 3, 5, 7, 11, 13, 17, 19,
4400                     23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83,
4401                     89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149,
4402                     151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211,
4403                     223, 227, 229, 233, 239, 241, 251, 257, 263};
4404                 unsigned nprimes, parenas;
4405
4406                 /*
4407                  * Pick a prime number of hash arenas that is more than narenas
4408                  * so that direct hashing of pthread_self() pointers tends to
4409                  * spread allocations evenly among the arenas.
4410                  */
4411                 assert((narenas & 1) == 0); /* narenas must be even. */
4412                 nprimes = (sizeof(primes) >> SIZEOF_INT_2POW);
4413                 parenas = primes[nprimes - 1]; /* In case not enough primes. */
4414                 for (i = 1; i < nprimes; i++) {
4415                         if (primes[i] > narenas) {
4416                                 parenas = primes[i];
4417                                 break;
4418                         }
4419                 }
4420                 narenas = parenas;
4421         }
4422 #endif
4423
4424 #ifndef NO_TLS
4425 #  ifndef MALLOC_BALANCE
4426         next_arena = 0;
4427 #  endif
4428 #endif
4429
4430         /* Allocate and initialize arenas. */
4431         arenas = (arena_t **)base_alloc(sizeof(arena_t *) * narenas);
4432         if (arenas == NULL) {
4433                 malloc_mutex_unlock(&init_lock);
4434                 return (true);
4435         }
4436         /*
4437          * Zero the array.  In practice, this should always be pre-zeroed,
4438          * since it was just mmap()ed, but let's be sure.
4439          */
4440         memset(arenas, 0, sizeof(arena_t *) * narenas);
4441
4442         /*
4443          * Initialize one arena here.  The rest are lazily created in
4444          * choose_arena_hard().
4445          */
4446         arenas_extend(0);
4447         if (arenas[0] == NULL) {
4448                 malloc_mutex_unlock(&init_lock);
4449                 return (true);
4450         }
4451 #ifndef NO_TLS
4452         /*
4453          * Assign the initial arena to the initial thread, in order to avoid
4454          * spurious creation of an extra arena if the application switches to
4455          * threaded mode.
4456          */
4457         arenas_map = arenas[0];
4458 #endif
4459         /*
4460          * Seed here for the initial thread, since choose_arena_hard() is only
4461          * called for other threads.  The seed value doesn't really matter.
4462          */
4463 #ifdef MALLOC_BALANCE
4464         SPRN(balance, 42);
4465 #endif
4466
4467         malloc_spin_init(&arenas_lock);
4468
4469         malloc_initialized = true;
4470         malloc_mutex_unlock(&init_lock);
4471         return (false);
4472 }
4473
4474 /*
4475  * End general internal functions.
4476  */
4477 /******************************************************************************/
4478 /*
4479  * Begin malloc(3)-compatible functions.
4480  */
4481
4482 void *
4483 malloc(size_t size)
4484 {
4485         void *ret;
4486
4487         if (malloc_init()) {
4488                 ret = NULL;
4489                 goto RETURN;
4490         }
4491
4492         if (size == 0) {
4493                 if (opt_sysv == false)
4494                         size = 1;
4495                 else {
4496                         ret = NULL;
4497                         goto RETURN;
4498                 }
4499         }
4500
4501         ret = imalloc(size);
4502
4503 RETURN:
4504         if (ret == NULL) {
4505                 if (opt_xmalloc) {
4506                         _malloc_message(_getprogname(),
4507                             ": (malloc) Error in malloc(): out of memory\n", "",
4508                             "");
4509                         abort();
4510                 }
4511                 errno = ENOMEM;
4512         }
4513
4514         UTRACE(0, size, ret);
4515         return (ret);
4516 }
4517
4518 int
4519 posix_memalign(void **memptr, size_t alignment, size_t size)
4520 {
4521         int ret;
4522         void *result;
4523
4524         if (malloc_init())
4525                 result = NULL;
4526         else {
4527                 /* Make sure that alignment is a large enough power of 2. */
4528                 if (((alignment - 1) & alignment) != 0
4529                     || alignment < sizeof(void *)) {
4530                         if (opt_xmalloc) {
4531                                 _malloc_message(_getprogname(),
4532                                     ": (malloc) Error in posix_memalign(): "
4533                                     "invalid alignment\n", "", "");
4534                                 abort();
4535                         }
4536                         result = NULL;
4537                         ret = EINVAL;
4538                         goto RETURN;
4539                 }
4540
4541                 result = ipalloc(alignment, size);
4542         }
4543
4544         if (result == NULL) {
4545                 if (opt_xmalloc) {
4546                         _malloc_message(_getprogname(),
4547                         ": (malloc) Error in posix_memalign(): out of memory\n",
4548                         "", "");
4549                         abort();
4550                 }
4551                 ret = ENOMEM;
4552                 goto RETURN;
4553         }
4554
4555         *memptr = result;
4556         ret = 0;
4557
4558 RETURN:
4559         UTRACE(0, size, result);
4560         return (ret);
4561 }
4562
4563 void *
4564 calloc(size_t num, size_t size)
4565 {
4566         void *ret;
4567         size_t num_size;
4568
4569         if (malloc_init()) {
4570                 num_size = 0;
4571                 ret = NULL;
4572                 goto RETURN;
4573         }
4574
4575         num_size = num * size;
4576         if (num_size == 0) {
4577                 if ((opt_sysv == false) && ((num == 0) || (size == 0)))
4578                         num_size = 1;
4579                 else {
4580                         ret = NULL;
4581                         goto RETURN;
4582                 }
4583         /*
4584          * Try to avoid division here.  We know that it isn't possible to
4585          * overflow during multiplication if neither operand uses any of the
4586          * most significant half of the bits in a size_t.
4587          */
4588         } else if (((num | size) & (SIZE_T_MAX << (sizeof(size_t) << 2)))
4589             && (num_size / size != num)) {
4590                 /* size_t overflow. */
4591                 ret = NULL;
4592                 goto RETURN;
4593         }
4594
4595         ret = icalloc(num_size);
4596
4597 RETURN:
4598         if (ret == NULL) {
4599                 if (opt_xmalloc) {
4600                         _malloc_message(_getprogname(),
4601                             ": (malloc) Error in calloc(): out of memory\n", "",
4602                             "");
4603                         abort();
4604                 }
4605                 errno = ENOMEM;
4606         }
4607
4608         UTRACE(0, num_size, ret);
4609         return (ret);
4610 }
4611
4612 void *
4613 realloc(void *ptr, size_t size)
4614 {
4615         void *ret;
4616
4617         if (size == 0) {
4618                 if (opt_sysv == false)
4619                         size = 1;
4620                 else {
4621                         if (ptr != NULL)
4622                                 idalloc(ptr);
4623                         ret = NULL;
4624                         goto RETURN;
4625                 }
4626         }
4627
4628         if (ptr != NULL) {
4629                 assert(malloc_initialized);
4630
4631                 ret = iralloc(ptr, size);
4632
4633                 if (ret == NULL) {
4634                         if (opt_xmalloc) {
4635                                 _malloc_message(_getprogname(),
4636                                     ": (malloc) Error in realloc(): out of "
4637                                     "memory\n", "", "");
4638                                 abort();
4639                         }
4640                         errno = ENOMEM;
4641                 }
4642         } else {
4643                 if (malloc_init())
4644                         ret = NULL;
4645                 else
4646                         ret = imalloc(size);
4647
4648                 if (ret == NULL) {
4649                         if (opt_xmalloc) {
4650                                 _malloc_message(_getprogname(),
4651                                     ": (malloc) Error in realloc(): out of "
4652                                     "memory\n", "", "");
4653                                 abort();
4654                         }
4655                         errno = ENOMEM;
4656                 }
4657         }
4658
4659 RETURN:
4660         UTRACE(ptr, size, ret);
4661         return (ret);
4662 }
4663
4664 void
4665 free(void *ptr)
4666 {
4667
4668         UTRACE(ptr, 0, 0);
4669         if (ptr != NULL) {
4670                 assert(malloc_initialized);
4671
4672                 idalloc(ptr);
4673         }
4674 }
4675
4676 /*
4677  * End malloc(3)-compatible functions.
4678  */
4679 /******************************************************************************/
4680 /*
4681  * Begin non-standard functions.
4682  */
4683
4684 size_t
4685 malloc_usable_size(const void *ptr)
4686 {
4687
4688         assert(ptr != NULL);
4689
4690         return (isalloc(ptr));
4691 }
4692
4693 /*
4694  * End non-standard functions.
4695  */
4696
4697 /*
4698  * We provide an unpublished interface in order to receive notifications from
4699  * the pthreads library whenever a thread exits.  This allows us to clean up
4700  * thread caches.
4701  */
4702 void
4703 _malloc_thread_cleanup(void)
4704 {
4705 }
4706
4707 /******************************************************************************/
4708 /*
4709  * Begin library-private functions, used by threading libraries for protection
4710  * of malloc during fork().  These functions are only called if the program is
4711  * running in threaded mode, so there is no need to check whether the program
4712  * is threaded here.
4713  */
4714
4715 void
4716 _malloc_prefork(void)
4717 {
4718         unsigned i;
4719
4720         /* Acquire all mutexes in a safe order. */
4721
4722         malloc_spin_lock(&arenas_lock);
4723         for (i = 0; i < narenas; i++) {
4724                 if (arenas[i] != NULL)
4725                         malloc_spin_lock(&arenas[i]->lock);
4726         }
4727         malloc_spin_unlock(&arenas_lock);
4728
4729         malloc_mutex_lock(&base_mtx);
4730
4731         malloc_mutex_lock(&huge_mtx);
4732
4733 #ifdef MALLOC_DSS
4734         malloc_mutex_lock(&dss_mtx);
4735 #endif
4736 }
4737
4738 void
4739 _malloc_postfork(void)
4740 {
4741         unsigned i;
4742
4743         /* Release all mutexes, now that fork() has completed. */
4744
4745 #ifdef MALLOC_DSS
4746         malloc_mutex_unlock(&dss_mtx);
4747 #endif
4748
4749         malloc_mutex_unlock(&huge_mtx);
4750
4751         malloc_mutex_unlock(&base_mtx);
4752
4753         malloc_spin_lock(&arenas_lock);
4754         for (i = 0; i < narenas; i++) {
4755                 if (arenas[i] != NULL)
4756                         malloc_spin_unlock(&arenas[i]->lock);
4757         }
4758         malloc_spin_unlock(&arenas_lock);
4759 }
4760
4761 /*
4762  * End library-private functions.
4763  */
4764 /******************************************************************************/