summaryrefslogtreecommitdiffstats
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
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.
-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