xref: /redis-3.2.3/deps/jemalloc/src/jemalloc.c (revision 414c3dea)
1 #define	JEMALLOC_C_
2 #include "jemalloc/internal/jemalloc_internal.h"
3 
4 /******************************************************************************/
5 /* Data. */
6 
7 malloc_mutex_t		arenas_lock;
8 arena_t			**arenas;
9 unsigned		narenas;
10 
11 pthread_key_t		arenas_tsd;
12 #ifndef NO_TLS
13 __thread arena_t	*arenas_tls JEMALLOC_ATTR(tls_model("initial-exec"));
14 #endif
15 
16 #ifdef JEMALLOC_STATS
17 #  ifndef NO_TLS
18 __thread thread_allocated_t	thread_allocated_tls;
19 #  else
20 pthread_key_t		thread_allocated_tsd;
21 #  endif
22 #endif
23 
24 /* Set to true once the allocator has been initialized. */
25 static bool		malloc_initialized = false;
26 
27 /* Used to let the initializing thread recursively allocate. */
28 static pthread_t	malloc_initializer = (unsigned long)0;
29 
30 /* Used to avoid initialization races. */
31 static malloc_mutex_t	init_lock =
32 #ifdef JEMALLOC_OSSPIN
33     0
34 #else
35     MALLOC_MUTEX_INITIALIZER
36 #endif
37     ;
38 
39 #ifdef DYNAMIC_PAGE_SHIFT
40 size_t		pagesize;
41 size_t		pagesize_mask;
42 size_t		lg_pagesize;
43 #endif
44 
45 unsigned	ncpus;
46 
47 /* Runtime configuration options. */
48 const char	*JEMALLOC_P(malloc_conf) JEMALLOC_ATTR(visibility("default"));
49 #ifdef JEMALLOC_DEBUG
50 bool	opt_abort = true;
51 #  ifdef JEMALLOC_FILL
52 bool	opt_junk = true;
53 #  endif
54 #else
55 bool	opt_abort = false;
56 #  ifdef JEMALLOC_FILL
57 bool	opt_junk = false;
58 #  endif
59 #endif
60 #ifdef JEMALLOC_SYSV
61 bool	opt_sysv = false;
62 #endif
63 #ifdef JEMALLOC_XMALLOC
64 bool	opt_xmalloc = false;
65 #endif
66 #ifdef JEMALLOC_FILL
67 bool	opt_zero = false;
68 #endif
69 size_t	opt_narenas = 0;
70 
71 /******************************************************************************/
72 /* Function prototypes for non-inline static functions. */
73 
74 static void	wrtmessage(void *cbopaque, const char *s);
75 static void	stats_print_atexit(void);
76 static unsigned	malloc_ncpus(void);
77 static void	arenas_cleanup(void *arg);
78 #if (defined(JEMALLOC_STATS) && defined(NO_TLS))
79 static void	thread_allocated_cleanup(void *arg);
80 #endif
81 static bool	malloc_conf_next(char const **opts_p, char const **k_p,
82     size_t *klen_p, char const **v_p, size_t *vlen_p);
83 static void	malloc_conf_error(const char *msg, const char *k, size_t klen,
84     const char *v, size_t vlen);
85 static void	malloc_conf_init(void);
86 static bool	malloc_init_hard(void);
87 static int	imemalign(void **memptr, size_t alignment, size_t size);
88 
89 /******************************************************************************/
90 /* malloc_message() setup. */
91 
92 #ifdef JEMALLOC_HAVE_ATTR
93 JEMALLOC_ATTR(visibility("hidden"))
94 #else
95 static
96 #endif
97 void
98 wrtmessage(void *cbopaque, const char *s)
99 {
100 #ifdef JEMALLOC_CC_SILENCE
101 	int result =
102 #endif
103 	    write(STDERR_FILENO, s, strlen(s));
104 #ifdef JEMALLOC_CC_SILENCE
105 	if (result < 0)
106 		result = errno;
107 #endif
108 }
109 
110 void	(*JEMALLOC_P(malloc_message))(void *, const char *s)
111     JEMALLOC_ATTR(visibility("default")) = wrtmessage;
112 
113 /******************************************************************************/
114 /*
115  * Begin miscellaneous support functions.
116  */
117 
118 /* Create a new arena and insert it into the arenas array at index ind. */
119 arena_t *
120 arenas_extend(unsigned ind)
121 {
122 	arena_t *ret;
123 
124 	/* Allocate enough space for trailing bins. */
125 	ret = (arena_t *)base_alloc(offsetof(arena_t, bins)
126 	    + (sizeof(arena_bin_t) * nbins));
127 	if (ret != NULL && arena_new(ret, ind) == false) {
128 		arenas[ind] = ret;
129 		return (ret);
130 	}
131 	/* Only reached if there is an OOM error. */
132 
133 	/*
134 	 * OOM here is quite inconvenient to propagate, since dealing with it
135 	 * would require a check for failure in the fast path.  Instead, punt
136 	 * by using arenas[0].  In practice, this is an extremely unlikely
137 	 * failure.
138 	 */
139 	malloc_write("<jemalloc>: Error initializing arena\n");
140 	if (opt_abort)
141 		abort();
142 
143 	return (arenas[0]);
144 }
145 
146 /*
147  * Choose an arena based on a per-thread value (slow-path code only, called
148  * only by choose_arena()).
149  */
150 arena_t *
151 choose_arena_hard(void)
152 {
153 	arena_t *ret;
154 
155 	if (narenas > 1) {
156 		unsigned i, choose, first_null;
157 
158 		choose = 0;
159 		first_null = narenas;
160 		malloc_mutex_lock(&arenas_lock);
161 		assert(arenas[0] != NULL);
162 		for (i = 1; i < narenas; i++) {
163 			if (arenas[i] != NULL) {
164 				/*
165 				 * Choose the first arena that has the lowest
166 				 * number of threads assigned to it.
167 				 */
168 				if (arenas[i]->nthreads <
169 				    arenas[choose]->nthreads)
170 					choose = i;
171 			} else if (first_null == narenas) {
172 				/*
173 				 * Record the index of the first uninitialized
174 				 * arena, in case all extant arenas are in use.
175 				 *
176 				 * NB: It is possible for there to be
177 				 * discontinuities in terms of initialized
178 				 * versus uninitialized arenas, due to the
179 				 * "thread.arena" mallctl.
180 				 */
181 				first_null = i;
182 			}
183 		}
184 
185 		if (arenas[choose] == 0 || first_null == narenas) {
186 			/*
187 			 * Use an unloaded arena, or the least loaded arena if
188 			 * all arenas are already initialized.
189 			 */
190 			ret = arenas[choose];
191 		} else {
192 			/* Initialize a new arena. */
193 			ret = arenas_extend(first_null);
194 		}
195 		ret->nthreads++;
196 		malloc_mutex_unlock(&arenas_lock);
197 	} else {
198 		ret = arenas[0];
199 		malloc_mutex_lock(&arenas_lock);
200 		ret->nthreads++;
201 		malloc_mutex_unlock(&arenas_lock);
202 	}
203 
204 	ARENA_SET(ret);
205 
206 	return (ret);
207 }
208 
209 /*
210  * glibc provides a non-standard strerror_r() when _GNU_SOURCE is defined, so
211  * provide a wrapper.
212  */
213 int
214 buferror(int errnum, char *buf, size_t buflen)
215 {
216 #ifdef _GNU_SOURCE
217 	char *b = strerror_r(errno, buf, buflen);
218 	if (b != buf) {
219 		strncpy(buf, b, buflen);
220 		buf[buflen-1] = '\0';
221 	}
222 	return (0);
223 #else
224 	return (strerror_r(errno, buf, buflen));
225 #endif
226 }
227 
228 static void
229 stats_print_atexit(void)
230 {
231 
232 #if (defined(JEMALLOC_TCACHE) && defined(JEMALLOC_STATS))
233 	unsigned i;
234 
235 	/*
236 	 * Merge stats from extant threads.  This is racy, since individual
237 	 * threads do not lock when recording tcache stats events.  As a
238 	 * consequence, the final stats may be slightly out of date by the time
239 	 * they are reported, if other threads continue to allocate.
240 	 */
241 	for (i = 0; i < narenas; i++) {
242 		arena_t *arena = arenas[i];
243 		if (arena != NULL) {
244 			tcache_t *tcache;
245 
246 			/*
247 			 * tcache_stats_merge() locks bins, so if any code is
248 			 * introduced that acquires both arena and bin locks in
249 			 * the opposite order, deadlocks may result.
250 			 */
251 			malloc_mutex_lock(&arena->lock);
252 			ql_foreach(tcache, &arena->tcache_ql, link) {
253 				tcache_stats_merge(tcache, arena);
254 			}
255 			malloc_mutex_unlock(&arena->lock);
256 		}
257 	}
258 #endif
259 	JEMALLOC_P(malloc_stats_print)(NULL, NULL, NULL);
260 }
261 
262 #if (defined(JEMALLOC_STATS) && defined(NO_TLS))
263 thread_allocated_t *
264 thread_allocated_get_hard(void)
265 {
266 	thread_allocated_t *thread_allocated = (thread_allocated_t *)
267 	    imalloc(sizeof(thread_allocated_t));
268 	if (thread_allocated == NULL) {
269 		static thread_allocated_t static_thread_allocated = {0, 0};
270 		malloc_write("<jemalloc>: Error allocating TSD;"
271 		    " mallctl(\"thread.{de,}allocated[p]\", ...)"
272 		    " will be inaccurate\n");
273 		if (opt_abort)
274 			abort();
275 		return (&static_thread_allocated);
276 	}
277 	pthread_setspecific(thread_allocated_tsd, thread_allocated);
278 	thread_allocated->allocated = 0;
279 	thread_allocated->deallocated = 0;
280 	return (thread_allocated);
281 }
282 #endif
283 
284 /*
285  * End miscellaneous support functions.
286  */
287 /******************************************************************************/
288 /*
289  * Begin initialization functions.
290  */
291 
292 static unsigned
293 malloc_ncpus(void)
294 {
295 	unsigned ret;
296 	long result;
297 
298 	result = sysconf(_SC_NPROCESSORS_ONLN);
299 	if (result == -1) {
300 		/* Error. */
301 		ret = 1;
302 	}
303 	ret = (unsigned)result;
304 
305 	return (ret);
306 }
307 
308 static void
309 arenas_cleanup(void *arg)
310 {
311 	arena_t *arena = (arena_t *)arg;
312 
313 	malloc_mutex_lock(&arenas_lock);
314 	arena->nthreads--;
315 	malloc_mutex_unlock(&arenas_lock);
316 }
317 
318 #if (defined(JEMALLOC_STATS) && defined(NO_TLS))
319 static void
320 thread_allocated_cleanup(void *arg)
321 {
322 	uint64_t *allocated = (uint64_t *)arg;
323 
324 	if (allocated != NULL)
325 		idalloc(allocated);
326 }
327 #endif
328 
329 /*
330  * FreeBSD's pthreads implementation calls malloc(3), so the malloc
331  * implementation has to take pains to avoid infinite recursion during
332  * initialization.
333  */
334 static inline bool
335 malloc_init(void)
336 {
337 
338 	if (malloc_initialized == false)
339 		return (malloc_init_hard());
340 
341 	return (false);
342 }
343 
344 static bool
345 malloc_conf_next(char const **opts_p, char const **k_p, size_t *klen_p,
346     char const **v_p, size_t *vlen_p)
347 {
348 	bool accept;
349 	const char *opts = *opts_p;
350 
351 	*k_p = opts;
352 
353 	for (accept = false; accept == false;) {
354 		switch (*opts) {
355 			case 'A': case 'B': case 'C': case 'D': case 'E':
356 			case 'F': case 'G': case 'H': case 'I': case 'J':
357 			case 'K': case 'L': case 'M': case 'N': case 'O':
358 			case 'P': case 'Q': case 'R': case 'S': case 'T':
359 			case 'U': case 'V': case 'W': case 'X': case 'Y':
360 			case 'Z':
361 			case 'a': case 'b': case 'c': case 'd': case 'e':
362 			case 'f': case 'g': case 'h': case 'i': case 'j':
363 			case 'k': case 'l': case 'm': case 'n': case 'o':
364 			case 'p': case 'q': case 'r': case 's': case 't':
365 			case 'u': case 'v': case 'w': case 'x': case 'y':
366 			case 'z':
367 			case '0': case '1': case '2': case '3': case '4':
368 			case '5': case '6': case '7': case '8': case '9':
369 			case '_':
370 				opts++;
371 				break;
372 			case ':':
373 				opts++;
374 				*klen_p = (uintptr_t)opts - 1 - (uintptr_t)*k_p;
375 				*v_p = opts;
376 				accept = true;
377 				break;
378 			case '\0':
379 				if (opts != *opts_p) {
380 					malloc_write("<jemalloc>: Conf string "
381 					    "ends with key\n");
382 				}
383 				return (true);
384 			default:
385 				malloc_write("<jemalloc>: Malformed conf "
386 				    "string\n");
387 				return (true);
388 		}
389 	}
390 
391 	for (accept = false; accept == false;) {
392 		switch (*opts) {
393 			case ',':
394 				opts++;
395 				/*
396 				 * Look ahead one character here, because the
397 				 * next time this function is called, it will
398 				 * assume that end of input has been cleanly
399 				 * reached if no input remains, but we have
400 				 * optimistically already consumed the comma if
401 				 * one exists.
402 				 */
403 				if (*opts == '\0') {
404 					malloc_write("<jemalloc>: Conf string "
405 					    "ends with comma\n");
406 				}
407 				*vlen_p = (uintptr_t)opts - 1 - (uintptr_t)*v_p;
408 				accept = true;
409 				break;
410 			case '\0':
411 				*vlen_p = (uintptr_t)opts - (uintptr_t)*v_p;
412 				accept = true;
413 				break;
414 			default:
415 				opts++;
416 				break;
417 		}
418 	}
419 
420 	*opts_p = opts;
421 	return (false);
422 }
423 
424 static void
425 malloc_conf_error(const char *msg, const char *k, size_t klen, const char *v,
426     size_t vlen)
427 {
428 	char buf[PATH_MAX + 1];
429 
430 	malloc_write("<jemalloc>: ");
431 	malloc_write(msg);
432 	malloc_write(": ");
433 	memcpy(buf, k, klen);
434 	memcpy(&buf[klen], ":", 1);
435 	memcpy(&buf[klen+1], v, vlen);
436 	buf[klen+1+vlen] = '\0';
437 	malloc_write(buf);
438 	malloc_write("\n");
439 }
440 
441 static void
442 malloc_conf_init(void)
443 {
444 	unsigned i;
445 	char buf[PATH_MAX + 1];
446 	const char *opts, *k, *v;
447 	size_t klen, vlen;
448 
449 	for (i = 0; i < 3; i++) {
450 		/* Get runtime configuration. */
451 		switch (i) {
452 		case 0:
453 			if (JEMALLOC_P(malloc_conf) != NULL) {
454 				/*
455 				 * Use options that were compiled into the
456 				 * program.
457 				 */
458 				opts = JEMALLOC_P(malloc_conf);
459 			} else {
460 				/* No configuration specified. */
461 				buf[0] = '\0';
462 				opts = buf;
463 			}
464 			break;
465 		case 1: {
466 			int linklen;
467 			const char *linkname =
468 #ifdef JEMALLOC_PREFIX
469 			    "/etc/"JEMALLOC_PREFIX"malloc.conf"
470 #else
471 			    "/etc/malloc.conf"
472 #endif
473 			    ;
474 
475 			if ((linklen = readlink(linkname, buf,
476 			    sizeof(buf) - 1)) != -1) {
477 				/*
478 				 * Use the contents of the "/etc/malloc.conf"
479 				 * symbolic link's name.
480 				 */
481 				buf[linklen] = '\0';
482 				opts = buf;
483 			} else {
484 				/* No configuration specified. */
485 				buf[0] = '\0';
486 				opts = buf;
487 			}
488 			break;
489 		}
490 		case 2: {
491 			const char *envname =
492 #ifdef JEMALLOC_PREFIX
493 			    JEMALLOC_CPREFIX"MALLOC_CONF"
494 #else
495 			    "MALLOC_CONF"
496 #endif
497 			    ;
498 
499 			if ((opts = getenv(envname)) != NULL) {
500 				/*
501 				 * Do nothing; opts is already initialized to
502 				 * the value of the MALLOC_CONF environment
503 				 * variable.
504 				 */
505 			} else {
506 				/* No configuration specified. */
507 				buf[0] = '\0';
508 				opts = buf;
509 			}
510 			break;
511 		}
512 		default:
513 			/* NOTREACHED */
514 			assert(false);
515 			buf[0] = '\0';
516 			opts = buf;
517 		}
518 
519 		while (*opts != '\0' && malloc_conf_next(&opts, &k, &klen, &v,
520 		    &vlen) == false) {
521 #define	CONF_HANDLE_BOOL(n)						\
522 			if (sizeof(#n)-1 == klen && strncmp(#n, k,	\
523 			    klen) == 0) {				\
524 				if (strncmp("true", v, vlen) == 0 &&	\
525 				    vlen == sizeof("true")-1)		\
526 					opt_##n = true;			\
527 				else if (strncmp("false", v, vlen) ==	\
528 				    0 && vlen == sizeof("false")-1)	\
529 					opt_##n = false;		\
530 				else {					\
531 					malloc_conf_error(		\
532 					    "Invalid conf value",	\
533 					    k, klen, v, vlen);		\
534 				}					\
535 				continue;				\
536 			}
537 #define	CONF_HANDLE_SIZE_T(n, min, max)					\
538 			if (sizeof(#n)-1 == klen && strncmp(#n, k,	\
539 			    klen) == 0) {				\
540 				unsigned long ul;			\
541 				char *end;				\
542 									\
543 				errno = 0;				\
544 				ul = strtoul(v, &end, 0);		\
545 				if (errno != 0 || (uintptr_t)end -	\
546 				    (uintptr_t)v != vlen) {		\
547 					malloc_conf_error(		\
548 					    "Invalid conf value",	\
549 					    k, klen, v, vlen);		\
550 				} else if (ul < min || ul > max) {	\
551 					malloc_conf_error(		\
552 					    "Out-of-range conf value",	\
553 					    k, klen, v, vlen);		\
554 				} else					\
555 					opt_##n = ul;			\
556 				continue;				\
557 			}
558 #define	CONF_HANDLE_SSIZE_T(n, min, max)				\
559 			if (sizeof(#n)-1 == klen && strncmp(#n, k,	\
560 			    klen) == 0) {				\
561 				long l;					\
562 				char *end;				\
563 									\
564 				errno = 0;				\
565 				l = strtol(v, &end, 0);			\
566 				if (errno != 0 || (uintptr_t)end -	\
567 				    (uintptr_t)v != vlen) {		\
568 					malloc_conf_error(		\
569 					    "Invalid conf value",	\
570 					    k, klen, v, vlen);		\
571 				} else if (l < (ssize_t)min || l >	\
572 				    (ssize_t)max) {			\
573 					malloc_conf_error(		\
574 					    "Out-of-range conf value",	\
575 					    k, klen, v, vlen);		\
576 				} else					\
577 					opt_##n = l;			\
578 				continue;				\
579 			}
580 #define	CONF_HANDLE_CHAR_P(n, d)					\
581 			if (sizeof(#n)-1 == klen && strncmp(#n, k,	\
582 			    klen) == 0) {				\
583 				size_t cpylen = (vlen <=		\
584 				    sizeof(opt_##n)-1) ? vlen :		\
585 				    sizeof(opt_##n)-1;			\
586 				strncpy(opt_##n, v, cpylen);		\
587 				opt_##n[cpylen] = '\0';			\
588 				continue;				\
589 			}
590 
591 			CONF_HANDLE_BOOL(abort)
592 			CONF_HANDLE_SIZE_T(lg_qspace_max, LG_QUANTUM,
593 			    PAGE_SHIFT-1)
594 			CONF_HANDLE_SIZE_T(lg_cspace_max, LG_QUANTUM,
595 			    PAGE_SHIFT-1)
596 			/*
597 			 * Chunks always require at least one * header page,
598 			 * plus one data page.
599 			 */
600 			CONF_HANDLE_SIZE_T(lg_chunk, PAGE_SHIFT+1,
601 			    (sizeof(size_t) << 3) - 1)
602 			CONF_HANDLE_SIZE_T(narenas, 1, SIZE_T_MAX)
603 			CONF_HANDLE_SSIZE_T(lg_dirty_mult, -1,
604 			    (sizeof(size_t) << 3) - 1)
605 			CONF_HANDLE_BOOL(stats_print)
606 #ifdef JEMALLOC_FILL
607 			CONF_HANDLE_BOOL(junk)
608 			CONF_HANDLE_BOOL(zero)
609 #endif
610 #ifdef JEMALLOC_SYSV
611 			CONF_HANDLE_BOOL(sysv)
612 #endif
613 #ifdef JEMALLOC_XMALLOC
614 			CONF_HANDLE_BOOL(xmalloc)
615 #endif
616 #ifdef JEMALLOC_TCACHE
617 			CONF_HANDLE_BOOL(tcache)
618 			CONF_HANDLE_SSIZE_T(lg_tcache_gc_sweep, -1,
619 			    (sizeof(size_t) << 3) - 1)
620 			CONF_HANDLE_SSIZE_T(lg_tcache_max, -1,
621 			    (sizeof(size_t) << 3) - 1)
622 #endif
623 #ifdef JEMALLOC_PROF
624 			CONF_HANDLE_BOOL(prof)
625 			CONF_HANDLE_CHAR_P(prof_prefix, "jeprof")
626 			CONF_HANDLE_SIZE_T(lg_prof_bt_max, 0, LG_PROF_BT_MAX)
627 			CONF_HANDLE_BOOL(prof_active)
628 			CONF_HANDLE_SSIZE_T(lg_prof_sample, 0,
629 			    (sizeof(uint64_t) << 3) - 1)
630 			CONF_HANDLE_BOOL(prof_accum)
631 			CONF_HANDLE_SSIZE_T(lg_prof_tcmax, -1,
632 			    (sizeof(size_t) << 3) - 1)
633 			CONF_HANDLE_SSIZE_T(lg_prof_interval, -1,
634 			    (sizeof(uint64_t) << 3) - 1)
635 			CONF_HANDLE_BOOL(prof_gdump)
636 			CONF_HANDLE_BOOL(prof_leak)
637 #endif
638 #ifdef JEMALLOC_SWAP
639 			CONF_HANDLE_BOOL(overcommit)
640 #endif
641 			malloc_conf_error("Invalid conf pair", k, klen, v,
642 			    vlen);
643 #undef CONF_HANDLE_BOOL
644 #undef CONF_HANDLE_SIZE_T
645 #undef CONF_HANDLE_SSIZE_T
646 #undef CONF_HANDLE_CHAR_P
647 		}
648 
649 		/* Validate configuration of options that are inter-related. */
650 		if (opt_lg_qspace_max+1 >= opt_lg_cspace_max) {
651 			malloc_write("<jemalloc>: Invalid lg_[qc]space_max "
652 			    "relationship; restoring defaults\n");
653 			opt_lg_qspace_max = LG_QSPACE_MAX_DEFAULT;
654 			opt_lg_cspace_max = LG_CSPACE_MAX_DEFAULT;
655 		}
656 	}
657 }
658 
659 static bool
660 malloc_init_hard(void)
661 {
662 	arena_t *init_arenas[1];
663 
664 	malloc_mutex_lock(&init_lock);
665 	if (malloc_initialized || malloc_initializer == pthread_self()) {
666 		/*
667 		 * Another thread initialized the allocator before this one
668 		 * acquired init_lock, or this thread is the initializing
669 		 * thread, and it is recursively allocating.
670 		 */
671 		malloc_mutex_unlock(&init_lock);
672 		return (false);
673 	}
674 	if (malloc_initializer != (unsigned long)0) {
675 		/* Busy-wait until the initializing thread completes. */
676 		do {
677 			malloc_mutex_unlock(&init_lock);
678 			CPU_SPINWAIT;
679 			malloc_mutex_lock(&init_lock);
680 		} while (malloc_initialized == false);
681 		malloc_mutex_unlock(&init_lock);
682 		return (false);
683 	}
684 
685 #ifdef DYNAMIC_PAGE_SHIFT
686 	/* Get page size. */
687 	{
688 		long result;
689 
690 		result = sysconf(_SC_PAGESIZE);
691 		assert(result != -1);
692 		pagesize = (size_t)result;
693 
694 		/*
695 		 * We assume that pagesize is a power of 2 when calculating
696 		 * pagesize_mask and lg_pagesize.
697 		 */
698 		assert(((result - 1) & result) == 0);
699 		pagesize_mask = result - 1;
700 		lg_pagesize = ffs((int)result) - 1;
701 	}
702 #endif
703 
704 #ifdef JEMALLOC_PROF
705 	prof_boot0();
706 #endif
707 
708 	malloc_conf_init();
709 
710 	/* Register fork handlers. */
711 	if (pthread_atfork(jemalloc_prefork, jemalloc_postfork,
712 	    jemalloc_postfork) != 0) {
713 		malloc_write("<jemalloc>: Error in pthread_atfork()\n");
714 		if (opt_abort)
715 			abort();
716 	}
717 
718 	if (ctl_boot()) {
719 		malloc_mutex_unlock(&init_lock);
720 		return (true);
721 	}
722 
723 	if (opt_stats_print) {
724 		/* Print statistics at exit. */
725 		if (atexit(stats_print_atexit) != 0) {
726 			malloc_write("<jemalloc>: Error in atexit()\n");
727 			if (opt_abort)
728 				abort();
729 		}
730 	}
731 
732 	if (chunk_boot()) {
733 		malloc_mutex_unlock(&init_lock);
734 		return (true);
735 	}
736 
737 	if (base_boot()) {
738 		malloc_mutex_unlock(&init_lock);
739 		return (true);
740 	}
741 
742 #ifdef JEMALLOC_PROF
743 	prof_boot1();
744 #endif
745 
746 	if (arena_boot()) {
747 		malloc_mutex_unlock(&init_lock);
748 		return (true);
749 	}
750 
751 #ifdef JEMALLOC_TCACHE
752 	if (tcache_boot()) {
753 		malloc_mutex_unlock(&init_lock);
754 		return (true);
755 	}
756 #endif
757 
758 	if (huge_boot()) {
759 		malloc_mutex_unlock(&init_lock);
760 		return (true);
761 	}
762 
763 #if (defined(JEMALLOC_STATS) && defined(NO_TLS))
764 	/* Initialize allocation counters before any allocations can occur. */
765 	if (pthread_key_create(&thread_allocated_tsd, thread_allocated_cleanup)
766 	    != 0) {
767 		malloc_mutex_unlock(&init_lock);
768 		return (true);
769 	}
770 #endif
771 
772 	if (malloc_mutex_init(&arenas_lock))
773 		return (true);
774 
775 	if (pthread_key_create(&arenas_tsd, arenas_cleanup) != 0) {
776 		malloc_mutex_unlock(&init_lock);
777 		return (true);
778 	}
779 
780 	/*
781 	 * Create enough scaffolding to allow recursive allocation in
782 	 * malloc_ncpus().
783 	 */
784 	narenas = 1;
785 	arenas = init_arenas;
786 	memset(arenas, 0, sizeof(arena_t *) * narenas);
787 
788 	/*
789 	 * Initialize one arena here.  The rest are lazily created in
790 	 * choose_arena_hard().
791 	 */
792 	arenas_extend(0);
793 	if (arenas[0] == NULL) {
794 		malloc_mutex_unlock(&init_lock);
795 		return (true);
796 	}
797 
798 	/*
799 	 * Assign the initial arena to the initial thread, in order to avoid
800 	 * spurious creation of an extra arena if the application switches to
801 	 * threaded mode.
802 	 */
803 	ARENA_SET(arenas[0]);
804 	arenas[0]->nthreads++;
805 
806 #ifdef JEMALLOC_PROF
807 	if (prof_boot2()) {
808 		malloc_mutex_unlock(&init_lock);
809 		return (true);
810 	}
811 #endif
812 
813 	/* Get number of CPUs. */
814 	malloc_initializer = pthread_self();
815 	malloc_mutex_unlock(&init_lock);
816 	ncpus = malloc_ncpus();
817 	malloc_mutex_lock(&init_lock);
818 
819 	if (opt_narenas == 0) {
820 		/*
821 		 * For SMP systems, create more than one arena per CPU by
822 		 * default.
823 		 */
824 		if (ncpus > 1)
825 			opt_narenas = ncpus << 2;
826 		else
827 			opt_narenas = 1;
828 	}
829 	narenas = opt_narenas;
830 	/*
831 	 * Make sure that the arenas array can be allocated.  In practice, this
832 	 * limit is enough to allow the allocator to function, but the ctl
833 	 * machinery will fail to allocate memory at far lower limits.
834 	 */
835 	if (narenas > chunksize / sizeof(arena_t *)) {
836 		char buf[UMAX2S_BUFSIZE];
837 
838 		narenas = chunksize / sizeof(arena_t *);
839 		malloc_write("<jemalloc>: Reducing narenas to limit (");
840 		malloc_write(u2s(narenas, 10, buf));
841 		malloc_write(")\n");
842 	}
843 
844 	/* Allocate and initialize arenas. */
845 	arenas = (arena_t **)base_alloc(sizeof(arena_t *) * narenas);
846 	if (arenas == NULL) {
847 		malloc_mutex_unlock(&init_lock);
848 		return (true);
849 	}
850 	/*
851 	 * Zero the array.  In practice, this should always be pre-zeroed,
852 	 * since it was just mmap()ed, but let's be sure.
853 	 */
854 	memset(arenas, 0, sizeof(arena_t *) * narenas);
855 	/* Copy the pointer to the one arena that was already initialized. */
856 	arenas[0] = init_arenas[0];
857 
858 #ifdef JEMALLOC_ZONE
859 	/* Register the custom zone. */
860 	malloc_zone_register(create_zone());
861 
862 	/*
863 	 * Convert the default szone to an "overlay zone" that is capable of
864 	 * deallocating szone-allocated objects, but allocating new objects
865 	 * from jemalloc.
866 	 */
867 	szone2ozone(malloc_default_zone());
868 #endif
869 
870 	malloc_initialized = true;
871 	malloc_mutex_unlock(&init_lock);
872 	return (false);
873 }
874 
875 #ifdef JEMALLOC_ZONE
876 JEMALLOC_ATTR(constructor)
877 void
878 jemalloc_darwin_init(void)
879 {
880 
881 	if (malloc_init_hard())
882 		abort();
883 }
884 #endif
885 
886 /*
887  * End initialization functions.
888  */
889 /******************************************************************************/
890 /*
891  * Begin malloc(3)-compatible functions.
892  */
893 
894 JEMALLOC_ATTR(malloc)
895 JEMALLOC_ATTR(visibility("default"))
896 void *
897 JEMALLOC_P(malloc)(size_t size)
898 {
899 	void *ret;
900 #if (defined(JEMALLOC_PROF) || defined(JEMALLOC_STATS))
901 	size_t usize
902 #  ifdef JEMALLOC_CC_SILENCE
903 	    = 0
904 #  endif
905 	    ;
906 #endif
907 #ifdef JEMALLOC_PROF
908 	prof_thr_cnt_t *cnt
909 #  ifdef JEMALLOC_CC_SILENCE
910 	    = NULL
911 #  endif
912 	    ;
913 #endif
914 
915 	if (malloc_init()) {
916 		ret = NULL;
917 		goto OOM;
918 	}
919 
920 	if (size == 0) {
921 #ifdef JEMALLOC_SYSV
922 		if (opt_sysv == false)
923 #endif
924 			size = 1;
925 #ifdef JEMALLOC_SYSV
926 		else {
927 #  ifdef JEMALLOC_XMALLOC
928 			if (opt_xmalloc) {
929 				malloc_write("<jemalloc>: Error in malloc(): "
930 				    "invalid size 0\n");
931 				abort();
932 			}
933 #  endif
934 			ret = NULL;
935 			goto RETURN;
936 		}
937 #endif
938 	}
939 
940 #ifdef JEMALLOC_PROF
941 	if (opt_prof) {
942 		usize = s2u(size);
943 		PROF_ALLOC_PREP(1, usize, cnt);
944 		if (cnt == NULL) {
945 			ret = NULL;
946 			goto OOM;
947 		}
948 		if (prof_promote && (uintptr_t)cnt != (uintptr_t)1U && usize <=
949 		    small_maxclass) {
950 			ret = imalloc(small_maxclass+1);
951 			if (ret != NULL)
952 				arena_prof_promoted(ret, usize);
953 		} else
954 			ret = imalloc(size);
955 	} else
956 #endif
957 	{
958 #ifdef JEMALLOC_STATS
959 		usize = s2u(size);
960 #endif
961 		ret = imalloc(size);
962 	}
963 
964 OOM:
965 	if (ret == NULL) {
966 #ifdef JEMALLOC_XMALLOC
967 		if (opt_xmalloc) {
968 			malloc_write("<jemalloc>: Error in malloc(): "
969 			    "out of memory\n");
970 			abort();
971 		}
972 #endif
973 		errno = ENOMEM;
974 	}
975 
976 #ifdef JEMALLOC_SYSV
977 RETURN:
978 #endif
979 #ifdef JEMALLOC_PROF
980 	if (opt_prof && ret != NULL)
981 		prof_malloc(ret, usize, cnt);
982 #endif
983 #ifdef JEMALLOC_STATS
984 	if (ret != NULL) {
985 		assert(usize == isalloc(ret));
986 		ALLOCATED_ADD(usize, 0);
987 	}
988 #endif
989 	return (ret);
990 }
991 
992 JEMALLOC_ATTR(nonnull(1))
993 #ifdef JEMALLOC_PROF
994 /*
995  * Avoid any uncertainty as to how many backtrace frames to ignore in
996  * PROF_ALLOC_PREP().
997  */
998 JEMALLOC_ATTR(noinline)
999 #endif
1000 static int
1001 imemalign(void **memptr, size_t alignment, size_t size)
1002 {
1003 	int ret;
1004 	size_t usize
1005 #ifdef JEMALLOC_CC_SILENCE
1006 	    = 0
1007 #endif
1008 	    ;
1009 	void *result;
1010 #ifdef JEMALLOC_PROF
1011 	prof_thr_cnt_t *cnt
1012 #  ifdef JEMALLOC_CC_SILENCE
1013 	    = NULL
1014 #  endif
1015 	    ;
1016 #endif
1017 
1018 	if (malloc_init())
1019 		result = NULL;
1020 	else {
1021 		if (size == 0) {
1022 #ifdef JEMALLOC_SYSV
1023 			if (opt_sysv == false)
1024 #endif
1025 				size = 1;
1026 #ifdef JEMALLOC_SYSV
1027 			else {
1028 #  ifdef JEMALLOC_XMALLOC
1029 				if (opt_xmalloc) {
1030 					malloc_write("<jemalloc>: Error in "
1031 					    "posix_memalign(): invalid size "
1032 					    "0\n");
1033 					abort();
1034 				}
1035 #  endif
1036 				result = NULL;
1037 				*memptr = NULL;
1038 				ret = 0;
1039 				goto RETURN;
1040 			}
1041 #endif
1042 		}
1043 
1044 		/* Make sure that alignment is a large enough power of 2. */
1045 		if (((alignment - 1) & alignment) != 0
1046 		    || alignment < sizeof(void *)) {
1047 #ifdef JEMALLOC_XMALLOC
1048 			if (opt_xmalloc) {
1049 				malloc_write("<jemalloc>: Error in "
1050 				    "posix_memalign(): invalid alignment\n");
1051 				abort();
1052 			}
1053 #endif
1054 			result = NULL;
1055 			ret = EINVAL;
1056 			goto RETURN;
1057 		}
1058 
1059 		usize = sa2u(size, alignment, NULL);
1060 		if (usize == 0) {
1061 			result = NULL;
1062 			ret = ENOMEM;
1063 			goto RETURN;
1064 		}
1065 
1066 #ifdef JEMALLOC_PROF
1067 		if (opt_prof) {
1068 			PROF_ALLOC_PREP(2, usize, cnt);
1069 			if (cnt == NULL) {
1070 				result = NULL;
1071 				ret = EINVAL;
1072 			} else {
1073 				if (prof_promote && (uintptr_t)cnt !=
1074 				    (uintptr_t)1U && usize <= small_maxclass) {
1075 					assert(sa2u(small_maxclass+1,
1076 					    alignment, NULL) != 0);
1077 					result = ipalloc(sa2u(small_maxclass+1,
1078 					    alignment, NULL), alignment, false);
1079 					if (result != NULL) {
1080 						arena_prof_promoted(result,
1081 						    usize);
1082 					}
1083 				} else {
1084 					result = ipalloc(usize, alignment,
1085 					    false);
1086 				}
1087 			}
1088 		} else
1089 #endif
1090 			result = ipalloc(usize, alignment, false);
1091 	}
1092 
1093 	if (result == NULL) {
1094 #ifdef JEMALLOC_XMALLOC
1095 		if (opt_xmalloc) {
1096 			malloc_write("<jemalloc>: Error in posix_memalign(): "
1097 			    "out of memory\n");
1098 			abort();
1099 		}
1100 #endif
1101 		ret = ENOMEM;
1102 		goto RETURN;
1103 	}
1104 
1105 	*memptr = result;
1106 	ret = 0;
1107 
1108 RETURN:
1109 #ifdef JEMALLOC_STATS
1110 	if (result != NULL) {
1111 		assert(usize == isalloc(result));
1112 		ALLOCATED_ADD(usize, 0);
1113 	}
1114 #endif
1115 #ifdef JEMALLOC_PROF
1116 	if (opt_prof && result != NULL)
1117 		prof_malloc(result, usize, cnt);
1118 #endif
1119 	return (ret);
1120 }
1121 
1122 JEMALLOC_ATTR(nonnull(1))
1123 JEMALLOC_ATTR(visibility("default"))
1124 int
1125 JEMALLOC_P(posix_memalign)(void **memptr, size_t alignment, size_t size)
1126 {
1127 
1128 	return imemalign(memptr, alignment, size);
1129 }
1130 
1131 JEMALLOC_ATTR(malloc)
1132 JEMALLOC_ATTR(visibility("default"))
1133 void *
1134 JEMALLOC_P(calloc)(size_t num, size_t size)
1135 {
1136 	void *ret;
1137 	size_t num_size;
1138 #if (defined(JEMALLOC_PROF) || defined(JEMALLOC_STATS))
1139 	size_t usize
1140 #  ifdef JEMALLOC_CC_SILENCE
1141 	    = 0
1142 #  endif
1143 	    ;
1144 #endif
1145 #ifdef JEMALLOC_PROF
1146 	prof_thr_cnt_t *cnt
1147 #  ifdef JEMALLOC_CC_SILENCE
1148 	    = NULL
1149 #  endif
1150 	    ;
1151 #endif
1152 
1153 	if (malloc_init()) {
1154 		num_size = 0;
1155 		ret = NULL;
1156 		goto RETURN;
1157 	}
1158 
1159 	num_size = num * size;
1160 	if (num_size == 0) {
1161 #ifdef JEMALLOC_SYSV
1162 		if ((opt_sysv == false) && ((num == 0) || (size == 0)))
1163 #endif
1164 			num_size = 1;
1165 #ifdef JEMALLOC_SYSV
1166 		else {
1167 			ret = NULL;
1168 			goto RETURN;
1169 		}
1170 #endif
1171 	/*
1172 	 * Try to avoid division here.  We know that it isn't possible to
1173 	 * overflow during multiplication if neither operand uses any of the
1174 	 * most significant half of the bits in a size_t.
1175 	 */
1176 	} else if (((num | size) & (SIZE_T_MAX << (sizeof(size_t) << 2)))
1177 	    && (num_size / size != num)) {
1178 		/* size_t overflow. */
1179 		ret = NULL;
1180 		goto RETURN;
1181 	}
1182 
1183 #ifdef JEMALLOC_PROF
1184 	if (opt_prof) {
1185 		usize = s2u(num_size);
1186 		PROF_ALLOC_PREP(1, usize, cnt);
1187 		if (cnt == NULL) {
1188 			ret = NULL;
1189 			goto RETURN;
1190 		}
1191 		if (prof_promote && (uintptr_t)cnt != (uintptr_t)1U && usize
1192 		    <= small_maxclass) {
1193 			ret = icalloc(small_maxclass+1);
1194 			if (ret != NULL)
1195 				arena_prof_promoted(ret, usize);
1196 		} else
1197 			ret = icalloc(num_size);
1198 	} else
1199 #endif
1200 	{
1201 #ifdef JEMALLOC_STATS
1202 		usize = s2u(num_size);
1203 #endif
1204 		ret = icalloc(num_size);
1205 	}
1206 
1207 RETURN:
1208 	if (ret == NULL) {
1209 #ifdef JEMALLOC_XMALLOC
1210 		if (opt_xmalloc) {
1211 			malloc_write("<jemalloc>: Error in calloc(): out of "
1212 			    "memory\n");
1213 			abort();
1214 		}
1215 #endif
1216 		errno = ENOMEM;
1217 	}
1218 
1219 #ifdef JEMALLOC_PROF
1220 	if (opt_prof && ret != NULL)
1221 		prof_malloc(ret, usize, cnt);
1222 #endif
1223 #ifdef JEMALLOC_STATS
1224 	if (ret != NULL) {
1225 		assert(usize == isalloc(ret));
1226 		ALLOCATED_ADD(usize, 0);
1227 	}
1228 #endif
1229 	return (ret);
1230 }
1231 
1232 JEMALLOC_ATTR(visibility("default"))
1233 void *
1234 JEMALLOC_P(realloc)(void *ptr, size_t size)
1235 {
1236 	void *ret;
1237 #if (defined(JEMALLOC_PROF) || defined(JEMALLOC_STATS))
1238 	size_t usize
1239 #  ifdef JEMALLOC_CC_SILENCE
1240 	    = 0
1241 #  endif
1242 	    ;
1243 	size_t old_size = 0;
1244 #endif
1245 #ifdef JEMALLOC_PROF
1246 	prof_thr_cnt_t *cnt
1247 #  ifdef JEMALLOC_CC_SILENCE
1248 	    = NULL
1249 #  endif
1250 	    ;
1251 	prof_ctx_t *old_ctx
1252 #  ifdef JEMALLOC_CC_SILENCE
1253 	    = NULL
1254 #  endif
1255 	    ;
1256 #endif
1257 
1258 	if (size == 0) {
1259 #ifdef JEMALLOC_SYSV
1260 		if (opt_sysv == false)
1261 #endif
1262 			size = 1;
1263 #ifdef JEMALLOC_SYSV
1264 		else {
1265 			if (ptr != NULL) {
1266 #if (defined(JEMALLOC_PROF) || defined(JEMALLOC_STATS))
1267 				old_size = isalloc(ptr);
1268 #endif
1269 #ifdef JEMALLOC_PROF
1270 				if (opt_prof) {
1271 					old_ctx = prof_ctx_get(ptr);
1272 					cnt = NULL;
1273 				}
1274 #endif
1275 				idalloc(ptr);
1276 			}
1277 #ifdef JEMALLOC_PROF
1278 			else if (opt_prof) {
1279 				old_ctx = NULL;
1280 				cnt = NULL;
1281 			}
1282 #endif
1283 			ret = NULL;
1284 			goto RETURN;
1285 		}
1286 #endif
1287 	}
1288 
1289 	if (ptr != NULL) {
1290 		assert(malloc_initialized || malloc_initializer ==
1291 		    pthread_self());
1292 
1293 #if (defined(JEMALLOC_PROF) || defined(JEMALLOC_STATS))
1294 		old_size = isalloc(ptr);
1295 #endif
1296 #ifdef JEMALLOC_PROF
1297 		if (opt_prof) {
1298 			usize = s2u(size);
1299 			old_ctx = prof_ctx_get(ptr);
1300 			PROF_ALLOC_PREP(1, usize, cnt);
1301 			if (cnt == NULL) {
1302 				old_ctx = NULL;
1303 				ret = NULL;
1304 				goto OOM;
1305 			}
1306 			if (prof_promote && (uintptr_t)cnt != (uintptr_t)1U &&
1307 			    usize <= small_maxclass) {
1308 				ret = iralloc(ptr, small_maxclass+1, 0, 0,
1309 				    false, false);
1310 				if (ret != NULL)
1311 					arena_prof_promoted(ret, usize);
1312 				else
1313 					old_ctx = NULL;
1314 			} else {
1315 				ret = iralloc(ptr, size, 0, 0, false, false);
1316 				if (ret == NULL)
1317 					old_ctx = NULL;
1318 			}
1319 		} else
1320 #endif
1321 		{
1322 #ifdef JEMALLOC_STATS
1323 			usize = s2u(size);
1324 #endif
1325 			ret = iralloc(ptr, size, 0, 0, false, false);
1326 		}
1327 
1328 #ifdef JEMALLOC_PROF
1329 OOM:
1330 #endif
1331 		if (ret == NULL) {
1332 #ifdef JEMALLOC_XMALLOC
1333 			if (opt_xmalloc) {
1334 				malloc_write("<jemalloc>: Error in realloc(): "
1335 				    "out of memory\n");
1336 				abort();
1337 			}
1338 #endif
1339 			errno = ENOMEM;
1340 		}
1341 	} else {
1342 #ifdef JEMALLOC_PROF
1343 		if (opt_prof)
1344 			old_ctx = NULL;
1345 #endif
1346 		if (malloc_init()) {
1347 #ifdef JEMALLOC_PROF
1348 			if (opt_prof)
1349 				cnt = NULL;
1350 #endif
1351 			ret = NULL;
1352 		} else {
1353 #ifdef JEMALLOC_PROF
1354 			if (opt_prof) {
1355 				usize = s2u(size);
1356 				PROF_ALLOC_PREP(1, usize, cnt);
1357 				if (cnt == NULL)
1358 					ret = NULL;
1359 				else {
1360 					if (prof_promote && (uintptr_t)cnt !=
1361 					    (uintptr_t)1U && usize <=
1362 					    small_maxclass) {
1363 						ret = imalloc(small_maxclass+1);
1364 						if (ret != NULL) {
1365 							arena_prof_promoted(ret,
1366 							    usize);
1367 						}
1368 					} else
1369 						ret = imalloc(size);
1370 				}
1371 			} else
1372 #endif
1373 			{
1374 #ifdef JEMALLOC_STATS
1375 				usize = s2u(size);
1376 #endif
1377 				ret = imalloc(size);
1378 			}
1379 		}
1380 
1381 		if (ret == NULL) {
1382 #ifdef JEMALLOC_XMALLOC
1383 			if (opt_xmalloc) {
1384 				malloc_write("<jemalloc>: Error in realloc(): "
1385 				    "out of memory\n");
1386 				abort();
1387 			}
1388 #endif
1389 			errno = ENOMEM;
1390 		}
1391 	}
1392 
1393 #ifdef JEMALLOC_SYSV
1394 RETURN:
1395 #endif
1396 #ifdef JEMALLOC_PROF
1397 	if (opt_prof)
1398 		prof_realloc(ret, usize, cnt, old_size, old_ctx);
1399 #endif
1400 #ifdef JEMALLOC_STATS
1401 	if (ret != NULL) {
1402 		assert(usize == isalloc(ret));
1403 		ALLOCATED_ADD(usize, old_size);
1404 	}
1405 #endif
1406 	return (ret);
1407 }
1408 
1409 JEMALLOC_ATTR(visibility("default"))
1410 void
1411 JEMALLOC_P(free)(void *ptr)
1412 {
1413 
1414 	if (ptr != NULL) {
1415 #if (defined(JEMALLOC_PROF) || defined(JEMALLOC_STATS))
1416 		size_t usize;
1417 #endif
1418 
1419 		assert(malloc_initialized || malloc_initializer ==
1420 		    pthread_self());
1421 
1422 #ifdef JEMALLOC_STATS
1423 		usize = isalloc(ptr);
1424 #endif
1425 #ifdef JEMALLOC_PROF
1426 		if (opt_prof) {
1427 #  ifndef JEMALLOC_STATS
1428 			usize = isalloc(ptr);
1429 #  endif
1430 			prof_free(ptr, usize);
1431 		}
1432 #endif
1433 #ifdef JEMALLOC_STATS
1434 		ALLOCATED_ADD(0, usize);
1435 #endif
1436 		idalloc(ptr);
1437 	}
1438 }
1439 
1440 /*
1441  * End malloc(3)-compatible functions.
1442  */
1443 /******************************************************************************/
1444 /*
1445  * Begin non-standard override functions.
1446  *
1447  * These overrides are omitted if the JEMALLOC_PREFIX is defined, since the
1448  * entire point is to avoid accidental mixed allocator usage.
1449  */
1450 #ifndef JEMALLOC_PREFIX
1451 
1452 #ifdef JEMALLOC_OVERRIDE_MEMALIGN
1453 JEMALLOC_ATTR(malloc)
1454 JEMALLOC_ATTR(visibility("default"))
1455 void *
1456 JEMALLOC_P(memalign)(size_t alignment, size_t size)
1457 {
1458 	void *ret;
1459 #ifdef JEMALLOC_CC_SILENCE
1460 	int result =
1461 #endif
1462 	    imemalign(&ret, alignment, size);
1463 #ifdef JEMALLOC_CC_SILENCE
1464 	if (result != 0)
1465 		return (NULL);
1466 #endif
1467 	return (ret);
1468 }
1469 #endif
1470 
1471 #ifdef JEMALLOC_OVERRIDE_VALLOC
1472 JEMALLOC_ATTR(malloc)
1473 JEMALLOC_ATTR(visibility("default"))
1474 void *
1475 JEMALLOC_P(valloc)(size_t size)
1476 {
1477 	void *ret;
1478 #ifdef JEMALLOC_CC_SILENCE
1479 	int result =
1480 #endif
1481 	    imemalign(&ret, PAGE_SIZE, size);
1482 #ifdef JEMALLOC_CC_SILENCE
1483 	if (result != 0)
1484 		return (NULL);
1485 #endif
1486 	return (ret);
1487 }
1488 #endif
1489 
1490 #endif /* JEMALLOC_PREFIX */
1491 /*
1492  * End non-standard override functions.
1493  */
1494 /******************************************************************************/
1495 /*
1496  * Begin non-standard functions.
1497  */
1498 
1499 JEMALLOC_ATTR(visibility("default"))
1500 size_t
1501 JEMALLOC_P(malloc_usable_size)(const void *ptr)
1502 {
1503 	size_t ret;
1504 
1505 	assert(malloc_initialized || malloc_initializer == pthread_self());
1506 
1507 #ifdef JEMALLOC_IVSALLOC
1508 	ret = ivsalloc(ptr);
1509 #else
1510 	assert(ptr != NULL);
1511 	ret = isalloc(ptr);
1512 #endif
1513 
1514 	return (ret);
1515 }
1516 
1517 JEMALLOC_ATTR(visibility("default"))
1518 void
1519 JEMALLOC_P(malloc_stats_print)(void (*write_cb)(void *, const char *),
1520     void *cbopaque, const char *opts)
1521 {
1522 
1523 	stats_print(write_cb, cbopaque, opts);
1524 }
1525 
1526 JEMALLOC_ATTR(visibility("default"))
1527 int
1528 JEMALLOC_P(mallctl)(const char *name, void *oldp, size_t *oldlenp, void *newp,
1529     size_t newlen)
1530 {
1531 
1532 	if (malloc_init())
1533 		return (EAGAIN);
1534 
1535 	return (ctl_byname(name, oldp, oldlenp, newp, newlen));
1536 }
1537 
1538 JEMALLOC_ATTR(visibility("default"))
1539 int
1540 JEMALLOC_P(mallctlnametomib)(const char *name, size_t *mibp, size_t *miblenp)
1541 {
1542 
1543 	if (malloc_init())
1544 		return (EAGAIN);
1545 
1546 	return (ctl_nametomib(name, mibp, miblenp));
1547 }
1548 
1549 JEMALLOC_ATTR(visibility("default"))
1550 int
1551 JEMALLOC_P(mallctlbymib)(const size_t *mib, size_t miblen, void *oldp,
1552     size_t *oldlenp, void *newp, size_t newlen)
1553 {
1554 
1555 	if (malloc_init())
1556 		return (EAGAIN);
1557 
1558 	return (ctl_bymib(mib, miblen, oldp, oldlenp, newp, newlen));
1559 }
1560 
1561 JEMALLOC_INLINE void *
1562 iallocm(size_t usize, size_t alignment, bool zero)
1563 {
1564 
1565 	assert(usize == ((alignment == 0) ? s2u(usize) : sa2u(usize, alignment,
1566 	    NULL)));
1567 
1568 	if (alignment != 0)
1569 		return (ipalloc(usize, alignment, zero));
1570 	else if (zero)
1571 		return (icalloc(usize));
1572 	else
1573 		return (imalloc(usize));
1574 }
1575 
1576 JEMALLOC_ATTR(nonnull(1))
1577 JEMALLOC_ATTR(visibility("default"))
1578 int
1579 JEMALLOC_P(allocm)(void **ptr, size_t *rsize, size_t size, int flags)
1580 {
1581 	void *p;
1582 	size_t usize;
1583 	size_t alignment = (ZU(1) << (flags & ALLOCM_LG_ALIGN_MASK)
1584 	    & (SIZE_T_MAX-1));
1585 	bool zero = flags & ALLOCM_ZERO;
1586 #ifdef JEMALLOC_PROF
1587 	prof_thr_cnt_t *cnt;
1588 #endif
1589 
1590 	assert(ptr != NULL);
1591 	assert(size != 0);
1592 
1593 	if (malloc_init())
1594 		goto OOM;
1595 
1596 	usize = (alignment == 0) ? s2u(size) : sa2u(size, alignment, NULL);
1597 	if (usize == 0)
1598 		goto OOM;
1599 
1600 #ifdef JEMALLOC_PROF
1601 	if (opt_prof) {
1602 		PROF_ALLOC_PREP(1, usize, cnt);
1603 		if (cnt == NULL)
1604 			goto OOM;
1605 		if (prof_promote && (uintptr_t)cnt != (uintptr_t)1U && usize <=
1606 		    small_maxclass) {
1607 			size_t usize_promoted = (alignment == 0) ?
1608 			    s2u(small_maxclass+1) : sa2u(small_maxclass+1,
1609 			    alignment, NULL);
1610 			assert(usize_promoted != 0);
1611 			p = iallocm(usize_promoted, alignment, zero);
1612 			if (p == NULL)
1613 				goto OOM;
1614 			arena_prof_promoted(p, usize);
1615 		} else {
1616 			p = iallocm(usize, alignment, zero);
1617 			if (p == NULL)
1618 				goto OOM;
1619 		}
1620 		prof_malloc(p, usize, cnt);
1621 		if (rsize != NULL)
1622 			*rsize = usize;
1623 	} else
1624 #endif
1625 	{
1626 		p = iallocm(usize, alignment, zero);
1627 		if (p == NULL)
1628 			goto OOM;
1629 #ifndef JEMALLOC_STATS
1630 		if (rsize != NULL)
1631 #endif
1632 		{
1633 #ifdef JEMALLOC_STATS
1634 			if (rsize != NULL)
1635 #endif
1636 				*rsize = usize;
1637 		}
1638 	}
1639 
1640 	*ptr = p;
1641 #ifdef JEMALLOC_STATS
1642 	assert(usize == isalloc(p));
1643 	ALLOCATED_ADD(usize, 0);
1644 #endif
1645 	return (ALLOCM_SUCCESS);
1646 OOM:
1647 #ifdef JEMALLOC_XMALLOC
1648 	if (opt_xmalloc) {
1649 		malloc_write("<jemalloc>: Error in allocm(): "
1650 		    "out of memory\n");
1651 		abort();
1652 	}
1653 #endif
1654 	*ptr = NULL;
1655 	return (ALLOCM_ERR_OOM);
1656 }
1657 
1658 JEMALLOC_ATTR(nonnull(1))
1659 JEMALLOC_ATTR(visibility("default"))
1660 int
1661 JEMALLOC_P(rallocm)(void **ptr, size_t *rsize, size_t size, size_t extra,
1662     int flags)
1663 {
1664 	void *p, *q;
1665 	size_t usize;
1666 #if (defined(JEMALLOC_PROF) || defined(JEMALLOC_STATS))
1667 	size_t old_size;
1668 #endif
1669 	size_t alignment = (ZU(1) << (flags & ALLOCM_LG_ALIGN_MASK)
1670 	    & (SIZE_T_MAX-1));
1671 	bool zero = flags & ALLOCM_ZERO;
1672 	bool no_move = flags & ALLOCM_NO_MOVE;
1673 #ifdef JEMALLOC_PROF
1674 	prof_thr_cnt_t *cnt;
1675 #endif
1676 
1677 	assert(ptr != NULL);
1678 	assert(*ptr != NULL);
1679 	assert(size != 0);
1680 	assert(SIZE_T_MAX - size >= extra);
1681 	assert(malloc_initialized || malloc_initializer == pthread_self());
1682 
1683 	p = *ptr;
1684 #ifdef JEMALLOC_PROF
1685 	if (opt_prof) {
1686 		/*
1687 		 * usize isn't knowable before iralloc() returns when extra is
1688 		 * non-zero.  Therefore, compute its maximum possible value and
1689 		 * use that in PROF_ALLOC_PREP() to decide whether to capture a
1690 		 * backtrace.  prof_realloc() will use the actual usize to
1691 		 * decide whether to sample.
1692 		 */
1693 		size_t max_usize = (alignment == 0) ? s2u(size+extra) :
1694 		    sa2u(size+extra, alignment, NULL);
1695 		prof_ctx_t *old_ctx = prof_ctx_get(p);
1696 		old_size = isalloc(p);
1697 		PROF_ALLOC_PREP(1, max_usize, cnt);
1698 		if (cnt == NULL)
1699 			goto OOM;
1700 		/*
1701 		 * Use minimum usize to determine whether promotion may happen.
1702 		 */
1703 		if (prof_promote && (uintptr_t)cnt != (uintptr_t)1U
1704 		    && ((alignment == 0) ? s2u(size) : sa2u(size,
1705 		    alignment, NULL)) <= small_maxclass) {
1706 			q = iralloc(p, small_maxclass+1, (small_maxclass+1 >=
1707 			    size+extra) ? 0 : size+extra - (small_maxclass+1),
1708 			    alignment, zero, no_move);
1709 			if (q == NULL)
1710 				goto ERR;
1711 			if (max_usize < PAGE_SIZE) {
1712 				usize = max_usize;
1713 				arena_prof_promoted(q, usize);
1714 			} else
1715 				usize = isalloc(q);
1716 		} else {
1717 			q = iralloc(p, size, extra, alignment, zero, no_move);
1718 			if (q == NULL)
1719 				goto ERR;
1720 			usize = isalloc(q);
1721 		}
1722 		prof_realloc(q, usize, cnt, old_size, old_ctx);
1723 		if (rsize != NULL)
1724 			*rsize = usize;
1725 	} else
1726 #endif
1727 	{
1728 #ifdef JEMALLOC_STATS
1729 		old_size = isalloc(p);
1730 #endif
1731 		q = iralloc(p, size, extra, alignment, zero, no_move);
1732 		if (q == NULL)
1733 			goto ERR;
1734 #ifndef JEMALLOC_STATS
1735 		if (rsize != NULL)
1736 #endif
1737 		{
1738 			usize = isalloc(q);
1739 #ifdef JEMALLOC_STATS
1740 			if (rsize != NULL)
1741 #endif
1742 				*rsize = usize;
1743 		}
1744 	}
1745 
1746 	*ptr = q;
1747 #ifdef JEMALLOC_STATS
1748 	ALLOCATED_ADD(usize, old_size);
1749 #endif
1750 	return (ALLOCM_SUCCESS);
1751 ERR:
1752 	if (no_move)
1753 		return (ALLOCM_ERR_NOT_MOVED);
1754 #ifdef JEMALLOC_PROF
1755 OOM:
1756 #endif
1757 #ifdef JEMALLOC_XMALLOC
1758 	if (opt_xmalloc) {
1759 		malloc_write("<jemalloc>: Error in rallocm(): "
1760 		    "out of memory\n");
1761 		abort();
1762 	}
1763 #endif
1764 	return (ALLOCM_ERR_OOM);
1765 }
1766 
1767 JEMALLOC_ATTR(nonnull(1))
1768 JEMALLOC_ATTR(visibility("default"))
1769 int
1770 JEMALLOC_P(sallocm)(const void *ptr, size_t *rsize, int flags)
1771 {
1772 	size_t sz;
1773 
1774 	assert(malloc_initialized || malloc_initializer == pthread_self());
1775 
1776 #ifdef JEMALLOC_IVSALLOC
1777 	sz = ivsalloc(ptr);
1778 #else
1779 	assert(ptr != NULL);
1780 	sz = isalloc(ptr);
1781 #endif
1782 	assert(rsize != NULL);
1783 	*rsize = sz;
1784 
1785 	return (ALLOCM_SUCCESS);
1786 }
1787 
1788 JEMALLOC_ATTR(nonnull(1))
1789 JEMALLOC_ATTR(visibility("default"))
1790 int
1791 JEMALLOC_P(dallocm)(void *ptr, int flags)
1792 {
1793 #if (defined(JEMALLOC_PROF) || defined(JEMALLOC_STATS))
1794 	size_t usize;
1795 #endif
1796 
1797 	assert(ptr != NULL);
1798 	assert(malloc_initialized || malloc_initializer == pthread_self());
1799 
1800 #ifdef JEMALLOC_STATS
1801 	usize = isalloc(ptr);
1802 #endif
1803 #ifdef JEMALLOC_PROF
1804 	if (opt_prof) {
1805 #  ifndef JEMALLOC_STATS
1806 		usize = isalloc(ptr);
1807 #  endif
1808 		prof_free(ptr, usize);
1809 	}
1810 #endif
1811 #ifdef JEMALLOC_STATS
1812 	ALLOCATED_ADD(0, usize);
1813 #endif
1814 	idalloc(ptr);
1815 
1816 	return (ALLOCM_SUCCESS);
1817 }
1818 
1819 /*
1820  * End non-standard functions.
1821  */
1822 /******************************************************************************/
1823 
1824 /*
1825  * The following functions are used by threading libraries for protection of
1826  * malloc during fork().
1827  */
1828 
1829 void
1830 jemalloc_prefork(void)
1831 {
1832 	unsigned i;
1833 
1834 	/* Acquire all mutexes in a safe order. */
1835 
1836 	malloc_mutex_lock(&arenas_lock);
1837 	for (i = 0; i < narenas; i++) {
1838 		if (arenas[i] != NULL)
1839 			malloc_mutex_lock(&arenas[i]->lock);
1840 	}
1841 
1842 	malloc_mutex_lock(&base_mtx);
1843 
1844 	malloc_mutex_lock(&huge_mtx);
1845 
1846 #ifdef JEMALLOC_DSS
1847 	malloc_mutex_lock(&dss_mtx);
1848 #endif
1849 
1850 #ifdef JEMALLOC_SWAP
1851 	malloc_mutex_lock(&swap_mtx);
1852 #endif
1853 }
1854 
1855 void
1856 jemalloc_postfork(void)
1857 {
1858 	unsigned i;
1859 
1860 	/* Release all mutexes, now that fork() has completed. */
1861 
1862 #ifdef JEMALLOC_SWAP
1863 	malloc_mutex_unlock(&swap_mtx);
1864 #endif
1865 
1866 #ifdef JEMALLOC_DSS
1867 	malloc_mutex_unlock(&dss_mtx);
1868 #endif
1869 
1870 	malloc_mutex_unlock(&huge_mtx);
1871 
1872 	malloc_mutex_unlock(&base_mtx);
1873 
1874 	for (i = 0; i < narenas; i++) {
1875 		if (arenas[i] != NULL)
1876 			malloc_mutex_unlock(&arenas[i]->lock);
1877 	}
1878 	malloc_mutex_unlock(&arenas_lock);
1879 }
1880 
1881 /******************************************************************************/
1882