perf: Fix buggy bitops
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 8 Sep 2017 14:51:53 +0000 (10:51 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 8 Sep 2017 17:49:51 +0000 (13:49 -0400)
The moral of the story here is to not rewrite your own bitops.  If you
don't like the existing ones, then fix them.

This:

static inline void ros_set_bit(void *addr, size_t nbit)
{
((uint8_t *) addr)[nbit % CHAR_BIT] |= 1 << (nbit % CHAR_BIT);
}

is just plain wrong.  The first '%' should be a '/'.  Select the byte with
/, then select the bit with %.

Oh, and test the damn thing once or twice.

I noticed this since perf was provisioning extra cores.  For instance, if
you asked for -C 4, you'd get 4 and 12.

As Ron put it: 'Oh fun!!'.  =)

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
tools/dev-util/perf/akaros.h

index 98c9779..fe68464 100644 (file)
 #include <stdio.h>
 #include <limits.h>
 #include <parlib/parlib.h>
+#include <parlib/bitmask.h>
 
-#define CORE_SET_SIZE DIV_ROUND_UP(MAX_NUM_CORES, CHAR_BIT)
+#define CORE_SET_SIZE BYTES_FOR_BITMASK(MAX_NUM_CORES)
 
 /* Not using sched.h CPU set because that file has definitions for a large
  * number of APIs Akaros does not support.
  * Making Akaros core_set.h visible in userslace might be a cleaner approach.
  */
 struct core_set {
-       uint8_t core_set[CORE_SET_SIZE];
+       DECL_BITMASK(core_set, MAX_NUM_CORES);
 };
 
 void ros_get_low_latency_core_set(struct core_set *cores);
@@ -34,15 +35,15 @@ void ros_or_core_sets(struct core_set *dcs, const struct core_set *scs);
 
 static inline void ros_set_bit(void *addr, size_t nbit)
 {
-       ((uint8_t *) addr)[nbit % CHAR_BIT] |= 1 << (nbit % CHAR_BIT);
+       SET_BITMASK_BIT(addr, nbit);
 }
 
 static inline void ros_clear_bit(void *addr, size_t nbit)
 {
-       ((uint8_t *) addr)[nbit % CHAR_BIT] &= ~(1 << (nbit % CHAR_BIT));
+       CLR_BITMASK_BIT(addr, nbit);
 }
 
 static inline bool ros_get_bit(const void *addr, size_t nbit)
 {
-       return ((const uint8_t *) addr)[nbit % CHAR_BIT] & (1 << (nbit % CHAR_BIT));
+       return GET_BITMASK_BIT(addr, nbit);
 }