From 180a60bc879ab0554297bc08a7a0b9274b119b55 Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Mon, 29 Dec 2014 17:51:36 +0100 Subject: macro: add DIV_ROUND_UP() This macro calculates A / B but rounds up instead of down. We explicitly do *NOT* use: (A + B - 1) / A as it suffers from an integer overflow, even though the passed values are properly tested against overflow. Our test-cases show this behavior. Instead, we use: A / B + !!(A % B) Note that on "Real CPUs" this does *NOT* result in two divisions. Instead, instructions like idivl@x86 provide both, the quotient and the remainder. Therefore, both algorithms should perform equally well (I didn't verify this, though). --- src/shared/macro.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'src/shared/macro.h') diff --git a/src/shared/macro.h b/src/shared/macro.h index 548294e47b..6a57428244 100644 --- a/src/shared/macro.h +++ b/src/shared/macro.h @@ -197,6 +197,17 @@ static inline unsigned long ALIGN_POWER2(unsigned long u) { UNIQ_T(X,xq); \ }) +/* [(x + y - 1) / y] suffers from an integer overflow, even though the + * computation should be possible in the given type. Therefore, we use + * [x / y + !!(x % y)]. Note that on "Real CPUs" a division returns both the + * quotient and the remainder, so both should be equally fast. */ +#define DIV_ROUND_UP(_x, _y) \ + __extension__ ({ \ + const typeof(_x) __x = (_x); \ + const typeof(_y) __y = (_y); \ + (__x / __y + !!(__x % __y)); \ + }) + #define assert_se(expr) \ do { \ if (_unlikely_(!(expr))) \ -- cgit v1.2.3-54-g00ecf