From 1f2e8d2d85ab7dac37653c4f9d034ce452f289ca Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Tue, 7 Oct 2014 12:59:14 -0700 Subject: [PATCH] flow: Clean up MINIFLOW_FOR_EACH_IN_MAP. It seemed awkward to have declarations outside the for loop. This may also be a little faster because it avoids some calls to count_1bits(). The idea for that change is due to Jarno Rajahalme . Signed-off-by: Ben Pfaff Acked-by: Jarno Rajahalme --- lib/flow.h | 52 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/lib/flow.h b/lib/flow.h index 7da4e4223..2b053da47 100644 --- a/lib/flow.h +++ b/lib/flow.h @@ -507,31 +507,45 @@ flow_get_next_in_map(const struct flow *flow, uint64_t map, uint32_t *value) (((UINT64_C(1) << FLOW_U32_SIZE(FIELD)) - 1) \ << (offsetof(struct flow, FIELD) / 4)) -static inline uint32_t -mf_get_next_in_map(uint64_t *fmap, uint64_t rm1bit, const uint32_t **fp, - uint32_t *value) -{ - *value = 0; - if (*fmap & rm1bit) { - uint64_t trash = *fmap & (rm1bit - 1); +struct mf_for_each_in_map_aux { + const uint32_t *values; + uint64_t fmap; + uint64_t map; +}; - if (trash) { - *fmap -= trash; - *fp += count_1bits(trash); +static inline bool +mf_get_next_in_map(struct mf_for_each_in_map_aux *aux, uint32_t *value) +{ + if (aux->map) { + uint64_t rm1bit = rightmost_1bit(aux->map); + aux->map -= rm1bit; + + if (aux->fmap & rm1bit) { + /* Advance 'aux->values' to point to the value for 'rm1bit'. */ + uint64_t trash = aux->fmap & (rm1bit - 1); + if (trash) { + aux->fmap -= trash; + aux->values += count_1bits(trash); + } + + /* Retrieve the value for 'rm1bit' then advance past it. */ + aux->fmap -= rm1bit; + *value = *aux->values++; + } else { + *value = 0; } - *value = **fp; + return true; + } else { + return false; } - return rm1bit != 0; } -/* Iterate through all miniflow u32 values specified by 'MAP'. - * This works as the first statement in a block.*/ +/* Iterate through all miniflow u32 values specified by 'MAP'. */ #define MINIFLOW_FOR_EACH_IN_MAP(VALUE, FLOW, MAP) \ - const uint32_t *fp_ = miniflow_get_u32_values(FLOW); \ - uint64_t rm1bit_, fmap_, map_; \ - for (fmap_ = (FLOW)->map, map_ = (MAP), rm1bit_ = rightmost_1bit(map_); \ - mf_get_next_in_map(&fmap_, rm1bit_, &fp_, &(VALUE)); \ - map_ -= rm1bit_, rm1bit_ = rightmost_1bit(map_)) + for (struct mf_for_each_in_map_aux aux__ \ + = { miniflow_get_u32_values(FLOW), (FLOW)->map, MAP }; \ + mf_get_next_in_map(&aux__, &(VALUE)); \ + ) /* Get the value of 'FIELD' of an up to 4 byte wide integer type 'TYPE' of * a miniflow. */ -- 2.39.2