[OPTIM] task: reduce the number of calls to task_queue()

Most of the time, task_queue() will immediately return. By extracting
the preliminary checks and putting them in an inline function, we can
significantly reduce the number of calls to the function itself, and
most of the tests can be optimized away due to the caller's context.

Another minor improvement in process_runnable_tasks() consisted in
taking benefit from the processor's branch prediction unit by making
a special case of the process_session() callback which is by far the
most common one.

All this improved performance by about 1%, mainly during the call
from process_runnable_tasks().
diff --git a/include/common/ticks.h b/include/common/ticks.h
index f3c1a7d..4587d56 100644
--- a/include/common/ticks.h
+++ b/include/common/ticks.h
@@ -113,6 +113,17 @@
 		return t2;
 }
 
+/* return the first one of the two timers, where only the first one may be infinite */
+static inline int tick_first_2nz(int t1, int t2)
+{
+	if (!tick_isset(t1))
+		return t2;
+	if ((t1 - t2) <= 0)
+		return t1;
+	else
+		return t2;
+}
+
 /* return the number of ticks remaining from <now> to <exp>, or zero if expired */
 static inline int tick_remain(int now, int exp)
 {
diff --git a/include/proto/task.h b/include/proto/task.h
index 67eb924..b5f2280 100644
--- a/include/proto/task.h
+++ b/include/proto/task.h
@@ -246,9 +246,27 @@
 }
 
 /* Place <task> into the wait queue, where it may already be. If the expiration
- * timer is infinite, the task is dequeued.
+ * timer is infinite, do nothing and rely on wake_expired_task to clean up.
  */
-void task_queue(struct task *task);
+void __task_queue(struct task *task);
+static inline void task_queue(struct task *task)
+{
+	/* If we already have a place in the wait queue no later than the
+	 * timeout we're trying to set, we'll stay there, because it is very
+	 * unlikely that we will reach the timeout anyway. If the timeout
+	 * has been disabled, it's useless to leave the queue as well. We'll
+	 * rely on wake_expired_tasks() to catch the node and move it to the
+	 * proper place should it ever happen. Finally we only add the task
+	 * to the queue if it was not there or if it was further than what
+	 * we want.
+	 */
+	if (!tick_isset(task->expire))
+		return;
+
+	if (((tick_to_timer(task->expire) - task->wq.key) & TIMER_SIGN_BIT)
+		|| !task_in_wq(task))
+		__task_queue(task);
+}
 
 /*
  * This does 4 things :