mirror of
https://github.com/openvswitch/ovs
synced 2025-09-01 14:55:18 +00:00
bitmap: Convert single bitmap functions to 64-bit.
Currently the functions to set, clear, and iterate over bitmaps only operate over 32 bit values. If we convert them to handle 64 bit bitmaps, they can be used in more places. Suggested-by: Ben Pfaff <blp@nicira.com> Signed-off-by: Jesse Gross <jesse@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
10
lib/bitmap.h
10
lib/bitmap.h
@@ -269,13 +269,13 @@ bitmap_is_all_zeros(const unsigned long *bitmap, size_t n)
|
|||||||
#define BITMAP_FOR_EACH_1(IDX, SIZE, BITMAP) \
|
#define BITMAP_FOR_EACH_1(IDX, SIZE, BITMAP) \
|
||||||
BITMAP_FOR_EACH_1_RANGE(IDX, 0, SIZE, BITMAP)
|
BITMAP_FOR_EACH_1_RANGE(IDX, 0, SIZE, BITMAP)
|
||||||
|
|
||||||
/* More efficient access to a map of single ulong. */
|
/* More efficient access to a map of single ullong. */
|
||||||
#define ULONG_FOR_EACH_1(IDX, MAP) \
|
#define ULLONG_FOR_EACH_1(IDX, MAP) \
|
||||||
for (unsigned long map__ = (MAP); \
|
for (uint64_t map__ = (MAP); \
|
||||||
map__ && (((IDX) = raw_ctz(map__)), true); \
|
map__ && (((IDX) = raw_ctz(map__)), true); \
|
||||||
map__ = zero_rightmost_1bit(map__))
|
map__ = zero_rightmost_1bit(map__))
|
||||||
|
|
||||||
#define ULONG_SET0(MAP, OFFSET) ((MAP) &= ~(1UL << (OFFSET)))
|
#define ULLONG_SET0(MAP, OFFSET) ((MAP) &= ~(1ULL << (OFFSET)))
|
||||||
#define ULONG_SET1(MAP, OFFSET) ((MAP) |= 1UL << (OFFSET))
|
#define ULLONG_SET1(MAP, OFFSET) ((MAP) |= 1ULL << (OFFSET))
|
||||||
|
|
||||||
#endif /* bitmap.h */
|
#endif /* bitmap.h */
|
||||||
|
10
lib/cmap.c
10
lib/cmap.c
@@ -390,13 +390,13 @@ cmap_find_batch(const struct cmap *cmap, unsigned long map,
|
|||||||
uint32_t c1s[sizeof map * CHAR_BIT];
|
uint32_t c1s[sizeof map * CHAR_BIT];
|
||||||
|
|
||||||
/* Compute hashes and prefetch 1st buckets. */
|
/* Compute hashes and prefetch 1st buckets. */
|
||||||
ULONG_FOR_EACH_1(i, map) {
|
ULLONG_FOR_EACH_1(i, map) {
|
||||||
h1s[i] = rehash(impl, hashes[i]);
|
h1s[i] = rehash(impl, hashes[i]);
|
||||||
b1s[i] = &impl->buckets[h1s[i] & impl->mask];
|
b1s[i] = &impl->buckets[h1s[i] & impl->mask];
|
||||||
OVS_PREFETCH(b1s[i]);
|
OVS_PREFETCH(b1s[i]);
|
||||||
}
|
}
|
||||||
/* Lookups, Round 1. Only look up at the first bucket. */
|
/* Lookups, Round 1. Only look up at the first bucket. */
|
||||||
ULONG_FOR_EACH_1(i, map) {
|
ULLONG_FOR_EACH_1(i, map) {
|
||||||
uint32_t c1;
|
uint32_t c1;
|
||||||
const struct cmap_bucket *b1 = b1s[i];
|
const struct cmap_bucket *b1 = b1s[i];
|
||||||
const struct cmap_node *node;
|
const struct cmap_node *node;
|
||||||
@@ -414,12 +414,12 @@ cmap_find_batch(const struct cmap *cmap, unsigned long map,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* Found. */
|
/* Found. */
|
||||||
ULONG_SET0(map, i); /* Ignore this on round 2. */
|
ULLONG_SET0(map, i); /* Ignore this on round 2. */
|
||||||
OVS_PREFETCH(node);
|
OVS_PREFETCH(node);
|
||||||
nodes[i] = node;
|
nodes[i] = node;
|
||||||
}
|
}
|
||||||
/* Round 2. Look into the 2nd bucket, if needed. */
|
/* Round 2. Look into the 2nd bucket, if needed. */
|
||||||
ULONG_FOR_EACH_1(i, map) {
|
ULLONG_FOR_EACH_1(i, map) {
|
||||||
uint32_t c2;
|
uint32_t c2;
|
||||||
const struct cmap_bucket *b2 = b2s[i];
|
const struct cmap_bucket *b2 = b2s[i];
|
||||||
const struct cmap_node *node;
|
const struct cmap_node *node;
|
||||||
@@ -445,7 +445,7 @@ cmap_find_batch(const struct cmap *cmap, unsigned long map,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Not found. */
|
/* Not found. */
|
||||||
ULONG_SET0(result, i); /* Fix the result. */
|
ULLONG_SET0(result, i); /* Fix the result. */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
found:
|
found:
|
||||||
|
@@ -3916,14 +3916,14 @@ dpcls_lookup(const struct dpcls *cls, const struct netdev_flow_key keys[],
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Compute hashes for the remaining keys. */
|
/* Compute hashes for the remaining keys. */
|
||||||
ULONG_FOR_EACH_1(i, map) {
|
ULLONG_FOR_EACH_1(i, map) {
|
||||||
hashes[i] = netdev_flow_key_hash_in_mask(&mkeys[i],
|
hashes[i] = netdev_flow_key_hash_in_mask(&mkeys[i],
|
||||||
&subtable->mask);
|
&subtable->mask);
|
||||||
}
|
}
|
||||||
/* Lookup. */
|
/* Lookup. */
|
||||||
map = cmap_find_batch(&subtable->rules, map, hashes, nodes);
|
map = cmap_find_batch(&subtable->rules, map, hashes, nodes);
|
||||||
/* Check results. */
|
/* Check results. */
|
||||||
ULONG_FOR_EACH_1(i, map) {
|
ULLONG_FOR_EACH_1(i, map) {
|
||||||
struct dpcls_rule *rule;
|
struct dpcls_rule *rule;
|
||||||
|
|
||||||
CMAP_NODE_FOR_EACH (rule, cmap_node, nodes[i]) {
|
CMAP_NODE_FOR_EACH (rule, cmap_node, nodes[i]) {
|
||||||
@@ -3932,7 +3932,7 @@ dpcls_lookup(const struct dpcls *cls, const struct netdev_flow_key keys[],
|
|||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ULONG_SET0(map, i); /* Did not match. */
|
ULLONG_SET0(map, i); /* Did not match. */
|
||||||
next:
|
next:
|
||||||
; /* Keep Sparse happy. */
|
; /* Keep Sparse happy. */
|
||||||
}
|
}
|
||||||
|
@@ -127,7 +127,7 @@ check_cmap(struct cmap *cmap, const int values[], size_t n,
|
|||||||
}
|
}
|
||||||
map = cmap_find_batch(cmap, map, hashes, nodes);
|
map = cmap_find_batch(cmap, map, hashes, nodes);
|
||||||
|
|
||||||
ULONG_FOR_EACH_1(k, map) {
|
ULLONG_FOR_EACH_1(k, map) {
|
||||||
struct element *e;
|
struct element *e;
|
||||||
|
|
||||||
CMAP_NODE_FOR_EACH (e, node, nodes[k]) {
|
CMAP_NODE_FOR_EACH (e, node, nodes[k]) {
|
||||||
@@ -435,7 +435,7 @@ find_batch(const struct cmap *cmap, const int value)
|
|||||||
map >>= BITMAP_ULONG_BITS - i; /* Clear excess bits. */
|
map >>= BITMAP_ULONG_BITS - i; /* Clear excess bits. */
|
||||||
map = cmap_find_batch(cmap, map, hashes, nodes);
|
map = cmap_find_batch(cmap, map, hashes, nodes);
|
||||||
|
|
||||||
ULONG_FOR_EACH_1(i, map) {
|
ULLONG_FOR_EACH_1(i, map) {
|
||||||
struct element *e;
|
struct element *e;
|
||||||
|
|
||||||
CMAP_NODE_FOR_EACH (e, node, nodes[i]) {
|
CMAP_NODE_FOR_EACH (e, node, nodes[i]) {
|
||||||
|
Reference in New Issue
Block a user