diff --git a/src/bits.c b/src/bits.c index 48391fb..6b7a351 100644 --- a/src/bits.c +++ b/src/bits.c @@ -7,6 +7,8 @@ #include #include +#define noreturn __attribute__((noreturn)) +#define noinline __attribute__((noinline)) #define BUFFER_SIZE 4096 #define IGNORE(param) do { (void)(param); } while(0) #define LIKELY(ex) __builtin_expect((ex), 1) @@ -39,19 +41,21 @@ static void pbits(char out[restrict 8], unsigned char byte, const char bit[stati //TODO: In explicitly threaded version, we can use an atomic (atomic.h) 64-bit integer `store()` to output those 8 bytes in `out`, which will be re-cast as `uint64_t out[restrict 1]` } -// Light assertion (likely to succeed) -static inline int lcheck(int val, const char* msg) +static noinline noreturn void die(const char* msg) { - LIF(val) return val; fprintf(stderr, "error: %s\n", msg); exit(1); } +// Light assertion (likely to succeed) +//TODO: Where do we have the __builtin_expect here? On the inside or the outside of the expression? Or both? For now, both. +#define Lcheck(value, message) (LIKELY(LIKELY(!!(value)) ? 1 : (die(message), 0))) + int main(int argc, char **argv) { IGNORE(argc); - const char* mask = argv[1] && lcheck(argv[1][0] && argv[1][1], "expected 2 character mask") ? argv[1] : "01"; + const char* mask = argv[1] && Lcheck(argv[1][0] && argv[1][1], "expected 2 character mask") ? argv[1] : "01"; unsigned char buf[BUFFER_SIZE]; char tbuf[BUFFER_SIZE * 8]; size_t bsz = BUFFER_SIZE;