[PATCH] include: introduce byte counting functions.

Peter Hutterer peter.hutterer at who-t.net
Sun Jun 28 20:09:57 PDT 2009


This patch adds the following three functions:
 num_bytes_for_bits(bits) - the number of bytes needed to hold 'bits'
 num_dwords_for_bytes(bytes) - the number of 4-byte units to hold 'bytes'
 pad_to_dwords(bytes) - the closest multiple of 4 equal to or larger than
                        'bytes'.

All three operations are common in protocol processing and currently the
server has ((foo + 7)/8 + 3)/4 operations all over the place. A common set
of functions reduce the error rate of these (albeit simple) calculations and
improve readability of the code.

The functions do not check for overflow.

Signed-off-by: Peter Hutterer <peter.hutterer at who-t.net>
---
This is the same patch as previously sent, except that the macros are now
inline functions. The places where these are called are not performance
criticial anyway, so the inlines may just be a tad better.
http://lists.x.org/archives/xorg-devel/2009-June/001131.html

 include/misc.h |   29 +++++++++++++++++++++++++++++
 test/input.c   |   39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+), 0 deletions(-)

diff --git a/include/misc.h b/include/misc.h
index 61dd947..bd0d2eb 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -180,6 +180,35 @@ typedef struct _xReq *xReqPtr;
 
 #endif
 
+/**
+ * Calculate the number of bytes needed to hold bits.
+ * @param bits The minimum number of bits needed.
+ * @return The number of bytes needed to hold bits.
+ */
+static inline int
+num_bytes_for_bits(const int bits) {
+    return ((bits + 7) >> 3);
+}
+/**
+ * Calculate the number of 4-byte units needed to hold the given number of
+ * bytes.
+ * @param bytes The minimum number of bytes needed.
+ * @return The number of 4-byte units neede to hold bytes.
+ */
+static inline int
+num_dwords_for_bytes(const int bytes) {
+    return (((bytes) + 3) >> 2);
+}
+/**
+ * Calculate the number of bytes (in multiples of 4) needed to hold bytes.
+ * @param bytes The minimum number of bytes needed.
+ * @return The closest multiple of 4 that is equal or higher than bytes.
+ */
+static inline int
+pad_to_dwords(const int bytes) {
+    return (((bytes) + 3) & ~3);
+}
+
 /* some macros to help swap requests, replies, and events */
 
 #define LengthRestB(stuff) \
diff --git a/test/input.c b/test/input.c
index b80e1f5..c7a30fc 100644
--- a/test/input.c
+++ b/test/input.c
@@ -677,6 +677,44 @@ static void dix_grab_matching(void)
     g_assert(rc == TRUE);
 }
 
+static void include_byte_padding_macros(void)
+{
+    int i;
+    g_test_message("Testing num_bytes_for_bits()");
+
+    /* the macros don't provide overflow protection */
+    for (i = 0; i < INT_MAX - 7; i++)
+    {
+        int expected_bytes;
+        expected_bytes = (i + 7)/8;
+
+        g_assert(num_bytes_for_bits(i) >= i/8);
+        g_assert((num_bytes_for_bits(i) * 8) - i <= 7);
+    }
+
+    g_test_message("Testing num_dwords_for_bytes()");
+    for (i = 0; i < INT_MAX - 3; i++)
+    {
+        int expected_4byte;
+        expected_4byte = (i + 3)/4;
+
+        g_assert(num_dwords_for_bytes(i) <= i);
+        g_assert((num_dwords_for_bytes(i) * 4) - i <= 3);
+    }
+
+    g_test_message("Testing pad_to_dwords");
+
+    for (i = 0; i < INT_MAX - 3; i++)
+    {
+        int expected_bytes;
+        expected_bytes = ((i + 3)/4) * 4;
+
+        g_assert(pad_to_dwords(i) >= i);
+        g_assert(pad_to_dwords(i) - i <= 3);
+    }
+
+}
+
 int main(int argc, char** argv)
 {
     g_test_init(&argc, &argv,NULL);
@@ -687,6 +725,7 @@ int main(int argc, char** argv)
     g_test_add_func("/dix/input/check-grab-values", dix_check_grab_values);
     g_test_add_func("/dix/input/xi2-struct-sizes", xi2_struct_sizes);
     g_test_add_func("/dix/input/grab_matching", dix_grab_matching);
+    g_test_add_func("/include/byte_padding_macros", include_byte_padding_macros);
 
     return g_test_run();
 }
-- 
1.6.3.rc1.2.g0164.dirty


More information about the xorg-devel mailing list