I might as well update this one too, so here's an incremental that
updates a comment and adds a tests, followed by a replacement commit.
diff --git a/lib/util.c b/lib/util.c
index 694ba04..dfdc51e 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -804,9 +804,13 @@ bitwise_copy(const void *src_, unsigned int src_len,
unsigned int src_ofs,
}
/* Zeros the 'n_bits' bits starting from bit 'dst_ofs' in 'dst'. 'dst' is
- * 'dst_len' bytes long. Bit 0 of 'dst' is the bit with value 1 in dst[dst_len
- * - 1], bit 1 is the bit with value 2, bit 8 is the bit with value 1 in
- * dst[dst_len - 2], and so on.
+ * 'dst_len' bytes long.
+ *
+ * If you consider all of 'dst' to be a single unsigned integer in network byte
+ * order, then bit N is the bit with value 2**N. That is, bit 0 is the bit
+ * with value 1 in dst[dst_len - 1], bit 1 is the bit with value 2, bit 2 is
+ * the bit with value 4, ..., bit 8 is the bit with value 1 in dst[dst_len -
+ * 2], and so on.
*
* Required invariant:
* dst_ofs + n_bits <= dst_len * 8
diff --git a/tests/test-util.c b/tests/test-util.c
index 45ea8f2..82d0861 100644
--- a/tests/test-util.c
+++ b/tests/test-util.c
@@ -102,6 +102,47 @@ check_bitwise_copy(void)
}
}
+static void
+check_bitwise_zero(void)
+{
+ unsigned int n_loops;
+ int dst_ofs;
+ int n_bits;
+
+ n_loops = 0;
+ for (n_bits = 0; n_bits <= 64; n_bits++) {
+ for (dst_ofs = 0; dst_ofs < 64 - n_bits; dst_ofs++) {
+ ovs_be64 dst = htonll(random_uint64());
+ ovs_be64 orig_dst = dst;
+ ovs_be64 expect;
+
+ if (n_bits == 64) {
+ expect = htonll(0);
+ } else {
+ uint64_t mask = (UINT64_C(1) << n_bits) - 1;
+ expect = orig_dst & ~htonll(mask << dst_ofs);
+ }
+
+ bitwise_zero(&dst, sizeof dst, dst_ofs, n_bits);
+ if (expect != dst) {
+ fprintf(stderr,"bitwise_zero(0x%016"PRIx64",8,%d, %d) "
+ "yielded 0x%016"PRIx64" "
+ "instead of the expected 0x%016"PRIx64"\n",
+ ntohll(orig_dst), dst_ofs,
+ n_bits,
+ ntohll(dst), ntohll(expect));
+ abort();
+ }
+
+ n_loops++;
+ }
+ }
+
+ if (n_loops != 64 * (64 + 1) / 2) {
+ abort();
+ }
+}
+
int
main(void)
{
@@ -127,5 +168,7 @@ main(void)
check_bitwise_copy();
+ check_bitwise_zero();
+
return 0;
}
--8<--------------------------cut here-------------------------->8--
From: Ben Pfaff <[email protected]>
Date: Tue, 17 Jan 2012 16:53:29 -0800
Subject: [PATCH] util: New function bitwise_zero().
Signed-off-by: Ben Pfaff <[email protected]>
---
lib/util.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
lib/util.h | 4 +++-
tests/test-util.c | 43 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 94 insertions(+), 1 deletions(-)
diff --git a/lib/util.c b/lib/util.c
index 811902a..dfdc51e 100644
--- a/lib/util.c
+++ b/lib/util.c
@@ -803,6 +803,54 @@ bitwise_copy(const void *src_, unsigned int src_len,
unsigned int src_ofs,
}
}
+/* Zeros the 'n_bits' bits starting from bit 'dst_ofs' in 'dst'. 'dst' is
+ * 'dst_len' bytes long.
+ *
+ * If you consider all of 'dst' to be a single unsigned integer in network byte
+ * order, then bit N is the bit with value 2**N. That is, bit 0 is the bit
+ * with value 1 in dst[dst_len - 1], bit 1 is the bit with value 2, bit 2 is
+ * the bit with value 4, ..., bit 8 is the bit with value 1 in dst[dst_len -
+ * 2], and so on.
+ *
+ * Required invariant:
+ * dst_ofs + n_bits <= dst_len * 8
+ */
+void
+bitwise_zero(void *dst_, unsigned int dst_len, unsigned dst_ofs,
+ unsigned int n_bits)
+{
+ uint8_t *dst = dst_;
+
+ if (!n_bits) {
+ return;
+ }
+
+ dst += dst_len - (dst_ofs / 8 + 1);
+ dst_ofs %= 8;
+
+ if (dst_ofs) {
+ unsigned int chunk = MIN(n_bits, 8 - dst_ofs);
+
+ *dst &= ~(((1 << chunk) - 1) << dst_ofs);
+
+ n_bits -= chunk;
+ if (!n_bits) {
+ return;
+ }
+
+ dst--;
+ }
+
+ while (n_bits >= 8) {
+ *dst-- = 0;
+ n_bits -= 8;
+ }
+
+ if (n_bits) {
+ *dst &= ~((1 << n_bits) - 1);
+ }
+}
+
/* Copies the 'n_bits' low-order bits of 'value' into the 'n_bits' bits
* starting at bit 'dst_ofs' in 'dst', which is 'dst_len' bytes long.
*
diff --git a/lib/util.h b/lib/util.h
index c8eb004..d504f2f 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks.
+ * Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -211,6 +211,8 @@ bool is_all_ones(const uint8_t *, size_t);
void bitwise_copy(const void *src, unsigned int src_len, unsigned int src_ofs,
void *dst, unsigned int dst_len, unsigned int dst_ofs,
unsigned int n_bits);
+void bitwise_zero(void *dst_, unsigned int dst_len, unsigned dst_ofs,
+ unsigned int n_bits);
void bitwise_put(uint64_t value,
void *dst, unsigned int dst_len, unsigned int dst_ofs,
unsigned int n_bits);
diff --git a/tests/test-util.c b/tests/test-util.c
index 45ea8f2..82d0861 100644
--- a/tests/test-util.c
+++ b/tests/test-util.c
@@ -102,6 +102,47 @@ check_bitwise_copy(void)
}
}
+static void
+check_bitwise_zero(void)
+{
+ unsigned int n_loops;
+ int dst_ofs;
+ int n_bits;
+
+ n_loops = 0;
+ for (n_bits = 0; n_bits <= 64; n_bits++) {
+ for (dst_ofs = 0; dst_ofs < 64 - n_bits; dst_ofs++) {
+ ovs_be64 dst = htonll(random_uint64());
+ ovs_be64 orig_dst = dst;
+ ovs_be64 expect;
+
+ if (n_bits == 64) {
+ expect = htonll(0);
+ } else {
+ uint64_t mask = (UINT64_C(1) << n_bits) - 1;
+ expect = orig_dst & ~htonll(mask << dst_ofs);
+ }
+
+ bitwise_zero(&dst, sizeof dst, dst_ofs, n_bits);
+ if (expect != dst) {
+ fprintf(stderr,"bitwise_zero(0x%016"PRIx64",8,%d, %d) "
+ "yielded 0x%016"PRIx64" "
+ "instead of the expected 0x%016"PRIx64"\n",
+ ntohll(orig_dst), dst_ofs,
+ n_bits,
+ ntohll(dst), ntohll(expect));
+ abort();
+ }
+
+ n_loops++;
+ }
+ }
+
+ if (n_loops != 64 * (64 + 1) / 2) {
+ abort();
+ }
+}
+
int
main(void)
{
@@ -127,5 +168,7 @@ main(void)
check_bitwise_copy();
+ check_bitwise_zero();
+
return 0;
}
--
1.7.2.5
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev