From 30926570a4ccf3050a4493316a7f23620495bcc8 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Mon, 20 Oct 2014 20:30:07 -0400 Subject: [PATCH] workqueue: test for empty queue before taking lock Signed-off-by: Mathieu Desnoyers --- urcu/workqueue-fifo.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/urcu/workqueue-fifo.h b/urcu/workqueue-fifo.h index 65d3a2e..ffdb974 100644 --- a/urcu/workqueue-fifo.h +++ b/urcu/workqueue-fifo.h @@ -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); -- 2.34.1