[ovs-dev] [threads v2 09/13] util: New macros ROUND_UP_POW2, ROUND_DOWN_POW2.

Ben Pfaff blp at nicira.com
Wed Jul 17 20:36:24 UTC 2013


Thank you.  I pushed this to master.

On Wed, Jul 17, 2013 at 12:30:33PM -0700, Alex Wang wrote:
> Looks good to me, thanks.
> 
> 
> On Fri, Jul 12, 2013 at 2:54 PM, Ben Pfaff <blp at nicira.com> wrote:
> 
> > Signed-off-by: Ben Pfaff <blp at nicira.com>
> > ---
> >  lib/util.h        |   19 +++++++++++++++
> >  tests/library.at  |    2 +
> >  tests/test-util.c |   65
> > +++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 86 insertions(+), 0 deletions(-)
> >
> > diff --git a/lib/util.h b/lib/util.h
> > index ae8bfd7..2159594 100644
> > --- a/lib/util.h
> > +++ b/lib/util.h
> > @@ -108,6 +108,25 @@ is_pow2(uintmax_t x)
> >      return IS_POW2(x);
> >  }
> >
> > +/* Returns X rounded up to a power of 2.  X must be a constant
> > expression. */
> > +#define ROUND_UP_POW2(X) RUP2__(X)
> > +#define RUP2__(X) (RUP2_1(X) + 1)
> > +#define RUP2_1(X) (RUP2_2(X) | (RUP2_2(X) >> 16))
> > +#define RUP2_2(X) (RUP2_3(X) | (RUP2_3(X) >> 8))
> > +#define RUP2_3(X) (RUP2_4(X) | (RUP2_4(X) >> 4))
> > +#define RUP2_4(X) (RUP2_5(X) | (RUP2_5(X) >> 2))
> > +#define RUP2_5(X) (RUP2_6(X) | (RUP2_6(X) >> 1))
> > +#define RUP2_6(X) ((X) - 1)
> > +
> > +/* Returns X rounded down to a power of 2.  X must be a constant
> > expression. */
> > +#define ROUND_DOWN_POW2(X) RDP2__(X)
> > +#define RDP2__(X) (RDP2_1(X) - (RDP2_1(X) >> 1))
> > +#define RDP2_1(X) (RDP2_2(X) | (RDP2_2(X) >> 16))
> > +#define RDP2_2(X) (RDP2_3(X) | (RDP2_3(X) >> 8))
> > +#define RDP2_3(X) (RDP2_4(X) | (RDP2_4(X) >> 4))
> > +#define RDP2_4(X) (RDP2_5(X) | (RDP2_5(X) >> 2))
> > +#define RDP2_5(X) (      (X) | (      (X) >> 1))
> > +
> >  #ifndef MIN
> >  #define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
> >  #endif
> > diff --git a/tests/library.at b/tests/library.at
> > index f84a55b..92ec49b 100644
> > --- a/tests/library.at
> > +++ b/tests/library.at
> > @@ -112,6 +112,8 @@ AT_CLEANUP
> >  m4_foreach(
> >    [testname],
> >    [[ctz],
> > +   [round_up_pow2],
> > +   [round_down_pow2],
> >     [popcount],
> >     [log_2_floor],
> >     [bitwise_copy],
> > diff --git a/tests/test-util.c b/tests/test-util.c
> > index 5afe2f7..6bf8ed5 100644
> > --- a/tests/test-util.c
> > +++ b/tests/test-util.c
> > @@ -90,6 +90,69 @@ test_ctz(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
> >      check_ctz(0, 32);
> >  }
> >
> > +/* Returns a random number in the range 'min'...'max' inclusive. */
> > +static uint32_t
> > +random_in_range(uint32_t min, uint32_t max)
> > +{
> > +    return min == max ? min : min + random_range(max - min + 1);
> > +}
> > +
> > +static void
> > +check_rup2(uint32_t x, int n)
> > +{
> > +    uint32_t rup2 = ROUND_UP_POW2(x);
> > +    if (rup2 != n) {
> > +        fprintf(stderr, "ROUND_UP_POW2(%#"PRIx32") is %#"PRIx32" "
> > +                "but should be %#"PRIx32"\n", x, rup2, n);
> > +        abort();
> > +    }
> > +}
> > +
> > +static void
> > +test_round_up_pow2(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
> > +{
> > +    int n;
> > +
> > +    for (n = 0; n < 32; n++) {
> > +        /* Min, max value for which ROUND_UP_POW2 should yield (1 << n).
> > */
> > +        uint32_t min = ((1u << n) >> 1) + 1;
> > +        uint32_t max = 1u << n;
> > +
> > +        check_rup2(min, 1u << n);
> > +        check_rup2(max, 1u << n);
> > +        check_rup2(random_in_range(min, max), 1u << n);
> > +    }
> > +    check_rup2(0, 0);
> > +}
> > +
> > +static void
> > +check_rdp2(uint32_t x, int n)
> > +{
> > +    uint32_t rdp2 = ROUND_DOWN_POW2(x);
> > +    if (rdp2 != n) {
> > +        fprintf(stderr, "ROUND_DOWN_POW2(%#"PRIx32") is %#"PRIx32" "
> > +                "but should be %#"PRIx32"\n", x, rdp2, n);
> > +        abort();
> > +    }
> > +}
> > +
> > +static void
> > +test_round_down_pow2(int argc OVS_UNUSED, char *argv[] OVS_UNUSED)
> > +{
> > +    int n;
> > +
> > +    for (n = 0; n < 32; n++) {
> > +        /* Min, max value for which ROUND_DOWN_POW2 should yield (1 <<
> > n). */
> > +        uint32_t min = 1u << n;
> > +        uint32_t max = ((1u << n) << 1) - 1;
> > +
> > +        check_rdp2(min, 1u << n);
> > +        check_rdp2(max, 1u << n);
> > +        check_rdp2(random_in_range(min, max), 1u << n);
> > +    }
> > +    check_rdp2(0, 0);
> > +}
> > +
> >  static void
> >  shuffle(unsigned int *p, size_t n)
> >  {
> > @@ -346,6 +409,8 @@ test_assert(int argc OVS_UNUSED, char *argv[]
> > OVS_UNUSED)
> >
> >  static const struct command commands[] = {
> >      {"ctz", 0, 0, test_ctz},
> > +    {"round_up_pow2", 0, 0, test_round_up_pow2},
> > +    {"round_down_pow2", 0, 0, test_round_down_pow2},
> >      {"popcount", 0, 0, test_popcount},
> >      {"log_2_floor", 0, 0, test_log_2_floor},
> >      {"bitwise_copy", 0, 0, test_bitwise_copy},
> > --
> > 1.7.2.5
> >
> > _______________________________________________
> > dev mailing list
> > dev at openvswitch.org
> > http://openvswitch.org/mailman/listinfo/dev
> >



More information about the dev mailing list