workqueue: test for empty queue before taking lock
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 21 Oct 2014 00:30:07 +0000 (20:30 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Tue, 21 Oct 2014 00:30:07 +0000 (20:30 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
urcu/workqueue-fifo.h

index 65d3a2e222cc0fbe991c986bce41f4e35722b309..ffdb974bb5a720f317ff9e539e15fcfd31eef468 100644 (file)
@@ -173,6 +173,11 @@ static inline
 void ___urcu_steal_work(struct urcu_worker *worker,
                struct urcu_worker *sibling)
 {
+       /*
+        * Don't bother grabbing the sibling queue lock if it is empty.
+        */
+       if (cds_wfcq_empty(&sibling->head, &sibling->tail))
+               return;
        cds_wfcq_dequeue_lock(&sibling->head, &sibling->tail);
        (void) __cds_wfcq_splice_blocking(&worker->head,
                        &worker->tail,
@@ -331,12 +336,19 @@ struct urcu_work *urcu_dequeue_work(struct urcu_worker *worker)
         * If we are registered for work stealing, we need to dequeue
         * safely against siblings.
         */
-       if (worker->flags & URCU_WORKER_STEAL)
+       if (worker->flags & URCU_WORKER_STEAL) {
+               /*
+                * Don't bother grabbing the worker queue lock if it is
+                * empty.
+                */
+               if (cds_wfcq_empty(&worker->head, &worker->tail))
+                       return NULL;
                node = cds_wfcq_dequeue_blocking(&worker->head,
                                &worker->tail);
-       else
+       } else {
                node = ___cds_wfcq_dequeue_with_state(&worker->head,
                                &worker->tail, NULL, 1, 0);
+       }
        if (!node)
                return NULL;
        return caa_container_of(node, struct urcu_work, node);
This page took 0.039748 seconds and 4 git commands to generate.