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 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 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.
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_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_EXCLflag 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 processes under execution
      would be exceeded. The limit is given by the sysctl(3)
      MIB variable KERN_MAXPROC.
- [EINVAL]
- A flag other than IT_SOFTwas 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:
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.
| August 25, 2006 | Debian |