2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-05 00:35:33 +00:00

util: Generalize rightmost_1bit_idx(), leftmost_1bit_idx().

These functions could only work with 32-bit integers because of their
special cases for an argument of value 0.  However, none of the existing
users depended on this special case, and some of the users did try to use
these functions with 64-bit integer arguments.  Thus, this commit changes
them to support 64-bit integer arguments and drops the special cases for
zero.

This fixes a latent bug that applied rightmost_1bit_idx() to an ofpact
bitmap, which only becomes visible when an OFPACT_* with value greater than
32 is included in the bitmap.

Reported-by: Kyle Upton <kupton@baymicrosystems.com>
Reported-at: http://openvswitch.org/pipermail/dev/2015-September/060128.html
Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Ben Pfaff
2015-09-18 15:26:28 -07:00
parent b91d3d0339
commit 4ed471445e

View File

@@ -506,25 +506,20 @@ zero_rightmost_1bit(uintmax_t x)
return x & (x - 1);
}
/* Returns the index of the rightmost 1-bit in 'x' (e.g. 01011000 => 3), or 32
* if 'x' is 0.
*
* Unlike the other functions for rightmost 1-bits, this function only works
* with 32-bit integers. */
/* Returns the index of the rightmost 1-bit in 'x' (e.g. 01011000 => 3), or an
* undefined value if 'x' is 0. */
static inline int
rightmost_1bit_idx(uint32_t x)
rightmost_1bit_idx(uint64_t x)
{
return ctz32(x);
return ctz64(x);
}
/* Returns the index of the leftmost 1-bit in 'x' (e.g. 01011000 => 6), or 32
* if 'x' is 0.
*
* This function only works with 32-bit integers. */
/* Returns the index of the leftmost 1-bit in 'x' (e.g. 01011000 => 6), or an
* undefined value if 'x' is 0. */
static inline uint32_t
leftmost_1bit_idx(uint32_t x)
leftmost_1bit_idx(uint64_t x)
{
return x ? log_2_floor(x) : 32;
return log_2_floor(x);
}
/* Return a ovs_be32 prefix in network byte order with 'plen' highest bits set.