#ifndef _SYS_TASKQUEUE_H_
#define _SYS_TASKQUEUE_H_
#if !defined(_KERNEL)
#error "This file should not be included by userland programs."
#endif
#include <sys/queue.h>
#include <sys/callout.h>
struct taskqueue;
typedef void task_fn_t(void *context, int pending);
typedef void (*taskqueue_enqueue_fn)(void *context);
struct task {
STAILQ_ENTRY(task) ta_link;
struct taskqueue *ta_queue;
int ta_pending;
int ta_priority;
task_fn_t *ta_func;
void *ta_context;
};
struct timeout_task {
struct task t;
struct callout c;
int f;
};
struct taskqueue *taskqueue_create(const char *name, int mflags,
taskqueue_enqueue_fn enqueue,
void *context);
int taskqueue_start_threads(struct taskqueue **tqp, int count, int pri,
int ncpu, const char *name, ...)
__printflike(5, 6);
int taskqueue_enqueue(struct taskqueue *queue, struct task *task);
int taskqueue_enqueue_optq(struct taskqueue *queue,
struct taskqueue **qpp, struct task *task);
int taskqueue_enqueue_timeout(struct taskqueue *queue,
struct timeout_task *timeout_task, int ticks);
int taskqueue_cancel(struct taskqueue *queue, struct task *task,
u_int *pendp);
int taskqueue_cancel_simple(struct task *task);
int taskqueue_cancel_timeout(struct taskqueue *queue,
struct timeout_task *timeout_task, u_int *pendp);
void taskqueue_drain(struct taskqueue *queue, struct task *task);
void taskqueue_drain_simple(struct task *task);
void taskqueue_drain_timeout(struct taskqueue *queue,
struct timeout_task *timeout_task);
struct taskqueue *taskqueue_find(const char *name);
void taskqueue_free(struct taskqueue *queue);
void taskqueue_block(struct taskqueue *queue);
void taskqueue_unblock(struct taskqueue *queue);
#define TASK_INITIALIZER(priority, func, context) \
{ .ta_queue = NULL, \
.ta_pending = 0, \
.ta_priority = (priority), \
.ta_func = (func), \
.ta_context = (context) }
void taskqueue_thread_loop(void *arg);
void taskqueue_thread_enqueue(void *context);
#define TASK_INIT(task, priority, func, context) do { \
(task)->ta_queue = NULL; \
(task)->ta_pending = 0; \
(task)->ta_priority = (priority); \
(task)->ta_func = (func); \
(task)->ta_context = (context); \
} while (0)
void _timeout_task_init(struct taskqueue *queue,
struct timeout_task *timeout_task, int priority, task_fn_t func,
void *context);
#define TIMEOUT_TASK_INIT(queue, timeout_task, priority, func, context) \
_timeout_task_init(queue, timeout_task, priority, func, context);
#define TASKQUEUE_DECLARE(name) \
extern struct taskqueue *taskqueue_##name
#define TASKQUEUE_DEFINE(name, enqueue, context, init) \
\
struct taskqueue *taskqueue_##name; \
\
static void \
taskqueue_define_##name(void *arg) \
{ \
taskqueue_##name = \
taskqueue_create(#name, M_INTWAIT, (enqueue), (context)); \
init; \
} \
\
SYSINIT(taskqueue_##name, SI_SUB_PRE_DRIVERS, SI_ORDER_SECOND, \
taskqueue_define_##name, NULL); \
\
struct __hack
#define TASKQUEUE_DEFINE_THREAD(name) \
TASKQUEUE_DEFINE(name, taskqueue_thread_enqueue, &taskqueue_##name, \
taskqueue_start_threads(&taskqueue_##name, 1, \
TDPRI_KERN_DAEMON, -1, "%s taskq", #name))
TASKQUEUE_DECLARE(swi);
TASKQUEUE_DECLARE(swi_mp);
extern struct taskqueue *taskqueue_thread[];
#endif