diff --git a/include/common/time.h b/include/common/time.h index 1546921e98..36c5ca5a2b 100644 --- a/include/common/time.h +++ b/include/common/time.h @@ -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 and : 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 and : 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 and 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 and : 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; diff --git a/src/task.c b/src/task.c index b49bc74d5c..ca262d634e 100644 --- a/src/task.c +++ b/src/task.c @@ -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); diff --git a/src/time.c b/src/time.c index 75f385ef81..1c5732f3eb 100644 --- a/src/time.c +++ b/src/time.c @@ -13,6 +13,7 @@ #include #include +#include #include 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 and : 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 and : 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)