Date: Thu, 28 Nov 2013 18:56:35 +0000 (UTC) From: Andriy Gapon <avg@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r258713 - in head/sys: kern sys Message-ID: <201311281856.rASIuZu8059699@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: avg Date: Thu Nov 28 18:56:34 2013 New Revision: 258713 URL: http://svnweb.freebsd.org/changeset/base/258713 Log: add taskqueue_drain_all This API has semantics similar to that of taskqueue_drain but acts on all tasks that might be queued or running on a taskqueue. A caller must ensure that no new tasks are being enqueued otherwise this call would be totally meaningless. For example, if the tasks are enqueued by an interrupt filter then its interrupt must be disabled. MFC after: 10 days Modified: head/sys/kern/subr_taskqueue.c head/sys/sys/taskqueue.h Modified: head/sys/kern/subr_taskqueue.c ============================================================================== --- head/sys/kern/subr_taskqueue.c Thu Nov 28 16:36:03 2013 (r258712) +++ head/sys/kern/subr_taskqueue.c Thu Nov 28 18:56:34 2013 (r258713) @@ -300,6 +300,15 @@ taskqueue_enqueue_timeout(struct taskque 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) { @@ -350,6 +359,8 @@ taskqueue_run_locked(struct taskqueue *q wakeup(task); } TAILQ_REMOVE(&queue->tq_active, &tb, tb_link); + if (TAILQ_EMPTY(&queue->tq_active)) + wakeup(&queue->tq_active); } void @@ -434,6 +445,25 @@ taskqueue_drain(struct taskqueue *queue, } 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) { Modified: head/sys/sys/taskqueue.h ============================================================================== --- head/sys/sys/taskqueue.h Thu Nov 28 16:36:03 2013 (r258712) +++ head/sys/sys/taskqueue.h Thu Nov 28 18:56:34 2013 (r258713) @@ -81,6 +81,7 @@ int taskqueue_cancel_timeout(struct task void taskqueue_drain(struct taskqueue *queue, struct task *task); void taskqueue_drain_timeout(struct taskqueue *queue, struct timeout_task *timeout_task); +void taskqueue_drain_all(struct taskqueue *queue); void taskqueue_free(struct taskqueue *queue); void taskqueue_run(struct taskqueue *queue); void taskqueue_block(struct taskqueue *queue);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201311281856.rASIuZu8059699>