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.
This commit is contained in:
jmg 2004-08-08 02:37:22 +00:00
parent 6b8c5a5e67
commit 6967b9b093
3 changed files with 44 additions and 18 deletions

@ -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 ,

@ -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;
mtx_assert(&taskqueue_thread->tq_mutex, MA_OWNED);
wakeup(taskqueue_thread);
tqp = context;
tq = *tqp;
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)

@ -55,6 +55,12 @@ struct taskqueue *taskqueue_find(const char *name);
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.
*/
@ -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