The SYSINIT()
macro creates the
necessary SYSINIT data in SYSINIT's startup data set for
SYSINIT to sort and dispatch a function at system startup and
module load. SYSINIT()
takes a uniquifier
that SYSINIT uses to identify the particular function dispatch
data, the subsystem order, the subsystem element order, the
function to call, and the data to pass the function. All
functions must take a constant pointer argument.
SYSINIT()
#include <sys/kernel.h> void foo_null(void *unused) { foo_doo(); } SYSINIT(foo, SI_SUB_FOO, SI_ORDER_FOO, foo_null, NULL); struct foo foo_voodoo = { FOO_VOODOO; } void foo_arg(void *vdata) { struct foo *foo = (struct foo *)vdata; foo_data(foo); } SYSINIT(bar, SI_SUB_FOO, SI_ORDER_FOO, foo_arg, &foo_voodoo);
Note that SI_SUB_FOO
and
SI_ORDER_FOO
need to be in the
sysinit_sub_id
and
sysinit_elem_order
enum's as mentioned
above. Either use existing ones or add your own to the
enum's. You can also use math for fine-tuning the order
a SYSINIT will run in. This example shows a SYSINIT that
needs to be run just barely before the SYSINIT's that
handle tuning kernel parameters.
SYSINIT()
Orderstatic void mptable_register(void *dummy __unused) { apic_register_enumerator(&mptable_enumerator); } SYSINIT(mptable_register, SI_SUB_TUNABLES - 1, SI_ORDER_FIRST, mptable_register, NULL);
The SYSUNINIT()
macro behaves similarly
to the SYSINIT()
macro except that it adds
the SYSINIT data to SYSINIT's shutdown data set.
SYSUNINIT()
#include <sys/kernel.h> void foo_cleanup(void *unused) { foo_kill(); } SYSUNINIT(foobar, SI_SUB_FOO, SI_ORDER_FOO, foo_cleanup, NULL); struct foo_stack foo_stack = { FOO_STACK_VOODOO; } void foo_flush(void *vdata) { } SYSUNINIT(barfoo, SI_SUB_FOO, SI_ORDER_FOO, foo_flush, &foo_stack);
All FreeBSD documents are available for download at http://ftp.FreeBSD.org/pub/FreeBSD/doc/
Questions that are not answered by the
documentation may be
sent to <[email protected]>.
Send questions about this document to <[email protected]>.