]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MINOR] slightly optimize time calculation for rbtree
authorWilly Tarreau <w@1wt.eu>
Sun, 11 Feb 2007 23:59:08 +0000 (00:59 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 11 Feb 2007 23:59:08 +0000 (00:59 +0100)
The new rbtree-based scheduler makes heavy use of tv_cmp2(), and
this function becomes a huge CPU eater. Refine it a little bit in
order to slightly reduce CPU usage.

include/common/time.h
src/task.c
src/time.c

index 1546921e98459093914a8bd9ac618801cf5d5c1d..36c5ca5a2b16d04681cdda9e7eb8f5078f531b8d 100644 (file)
@@ -47,11 +47,18 @@ REGPRM3 struct timeval *tv_delayfrom(struct timeval *tv, const struct timeval *f
  */
 REGPRM2 int tv_cmp_ms(const struct timeval *tv1, const struct timeval *tv2);
 
+/*
+ * compares <tv1> and <tv2> : returns 0 if tv1 < tv2, 1 if tv1 >= tv2,
+ * considering that 0 is the eternity.
+ */
+REGPRM2 int tv_cmp_ge2(const struct timeval *tv1, const struct timeval *tv2);
+
 /*
  * compares <tv1> and <tv2> : returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2,
  * considering that 0 is the eternity.
  */
 REGPRM2 int tv_cmp2(const struct timeval *tv1, const struct timeval *tv2);
+
 /*
  * compares <tv1> and <tv2> modulo 1 ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2,
  * considering that 0 is the eternity.
@@ -92,6 +99,20 @@ REGPRM2 static inline int tv_cmp(const struct timeval *tv1, const struct timeval
                return 0;
 }
 
+/*
+ * compares <tv1> and <tv2> : returns 0 if tv1 < tv2, 1 if tv1 >= tv2
+ */
+REGPRM2 static inline int tv_cmp_ge(const struct timeval *tv1, const struct timeval *tv2)
+{
+       if (tv1->tv_sec > tv2->tv_sec)
+               return 1;
+       if (tv1->tv_sec < tv2->tv_sec)
+               return 0;
+       if (tv1->tv_usec >= tv2->tv_usec)
+               return 1;
+       return 0;
+}
+
 /*
  * returns the difference, in ms, between tv1 and tv2
  * Must not be used when either argument is eternity.
@@ -144,7 +165,7 @@ REGPRM1 static inline struct timeval *tv_eternity(struct timeval *tv)
  */
 REGPRM1 static inline int tv_iseternity(const struct timeval *tv)
 {
-       if (tv->tv_sec == 0 && tv->tv_usec == 0)
+       if ((tv->tv_sec | tv->tv_usec) == 0)
                return 1;
        else
                return 0;
index b49bc74d5c918c3570534c36dddd8f3b72401ead..ca262d634e5a4df0af8f2611b1f3513a16808350 100644 (file)
@@ -39,7 +39,7 @@ static inline void __rb_insert_task_queue(struct task *newtask)
        {
                parent = *p;
                task = rb_entry(parent, struct task, rb_node);
-               if (tv_cmp2(&task->expire, &newtask->expire) >= 0)
+               if (tv_cmp_ge2(&task->expire, &newtask->expire))
                        p = &(*p)->rb_left;
                else
                        p = &(*p)->rb_right;
@@ -82,7 +82,7 @@ struct task *task_queue(struct task *task)
                node = rb_prev(&task->rb_node);
                if (node) {
                        prev = rb_entry(node, struct task, rb_node);
-                       if (tv_cmp2(&prev->expire, &task->expire) >= 0) {
+                       if (tv_cmp_ge(&prev->expire, &task->expire)) {
                                task_delete(task);
                                task->wq = &wait_queue[0];
                                rb_insert_task_queue(task);
@@ -93,7 +93,7 @@ struct task *task_queue(struct task *task)
                node = rb_next(&task->rb_node);
                if (node) {
                        next = rb_entry(node, struct task, rb_node);
-                       if (tv_cmp2(&task->expire, &next->expire) > 0) {
+                       if (tv_cmp_ge(&task->expire, &next->expire)) {
                                task_delete(task);
                                task->wq = &wait_queue[0];
                                rb_insert_task_queue(task);
index 75f385ef812f7f7c77c987dab197f3ef03d25b10..1c5732f3eb46307477ca2ccc97f0045e9fcfb3c6 100644 (file)
@@ -13,6 +13,7 @@
 #include <sys/time.h>
 
 #include <common/config.h>
+#include <common/standard.h>
 #include <common/time.h>
 
 struct timeval now;             /* the current date at any moment */
@@ -58,18 +59,38 @@ REGPRM2 int tv_cmp_ms(const struct timeval *tv1, const struct timeval *tv2)
                return 0;
 }
 
+/*
+ * compares <tv1> and <tv2> : returns 0 if tv1 < tv2, 1 if tv1 >= tv2,
+ * considering that 0 is the eternity.
+ */
+REGPRM2 int tv_cmp_ge2(const struct timeval *tv1, const struct timeval *tv2)
+{
+       if (unlikely(tv_iseternity(tv1)))
+               return 1;
+       if (unlikely(tv_iseternity(tv2)))
+               return 0; /* same */
+
+       if (tv1->tv_sec > tv2->tv_sec)
+               return 1;
+       if (tv1->tv_sec < tv2->tv_sec)
+               return 0;
+       if (tv1->tv_usec >= tv2->tv_usec)
+               return 1;
+       return 0;
+}
+
 /*
  * compares <tv1> and <tv2> : returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2,
  * considering that 0 is the eternity.
  */
 REGPRM2 int tv_cmp2(const struct timeval *tv1, const struct timeval *tv2)
 {
-       if (tv_iseternity(tv1))
-               if (tv_iseternity(tv2))
+       if (unlikely(tv_iseternity(tv1)))
+               if (unlikely(tv_iseternity(tv2)))
                        return 0; /* same */
                else
                        return 1; /* tv1 later than tv2 */
-       else if (tv_iseternity(tv2))
+       else if (likely(tv_iseternity(tv2)))
                return -1; /* tv2 later than tv1 */
     
        if (tv1->tv_sec > tv2->tv_sec)