odp-util: Avoid branch in odp_actions_add().
authorBen Pfaff <blp@nicira.com>
Wed, 4 Aug 2010 17:50:40 +0000 (10:50 -0700)
committerBen Pfaff <blp@nicira.com>
Fri, 13 Aug 2010 17:06:11 +0000 (10:06 -0700)
I have no idea why, but the test and branch in odp_actions_add() has always
bugged me.  This commit eliminates it.

lib/odp-util.c
lib/odp-util.h
ofproto/ofproto.c

index ccf05c6..442c939 100644 (file)
@@ -30,13 +30,10 @@ union odp_action *
 odp_actions_add(struct odp_actions *actions, uint16_t type)
 {
     union odp_action *a;
-    if (actions->n_actions < MAX_ODP_ACTIONS) {
-        a = &actions->actions[actions->n_actions++];
-    } else {
-        COVERAGE_INC(odp_overflow);
-        actions->n_actions = MAX_ODP_ACTIONS + 1;
-        a = &actions->actions[MAX_ODP_ACTIONS - 1];
-    }
+    size_t idx;
+
+    idx = actions->n_actions++ & (MAX_ODP_ACTIONS - 1);
+    a = &actions->actions[idx];
     memset(a, 0, sizeof *a);
     a->type = type;
     return a;
index dc9a43d..420bde5 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdint.h>
 #include "openflow/openflow.h"
 #include "openvswitch/datapath-protocol.h"
+#include "util.h"
 
 struct ds;
 
@@ -29,6 +30,9 @@ struct ds;
  * memory, so there is no point in allocating more than that.  */
 enum { MAX_ODP_ACTIONS = 4096 / sizeof(union odp_action) };
 
+/* odp_actions_add() assumes that MAX_ODP_ACTIONS is a power of 2. */
+BUILD_ASSERT_DECL(IS_POW2(MAX_ODP_ACTIONS));
+
 struct odp_actions {
     size_t n_actions;
     union odp_action actions[MAX_ODP_ACTIONS];
index d74f321..91ff023 100644 (file)
@@ -2772,6 +2772,7 @@ xlate_actions(const union ofp_action *in, size_t n_in,
         *nf_output_iface = ctx.nf_output_iface;
     }
     if (odp_actions_overflow(out)) {
+        COVERAGE_INC(odp_overflow);
         odp_actions_init(out);
         return ofp_mkerr(OFPET_BAD_ACTION, OFPBAC_TOO_MANY);
     }