Hi List!

I found a code duplication in run_tasks_from_lists(), when a task's
process() callback runs. Initially I wanted just eliminate the duplication,
but discovered there was a branch prediction optimization (see f0c531ab5
(MEDIUM: tasks: implement a lockless scheduler for single-thread usage,
2017-11-05):

    /* This is an optimisation to help the processor's branch
     * predictor take this most common call.
     */
    if (likely(t->process == process_stream))
        t = process_stream(t);
    else
        t = t->process(t);

Along the way, this became into this:

    if (process == process_stream)
        t = EXEC_CTX_WITH_RET(EXEC_CTX_MAKE(TH_EX_CTX_TASK, process_stream),
                              process_stream(t, ctx, state));
    else
        t = EXEC_CTX_WITH_RET(EXEC_CTX_MAKE(TH_EX_CTX_TASK, process),
                              process(t, ctx, state));

Should this optimization be restored? If not, maybe it's better to just
remove the code duplication?

-->8--

Drop a tautologic if statement when run a regular task, which does the
same things in both cases. Also, the process() callback is same for task
and tasklet, so the distinction is pointless.
---
 src/task.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/src/task.c b/src/task.c
index 0e25a8bc6..459f00dc2 100644
--- a/src/task.c
+++ b/src/task.c
@@ -653,23 +653,18 @@ unsigned int run_tasks_from_lists(unsigned int budgets[])
                }
 
                /* OK now the task or tasklet is well alive and is going to be 
run */
+
+               t = EXEC_CTX_WITH_RET(EXEC_CTX_MAKE(TH_EX_CTX_TASK, process),
+                                     process(t, ctx, state));
+
                if (state & TASK_F_TASKLET) {
                        /* this is a tasklet */
 
-                       t = EXEC_CTX_WITH_RET(EXEC_CTX_MAKE(TH_EX_CTX_TASK, 
process),
-                                             process(t, ctx, state));
                        if (t != NULL)
                                _HA_ATOMIC_AND(&t->state, ~TASK_RUNNING);
                } else {
                        /* This is a regular task */
 
-                       if (process == process_stream)
-                               t = 
EXEC_CTX_WITH_RET(EXEC_CTX_MAKE(TH_EX_CTX_TASK, process_stream),
-                                                     process_stream(t, ctx, 
state));
-                       else
-                               t = 
EXEC_CTX_WITH_RET(EXEC_CTX_MAKE(TH_EX_CTX_TASK, process),
-                                                     process(t, ctx, state));
-
                        /* If there is a pending state, we have to wake up the 
task
                         * immediately, else we defer it into wait queue.
                         */
-- 
Egor Shestakov
egor ascii(0x40) ved1 ascii(0x2E) me



Reply via email to