From f5aef027cefe3066a6546580e599734b174bcd5f Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Tue, 14 Jun 2022 15:04:34 +0200 Subject: [PATCH] OPTIM: task: do not consult shared WQ when we're already full If we've stopped consulting the local wait queue due to too many tasks (max_processed <= 0), there's no point starting to lock the shared WQ, check the first task's expiration date, upgrading the lock just to refrain from doing the work because of the limit. All this does is increase contention on an already contended system. Note that there is still a fairness issue in this WQ dequeuing code. If each thread is busy with expired tasks, no thread will dequeue the global ones. In practice it doesn't make much sense and should quickly resorb, but it could be nice to have an alternating flag indicating where to start from on next call to improve this. --- src/task.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/task.c b/src/task.c index 9512500614..04d11f7349 100644 --- a/src/task.c +++ b/src/task.c @@ -297,8 +297,10 @@ void wake_expired_tasks() struct eb32_node *eb; __decl_thread(int key); - while (max_processed-- > 0) { - lookup_next_local: + while (1) { + if (max_processed-- <= 0) + goto leave; + eb = eb32_lookup_ge(&tt->timers, now_ms - TIMER_LOOK_BACK); if (!eb) { /* we might have reached the end of the tree, typically because