20.3. Task Queues Kernel Programming InterfacesKernel users should use the documented DDI interface for all taskq operations. These interfaces are defined in the usr/src/uts/common/sys/sunddi.h header file. The exported interface consists of the following functions. taskq_t *taskq_create(const char *name, int nthreads, pri_t pri, int minalloc, int maxalloc, int flags); Creates a task queue with nthreads worker threads at priority pri and returns the pointer to the opaque taskq_t type. The minalloc and maxalloc arguments describe the behavior of the task entries cache. The flags may be any combination of the following - TASKQ_PREPOPULATE: Prepopulate task entries cache with minalloc entries.TASKQ_CPR_SAFE: Task queue uses special CPR protocol. This flag is only used by special system task queues and is not intended for general use. Since taskqs are queues, tasks are guaranteed to be executed in the order they are scheduled if nthreads equals one. Otherwise, task execution order is not predictable. Specifying a flag of TASKQ_DYNAMIC creates a taskq with dynamic semantics. The taskq created using this flag consists of a regular sequential task queue with a single worker thread (we call it "backing queue") and a set of data structures needed to implement a dynamic pool. All servicing threads needed to process a task pool are created dynamically when tasks are dispatched. The TASKQ_DYNAMIC flag changes the meaning of the arguments, passed to taskq_create(). With this flag set, nthreads means the maximum number of worker threads, servicing task pool (not counting a single task queue thread). The minalloc and maxalloc arguments are used in the usual way for the backing task queue. The TASKQ_DYNAMIC flag can not be used together with TASKQ_CPR_SAFE, and TASKQ_PREPOPULATE flag prepopulates the backing task queue in the usual way. void taskq_destroy(taskq_t *tq); Waits for any scheduled tasks to complete, then destroys the taskq. int taskq_dispatch(taskq_t *tq, task_func_t f, void *a, int flags); Dispatches the task specified by function f and argument a to taskq tq. It returns 1 on success and 0 on failure. Flags can be one of: TQ_NOQUEUE: Do not enqueue a task if it can't be dispatched due to lack of available resources and return NULL. If this flag is not set and the task pool is exhausted, the task may be scheduled in backing task queue. This flag should always be used when a task queue is used for tasks that may depend on each other for completion. Enqueueing dependent tasks may create deadlocks. TQ_SLEEP: Do not wait for resources; may return NULL. TQ_NOSLEEP: May block waiting for resources. May still fail for dynamic task queues if TQ_NOQUEUE is also specified. void taskq_wait(taskq_t *tq); Waits for all previously scheduled tasks to complete. krwlock_t *taskq_lock(taskq_t *tq); Returns a pointer to the task queue's thread lock, which is always held as RW_READER by taskq threads while executing tasks. There are two intended uses for this: 1. To ASSERT that a given function is called in taskq context only, and 2. To allow the caller to suspend all task execution temporarily by grabbing the lock as RW_WRITER. See usr/src/uts/common/sys/sunddi.h |