taskqueue.h revision 136131
1225361Sdougb/*- 2135446Strhodes * Copyright (c) 2000 Doug Rabson 3135446Strhodes * All rights reserved. 4174187Sdougb * 5135446Strhodes * Redistribution and use in source and binary forms, with or without 6135446Strhodes * modification, are permitted provided that the following conditions 7135446Strhodes * are met: 8135446Strhodes * 1. Redistributions of source code must retain the above copyright 9135446Strhodes * notice, this list of conditions and the following disclaimer. 10135446Strhodes * 2. Redistributions in binary form must reproduce the above copyright 11135446Strhodes * notice, this list of conditions and the following disclaimer in the 12135446Strhodes * documentation and/or other materials provided with the distribution. 13135446Strhodes * 14135446Strhodes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15135446Strhodes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16225361Sdougb * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17135446Strhodes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18135446Strhodes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19135446Strhodes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20135446Strhodes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21135446Strhodes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22135446Strhodes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23135446Strhodes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24135446Strhodes * SUCH DAMAGE. 25135446Strhodes * 26135446Strhodes * $FreeBSD: head/sys/sys/taskqueue.h 136131 2004-10-05 04:16:01Z imp $ 27135446Strhodes */ 28135446Strhodes 29135446Strhodes#ifndef _SYS_TASKQUEUE_H_ 30135446Strhodes#define _SYS_TASKQUEUE_H_ 31135446Strhodes 32135446Strhodes#ifndef _KERNEL 33135446Strhodes#error "no user-servicable parts inside" 34135446Strhodes#endif 35135446Strhodes 36135446Strhodes#include <sys/queue.h> 37193149Sdougb#include <sys/_task.h> 38224092Sdougb 39224092Sdougbstruct taskqueue; 40135446Strhodes 41135446Strhodes/* 42135446Strhodes * A notification callback function which is called from 43135446Strhodes * taskqueue_enqueue(). The context argument is given in the call to 44135446Strhodes * taskqueue_create(). This function would normally be used to allow the 45135446Strhodes * queue to arrange to run itself later (e.g., by scheduling a software 46135446Strhodes * interrupt or waking a kernel thread). 47135446Strhodes */ 48135446Strhodestypedef void (*taskqueue_enqueue_fn)(void *context); 49135446Strhodes 50135446Strhodesstruct taskqueue *taskqueue_create(const char *name, int mflags, 51135446Strhodes taskqueue_enqueue_fn enqueue, 52135446Strhodes void *context); 53225361Sdougbint taskqueue_enqueue(struct taskqueue *queue, struct task *task); 54135446Strhodesvoid taskqueue_drain(struct taskqueue *queue, struct task *task); 55135446Strhodesstruct taskqueue *taskqueue_find(const char *name); 56135446Strhodesvoid taskqueue_free(struct taskqueue *queue); 57135446Strhodesvoid taskqueue_run(struct taskqueue *queue); 58135446Strhodes 59135446Strhodes/* 60135446Strhodes * Functions for dedicated thread taskqueues 61135446Strhodes */ 62225361Sdougbvoid taskqueue_thread_loop(void *arg); 63135446Strhodesvoid taskqueue_thread_enqueue(void *context); 64135446Strhodes 65135446Strhodes/* 66135446Strhodes * Initialise a task structure. 67225361Sdougb */ 68135446Strhodes#define TASK_INIT(task, priority, func, context) do { \ 69135446Strhodes (task)->ta_pending = 0; \ 70135446Strhodes (task)->ta_priority = (priority); \ 71135446Strhodes (task)->ta_func = (func); \ 72135446Strhodes (task)->ta_context = (context); \ 73135446Strhodes (task)->ta_flags = 0; \ 74135446Strhodes} while (0) 75135446Strhodes 76135446Strhodes/* 77225361Sdougb * Declare a reference to a taskqueue. 78225361Sdougb */ 79225361Sdougb#define TASKQUEUE_DECLARE(name) \ 80225361Sdougbextern struct taskqueue *taskqueue_##name 81225361Sdougb 82225361Sdougb/* 83225361Sdougb * Define and initialise a taskqueue. 84225361Sdougb */ 85225361Sdougb#define TASKQUEUE_DEFINE(name, enqueue, context, init) \ 86225361Sdougb \ 87225361Sdougbstruct taskqueue *taskqueue_##name; \ 88135446Strhodes \ 89135446Strhodesstatic void \ 90135446Strhodestaskqueue_define_##name(void *arg) \ 91135446Strhodes{ \ 92135446Strhodes taskqueue_##name = \ 93135446Strhodes taskqueue_create(#name, M_NOWAIT, (enqueue), (context)); \ 94135446Strhodes init; \ 95135446Strhodes} \ 96135446Strhodes \ 97135446StrhodesSYSINIT(taskqueue_##name, SI_SUB_CONFIGURE, SI_ORDER_SECOND, \ 98135446Strhodes taskqueue_define_##name, NULL) \ 99135446Strhodes \ 100135446Strhodesstruct __hack 101135446Strhodes#define TASKQUEUE_DEFINE_THREAD(name) \ 102135446Strhodesstatic struct proc *taskqueue_##name##_proc; \ 103135446StrhodesTASKQUEUE_DEFINE(name, taskqueue_thread_enqueue, &taskqueue_##name, \ 104135446Strhodes kthread_create(taskqueue_thread_loop, &taskqueue_##name, \ 105135446Strhodes &taskqueue_##name##_proc, 0, 0, #name " taskq")) 106135446Strhodes 107135446Strhodes/* 108135446Strhodes * These queues are serviced by software interrupt handlers. To enqueue 109135446Strhodes * a task, call taskqueue_enqueue(taskqueue_swi, &task) or 110135446Strhodes * taskqueue_enqueue(taskqueue_swi_giant, &task). 111135446Strhodes */ 112135446StrhodesTASKQUEUE_DECLARE(swi_giant); 113135446StrhodesTASKQUEUE_DECLARE(swi); 114135446Strhodes 115135446Strhodes/* 116135446Strhodes * This queue is serviced by a kernel thread. To enqueue a task, call 117135446Strhodes * taskqueue_enqueue(taskqueue_thread, &task). 118135446Strhodes */ 119165071SdougbTASKQUEUE_DECLARE(thread); 120165071Sdougb 121165071Sdougb/* 122186462Sdougb * Queue for swi handlers dispatched from fast interrupt handlers. 123165071Sdougb * These are necessarily different from the above because the queue 124165071Sdougb * must be locked with spinlocks since sleep mutex's cannot be used 125135446Strhodes * from a fast interrupt handler context. 126135446Strhodes */ 127135446StrhodesTASKQUEUE_DECLARE(fast); 128135446Strhodesint taskqueue_enqueue_fast(struct taskqueue *queue, struct task *task); 129135446Strhodes 130135446Strhodes#endif /* !_SYS_TASKQUEUE_H_ */ 131135446Strhodes