<sect1><title>Scheduling Tasks</title>

	<indexterm><primary>scheduling tasks</primary></indexterm>
	<indexterm><primary>tasks</primary><secondary>scheduling</secondary></indexterm>
	<indexterm><primary>housekeeping</primary></indexterm>
	<indexterm><primary>crontab</primary></indexterm>

	<para>Very often, we have <quote>housekeeping</quote> tasks which have to be done at a certain time, or every so often. If the
	task is to be done by a process, we do it by putting it in the <filename>crontab</filename> file.  If the task is to be done
	by a kernel module, we have two possibilities.  The first is to put a process in the <filename>crontab</filename> file which
	will wake up the module by a system call when necessary, for example by opening a file. This is terribly inefficient, however
	-- we run a new process off of <filename>crontab</filename>, read a new executable to memory, and all this just to wake up a
	kernel module which is in memory anyway.</para>

	<indexterm><primary>task</primary></indexterm>
	<indexterm><primary>workqueue_struct</primary></indexterm>
	<indexterm><primary>queue_delayed_work</primary></indexterm>

	<para>Instead of doing that, we can create a function that will be called once for every timer interrupt.  The way we do this
	is we create a task, held in a <structname>workqueue_struct</structname> structure, which will hold a pointer to the function.  Then,
	we use <function>queue_delayed_work</function> to put that task on a task list called <structname>my_workqueue</structname>, 
	which is the list of tasks to be executed on the next timer interrupt.  Because we want the function to keep on being executed,
	we need to put it back on <structname>my_workqueue</structname> whenever it is called, for the next timer interrupt.</para>

	<indexterm><primary>rmmod</primary></indexterm>
	<indexterm><primary>reference count</primary></indexterm>
	<indexterm><primary>module_cleanup</primary></indexterm>

	<para>There's one more point we need to remember here.  When a module is removed by <command>rmmod</command>, first its
	reference count is checked.  If it is zero, <function>module_cleanup</function> is called.  Then, the module is removed from
	memory with all its functions. Things need to be shut down properly, or bad things will happen. See the code below how
	this can be done in a safe way.  </para>

	<indexterm><primary>source file</primary><secondary>sched.c</secondary></indexterm>

<example><title>sched.c</title><programlisting><inlinegraphic fileref="lkmpg-examples/11-SchedulingTasks/sched.c" format="linespecific"/></inlinegraphic></programlisting></example>
</sect1>


<!--
vim: tw=128
-->
