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