[MINOR] slightly optimize time calculation for rbtree
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.
This commit is contained in:
parent
b1b8272a54
commit
5e8f066961
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
27
src/time.c
27
src/time.c
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue