[ovs-dev] [bug10576 5/5] learn: Make it possible to parse "load" actions wider than 64 bits.
Ethan Jackson
ethan at nicira.com
Sat Apr 14 06:34:51 UTC 2012
Sounds good, thanks.
Ethan
On Fri, Apr 13, 2012 at 21:15, Ben Pfaff <blp at nicira.com> wrote:
> On Fri, Apr 13, 2012 at 06:06:47PM -0700, Ethan Jackson wrote:
>> I would think that bitwise_is_all_zeros() belongs in it's own patch
>> just line bitwise_one(), but I don't think it matters much.
>
> I was lazy.
>
> I broke this out as a new patch just after patch 1, and I added a test.
> Good thing, too, because bitwise_is_all_zeros() was buggy.
>
> Here's the new patch. The incremental for the last patch should be
> obvious (just don't add the new code).
>
> --8<--------------------------cut here-------------------------->8--
>
> From: Ben Pfaff <blp at nicira.com>
> Date: Fri, 13 Apr 2012 21:12:37 -0700
> Subject: [PATCH] util: New function bitwise_is_all_zeros().
>
> Signed-off-by: Ben Pfaff <blp at nicira.com>
> ---
> lib/util.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++
> lib/util.h | 2 +
> tests/test-util.c | 47 ++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 105 insertions(+), 0 deletions(-)
>
> diff --git a/lib/util.c b/lib/util.c
> index 14a97f2..f9880f3 100644
> --- a/lib/util.c
> +++ b/lib/util.c
> @@ -913,6 +913,62 @@ bitwise_one(void *dst_, unsigned int dst_len, unsigned dst_ofs,
> }
> }
>
> +/* Scans the 'n_bits' bits starting from bit 'dst_ofs' in 'dst' for 1-bits.
> + * Returns false if any 1-bits are found, otherwise true. '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
> + */
> +bool
> +bitwise_is_all_zeros(const void *p_, unsigned int len, unsigned int ofs,
> + unsigned int n_bits)
> +{
> + const uint8_t *p = p_;
> +
> + if (!n_bits) {
> + return true;
> + }
> +
> + p += len - (ofs / 8 + 1);
> + ofs %= 8;
> +
> + if (ofs) {
> + unsigned int chunk = MIN(n_bits, 8 - ofs);
> +
> + if (*p & (((1 << chunk) - 1) << ofs)) {
> + return false;
> + }
> +
> + n_bits -= chunk;
> + if (!n_bits) {
> + return true;
> + }
> +
> + p--;
> + }
> +
> + while (n_bits >= 8) {
> + if (*p) {
> + return false;
> + }
> + n_bits -= 8;
> + p--;
> + }
> +
> + if (n_bits && *p & ((1 << n_bits) - 1)) {
> + return false;
> + }
> +
> + return true;
> +}
> +
> /* 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 63f4a24..e5d1c3a 100644
> --- a/lib/util.h
> +++ b/lib/util.h
> @@ -230,6 +230,8 @@ void bitwise_zero(void *dst_, unsigned int dst_len, unsigned dst_ofs,
> unsigned int n_bits);
> void bitwise_one(void *dst_, unsigned int dst_len, unsigned dst_ofs,
> unsigned int n_bits);
> +bool bitwise_is_all_zeros(const void *, unsigned int len, unsigned int 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 ed98295..23b86e8 100644
> --- a/tests/test-util.c
> +++ b/tests/test-util.c
> @@ -184,6 +184,51 @@ check_bitwise_one(void)
> }
> }
>
> +static void
> +check_bitwise_is_all_zeros(void)
> +{
> + int n_loops;
> +
> + n_loops = 0;
> + for (n_loops = 0; n_loops < 100; n_loops++) {
> + ovs_be64 x = htonll(0);
> + int i;
> +
> + for (i = 0; i < 64; i++) {
> + ovs_be64 bit;
> + int ofs, n;
> +
> + /* Change a random 0-bit into a 1-bit. */
> + do {
> + bit = htonll(UINT64_C(1) << (random_uint32() % 64));
> + } while (x & bit);
> + x |= bit;
> +
> + for (ofs = 0; ofs < 64; ofs++) {
> + for (n = 0; n <= 64 - ofs; n++) {
> + bool expect;
> + bool answer;
> +
> + expect = (n == 64
> + ? x == 0
> + : !(x & htonll(((UINT64_C(1) << n) - 1)
> + << ofs)));
> + answer = bitwise_is_all_zeros(&x, sizeof x, ofs, n);
> + if (expect != answer) {
> + fprintf(stderr,
> + "bitwise_is_all_zeros(0x%016"PRIx64",8,%d,%d "
> + "returned %s instead of %s\n",
> + ntohll(x), ofs, n,
> + answer ? "true" : "false",
> + expect ? "true" : "false");
> + abort();
> + }
> + }
> + }
> + }
> + }
> +}
> +
> int
> main(void)
> {
> @@ -213,5 +258,7 @@ main(void)
>
> check_bitwise_one();
>
> + check_bitwise_is_all_zeros();
> +
> return 0;
> }
> --
> 1.7.2.5
>
More information about the dev
mailing list