mirror of
https://github.com/samba-team/samba.git
synced 2025-01-12 09:18:10 +03:00
5917d97991
Also general cleanups: (1) Don't assume that strings are folded by the compiler. (2) Implement likely_stats_reset(). (3) Return non-const string from likely_stats(), as caller must free it. (4) Don't use struct info indirection (that was from when we used callbacks?) (5) Close memory leak in run-debug.c Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> (Imported from CCAN commit 0e5d0e30b30bb07b6605843e5ff224210d8083d8)
122 lines
3.4 KiB
C
122 lines
3.4 KiB
C
/* Licensed under LGPLv2.1+ - see LICENSE file for details */
|
|
#ifndef CCAN_LIKELY_H
|
|
#define CCAN_LIKELY_H
|
|
#include "config.h"
|
|
#include <ccan/str/str.h>
|
|
#include <stdbool.h>
|
|
|
|
#ifndef CCAN_LIKELY_DEBUG
|
|
#if HAVE_BUILTIN_EXPECT
|
|
/**
|
|
* likely - indicate that a condition is likely to be true.
|
|
* @cond: the condition
|
|
*
|
|
* This uses a compiler extension where available to indicate a likely
|
|
* code path and optimize appropriately; it's also useful for readers
|
|
* to quickly identify exceptional paths through functions. The
|
|
* threshold for "likely" is usually considered to be between 90 and
|
|
* 99%; marginal cases should not be marked either way.
|
|
*
|
|
* See Also:
|
|
* unlikely(), likely_stats()
|
|
*
|
|
* Example:
|
|
* // Returns false if we overflow.
|
|
* static inline bool inc_int(unsigned int *val)
|
|
* {
|
|
* (*val)++;
|
|
* if (likely(*val))
|
|
* return true;
|
|
* return false;
|
|
* }
|
|
*/
|
|
#ifndef likely
|
|
#define likely(cond) __builtin_expect(!!(cond), 1)
|
|
#endif
|
|
|
|
/**
|
|
* unlikely - indicate that a condition is unlikely to be true.
|
|
* @cond: the condition
|
|
*
|
|
* This uses a compiler extension where available to indicate an unlikely
|
|
* code path and optimize appropriately; see likely() above.
|
|
*
|
|
* See Also:
|
|
* likely(), likely_stats(), COLD (compiler.h)
|
|
*
|
|
* Example:
|
|
* // Prints a warning if we overflow.
|
|
* static inline void inc_int(unsigned int *val)
|
|
* {
|
|
* (*val)++;
|
|
* if (unlikely(*val == 0))
|
|
* fprintf(stderr, "Overflow!");
|
|
* }
|
|
*/
|
|
#ifndef unlikely
|
|
#define unlikely(cond) __builtin_expect(!!(cond), 0)
|
|
#endif
|
|
#else
|
|
#ifndef likely
|
|
#define likely(cond) (!!(cond))
|
|
#endif
|
|
#ifndef unlikely
|
|
#define unlikely(cond) (!!(cond))
|
|
#endif
|
|
#endif
|
|
#else /* CCAN_LIKELY_DEBUG versions */
|
|
#define likely(cond) \
|
|
(_likely_trace(!!(cond), 1, stringify(cond), __FILE__, __LINE__))
|
|
#define unlikely(cond) \
|
|
(_likely_trace(!!(cond), 0, stringify(cond), __FILE__, __LINE__))
|
|
|
|
long _likely_trace(bool cond, bool expect,
|
|
const char *condstr,
|
|
const char *file, unsigned int line);
|
|
#endif
|
|
|
|
#ifdef CCAN_LIKELY_DEBUG
|
|
/**
|
|
* likely_stats - return description of abused likely()/unlikely()
|
|
* @min_hits: minimum number of hits
|
|
* @percent: maximum percentage correct
|
|
*
|
|
* When CCAN_LIKELY_DEBUG is defined, likely() and unlikely() trace their
|
|
* results: this causes a significant slowdown, but allows analysis of
|
|
* whether the branches are labelled correctly.
|
|
*
|
|
* This function returns a malloc'ed description of the least-correct
|
|
* usage of likely() or unlikely(). It ignores places which have been
|
|
* called less than @min_hits times, and those which were predicted
|
|
* correctly more than @percent of the time. It returns NULL when
|
|
* nothing meets those criteria.
|
|
*
|
|
* Note that this call is destructive; the returned offender is
|
|
* removed from the trace so that the next call to likely_stats() will
|
|
* return the next-worst likely()/unlikely() usage.
|
|
*
|
|
* Example:
|
|
* // Print every place hit more than twice which was wrong > 5%.
|
|
* static void report_stats(void)
|
|
* {
|
|
* #ifdef CCAN_LIKELY_DEBUG
|
|
* const char *bad;
|
|
*
|
|
* while ((bad = likely_stats(2, 95)) != NULL) {
|
|
* printf("Suspicious likely: %s", bad);
|
|
* free(bad);
|
|
* }
|
|
* #endif
|
|
* }
|
|
*/
|
|
char *likely_stats(unsigned int min_hits, unsigned int percent);
|
|
|
|
/**
|
|
* likely_stats_reset - free up memory of likely()/unlikely() branches.
|
|
*
|
|
* This can also plug memory leaks.
|
|
*/
|
|
void likely_stats_reset(void);
|
|
#endif /* CCAN_LIKELY_DEBUG */
|
|
#endif /* CCAN_LIKELY_H */
|