table of contents
ITHREAD(9) | Kernel Developer's Manual | ITHREAD(9) |
NAME¶
ithread_add_handler, ithread_create, ithread_destroy, ithread_priority, ithread_remove_handler, ithread_schedule — kernel interrupt threadsSYNOPSIS¶
#include <sys/param.h>#include <sys/bus.h>
#include <sys/interrupt.h> int
ithread_add_handler(struct ithd *ithread, const char *name, driver_intr_t handler, void *arg, u_char pri, enum intr_type flags, void **cookiep); int
ithread_create(struct ithd **ithread, int vector, int flags, void (*disable)(int), void (*enable)(int), const char *fmt, ...); int
ithread_destroy(struct ithd *ithread); u_char
ithread_priority(enum intr_type flags); int
ithread_remove_handler(void *cookie); int
ithread_schedule(struct ithd *ithread, int do_switch);
DESCRIPTION¶
Interrupt threads are kernel threads that run a list of handlers when triggered by either a hardware or software interrupt. Each interrupt handler has a name, handler function, handler argument, priority, and various flags. Each interrupt thread maintains a list of handlers sorted by priority. This results in higher priority handlers being executed prior to lower priority handlers. Each thread assumes the priority of its highest priority handler for its process priority, orPRIO_MAX
if it has no handlers.
Interrupt threads are also associated with a single interrupt source,
represented as a vector number.
The ithread_create() function creates a new interrupt thread.
The ithread argument points to an struct
ithd pointer that will point to the newly created thread upon success.
The vector argument specifies the interrupt source to
associate this thread with. The flags argument is a mask
of properties of this thread. The only valid flag currently for
ithread_create() is IT_SOFT
to
specify that this interrupt thread is a software interrupt. The
enable and disable arguments
specify optional functions used to enable and disable this interrupt thread's
interrupt source. The functions receive the vector corresponding to the
thread's interrupt source as their only argument. The remaining arguments form
a printf(9) argument list that is used to build the base
name of the new ithread. The full name of an interrupt thread is formed by
concatenating the base name of an interrupt thread with the names of all of
its interrupt handlers.
The ithread_destroy() function destroys a previously created
interrupt thread by releasing its resources and arranging for the backing
kernel thread to terminate. An interrupt thread can only be destroyed if it
has no handlers remaining.
The ithread_add_handler() function adds a new handler to an
existing interrupt thread specified by ithread. The
name argument specifies a name for this handler. The
handler and arg arguments provide
the function to execute for this handler and an argument to pass to it. The
pri argument specifies the priority of this handler and
is used both in sorting it in relation to the other handlers for this thread
and to specify the priority of the backing kernel thread. The
flags argument can be used to specify properties of this
handler as defined in <sys/bus.h>.
If cookiep is not NULL
, then it
will be assigned a cookie that can be used later to remove this handler.
The ithread_remove_handler() removes a handler from an
interrupt thread. The cookie argument specifies the
handler to remove from its thread.
The ithread_schedule() function schedules an interrupt thread
to run. If the do_switch argument is non-zero and the
interrupt thread is idle, then a context switch will be forced after putting
the interrupt thread on the run queue.
The ithread_priority() function translates the
INTR_TYPE_*
interrupt flags into interrupt handler
priorities.
The interrupt flags not related to the type of a particular interrupt
(INTR_TYPE_*
) can be used to specify additional
properties of both hardware and software interrupt handlers. The
INTR_EXCL
flag specifies that this handler cannot
share an interrupt thread with another handler. The
INTR_FAST
flag specifies that when this handler is
executed, it should be run immediately rather than being run asynchronously
when its interrupt thread is scheduled to run. The
INTR_FAST
flag implies
INTR_EXCL
. The INTR_MPSAFE
flag specifies that this handler is MP safe in that it does not need the Giant
mutex to be held while it is executed. The
INTR_ENTROPY
flag specifies that the interrupt source
this handler is tied to is a good source of entropy, and thus that entropy
should be gathered when an interrupt from the handler's source triggers.
Presently, the INTR_FAST
and
INTR_ENTROPY
flags are not valid for software
interrupt handlers.
It is not permitted to sleep in an interrupt thread; hence, any memory or zone
allocations in an interrupt thread should be specified with the
M_NOWAIT
flag set. Any allocation errors must be
handled thereafter.
RETURN VALUES¶
The ithread_add_handler(), ithread_create(), ithread_destroy(), ithread_remove_handler(), and ithread_schedule() functions return zero on success and non-zero on failure. The ithread_priority() function returns a process priority corresponding to the passed in interrupt flags.EXAMPLES¶
The swi_add() function demonstrates the use of ithread_create() and ithread_add_handler().int swi_add(struct ithd **ithdp, const char *name, driver_intr_t handler, void *arg, int pri, enum intr_type flags, void **cookiep) { struct proc *p; struct ithd *ithd; int error; if (flags & (INTR_FAST | INTR_ENTROPY)) return (EINVAL); ithd = (ithdp != NULL) ? *ithdp : NULL; if (ithd != NULL) { if ((ithd->it_flags & IT_SOFT) == 0) return(EINVAL); } else { error = ithread_create(&ithd, pri, IT_SOFT, NULL, NULL, "swi%d:", pri); if (error) return (error); if (ithdp != NULL) *ithdp = ithd; } return (ithread_add_handler(ithd, name, handler, arg, pri + PI_SOFT, flags, cookiep)); }
ERRORS¶
The ithread_add_handler() function will fail if:- [
EINVAL
] - Any of the ithread,
handler, or name arguments are
NULL
. - [
EINVAL
] - The
INTR_EXCL
flag is specified and the interrupt thread ithread already has at least one handler, or the interrupt thread ithread already has an exclusive handler. - [
ENOMEM
] - Could not allocate needed memory for this handler.
- [
EAGAIN
] - The system-imposed limit on the total number of processes
under execution would be exceeded. The limit is given by the
sysctl(3) MIB variable
KERN_MAXPROC
. - [
EINVAL
] - A flag other than
IT_SOFT
was specified in the flags parameter. - [
ENOMEM
] - Could not allocate needed memory for this interrupt thread.
- [
EINVAL
] - The ithread argument is
NULL
. - [
EINVAL
] - The interrupt thread pointed to by ithread has at least one handler.
- [
EINVAL
] - The cookie argument is
NULL
.
- [
EINVAL
] - The ithread argument is
NULL
. - [
EINVAL
] - The interrupt thread pointed to by ithread has no interrupt handlers.
SEE ALSO¶
kthread(9), malloc(9), swi(9), uma(9)HISTORY¶
Interrupt threads and their corresponding API first appeared in FreeBSD 5.0.BUGS¶
Currently struct ithd represents both an interrupt source and an interrupt thread. There should be a separate struct isrc that contains a vector number, enable and disable functions, etc. that an ithread holds a reference to.August 25, 2006 | Debian |