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);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to