From 812b32dd8f637118bf65de2cdff0e95b421a963b Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Mon, 28 May 2018 21:26:47 +0200 Subject: Add VLIB_NODE_FN() macro to simplify multiversioning of node functions Change-Id: Ibab5e27277f618ceb2d543b9d6a1a5f191e7d1db Signed-off-by: Damjan Marion --- src/vlib/node.c | 20 ++++++++++++++++++++ src/vlib/node.h | 28 ++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) (limited to 'src/vlib') 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) -- cgit 1.2.3-korg