[PATCH 01/18] include: introduce byte counting functions.
Peter Hutterer
peter.hutterer at who-t.net
Wed Jul 8 17:04:59 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>
---
include/misc.h | 30 ++++++++++++++++++++++++++++++
test/input.c | 39 +++++++++++++++++++++++++++++++++++++++
2 files changed, 69 insertions(+), 0 deletions(-)
diff --git a/include/misc.h b/include/misc.h
index 61dd947..1838cbd 100644
--- a/include/misc.h
+++ b/include/misc.h
@@ -180,6 +180,36 @@ 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 needed 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 bb32491..83eddb1 100644
--- a/test/input.c
+++ b/test/input.c
@@ -678,6 +678,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);
@@ -688,6 +726,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