Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/sys Fix C arithmetic quirks in roundup2 and avoid multip...



details:   https://anonhg.NetBSD.org/src/rev/9a6cb8cdd687
branches:  trunk
changeset: 807721:9a6cb8cdd687
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Mon Apr 20 15:18:59 2015 +0000

description:
Fix C arithmetic quirks in roundup2 and avoid multiple evaluation.

Add rounddown2.

Discussed on tech-kern a while ago:

https://mail-index.netbsd.org/tech-kern/2013/03/21/msg015131.html

diffstat:

 sys/sys/param.h |  22 ++++++++++++++++++++--
 1 files changed, 20 insertions(+), 2 deletions(-)

diffs (36 lines):

diff -r 8f1af99fa026 -r 9a6cb8cdd687 sys/sys/param.h
--- a/sys/sys/param.h   Mon Apr 20 14:10:31 2015 +0000
+++ b/sys/sys/param.h   Mon Apr 20 15:18:59 2015 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: param.h,v 1.470 2015/04/13 21:32:04 riastradh Exp $    */
+/*     $NetBSD: param.h,v 1.471 2015/04/20 15:18:59 riastradh Exp $    */
 
 /*-
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -374,7 +374,25 @@
 #endif
 #define        roundup(x, y)   ((((x)+((y)-1))/(y))*(y))
 #define        rounddown(x,y)  (((x)/(y))*(y))
-#define        roundup2(x, m)  (((x) + (m) - 1) & ~((m) - 1))
+
+/*
+ * Rounding to powers of two.  The naive definitions of roundup2 and
+ * rounddown2,
+ *
+ *     #define roundup2(x,m)   (((x) + ((m) - 1)) & ~((m) - 1))
+ *     #define rounddown2(x,m) ((x) & ~((m) - 1)),
+ *
+ * exhibit a quirk of integer arithmetic in C because the complement
+ * happens in the type of m, not in the type of x.  So if unsigned int
+ * is 32-bit, and m is an unsigned int while x is a uint64_t, then
+ * roundup2 and rounddown2 would have the unintended effect of clearing
+ * the upper 32 bits of the result(!).  These definitions avoid the
+ * pitfalls of C arithmetic depending on the types of x and m, and
+ * additionally avoid multiply evaluating their arguments.
+ */
+#define        roundup2(x,m)   ((((x) - 1) | ((m) - 1)) + 1)
+#define        rounddown2(x,m) ((x) & ~((__typeof__(x))((m) - 1)))
+
 #define        powerof2(x)     ((((x)-1)&(x))==0)
 
 /*



Home | Main Index | Thread Index | Old Index