ITHREAD(9) | Kernel Developer's Manual | ITHREAD(9) |
ithread_add_handler
,
ithread_create
,
ithread_destroy
,
ithread_priority
,
ithread_remove_handler
,
ithread_schedule
— kernel
interrupt threads
#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);
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, or
PRIO_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_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_ENTROPY
flag is
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.
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.
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_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)); }
The ithread_add_handler
() function will
fail if:
EINVAL
]NULL
.EINVAL
]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
]The ithread_create
() function will fail
if:
EAGAIN
]KERN_MAXPROC
.EINVAL
]IT_SOFT
was specified in the
flags parameter.ENOMEM
]The ithread_destroy
() function will fail
if:
EINVAL
]NULL
.EINVAL
]The ithread_remove_handler
() function will
fail if:
EINVAL
]NULL
.The ithread_schedule
() function will fail
if:
Interrupt threads and their corresponding API first appeared in FreeBSD 5.0.
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 |