damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

likely.h (3502B)


      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 */