summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_taskqueue.c
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2004-02-19 22:03:52 +0000
committerjhb <jhb@FreeBSD.org>2004-02-19 22:03:52 +0000
commita0f2609521e3d2c81a71159e0b06f43371aa11eb (patch)
treee5b31707f4b54ede4588ccf006d6b566539d6dcd /sys/kern/subr_taskqueue.c
parent9d5e12afecfe191b704ae621a55b67f07261dd7d (diff)
downloadFreeBSD-src-a0f2609521e3d2c81a71159e0b06f43371aa11eb.zip
FreeBSD-src-a0f2609521e3d2c81a71159e0b06f43371aa11eb.tar.gz
Tidy up the thread taskqueue implementation and close a lost wakeup race.
Instead of creating a mutex that we msleep on but don't actually lock when doing the corresponding wakeup(), in the kthread, lock the mutex associated with our taskqueue and msleep while the queue is empty. Assert that the queue is locked when the callback function is called to wake the kthread.
Diffstat (limited to 'sys/kern/subr_taskqueue.c')
-rw-r--r--sys/kern/subr_taskqueue.c23
1 files changed, 9 insertions, 14 deletions
diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c
index aeebd08..953300a 100644
--- a/sys/kern/subr_taskqueue.c
+++ b/sys/kern/subr_taskqueue.c
@@ -235,28 +235,23 @@ taskqueue_swi_giant_run(void *dummy)
}
static void
-taskqueue_kthread(void *arg)
+taskqueue_thread_loop(void *arg)
{
- struct mtx kthread_mutex;
-
- bzero(&kthread_mutex, sizeof(kthread_mutex));
-
- mtx_init(&kthread_mutex, "taskqueue kthread", NULL, MTX_DEF);
-
- mtx_lock(&kthread_mutex);
-
for (;;) {
- mtx_unlock(&kthread_mutex);
+ mtx_lock(&taskqueue_thread->tq_mutex);
+ while (STAILQ_EMPTY(&taskqueue_thread->tq_queue))
+ msleep(taskqueue_thread, &taskqueue_thread->tq_mutex,
+ PWAIT, "-", 0);
+ mtx_unlock(&taskqueue_thread->tq_mutex);
taskqueue_run(taskqueue_thread);
- mtx_lock(&kthread_mutex);
- msleep(&taskqueue_thread, &kthread_mutex, PWAIT, "tqthr", 0);
}
}
static void
taskqueue_thread_enqueue(void *context)
{
- wakeup(&taskqueue_thread);
+ mtx_assert(&taskqueue_thread->tq_mutex, MA_OWNED);
+ wakeup(taskqueue_thread);
}
TASKQUEUE_DEFINE(swi, taskqueue_swi_enqueue, 0,
@@ -268,7 +263,7 @@ TASKQUEUE_DEFINE(swi_giant, taskqueue_swi_giant_enqueue, 0,
NULL, SWI_TQ_GIANT, 0, &taskqueue_giant_ih));
TASKQUEUE_DEFINE(thread, taskqueue_thread_enqueue, 0,
- kthread_create(taskqueue_kthread, NULL,
+ kthread_create(taskqueue_thread_loop, NULL,
&taskqueue_thread_proc, 0, 0, "taskqueue"));
int
OpenPOWER on IntegriCloud