Blame jemalloc/include/jemalloc/internal/ticker.h

Packit Service 724aca
#ifndef JEMALLOC_INTERNAL_TICKER_H
Packit Service 724aca
#define JEMALLOC_INTERNAL_TICKER_H
Packit Service 724aca
Packit Service 724aca
#include "jemalloc/internal/util.h"
Packit Service 724aca
Packit Service 724aca
/**
Packit Service 724aca
 * A ticker makes it easy to count-down events until some limit.  You
Packit Service 724aca
 * ticker_init the ticker to trigger every nticks events.  You then notify it
Packit Service 724aca
 * that an event has occurred with calls to ticker_tick (or that nticks events
Packit Service 724aca
 * have occurred with a call to ticker_ticks), which will return true (and reset
Packit Service 724aca
 * the counter) if the countdown hit zero.
Packit Service 724aca
 */
Packit Service 724aca
Packit Service 724aca
typedef struct {
Packit Service 724aca
	int32_t tick;
Packit Service 724aca
	int32_t nticks;
Packit Service 724aca
} ticker_t;
Packit Service 724aca
Packit Service 724aca
static inline void
Packit Service 724aca
ticker_init(ticker_t *ticker, int32_t nticks) {
Packit Service 724aca
	ticker->tick = nticks;
Packit Service 724aca
	ticker->nticks = nticks;
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
static inline void
Packit Service 724aca
ticker_copy(ticker_t *ticker, const ticker_t *other) {
Packit Service 724aca
	*ticker = *other;
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
static inline int32_t
Packit Service 724aca
ticker_read(const ticker_t *ticker) {
Packit Service 724aca
	return ticker->tick;
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
/*
Packit Service 724aca
 * Not intended to be a public API.  Unfortunately, on x86, neither gcc nor
Packit Service 724aca
 * clang seems smart enough to turn
Packit Service 724aca
 *   ticker->tick -= nticks;
Packit Service 724aca
 *   if (unlikely(ticker->tick < 0)) {
Packit Service 724aca
 *     fixup ticker
Packit Service 724aca
 *     return true;
Packit Service 724aca
 *   }
Packit Service 724aca
 *   return false;
Packit Service 724aca
 * into
Packit Service 724aca
 *   subq %nticks_reg, (%ticker_reg)
Packit Service 724aca
 *   js fixup ticker
Packit Service 724aca
 *
Packit Service 724aca
 * unless we force "fixup ticker" out of line.  In that case, gcc gets it right,
Packit Service 724aca
 * but clang now does worse than before.  So, on x86 with gcc, we force it out
Packit Service 724aca
 * of line, but otherwise let the inlining occur.  Ordinarily this wouldn't be
Packit Service 724aca
 * worth the hassle, but this is on the fast path of both malloc and free (via
Packit Service 724aca
 * tcache_event).
Packit Service 724aca
 */
Packit Service 724aca
#if defined(__GNUC__) && !defined(__clang__)				\
Packit Service 724aca
    && (defined(__x86_64__) || defined(__i386__))
Packit Service 724aca
JEMALLOC_NOINLINE
Packit Service 724aca
#endif
Packit Service 724aca
static bool
Packit Service 724aca
ticker_fixup(ticker_t *ticker) {
Packit Service 724aca
	ticker->tick = ticker->nticks;
Packit Service 724aca
	return true;
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
static inline bool
Packit Service 724aca
ticker_ticks(ticker_t *ticker, int32_t nticks) {
Packit Service 724aca
	ticker->tick -= nticks;
Packit Service 724aca
	if (unlikely(ticker->tick < 0)) {
Packit Service 724aca
		return ticker_fixup(ticker);
Packit Service 724aca
	}
Packit Service 724aca
	return false;
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
static inline bool
Packit Service 724aca
ticker_tick(ticker_t *ticker) {
Packit Service 724aca
	return ticker_ticks(ticker, 1);
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
/*
Packit Service 724aca
 * Try to tick.  If ticker would fire, return true, but rely on
Packit Service 724aca
 * slowpath to reset ticker.
Packit Service 724aca
 */
Packit Service 724aca
static inline bool
Packit Service 724aca
ticker_trytick(ticker_t *ticker) {
Packit Service 724aca
	--ticker->tick;
Packit Service 724aca
	if (unlikely(ticker->tick < 0)) {
Packit Service 724aca
		return true;
Packit Service 724aca
	}
Packit Service 724aca
	return false;
Packit Service 724aca
}
Packit Service 724aca
Packit Service 724aca
#endif /* JEMALLOC_INTERNAL_TICKER_H */