From 6967b9b093520d10a58f8d8ff6474706d19326b9 Mon Sep 17 00:00:00 2001 From: jmg Date: Sun, 8 Aug 2004 02:37:22 +0000 Subject: rearange some code that handles the thread taskqueue so that it is more generic. Introduce a new define TASKQUEUE_DEFINE_THREAD that takes a single arg, which is the name of the queue. Document these changes. --- share/man/man9/taskqueue.9 | 22 +++++++++++++++++----- sys/kern/subr_taskqueue.c | 29 ++++++++++++++++------------- sys/sys/taskqueue.h | 11 +++++++++++ 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/share/man/man9/taskqueue.9 b/share/man/man9/taskqueue.9 index 0848242..f15beca 100644 --- a/share/man/man9/taskqueue.9 +++ b/share/man/man9/taskqueue.9 @@ -68,6 +68,7 @@ struct task { .Fn TASK_INIT "struct task *task" "int priority" "task_fn_t *func" "void *context" .Fn TASKQUEUE_DECLARE "name" .Fn TASKQUEUE_DEFINE "name" "taskqueue_enqueue_fn enqueue" "void *context" "init" +.Fn TASKQUEUE_DEFINE_THREAD "name" .Sh DESCRIPTION These functions provide a simple interface for asynchronous execution of code. @@ -159,12 +160,13 @@ are simply copied into the task structure fields and the .Va ta_pending field is cleared. .Pp -Two macros -.Fn TASKQUEUE_DECLARE "name" +Three macros +.Fn TASKQUEUE_DECLARE "name" , +.Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init" , and -.Fn TASKQUEUE_DEFINE "name" "enqueue" "context" "init" -are used to declare a reference to a global queue -and to define the implementation of the queue. +.Fn TASKQUEUE_DEFINE_THREAD "name" +are used to declare a reference to a global queue, to define the +implementation of the queue, and declare a queue that uses it's own thread. The .Fn TASKQUEUE_DEFINE macro arranges to call @@ -183,6 +185,16 @@ argument to the macro is executed as a C statement, allowing any further initialisation to be performed (such as registering an interrupt handler etc.) .Pp +The +.Fn TASKQUEUE_DEFINE_THREAD +macro defines a new taskqueue with it's own kernel thread to serve tasks. The +variable +.Vt struct proc *taskqueue_name_proc +is defined which contains the kernel thread serving the tasks. +The variable +.Vt struct taskqueue *taskqueue_name +is used to enqueue tasks onto the queue. +.Pp The system provides three global taskqueues, .Va taskqueue_swi , .Va taskqueue_swi_giant , diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c index eaebd5d..a10e710 100644 --- a/sys/kern/subr_taskqueue.c +++ b/sys/kern/subr_taskqueue.c @@ -44,7 +44,6 @@ static void *taskqueue_giant_ih; static void *taskqueue_ih; static STAILQ_HEAD(taskqueue_list, taskqueue) taskqueue_queues; static struct mtx taskqueue_queues_mutex; -static struct proc *taskqueue_thread_proc; struct taskqueue { STAILQ_ENTRY(taskqueue) tq_link; @@ -226,24 +225,30 @@ taskqueue_swi_giant_run(void *dummy) taskqueue_run(taskqueue_swi_giant); } -static void -taskqueue_thread_loop(void *dummy) +void +taskqueue_thread_loop(void *arg) { + struct taskqueue **tqp, *tq; - mtx_lock(&taskqueue_thread->tq_mutex); + tqp = arg; + tq = *tqp; + mtx_lock(&tq->tq_mutex); for (;;) { - taskqueue_run(taskqueue_thread); - msleep(taskqueue_thread, &taskqueue_thread->tq_mutex, PWAIT, - "-", 0); + taskqueue_run(tq); + msleep(tq, &tq->tq_mutex, PWAIT, "-", 0); } } -static void +void taskqueue_thread_enqueue(void *context) { + struct taskqueue **tqp, *tq; + + tqp = context; + tq = *tqp; - mtx_assert(&taskqueue_thread->tq_mutex, MA_OWNED); - wakeup(taskqueue_thread); + mtx_assert(&tq->tq_mutex, MA_OWNED); + wakeup(tq); } TASKQUEUE_DEFINE(swi, taskqueue_swi_enqueue, 0, @@ -254,9 +259,7 @@ TASKQUEUE_DEFINE(swi_giant, taskqueue_swi_giant_enqueue, 0, swi_add(NULL, "Giant task queue", taskqueue_swi_giant_run, NULL, SWI_TQ_GIANT, 0, &taskqueue_giant_ih)); -TASKQUEUE_DEFINE(thread, taskqueue_thread_enqueue, 0, - kthread_create(taskqueue_thread_loop, NULL, - &taskqueue_thread_proc, 0, 0, "taskqueue")); +TASKQUEUE_DEFINE_THREAD(thread); int taskqueue_enqueue_fast(struct taskqueue *queue, struct task *task) diff --git a/sys/sys/taskqueue.h b/sys/sys/taskqueue.h index d35eb10..355f1ce 100644 --- a/sys/sys/taskqueue.h +++ b/sys/sys/taskqueue.h @@ -56,6 +56,12 @@ void taskqueue_free(struct taskqueue *queue); void taskqueue_run(struct taskqueue *queue); /* + * Functions for dedicated thread taskqueues + */ +void taskqueue_thread_loop(void *arg); +void taskqueue_thread_enqueue(void *context); + +/* * Initialise a task structure. */ #define TASK_INIT(task, priority, func, context) do { \ @@ -90,6 +96,11 @@ SYSINIT(taskqueue_##name, SI_SUB_CONFIGURE, SI_ORDER_SECOND, \ taskqueue_define_##name, NULL) \ \ struct __hack +#define TASKQUEUE_DEFINE_THREAD(name) \ +static struct proc *taskqueue_##name##_proc; \ +TASKQUEUE_DEFINE(name, taskqueue_thread_enqueue, &taskqueue_##name, \ + kthread_create(taskqueue_thread_loop, &taskqueue_##name, \ + &taskqueue_##name##_proc, 0, 0, #name " taskq")) /* * These queues are serviced by software interrupt handlers. To enqueue -- cgit v1.1