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