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:
parent
6b8c5a5e67
commit
6967b9b093
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user