summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_taskqueue.c
diff options
context:
space:
mode:
authoravg <avg@FreeBSD.org>2014-02-17 15:32:08 +0000
committeravg <avg@FreeBSD.org>2014-02-17 15:32:08 +0000
commit22073dc5fc6c528703efb1da893a0340043ffd69 (patch)
tree613ca9c92776cb1bcdeec1c04c2a71c5cc17b9bb /sys/kern/subr_taskqueue.c
parent9a6dcea530c74578e68091504a1abefc3e175832 (diff)
downloadFreeBSD-src-22073dc5fc6c528703efb1da893a0340043ffd69.zip
FreeBSD-src-22073dc5fc6c528703efb1da893a0340043ffd69.tar.gz
MFC r258713,262062: add taskqueue_drain_all
Diffstat (limited to 'sys/kern/subr_taskqueue.c')
-rw-r--r--sys/kern/subr_taskqueue.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/sys/kern/subr_taskqueue.c b/sys/kern/subr_taskqueue.c
index 951b5fd..f104bb5 100644
--- a/sys/kern/subr_taskqueue.c
+++ b/sys/kern/subr_taskqueue.c
@@ -285,6 +285,15 @@ taskqueue_enqueue_timeout(struct taskqueue *queue,
return (res);
}
+static void
+taskqueue_drain_running(struct taskqueue *queue)
+{
+
+ while (!TAILQ_EMPTY(&queue->tq_active))
+ TQ_SLEEP(queue, &queue->tq_active, &queue->tq_mutex,
+ PWAIT, "-", 0);
+}
+
void
taskqueue_block(struct taskqueue *queue)
{
@@ -337,6 +346,8 @@ taskqueue_run_locked(struct taskqueue *queue)
wakeup(task);
}
TAILQ_REMOVE(&queue->tq_active, &tb, tb_link);
+ if (TAILQ_EMPTY(&queue->tq_active))
+ wakeup(&queue->tq_active);
}
void
@@ -421,6 +432,25 @@ taskqueue_drain(struct taskqueue *queue, struct task *task)
}
void
+taskqueue_drain_all(struct taskqueue *queue)
+{
+ struct task *task;
+
+ if (!queue->tq_spin)
+ WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, __func__);
+
+ TQ_LOCK(queue);
+ task = STAILQ_LAST(&queue->tq_queue, task, ta_link);
+ if (task != NULL)
+ while (task->ta_pending != 0)
+ TQ_SLEEP(queue, task, &queue->tq_mutex, PWAIT, "-", 0);
+ taskqueue_drain_running(queue);
+ KASSERT(STAILQ_EMPTY(&queue->tq_queue),
+ ("taskqueue queue is not empty after draining"));
+ TQ_UNLOCK(queue);
+}
+
+void
taskqueue_drain_timeout(struct taskqueue *queue,
struct timeout_task *timeout_task)
{
OpenPOWER on IntegriCloud