From 712f57d8ab40f8aa1c3cfe81ae78a33d15ed73bc Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 19 Feb 2004 22:03:52 +0000 Subject: [PATCH] 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. --- sys/kern/subr_taskqueue.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c index aeebd084cffd..953300ac8e75 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