summaryrefslogtreecommitdiffstats
path: root/src/vlib
diff options
context:
space:
mode:
authorDamjan Marion <damarion@cisco.com>2018-05-28 21:26:47 +0200
committerFlorin Coras <florin.coras@gmail.com>2018-05-29 17:00:26 +0000
commit812b32dd8f637118bf65de2cdff0e95b421a963b (patch)
tree184d57889b841958875d57c6503d8bfb96cdaec7 /src/vlib
parent04e0bb2ff0f39dab45da01ecdbc7914035a36897 (diff)
Add VLIB_NODE_FN() macro to simplify multiversioning of node functions
Change-Id: Ibab5e27277f618ceb2d543b9d6a1a5f191e7d1db Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'src/vlib')
-rw-r--r--src/vlib/node.c20
-rw-r--r--src/vlib/node.h28
2 files changed, 48 insertions, 0 deletions
diff --git a/src/vlib/node.c b/src/vlib/node.c
index 17dd2ea87d4..cc1732bb90d 100644
--- a/src/vlib/node.c
+++ b/src/vlib/node.c
@@ -324,6 +324,26 @@ register_node (vlib_main_t * vm, vlib_node_registration_t * r)
ASSERT (VLIB_NODE_TYPE_INTERNAL == zero.type);
}
+ if (r->node_fn_registrations)
+ {
+ vlib_node_fn_registration_t *fnr = r->node_fn_registrations;
+ int priority = -1;
+
+ /* to avoid confusion, please remove ".function " statiement from
+ CLIB_NODE_REGISTRATION() if using function function candidates */
+ ASSERT (r->function == 0);
+
+ while (fnr)
+ {
+ if (fnr->priority > priority)
+ {
+ priority = fnr->priority;
+ r->function = fnr->function;
+ }
+ fnr = fnr->next_registration;
+ }
+ }
+
ASSERT (r->function != 0);
n = clib_mem_alloc_no_fail (sizeof (n[0]));
diff --git a/src/vlib/node.h b/src/vlib/node.h
index 7177bebeffb..67eaea3f0e8 100644
--- a/src/vlib/node.h
+++ b/src/vlib/node.h
@@ -75,11 +75,21 @@ typedef enum
VLIB_N_NODE_TYPE,
} vlib_node_type_t;
+typedef struct _vlib_node_fn_registration
+{
+ vlib_node_function_t *function;
+ int priority;
+ struct _vlib_node_fn_registration *next_registration;
+} vlib_node_fn_registration_t;
+
typedef struct _vlib_node_registration
{
/* Vector processing function for this node. */
vlib_node_function_t *function;
+ /* Node function candidate registration with priority */
+ vlib_node_fn_registration_t *node_fn_registrations;
+
/* Node name. */
char *name;
@@ -160,6 +170,24 @@ static void __vlib_rm_node_registration_##x (void) \
} \
__VA_ARGS__ vlib_node_registration_t x
+#define VLIB_NODE_FN(node) \
+uword CLIB_MARCH_SFX (node##_fn)(); \
+static vlib_node_fn_registration_t \
+ CLIB_MARCH_SFX(node##_fn_registration) = \
+ { .function = &CLIB_MARCH_SFX (node##_fn), }; \
+ \
+static void __clib_constructor \
+CLIB_MARCH_SFX (node##_multiarch_register) (void) \
+{ \
+ extern vlib_node_registration_t node; \
+ vlib_node_fn_registration_t *r; \
+ r = & CLIB_MARCH_SFX (node##_fn_registration); \
+ r->priority = CLIB_MARCH_FN_PRIORITY(); \
+ r->next_registration = node.node_fn_registrations; \
+ node.node_fn_registrations = r; \
+} \
+uword CLIB_CPU_OPTIMIZED CLIB_MARCH_SFX (node##_fn)
+
#if CLIB_DEBUG > 0
#define VLIB_NODE_FUNCTION_CLONE_TEMPLATE(arch, fn)
#define VLIB_NODE_FUNCTION_MULTIARCH_CLONE(fn)