ithread(9)
NAME
- ithread_add_handler, ithread_create, ithread_destroy,
- ithread_priority,
ithread_remove_handler, ithread_schedule - kernel interrupt - threads
SYNOPSIS
#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 han
- dlers when
triggered by either a hardware or software interrupt. Each - interrupt
handler has a name, handler function, handler argument, pri - ority, 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 cur - rently for
ithread_create() is IT_SOFT to specify that this interrupt - thread is a
software interrupt. The enable and disable arguments speci - fy 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 ar - guments 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 de - stroyed 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 pro - vide 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 argu - ment can be
used to specify properties of this handler as defined in 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 in
- terrupt 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 IN - TR_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 trig - gers.
Presently, the INTR_FAST and INTR_ENTROPY flags are not - valid for software interrupt handlers.
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, driv- er_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, han - dler, arg, pri + PI_SOFT,
- flags, cookiep));
- }
ERRORS
The ithread_add_handler() function will fail if:
- [EINVAL] Any of the ithread, handler, or name ar
- guments 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.
- The ithread_create() function will fail if:
- [EAGAIN] The system-imposed limit on the total
- number of pro
- cesses 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.
- The ithread_destroy() function will fail if:
- [EINVAL] The ithread argument is NULL.
- [EINVAL] The interrupt thread pointed to by
- ithread has at
- least one handler.
- The ithread_remove_handler() function will fail if:
- [EINVAL] The cookie argument is NULL.
- The ithread_schedule() function will fail if:
- [EINVAL] The ithread argument is NULL.
- [EINVAL] The interrupt thread pointed to by
- ithread has no
- interrupt handlers.
SEE ALSO
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. - BSD February 10, 2001