likely.h (3505B)
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 #ifndef likely 56 #define likely(cond) (!!(cond)) 57 #endif 58 #ifndef unlikely 59 #define unlikely(cond) (!!(cond)) 60 #endif 61 #endif 62 #else /* CCAN_LIKELY_DEBUG versions */ 63 #include <ccan/str/str.h> 64 65 #define likely(cond) \ 66 (_likely_trace(!!(cond), 1, stringify(cond), __FILE__, __LINE__)) 67 #define unlikely(cond) \ 68 (_likely_trace(!!(cond), 0, stringify(cond), __FILE__, __LINE__)) 69 70 long _likely_trace(bool cond, bool expect, 71 const char *condstr, 72 const char *file, unsigned int line); 73 /** 74 * likely_stats - return description of abused likely()/unlikely() 75 * @min_hits: minimum number of hits 76 * @percent: maximum percentage correct 77 * 78 * When CCAN_LIKELY_DEBUG is defined, likely() and unlikely() trace their 79 * results: this causes a significant slowdown, but allows analysis of 80 * whether the branches are labelled correctly. 81 * 82 * This function returns a malloc'ed description of the least-correct 83 * usage of likely() or unlikely(). It ignores places which have been 84 * called less than @min_hits times, and those which were predicted 85 * correctly more than @percent of the time. It returns NULL when 86 * nothing meets those criteria. 87 * 88 * Note that this call is destructive; the returned offender is 89 * removed from the trace so that the next call to likely_stats() will 90 * return the next-worst likely()/unlikely() usage. 91 * 92 * Example: 93 * // Print every place hit more than twice which was wrong > 5%. 94 * static void report_stats(void) 95 * { 96 * #ifdef CCAN_LIKELY_DEBUG 97 * const char *bad; 98 * 99 * while ((bad = likely_stats(2, 95)) != NULL) { 100 * printf("Suspicious likely: %s", bad); 101 * free(bad); 102 * } 103 * #endif 104 * } 105 */ 106 char *likely_stats(unsigned int min_hits, unsigned int percent); 107 108 /** 109 * likely_stats_reset - free up memory of likely()/unlikely() branches. 110 * 111 * This can also plug memory leaks. 112 */ 113 void likely_stats_reset(void); 114 #endif /* CCAN_LIKELY_DEBUG */ 115 #endif /* CCAN_LIKELY_H */