SYSINIT() fixes for Architecture Manual
Ken Smith
kensmith at cse.Buffalo.EDU
Tue Oct 14 03:48:40 UTC 2003
Murray suggested I just send this here, and he'd chime in if nobody
else feels like enough of an authority to say whether or not I'm
lying. :-)
While working on PR docs/57568 to fix the SYSINIT() examples I
decided to try and clarify a little bit what SYSINIT() is/isn't
used for. Can anyone say one way or another if I hit the target?
Thanks.
--- chapter.sgml_orig Sat Oct 11 20:07:09 2003
+++ chapter.sgml Mon Oct 13 21:23:37 2003
@@ -49,17 +49,27 @@
<para>Sysinit uses two priorities when ordering the functions for
execution. The first priority is a subsystem ID giving an
- overall order Sysinit's dispatch of functions. Current predeclared
- ID's are in <filename><sys/kernel.h></filename> in the enum
+ overall order for Sysinit's dispatch of functions. Current predeclared
+ ID's are in <filename><sys/kernel.h></filename> in the enum
list <literal>sysinit_sub_id</literal>. The second priority used
is an element order within the subsystem. Current predeclared
subsystem element orders are in
- <filename><sys/kernel.h></filename> in the enum list
+ <filename><sys/kernel.h></filename> in the enum list
<literal>sysinit_elem_order</literal>.</para>
<para>There are currently two uses for Sysinit. Function dispatch
at system startup and kernel module loads, and function dispatch
- at system shutdown and kernel module unload.</para>
+ at system shutdown and kernel module unload. Kernel subsystems
+ often use system startup Sysinits to initialize data structures,
+ for example the process scheduling subsystem uses a Sysinit to
+ initialize the run queue data structures. Device drivers
+ should avoid using <literal>SYSINIT()</literal> directly.
+ Instead drivers for real devices that are part of a bus structure
+ should use <literal>DRIVER_MODULE()</literal> to provide a
+ function that detects the device and, if it is present, initializes
+ the device. It will do a few things specific to devices and then calls
+ <literal>SYSINIT()</literal> itself. For pseudo-devices, which are
+ not part of a bus structure, use <literal>DEV_MODULE()</literal>.</para>
</sect1>
@@ -72,14 +82,14 @@
<sect3>
<title>Headers</title>
- <programlisting><sys/kernel.h></programlisting>
+ <programlisting><sys/kernel.h></programlisting>
</sect3>
<sect3>
<title>Macros</title>
<programlisting>SYSINIT(uniquifier, subsystem, order, func, ident)
- SYSUNINIT(uniquifier, subsystem, order, func, ident)</programlisting>
+SYSUNINIT(uniquifier, subsystem, order, func, ident)</programlisting>
</sect3>
</sect2>
@@ -90,21 +100,22 @@
necessary sysinit data in Sysinit's startup data set for
Sysinit to sort and dispatch a function at system startup and
module load. <literal>SYSINIT()</literal> takes a uniquifier
- that Sysinit uses identify the particular function dispatch
+ 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.
</para>
- <para>For example:</para>
+ <example>
+ <title>Example of a <literal>SYSINIT()</literal></title>
- <programlisting>#include <sys/kernel.h>
+ <programlisting>#include <sys/kernel.h>
void foo_null(void *unused)
{
foo_doo();
}
-SYSINIT(foo_null, SI_SUB_FOO, SI_ORDER_FOO, NULL);
+SYSINIT(foo, SI_SUB_FOO, SI_ORDER_FOO, foo_null, NULL);
struct foo foo_voodoo = {
FOO_VOODOO;
@@ -115,26 +126,34 @@
struct foo *foo = (struct foo *)vdata;
foo_data(foo);
}
-SYSINIT(foo_arg, SI_SUB_FOO, SI_ORDER_FOO, foo_voodoo);
- </programlisting>
+SYSINIT(foo, SI_SUB_FOO, SI_ORDER_FOO, foo_arg, foo_voodoo);
+ </programlisting>
+ </example>
+
+ <para>Note that <literal>SI_SUB_FOO</literal> and
+ <literal>SI_ORDER_FOO</literal> need to be in the
+ <literal>sysinit_sub_id</literal> and
+ <literal>sysinit_elem_order</literal> enum's as mentioned above.
+ Either use existing ones or add your own to the enum's.</para>
</sect2>
<sect2>
<title>Shutdown</title>
- <para>The <literal>SYSUNINIT()</literal> macro behaves similarly
+ <para>The <literal>SYSUNINIT()</literal> macro behaves similar
to the <literal>SYSINIT()</literal> macro except that it adds
the Sysinit data to Sysinit's shutdown data set.</para>
- <para>For example:</para>
+ <example>
+ <title>Example of a <literal>SYSUNINIT()</literal></title>
- <programlisting>#include <sys/kernel.h>
+ <programlisting>#include <sys/kernel.h>
void foo_cleanup(void *unused)
{
foo_kill();
}
-SYSUNINIT(foo_cleanup, SI_SUB_FOO, SI_ORDER_FOO, NULL);
+SYSUNINIT(foo, SI_SUB_FOO, SI_ORDER_FOO, foo_cleanup, NULL);
struct foo_stack foo_stack = {
FOO_STACK_VOODOO;
@@ -143,8 +162,9 @@
void foo_flush(void *vdata)
{
}
-SYSUNINIT(foo_flush, SI_SUB_FOO, SI_ORDER_FOO, foo_stack);
- </programlisting>
+SYSUNINIT(foo, SI_SUB_FOO, SI_ORDER_FOO, foo_flush, foo_stack);
+ </programlisting>
+ </example>
</sect2>
</sect1>
</chapter>
--
Ken Smith
- From there to here, from here to | kensmith at cse.buffalo.edu
there, funny things are everywhere. |
- Theodore Geisel |
More information about the freebsd-doc
mailing list