<commit_before>
VLIB (Vector Processing Library)
================================

The files associated with vlib are located in the ./src/{vlib,
vlibapi, vlibmemory} folders. These libraries provide vector
processing support including graph-node scheduling, reliable multicast
support, ultra-lightweight cooperative multi-tasking threads, a CLI,
plug in .DLL support, physical memory and Linux epoll support. Parts of
this library embody US Patent 7,961,636.

Init function discovery
-----------------------

vlib applications register for various \[initialization\] events by
placing structures and \_\_attribute\_\_((constructor)) functions into
the image. At appropriate times, the vlib framework walks
constructor-generated singly-linked structure lists, calling the
indicated functions. vlib applications create graph nodes, add CLI
functions, start cooperative multi-tasking threads, etc. etc. using this
mechanism.

vlib applications invariably include a number of VLIB\_INIT\_FUNCTION
(my\_init\_function) macros.

Each init / configure / etc. function has the return type clib\_error\_t
\*. Make sure that the function returns 0 if all is well, otherwise the
framework will announce an error and exit.

vlib applications must link against vppinfra, and often link against
other libraries such as VNET. In the latter case, it may be necessary to
explicitly reference symbol(s) otherwise large portions of the library
may be AWOL at runtime.

Node Graph Initialization
-------------------------

vlib packet-processing applications invariably define a set of graph
nodes to process packets.

One constructs a vlib\_node\_registration\_t, most often via the
VLIB\_REGISTER\_NODE macro. At runtime, the framework processes the set
of such registrations into a directed graph. It is easy enough to add
nodes to the graph at runtime. The framework does not support removing
nodes.
<commit_msg>DOC ONLY: document VLIB_INIT_FUNCTION scheme<commit_after>
VLIB (Vector Processing Library)
================================

The files associated with vlib are located in the ./src/{vlib,
vlibapi, vlibmemory} folders. These libraries provide vector
processing support including graph-node scheduling, reliable multicast
support, ultra-lightweight cooperative multi-tasking threads, a CLI,
plug in .DLL support, physical memory and Linux epoll support. Parts of
this library embody US Patent 7,961,636.

Init function discovery
-----------------------

vlib applications register for various \[initialization\] events by
placing structures and \_\_attribute\_\_((constructor)) functions into
the image. At appropriate times, the vlib framework walks
constructor-generated singly-linked structure lists, performs a
topological sort based on specified constraints, and calls the
indicated functions. Vlib applications create graph nodes, add CLI
functions, start cooperative multi-tasking threads, etc. etc. using
this mechanism.

vlib applications invariably include a number of VLIB\_INIT\_FUNCTION
(my\_init\_function) macros.

Each init / configure / etc. function has the return type clib\_error\_t
\*. Make sure that the function returns 0 if all is well, otherwise the
framework will announce an error and exit.

vlib applications must link against vppinfra, and often link against
other libraries such as VNET. In the latter case, it may be necessary to
explicitly reference symbol(s) otherwise large portions of the library
may be AWOL at runtime.

### Init function construction and constraint specification

It's easy to add an init function:

```
   static clib_error_t *my_init_function (vlib_main_t *vm)
   {
      /* ... initialize things ... */

      return 0; // or return clib_error_return (0, "BROKEN!");
   }
   VLIB_INIT_FUNCTION(my_init_function);
```

As given, my_init_function will be executed "at some point," but with
no ordering guarantees.

Specifying ordering constraints is easy:

```
   VLIB_INIT_FUNCTION(my_init_function) =
   {
      .runs_before = VLIB_INITS("we_run_before_function_1",
                                "we_run_before_function_2"),
      .runs_after = VLIB_INITS("we_run_after_function_1",
                               "we_run_after_function_2),
    };
```

It's also easy to specify bulk ordering constraints of the form "a
then b then c then d":

```
   VLIB_INIT_FUNCTION(my_init_function) =
   {
      .init_order = VLIB_INITS("a", "b", "c", "d"),
   };
```

It's OK to specify all three sorts of ordering constraints for a
single init function, although it's hard to imagine why it would be
necessary.


Node Graph Initialization
-------------------------

vlib packet-processing applications invariably define a set of graph
nodes to process packets.

One constructs a vlib\_node\_registration\_t, most often via the
VLIB\_REGISTER\_NODE macro. At runtime, the framework processes the set
of such registrations into a directed graph. It is easy enough to add
nodes to the graph at runtime. The framework does not support removing
nodes.

{'fraction_non_alphanumeric': 0.08992589625475667, 'fraction_numerical': 0.004406168636090527, 'mean_word_length': 3.994, 'pattern_counts': {'":': 1, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3816793', 'n_tokens_mistral': 1313, 'n_tokens_neox': 1238, 'n_words': 600}