Blame jemalloc/include/jemalloc/internal/jemalloc_internal_inlines_a.h

Packit 345191
#ifndef JEMALLOC_INTERNAL_INLINES_A_H
Packit 345191
#define JEMALLOC_INTERNAL_INLINES_A_H
Packit 345191
Packit 345191
#include "jemalloc/internal/atomic.h"
Packit 345191
#include "jemalloc/internal/bit_util.h"
Packit 345191
#include "jemalloc/internal/jemalloc_internal_types.h"
Packit 345191
#include "jemalloc/internal/sc.h"
Packit 345191
#include "jemalloc/internal/ticker.h"
Packit 345191
Packit 345191
JEMALLOC_ALWAYS_INLINE malloc_cpuid_t
Packit 345191
malloc_getcpu(void) {
Packit 345191
	assert(have_percpu_arena);
Packit 345191
#if defined(_WIN32)
Packit 345191
	return GetCurrentProcessorNumber();
Packit 345191
#elif defined(JEMALLOC_HAVE_SCHED_GETCPU)
Packit 345191
	return (malloc_cpuid_t)sched_getcpu();
Packit 345191
#else
Packit 345191
	not_reached();
Packit 345191
	return -1;
Packit 345191
#endif
Packit 345191
}
Packit 345191
Packit 345191
/* Return the chosen arena index based on current cpu. */
Packit 345191
JEMALLOC_ALWAYS_INLINE unsigned
Packit 345191
percpu_arena_choose(void) {
Packit 345191
	assert(have_percpu_arena && PERCPU_ARENA_ENABLED(opt_percpu_arena));
Packit 345191
Packit 345191
	malloc_cpuid_t cpuid = malloc_getcpu();
Packit 345191
	assert(cpuid >= 0);
Packit 345191
Packit 345191
	unsigned arena_ind;
Packit 345191
	if ((opt_percpu_arena == percpu_arena) || ((unsigned)cpuid < ncpus /
Packit 345191
	    2)) {
Packit 345191
		arena_ind = cpuid;
Packit 345191
	} else {
Packit 345191
		assert(opt_percpu_arena == per_phycpu_arena);
Packit 345191
		/* Hyper threads on the same physical CPU share arena. */
Packit 345191
		arena_ind = cpuid - ncpus / 2;
Packit 345191
	}
Packit 345191
Packit 345191
	return arena_ind;
Packit 345191
}
Packit 345191
Packit 345191
/* Return the limit of percpu auto arena range, i.e. arenas[0...ind_limit). */
Packit 345191
JEMALLOC_ALWAYS_INLINE unsigned
Packit 345191
percpu_arena_ind_limit(percpu_arena_mode_t mode) {
Packit 345191
	assert(have_percpu_arena && PERCPU_ARENA_ENABLED(mode));
Packit 345191
	if (mode == per_phycpu_arena && ncpus > 1) {
Packit 345191
		if (ncpus % 2) {
Packit 345191
			/* This likely means a misconfig. */
Packit 345191
			return ncpus / 2 + 1;
Packit 345191
		}
Packit 345191
		return ncpus / 2;
Packit 345191
	} else {
Packit 345191
		return ncpus;
Packit 345191
	}
Packit 345191
}
Packit 345191
Packit 345191
static inline arena_tdata_t *
Packit 345191
arena_tdata_get(tsd_t *tsd, unsigned ind, bool refresh_if_missing) {
Packit 345191
	arena_tdata_t *tdata;
Packit 345191
	arena_tdata_t *arenas_tdata = tsd_arenas_tdata_get(tsd);
Packit 345191
Packit 345191
	if (unlikely(arenas_tdata == NULL)) {
Packit 345191
		/* arenas_tdata hasn't been initialized yet. */
Packit 345191
		return arena_tdata_get_hard(tsd, ind);
Packit 345191
	}
Packit 345191
	if (unlikely(ind >= tsd_narenas_tdata_get(tsd))) {
Packit 345191
		/*
Packit 345191
		 * ind is invalid, cache is old (too small), or tdata to be
Packit 345191
		 * initialized.
Packit 345191
		 */
Packit 345191
		return (refresh_if_missing ? arena_tdata_get_hard(tsd, ind) :
Packit 345191
		    NULL);
Packit 345191
	}
Packit 345191
Packit 345191
	tdata = &arenas_tdata[ind];
Packit 345191
	if (likely(tdata != NULL) || !refresh_if_missing) {
Packit 345191
		return tdata;
Packit 345191
	}
Packit 345191
	return arena_tdata_get_hard(tsd, ind);
Packit 345191
}
Packit 345191
Packit 345191
static inline arena_t *
Packit 345191
arena_get(tsdn_t *tsdn, unsigned ind, bool init_if_missing) {
Packit 345191
	arena_t *ret;
Packit 345191
Packit 345191
	assert(ind < MALLOCX_ARENA_LIMIT);
Packit 345191
Packit 345191
	ret = (arena_t *)atomic_load_p(&arenas[ind], ATOMIC_ACQUIRE);
Packit 345191
	if (unlikely(ret == NULL)) {
Packit 345191
		if (init_if_missing) {
Packit 345191
			ret = arena_init(tsdn, ind,
Packit 345191
			    (extent_hooks_t *)&extent_hooks_default);
Packit 345191
		}
Packit 345191
	}
Packit 345191
	return ret;
Packit 345191
}
Packit 345191
Packit 345191
static inline ticker_t *
Packit 345191
decay_ticker_get(tsd_t *tsd, unsigned ind) {
Packit 345191
	arena_tdata_t *tdata;
Packit 345191
Packit 345191
	tdata = arena_tdata_get(tsd, ind, true);
Packit 345191
	if (unlikely(tdata == NULL)) {
Packit 345191
		return NULL;
Packit 345191
	}
Packit 345191
	return &tdata->decay_ticker;
Packit 345191
}
Packit 345191
Packit 345191
JEMALLOC_ALWAYS_INLINE cache_bin_t *
Packit 345191
tcache_small_bin_get(tcache_t *tcache, szind_t binind) {
Packit 345191
	assert(binind < SC_NBINS);
Packit 345191
	return &tcache->bins_small[binind];
Packit 345191
}
Packit 345191
Packit 345191
JEMALLOC_ALWAYS_INLINE cache_bin_t *
Packit 345191
tcache_large_bin_get(tcache_t *tcache, szind_t binind) {
Packit 345191
	assert(binind >= SC_NBINS &&binind < nhbins);
Packit 345191
	return &tcache->bins_large[binind - SC_NBINS];
Packit 345191
}
Packit 345191
Packit 345191
JEMALLOC_ALWAYS_INLINE bool
Packit 345191
tcache_available(tsd_t *tsd) {
Packit 345191
	/*
Packit 345191
	 * Thread specific auto tcache might be unavailable if: 1) during tcache
Packit 345191
	 * initialization, or 2) disabled through thread.tcache.enabled mallctl
Packit 345191
	 * or config options.  This check covers all cases.
Packit 345191
	 */
Packit 345191
	if (likely(tsd_tcache_enabled_get(tsd))) {
Packit 345191
		/* Associated arena == NULL implies tcache init in progress. */
Packit 345191
		assert(tsd_tcachep_get(tsd)->arena == NULL ||
Packit 345191
		    tcache_small_bin_get(tsd_tcachep_get(tsd), 0)->avail !=
Packit 345191
		    NULL);
Packit 345191
		return true;
Packit 345191
	}
Packit 345191
Packit 345191
	return false;
Packit 345191
}
Packit 345191
Packit 345191
JEMALLOC_ALWAYS_INLINE tcache_t *
Packit 345191
tcache_get(tsd_t *tsd) {
Packit 345191
	if (!tcache_available(tsd)) {
Packit 345191
		return NULL;
Packit 345191
	}
Packit 345191
Packit 345191
	return tsd_tcachep_get(tsd);
Packit 345191
}
Packit 345191
Packit 345191
static inline void
Packit 345191
pre_reentrancy(tsd_t *tsd, arena_t *arena) {
Packit 345191
	/* arena is the current context.  Reentry from a0 is not allowed. */
Packit 345191
	assert(arena != arena_get(tsd_tsdn(tsd), 0, false));
Packit 345191
Packit 345191
	bool fast = tsd_fast(tsd);
Packit 345191
	assert(tsd_reentrancy_level_get(tsd) < INT8_MAX);
Packit 345191
	++*tsd_reentrancy_levelp_get(tsd);
Packit 345191
	if (fast) {
Packit 345191
		/* Prepare slow path for reentrancy. */
Packit 345191
		tsd_slow_update(tsd);
Packit 345191
		assert(tsd_state_get(tsd) == tsd_state_nominal_slow);
Packit 345191
	}
Packit 345191
}
Packit 345191
Packit 345191
static inline void
Packit 345191
post_reentrancy(tsd_t *tsd) {
Packit 345191
	int8_t *reentrancy_level = tsd_reentrancy_levelp_get(tsd);
Packit 345191
	assert(*reentrancy_level > 0);
Packit 345191
	if (--*reentrancy_level == 0) {
Packit 345191
		tsd_slow_update(tsd);
Packit 345191
	}
Packit 345191
}
Packit 345191
Packit 345191
#endif /* JEMALLOC_INTERNAL_INLINES_A_H */