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