likely.h (3306B)
1 /* CC0 (Public domain) - see LICENSE file for details */ 2 #ifndef CCAN_LIKELY_H 3 #define CCAN_LIKELY_H 4 #include "config.h" 5 #include <stdbool.h> 6 7 #ifndef CCAN_LIKELY_DEBUG 8 #if HAVE_BUILTIN_EXPECT 9 /** 10 * likely - indicate that a condition is likely to be true. 11 * @cond: the condition 12 * 13 * This uses a compiler extension where available to indicate a likely 14 * code path and optimize appropriately; it's also useful for readers 15 * to quickly identify exceptional paths through functions. The 16 * threshold for "likely" is usually considered to be between 90 and 17 * 99%; marginal cases should not be marked either way. 18 * 19 * See Also: 20 * unlikely(), likely_stats() 21 * 22 * Example: 23 * // Returns false if we overflow. 24 * static inline bool inc_int(unsigned int *val) 25 * { 26 * (*val)++; 27 * if (likely(*val)) 28 * return true; 29 * return false; 30 * } 31 */ 32 #define likely(cond) __builtin_expect(!!(cond), 1) 33 34 /** 35 * unlikely - indicate that a condition is unlikely to be true. 36 * @cond: the condition 37 * 38 * This uses a compiler extension where available to indicate an unlikely 39 * code path and optimize appropriately; see likely() above. 40 * 41 * See Also: 42 * likely(), likely_stats(), COLD (compiler.h) 43 * 44 * Example: 45 * // Prints a warning if we overflow. 46 * static inline void inc_int(unsigned int *val) 47 * { 48 * (*val)++; 49 * if (unlikely(*val == 0)) 50 * fprintf(stderr, "Overflow!"); 51 * } 52 */ 53 #define unlikely(cond) __builtin_expect(!!(cond), 0) 54 #else 55 #define likely(cond) (!!(cond)) 56 #define unlikely(cond) (!!(cond)) 57 #endif 58 #else /* CCAN_LIKELY_DEBUG versions */ 59 #include <ccan/str/str.h> 60 61 #define likely(cond) \ 62 (_likely_trace(!!(cond), 1, stringify(cond), __FILE__, __LINE__)) 63 #define unlikely(cond) \ 64 (_likely_trace(!!(cond), 0, stringify(cond), __FILE__, __LINE__)) 65 66 long _likely_trace(bool cond, bool expect, 67 const char *condstr, 68 const char *file, unsigned int line); 69 /** 70 * likely_stats - return description of abused likely()/unlikely() 71 * @min_hits: minimum number of hits 72 * @percent: maximum percentage correct 73 * 74 * When CCAN_LIKELY_DEBUG is defined, likely() and unlikely() trace their 75 * results: this causes a significant slowdown, but allows analysis of 76 * whether the branches are labelled correctly. 77 * 78 * This function returns a malloc'ed description of the least-correct 79 * usage of likely() or unlikely(). It ignores places which have been 80 * called less than @min_hits times, and those which were predicted 81 * correctly more than @percent of the time. It returns NULL when 82 * nothing meets those criteria. 83 * 84 * Note that this call is destructive; the returned offender is 85 * removed from the trace so that the next call to likely_stats() will 86 * return the next-worst likely()/unlikely() usage. 87 * 88 * Example: 89 * // Print every place hit more than twice which was wrong > 5%. 90 * static void report_stats(void) 91 * { 92 * #ifdef CCAN_LIKELY_DEBUG 93 * const char *bad; 94 * 95 * while ((bad = likely_stats(2, 95)) != NULL) { 96 * printf("Suspicious likely: %s", bad); 97 * free(bad); 98 * } 99 * #endif 100 * } 101 */ 102 char *likely_stats(unsigned int min_hits, unsigned int percent); 103 104 /** 105 * likely_stats_reset - free up memory of likely()/unlikely() branches. 106 * 107 * This can also plug memory leaks. 108 */ 109 void likely_stats_reset(void); 110 #endif /* CCAN_LIKELY_DEBUG */ 111 #endif /* CCAN_LIKELY_H */