svn commit: r258713 - in head/sys: kern sys

Andriy Gapon avg at FreeBSD.org
Thu Nov 28 18:56:35 UTC 2013


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);


More information about the svn-src-head mailing list