Provided by: freebsd-manpages_6.2-1_all bug
 

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 inter‐
      rupt 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 func‐
      tion 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 sort‐
      ing 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 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 hard‐
      ware 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 soft‐
      ware interrupt handlers.
      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.
 
      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.
      kthread(9), swi(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 inter‐
      rupt thread.  There should be a separate struct isrc that contains a vec‐
      tor number, enable and disable functions, etc. that an ithread holds a
      reference to.