]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: task: perform atomic counter increments only once per wakeup
authorWilly Tarreau <w@1wt.eu>
Mon, 30 Nov 2020 14:39:00 +0000 (15:39 +0100)
committerWilly Tarreau <w@1wt.eu>
Mon, 30 Nov 2020 17:17:44 +0000 (18:17 +0100)
In process_runnable_tasks(), we walk the run queue and pick tasks to
insert them into the local list. And for each of these operations we
perform a few increments, some of which are atomic, and they're even
performed under the runqueue's lock. This is useless inside the loop,
better do them at the end, since we don't use these values inside the
loop and they're not used anywhere else either during this time. The
only one is task_list_size which is accessed in parallel by other
threads performing remote tasklet wakeups, but it's already
approximative and is used to decide to get out of the loop when the
limit is reached. So now we compute it first as an initial budget
instead.

src/task.c

index 8d574216f243432ab2b604ec1e54e1d8d0b90780..93e30227dae13a48808e223301d60921c6b044ae 100644 (file)
@@ -561,6 +561,8 @@ void process_runnable_tasks()
        struct mt_list *tmp_list;
        unsigned int queue;
        int max_processed;
+       int picked;
+       int budget;
 
        ti->flags &= ~TI_FL_STUCK; // this thread is still running
 
@@ -612,7 +614,9 @@ void process_runnable_tasks()
 
        /* pick up to max[TL_NORMAL] regular tasks from prio-ordered run queues */
        /* Note: the grq lock is always held when grq is not null */
-       while (tt->task_list_size < max[TL_NORMAL]) {
+       picked = 0;
+       budget = max[TL_NORMAL] - tt->task_list_size;
+       while (picked < budget) {
                if ((global_tasks_mask & tid_bit) && !grq) {
 #ifdef USE_THREAD
                        HA_SPIN_LOCK(TASK_RQ_LOCK, &rq_lock);
@@ -662,10 +666,7 @@ void process_runnable_tasks()
 
                /* Add it to the local task list */
                LIST_ADDQ(&tt->tasklets[TL_NORMAL], &((struct tasklet *)t)->list);
-               _HA_ATOMIC_ADD(&tasks_run_queue, 1);
-               tt->tl_class_mask |= 1 << TL_NORMAL;
-               _HA_ATOMIC_ADD(&tt->task_list_size, 1);
-               activity[tid].tasksw++;
+               picked++;
        }
 
        /* release the rqueue lock */
@@ -674,6 +675,13 @@ void process_runnable_tasks()
                grq = NULL;
        }
 
+       if (picked) {
+               tt->tl_class_mask |= 1 << TL_NORMAL;
+               _HA_ATOMIC_ADD(&tt->task_list_size, picked);
+               _HA_ATOMIC_ADD(&tasks_run_queue, picked);
+               activity[tid].tasksw += picked;
+       }
+
        /* Merge the list of tasklets waken up by other threads to the
         * main list.
         */