| THREADPOOL(9) | Kernel Developer's Manual | THREADPOOL(9) | 
threadpool —
#include <sys/threadpool.h>
typedef void threadpool_job_fn_t(struct threadpool_job *);
int
  
  threadpool_get(struct
    threadpool **poolp, pri_t
    pri);
void
  
  threadpool_put(struct
    threadpool *pool, pri_t
    pri);
int
  
  threadpool_percpu_get(struct
    threadpool_percpu **pool_percpup,
    pri_t pri);
void
  
  threadpool_percpu_put(struct
    threadpool_percpu *pool_percpu,
    pri_t pri);
struct threadpool *
  
  threadpool_percpu_ref(struct
    threadpool_percpu *pool);
struct threadpool *
  
  threadpool_percpu_ref_remote(struct
    threadpool_percpu *pool,
    struct cpu_info *ci);
void
  
  threadpool_job_init(struct
    threadpool_job *job,
    threadpool_job_fn_t fn,
    kmutex_t *interlock,
    const char *fmt,
    ...);
void
  
  threadpool_job_destroy(struct
    threadpool_job *job);
void
  
  threadpool_job_done(struct
    threadpool_job *job);
void
  
  threadpool_schedule_job(struct
    threadpool *pool, struct
    threadpool_job *job);
void
  
  threadpool_cancel_job(struct
    threadpool *pool, struct
    threadpool_job *job);
bool
  
  threadpool_cancel_job_async(struct
    threadpool *pool, struct
    threadpool_job *job);
threadpool abstraction is provided to share a pool
  of kthread(9) kernel threads
  for medium- to long-term actions, called jobs, which can be scheduled from
  contexts that do not allow sleeping.
For each priority level, there is one unbound thread pool, and one
    collection of per-CPU thread pools. Access to the unbound thread pools is
    provided by threadpool_get() and
    threadpool_put(). Access to the per-CPU thread pools
    is provided by threadpool_percpu_get() and
    threadpool_percpu_put().
Job state is stored in the threadpool_job
    structure. Callers of the threadpool abstraction
    must allocate memory for threadpool_job structures,
    but should consider them opaque, and should not inspect or copy them. Each
    job represented by a threadpool_job structure will be
    run only once at a time, until the action associated with it calls
    threadpool_job_done().
Jobs are run in thread context and may take arbitrarily long to run or sleep arbitrarily long.
threadpool_get(poolp,
    pri)May sleep.
threadpool_put(pool,
    pri)threadpool_get() to obtain
      pool.
    May sleep.
Do not use threadpool_put() with
        thread pools obtained from
        threadpool_percpu_ref() or
        threadpool_percpu_ref_remote().
threadpool_percpu_get(pool_percpup,
    pri)Use threadpool_percpu_ref() or
        threadpool_percpu_ref_remote() with it to get at
        the thread pool for a particular CPU.
May sleep.
threadpool_percpu_put(pool_percpu,
    pri)May sleep.
threadpool_percpu_ref(pool_percpu)The resulting thread pool pointer is stable until
        pool_percpu is released with
        threadpool_percpu_put(). Using it to schedule or
        cancel a job does not require being on the same CPU.
Do not use threadpool_put() with
        thread pools obtained from
        threadpool_percpu_ref().
threadpool_percpu_ref_remote(pool_percpu,
    ci)The resulting thread pool pointer is stable until
        pool_percpu is released with
        threadpool_percpu_put(). Using it to schedule or
        cancel a job does not require being on the same CPU, but it is faster
        and friendlier to the cache to use
        threadpool_percpu_ref() and use the resulting
        thread pool only on the same CPU.
Do not use threadpool_put() with
        thread pools obtained from
        threadpool_percpu_ref_remote().
threadpool_job_init(job,
    fn, interlock,
    fmt, ...)The mutex interlock is used to
        synchronize job scheduling and completion. The action
        fn is required to eventually call
        threadpool_job_done(), with
        interlock held. This is so that while the job is
        running and may be waiting for work to do, scheduling the job has no
        effect, but as soon as the job is done, scheduling the job will cause it
        to run again.
To change the action of a job, you must use
        threadpool_job_destroy() first and then call
        threadpool_job_init() again.
threadpool_job_destroy(job)threadpool_cancel_job() to cancel it. However,
      threadpool_cancel_job_async() is not enough.threadpool_job_done(job)threadpool_schedule_job() will cause it to re-run
      its action.
    threadpool_job_done() must be called
        exactly once by a job's action, and may not be called in any other
        context.
threadpool_schedule_job(pool,
    job)Caller must hold the interlock of job.
threadpool_schedule_job() may be
        called in any context, including hard interrupt context, except at
        interrupt priority levels above IPL_VM.
threadpool_cancel_job(pool,
    job)Caller must hold the interlock of job, which may be released in order to wait for completion.
If job has not been scheduled,
        threadpool_cancel_job() returns immediately. If
        job has been scheduled, it must have been
        scheduled in pool, not in any other thread
      pool.
May sleep.
threadpool_cancel_job_async(pool,
    job)threadpool_cancel_job(), but if it is already
      running, return false instead of waiting; otherwise,
      if it was not scheduled, or if it was scheduled and has not yet begun to
      run, return true.
    Caller must hold the interlock of job.
threadpool_cancel_job_async() may be
        called in any context, including hard interrupt context, except at
        interrupt priority levels above IPL_VM.
threadpool abstraction is implemented in
  sys/kern/kern_threadpool.c.
| December 26, 2018 | NetBSD 10.0 |