diff options
author | Damjan Marion <damarion@cisco.com> | 2018-05-28 21:26:47 +0200 |
---|---|---|
committer | Florin Coras <florin.coras@gmail.com> | 2018-05-29 17:00:26 +0000 |
commit | 812b32dd8f637118bf65de2cdff0e95b421a963b (patch) | |
tree | 184d57889b841958875d57c6503d8bfb96cdaec7 /src/vlib | |
parent | 04e0bb2ff0f39dab45da01ecdbc7914035a36897 (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.c | 20 | ||||
-rw-r--r-- | src/vlib/node.h | 28 |
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) |