From: Willy Tarreau Date: Sun, 29 Apr 2007 15:43:56 +0000 (+0200) Subject: [MEDIUM] many cleanups in the time functions X-Git-Tag: v1.3.10~27 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=42aae5c7cfc1db62309b92bf08d4ac19972d51c1;p=thirdparty%2Fhaproxy.git [MEDIUM] many cleanups in the time functions Now, functions whose name begins with '__tv_' are inlined. Also, 'tv_ms' is used as a prefix for functions using milliseconds. --- diff --git a/include/common/time.h b/include/common/time.h index 3d81759d11..770974ca00 100644 --- a/include/common/time.h +++ b/include/common/time.h @@ -2,7 +2,7 @@ include/common/time.h Time calculation functions and macros. - Copyright (C) 2000-2006 Willy Tarreau - w@1wt.eu + Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -25,6 +25,7 @@ #include #include #include +#include /* eternity when exprimed in timeval */ #ifndef TV_ETERNITY @@ -47,50 +48,74 @@ extern struct timeval now; /* the current date at any moment */ extern struct timeval start_date; /* the process's start date */ +/**** exported functions *************************************************/ + + /* * adds ms to , set the result to and returns a pointer */ -REGPRM3 struct timeval *tv_delayfrom(struct timeval *tv, const struct timeval *from, int ms); +REGPRM3 struct timeval *tv_ms_add(struct timeval *tv, const struct timeval *from, int ms); /* * compares and modulo 1ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2 - * Must not be used when either argument is eternity. Use tv_cmp2_ms() for that. + * Must not be used when either argument is eternity. Use tv_ms_cmp2() for that. */ -REGPRM2 int tv_cmp_ms(const struct timeval *tv1, const struct timeval *tv2); +REGPRM2 int tv_ms_cmp(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, * assuming that TV_ETERNITY is greater than everything. */ -REGPRM2 int tv_cmp2_ms(const struct timeval *tv1, const struct timeval *tv2); +REGPRM2 int tv_ms_cmp2(const struct timeval *tv1, const struct timeval *tv2); + +/**** general purpose functions and macros *******************************/ -/* - * compares and modulo 1 ms: returns 1 if tv1 <= tv2, 0 if tv1 > tv2, - * assuming that TV_ETERNITY is greater than everything. Returns 0 if tv1 is - * TV_ETERNITY, and always assumes that tv2 != TV_ETERNITY. Designed to replace - * occurrences of (tv_cmp2_ms(tv,now) <= 0). - */ -REGPRM2 int tv_cmp2_le(const struct timeval *tv1, const struct timeval *tv2); + +/* tv_now: sets to the current time */ +REGPRM1 static inline struct timeval *tv_now(struct timeval *tv) +{ + gettimeofday(tv, NULL); + return tv; +} /* - * returns the remaining time between tv1=now and event=tv2 - * if tv2 is passed, 0 is returned. - * Returns TIME_ETERNITY if tv2 is eternity. + * sets a struct timeval to its highest value so that it can never happen + * note that only tv_usec is necessary to detect it since a tv_usec > 999999 + * is normally not possible. + * */ -REGPRM2 unsigned long tv_remain2(const struct timeval *tv1, const struct timeval *tv2); -/* sets to the current time */ -REGPRM1 static inline struct timeval *tv_now(struct timeval *tv) +REGPRM1 static inline struct timeval *tv_eternity(struct timeval *tv) { - if (tv) - gettimeofday(tv, NULL); + tv->tv_sec = tv->tv_usec = TV_ETERNITY; return tv; } /* - * compares and : returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2 + * sets a struct timeval to 0 + * */ -REGPRM2 static inline int tv_cmp(const struct timeval *tv1, const struct timeval *tv2) +REGPRM1 static inline struct timeval *tv_zero(struct timeval *tv) { + tv->tv_sec = tv->tv_usec = 0; + return tv; +} + +/* + * returns non null if tv is [eternity], otherwise 0. + */ +#define tv_iseternity(tv) ((tv)->tv_usec == TV_ETERNITY) + +/* + * returns non null if tv is [0], otherwise 0. + */ +#define tv_iszero(tv) (((tv)->tv_sec | (tv)->tv_usec) == 0) + + +/**** comparision functions and macros ***********************************/ + + +/* tv_cmp: compares and : returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2. */ +REGPRM2 static inline int __tv_cmp(const struct timeval *tv1, const struct timeval *tv2) { if ((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec) return -1; @@ -104,34 +129,142 @@ REGPRM2 static inline int tv_cmp(const struct timeval *tv1, const struct timeval return 0; } +/* tv_iseq: compares and : returns 1 if tv1 == tv2, otherwise 0 */ +REGPRM2 static inline int __tv_iseq(const struct timeval *tv1, const struct timeval *tv2) +{ + return ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) && + ((unsigned)tv1->tv_usec == (unsigned)tv2->tv_usec); +} + +/* tv_isgt: compares and : returns 1 if tv1 > tv2, otherwise 0 */ +REGPRM2 static inline int __tv_isgt(const struct timeval *tv1, const struct timeval *tv2) +{ + return + ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) ? + ((unsigned)tv1->tv_usec > (unsigned)tv2->tv_usec) : + ((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec); +} + +/* tv_isge: compares and : returns 1 if tv1 >= tv2, otherwise 0 */ +REGPRM2 static inline int __tv_isge(const struct timeval *tv1, const struct timeval *tv2) +{ + return + ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) ? + ((unsigned)tv1->tv_usec >= (unsigned)tv2->tv_usec) : + ((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec); +} + +/* tv_islt: compares and : returns 1 if tv1 < tv2, otherwise 0 */ +REGPRM2 static inline int __tv_islt(const struct timeval *tv1, const struct timeval *tv2) +{ + return + ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) ? + ((unsigned)tv1->tv_usec < (unsigned)tv2->tv_usec) : + ((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec); +} + +/* tv_isle: compares and : returns 1 if tv1 <= tv2, otherwise 0 */ +REGPRM2 static inline int __tv_isle(const struct timeval *tv1, const struct timeval *tv2) +{ + return + ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) ? + ((unsigned)tv1->tv_usec <= (unsigned)tv2->tv_usec) : + ((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec); +} + /* - * compares and : returns 0 if tv1 < tv2, 1 if tv1 >= tv2 + * compares and modulo 1ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2 + * Must not be used when either argument is eternity. Use tv_ms_cmp2() for that. */ -REGPRM2 static inline int tv_cmp_ge(const struct timeval *tv1, const struct timeval *tv2) +#define tv_ms_cmp _tv_ms_cmp +REGPRM2 int _tv_ms_cmp(const struct timeval *tv1, const struct timeval *tv2); +REGPRM2 static inline int __tv_ms_cmp(const struct timeval *tv1, const struct timeval *tv2) { - if ((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec) + if ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) { + if ((unsigned)tv2->tv_usec >= (unsigned)tv1->tv_usec + 1000) + return -1; + else if ((unsigned)tv1->tv_usec >= (unsigned)tv2->tv_usec + 1000) + return 1; + else + return 0; + } + else if (((unsigned)tv2->tv_sec > (unsigned)tv1->tv_sec + 1) || + (((unsigned)tv2->tv_sec == (unsigned)tv1->tv_sec + 1) && + ((unsigned)tv2->tv_usec + 1000000 >= (unsigned)tv1->tv_usec + 1000))) + return -1; + else if (((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec + 1) || + (((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec + 1) && + ((unsigned)tv1->tv_usec + 1000000 >= (unsigned)tv2->tv_usec + 1000))) return 1; - if ((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec) + else return 0; - if ((unsigned)tv1->tv_usec >= (unsigned)tv2->tv_usec) +} + +/* + * compares and modulo 1 ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2, + * assuming that TV_ETERNITY is greater than everything. + */ +#define tv_ms_cmp2 _tv_ms_cmp2 +REGPRM2 int _tv_ms_cmp2(const struct timeval *tv1, const struct timeval *tv2); +REGPRM2 static inline int __tv_ms_cmp2(const struct timeval *tv1, const struct timeval *tv2) +{ + if (tv_iseternity(tv1)) + if (tv_iseternity(tv2)) + return 0; /* same */ + else + return 1; /* tv1 later than tv2 */ + else if (tv_iseternity(tv2)) + return -1; /* tv2 later than tv1 */ + return tv_ms_cmp(tv1, tv2); +} + +/* + * compares and modulo 1 ms: returns 1 if tv1 <= tv2, 0 if tv1 > tv2, + * assuming that TV_ETERNITY is greater than everything. Returns 0 if tv1 is + * TV_ETERNITY, and always assumes that tv2 != TV_ETERNITY. Designed to replace + * occurrences of (tv_ms_cmp2(tv,now) <= 0). + */ +#define tv_ms_le2 _tv_ms_le2 +REGPRM2 int _tv_ms_le2(const struct timeval *tv1, const struct timeval *tv2); +REGPRM2 static inline int __tv_ms_le2(const struct timeval *tv1, const struct timeval *tv2) +{ + if (likely((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec + 1)) + return 0; + + if (likely((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec)) + return 1; + + if (likely((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec)) { + if ((unsigned)tv2->tv_usec >= (unsigned)tv1->tv_usec + 1000) + return 1; + else + return 0; + } + + if (unlikely(((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec + 1) && + ((unsigned)tv1->tv_usec + 1000000 >= (unsigned)tv2->tv_usec + 1000))) + return 0; + else return 1; - return 0; } + +/**** operators **********************************************************/ + + /* - * returns the difference, in ms, between tv1 and tv2 + * Returns the time in ms elapsed between tv1 and tv2, assuming that tv1<=tv2. * Must not be used when either argument is eternity. */ -REGPRM2 static inline unsigned long tv_diff(const struct timeval *tv1, const struct timeval *tv2) +#define tv_ms_elapsed __tv_ms_elapsed +REGPRM2 unsigned long _tv_ms_elapsed(const struct timeval *tv1, const struct timeval *tv2); +REGPRM2 static inline unsigned long __tv_ms_elapsed(const struct timeval *tv1, const struct timeval *tv2) { unsigned long ret; - - ret = (tv2->tv_sec - tv1->tv_sec) * 1000; - if ((unsigned)tv2->tv_usec > (unsigned)tv1->tv_usec) - ret += (tv2->tv_usec - tv1->tv_usec) / 1000; - else - ret -= (tv1->tv_usec - tv2->tv_usec) / 1000; - return (unsigned long) ret; + + ret = ((signed long)(tv2->tv_sec - tv1->tv_sec)) * 1000; + ret += ((signed long)(tv2->tv_usec - tv1->tv_usec)) / 1000; + return ret; } /* @@ -139,53 +272,48 @@ REGPRM2 static inline unsigned long tv_diff(const struct timeval *tv1, const str * if tv2 is passed, 0 is returned. * Must not be used when either argument is eternity. */ -REGPRM2 static inline unsigned long tv_remain(const struct timeval *tv1, const struct timeval *tv2) + +#define tv_ms_remain __tv_ms_remain +REGPRM2 unsigned long _tv_ms_remain(const struct timeval *tv1, const struct timeval *tv2); +REGPRM2 static inline unsigned long __tv_ms_remain(const struct timeval *tv1, const struct timeval *tv2) { - unsigned long ret; - - if (tv_cmp_ms(tv1, tv2) >= 0) + if (tv_ms_cmp(tv1, tv2) >= 0) return 0; /* event elapsed */ - ret = (tv2->tv_sec - tv1->tv_sec) * 1000; - if ((unsigned)tv2->tv_usec > (unsigned)tv1->tv_usec) - ret += (tv2->tv_usec - tv1->tv_usec) / 1000; - else - ret -= (tv1->tv_usec - tv2->tv_usec) / 1000; - return (unsigned long) ret; + return __tv_ms_elapsed(tv1, tv2); } - /* - * sets a struct timeval to its highest value so that it can never happen - * note that only tv_usec is necessary to detect it since a tv_usec > 999999 - * is normally not possible. - * + * returns the remaining time between tv1=now and event=tv2 + * if tv2 is passed, 0 is returned. + * Returns TIME_ETERNITY if tv2 is eternity. */ - -REGPRM1 static inline struct timeval *tv_eternity(struct timeval *tv) +#define tv_ms_remain2 _tv_ms_remain2 +REGPRM2 unsigned long _tv_ms_remain2(const struct timeval *tv1, const struct timeval *tv2); +REGPRM2 static inline unsigned long __tv_ms_remain2(const struct timeval *tv1, const struct timeval *tv2) { - tv->tv_sec = tv->tv_usec = TV_ETERNITY; - return tv; + if (tv_iseternity(tv2)) + return TIME_ETERNITY; + + return tv_ms_remain(tv1, tv2); } /* - * sets a struct timeval to 0 - * + * adds ms to , set the result to and returns a pointer */ -REGPRM1 static inline struct timeval *tv_zero(struct timeval *tv) { - tv->tv_sec = tv->tv_usec = 0; +#define tv_ms_add _tv_ms_add +REGPRM3 struct timeval *_tv_ms_add(struct timeval *tv, const struct timeval *from, int ms); +REGPRM3 static inline struct timeval *__tv_ms_add(struct timeval *tv, const struct timeval *from, int ms) +{ + tv->tv_usec = from->tv_usec + (ms % 1000) * 1000; + tv->tv_sec = from->tv_sec + (ms / 1000); + while (tv->tv_usec >= 1000000) { + tv->tv_usec -= 1000000; + tv->tv_sec++; + } return tv; } -/* - * returns non null if tv is [eternity], otherwise 0. - */ -#define tv_iseternity(tv) ((tv)->tv_usec == TV_ETERNITY) - -/* - * returns non null if tv is [0], otherwise 0. - */ -#define tv_iszero(tv) (((tv)->tv_sec | (tv)->tv_usec) == 0) /* * compares and : returns 1 if is before , otherwise 0. diff --git a/src/appsession.c b/src/appsession.c index 0adbc332c3..d11fb19507 100644 --- a/src/appsession.c +++ b/src/appsession.c @@ -117,7 +117,7 @@ int appsession_task_init(void) t->qlist.p = NULL; t->state = TASK_IDLE; t->context = NULL; - tv_delayfrom(&t->expire, &now, TBLCHKINT); + tv_ms_add(&t->expire, &now, TBLCHKINT); task_queue(t); t->process = appsession_refresh; initialized ++; @@ -143,7 +143,7 @@ int appsession_refresh(struct task *t) for (element = list_head(&htbl->table[i]); element != NULL; element = list_next(element)) { asession = (appsess *)list_data(element); - if (tv_cmp2_ms(&asession->expire, &now) <= 0) { + if (tv_ms_le2(&asession->expire, &now)) { if ((global.mode & MODE_DEBUG) && (!(global.mode & MODE_QUIET) || (global.mode & MODE_VERBOSE))) { int len; @@ -165,7 +165,7 @@ int appsession_refresh(struct task *t) } else element = last; - }/* end if (tv_cmp2_ms(&asession->expire, &now) <= 0) */ + }/* end if (tv_ms_le2(&asession->expire, &now)) */ else last = element; }/* end for (element = list_head(&htbl->table[i]); element != NULL; element = list_next(element)) */ @@ -173,7 +173,7 @@ int appsession_refresh(struct task *t) } p = p->next; } - tv_delayfrom(&t->expire, &now, TBLCHKINT); /* check expiration every 5 seconds */ + tv_ms_add(&t->expire, &now, TBLCHKINT); /* check expiration every 5 seconds */ return TBLCHKINT; } /* end appsession_refresh */ diff --git a/src/backend.c b/src/backend.c index f096874f20..b35764684e 100644 --- a/src/backend.c +++ b/src/backend.c @@ -542,7 +542,7 @@ int connect_server(struct session *s) } if (s->be->contimeout) - tv_delayfrom(&s->req->cex, &now, s->be->contimeout); + tv_ms_add(&s->req->cex, &now, s->be->contimeout); else tv_eternity(&s->req->cex); return SN_ERR_NONE; /* connection is OK */ @@ -672,7 +672,7 @@ int srv_redispatch_connect(struct session *t) case SRV_STATUS_QUEUED: /* FIXME-20060503 : we should use the queue timeout instead */ if (t->be->contimeout) - tv_delayfrom(&t->req->cex, &now, t->be->contimeout); + tv_ms_add(&t->req->cex, &now, t->be->contimeout); else tv_eternity(&t->req->cex); t->srv_state = SV_STIDLE; diff --git a/src/cfgparse.c b/src/cfgparse.c index 289d634112..00b490807c 100644 --- a/src/cfgparse.c +++ b/src/cfgparse.c @@ -2469,8 +2469,8 @@ int readcfgfile(const char *file) t->context = newsrv; /* check this every ms */ - tv_delayfrom(&t->expire, &now, - newsrv->inter + mininter * srvpos / nbchk); + tv_ms_add(&t->expire, &now, + newsrv->inter + mininter * srvpos / nbchk); task_queue(t); //task_wakeup(&rq, t); srvpos++; diff --git a/src/checks.c b/src/checks.c index f9bc5c5a9c..df16cd1bd6 100644 --- a/src/checks.c +++ b/src/checks.c @@ -258,19 +258,19 @@ int process_chk(struct task *t) fd = s->curfd; if (fd < 0) { /* no check currently running */ //fprintf(stderr, "process_chk: 2\n"); - if (tv_cmp2_ms(&t->expire, &now) > 0) { /* not good time yet */ + if (!tv_ms_le2(&t->expire, &now)) { /* not good time yet */ task_queue(t); /* restore t to its place in the task list */ - return tv_remain2(&now, &t->expire); + return tv_ms_remain2(&now, &t->expire); } /* we don't send any health-checks when the proxy is stopped or when * the server should not be checked. */ if (!(s->state & SRV_CHECKED) || s->proxy->state == PR_STSTOPPED) { - while (tv_cmp2_ms(&t->expire, &now) <= 0) - tv_delayfrom(&t->expire, &t->expire, s->inter); + while (tv_ms_le2(&t->expire, &now)) + tv_ms_add(&t->expire, &t->expire, s->inter); task_queue(t); /* restore t to its place in the task list */ - return tv_remain2(&now, &t->expire); + return tv_ms_remain2(&now, &t->expire); } /* we'll initiate a new check */ @@ -375,9 +375,9 @@ int process_chk(struct task *t) assert (!EV_FD_ISSET(fd, DIR_RD)); #endif /* FIXME: we allow up to for a connection to establish, but we should use another parameter */ - tv_delayfrom(&t->expire, &now, s->inter); + tv_ms_add(&t->expire, &now, s->inter); task_queue(t); /* restore t to its place in the task list */ - return tv_remain(&now, &t->expire); + return tv_ms_remain(&now, &t->expire); } else if (errno != EALREADY && errno != EISCONN && errno != EAGAIN) { s->result = -1; /* a real error */ @@ -389,8 +389,8 @@ int process_chk(struct task *t) if (!s->result) { /* nothing done */ //fprintf(stderr, "process_chk: 6\n"); - while (tv_cmp2_ms(&t->expire, &now) <= 0) - tv_delayfrom(&t->expire, &t->expire, s->inter); + while (tv_ms_le2(&t->expire, &now)) + tv_ms_add(&t->expire, &t->expire, s->inter); goto new_chk; /* may be we should initialize a new check */ } @@ -404,8 +404,8 @@ int process_chk(struct task *t) //fprintf(stderr, "process_chk: 7\n"); /* FIXME: we allow up to for a connection to establish, but we should use another parameter */ - while (tv_cmp2_ms(&t->expire, &now) <= 0) - tv_delayfrom(&t->expire, &t->expire, s->inter); + while (tv_ms_le2(&t->expire, &now)) + tv_ms_add(&t->expire, &t->expire, s->inter); goto new_chk; } else { @@ -455,11 +455,11 @@ int process_chk(struct task *t) } s->curfd = -1; /* no check running anymore */ fd_delete(fd); - while (tv_cmp2_ms(&t->expire, &now) <= 0) - tv_delayfrom(&t->expire, &t->expire, s->inter); + while (tv_ms_le2(&t->expire, &now)) + tv_ms_add(&t->expire, &t->expire, s->inter); goto new_chk; } - else if (s->result < 0 || tv_cmp2_ms(&t->expire, &now) <= 0) { + else if (s->result < 0 || tv_ms_le2(&t->expire, &now)) { //fprintf(stderr, "process_chk: 10\n"); /* failure or timeout detected */ if (s->health > s->rise) { @@ -470,8 +470,8 @@ int process_chk(struct task *t) set_server_down(s); s->curfd = -1; fd_delete(fd); - while (tv_cmp2_ms(&t->expire, &now) <= 0) - tv_delayfrom(&t->expire, &t->expire, s->inter); + while (tv_ms_le2(&t->expire, &now)) + tv_ms_add(&t->expire, &t->expire, s->inter); goto new_chk; } /* if result is 0 and there's no timeout, we have to wait again */ @@ -479,7 +479,7 @@ int process_chk(struct task *t) //fprintf(stderr, "process_chk: 11\n"); s->result = 0; task_queue(t); /* restore t to its place in the task list */ - return tv_remain2(&now, &t->expire); + return tv_ms_remain2(&now, &t->expire); } diff --git a/src/client.c b/src/client.c index 028282ef1c..bba3774ab4 100644 --- a/src/client.c +++ b/src/client.c @@ -412,9 +412,9 @@ int event_accept(int fd) { if (s->fe->clitimeout) { if (EV_FD_ISSET(cfd, DIR_RD)) - tv_delayfrom(&s->req->rex, &now, s->fe->clitimeout); + tv_ms_add(&s->req->rex, &now, s->fe->clitimeout); if (EV_FD_ISSET(cfd, DIR_WR)) - tv_delayfrom(&s->rep->wex, &now, s->fe->clitimeout); + tv_ms_add(&s->rep->wex, &now, s->fe->clitimeout); } tv_min(&t->expire, &s->req->rex, &s->rep->wex); diff --git a/src/haproxy.c b/src/haproxy.c index 5776d18461..a2e335e1ee 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -281,7 +281,7 @@ void dump(int sig) qfprintf(stderr,"[dump] wq: task %p, still %ld ms, " "cli=%d, srv=%d, cr=%d, cw=%d, sr=%d, sw=%d, " "req=%d, rep=%d, clifd=%d\n", - s, tv_remain(&now, &t->expire), + s, tv_ms_remain(&now, &t->expire), s->cli_state, s->srv_state, EV_FD_ISSET(s->cli_fd, DIR_RD), diff --git a/src/proto_http.c b/src/proto_http.c index 4c58e5e216..fd9cff779e 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -441,7 +441,7 @@ void client_retnclose(struct session *s, const struct chunk *msg) EV_FD_SET(s->cli_fd, DIR_WR); tv_eternity(&s->req->rex); if (s->fe->clitimeout) - tv_delayfrom(&s->rep->wex, &now, s->fe->clitimeout); + tv_ms_add(&s->rep->wex, &now, s->fe->clitimeout); else tv_eternity(&s->rep->wex); s->cli_state = CL_STSHUTR; @@ -561,11 +561,11 @@ int process_session(struct task *t) /* DEBUG code : this should never ever happen, otherwise it indicates * that a task still has something to do and will provoke a quick loop. */ - if (tv_remain2(&now, &t->expire) <= 0) + if (tv_ms_remain2(&now, &t->expire) <= 0) exit(100); #endif - return tv_remain2(&now, &t->expire); /* nothing more to do */ + return tv_ms_remain2(&now, &t->expire); /* nothing more to do */ } s->fe->feconn--; @@ -582,7 +582,7 @@ int process_session(struct task *t) write(1, trash, len); } - s->logs.t_close = tv_diff(&s->logs.tv_accept, &now); + s->logs.t_close = tv_ms_elapsed(&s->logs.tv_accept, &now); if (s->req != NULL) s->logs.bytes_in = s->req->total; if (s->rep != NULL) @@ -1526,7 +1526,7 @@ int process_cli(struct session *t) } /* 3: has the read timeout expired ? */ - else if (unlikely(tv_cmp2_le(&req->rex, &now))) { + else if (unlikely(tv_ms_le2(&req->rex, &now))) { /* read timeout : give up with an error message. */ txn->status = 408; client_retnclose(t, error_message(t, HTTP_ERR_408)); @@ -1545,7 +1545,7 @@ int process_cli(struct session *t) * req->l == rlim-data */ if (t->fe->clitimeout) - tv_delayfrom(&req->rex, &now, t->fe->clitimeout); + tv_ms_add(&req->rex, &now, t->fe->clitimeout); else tv_eternity(&req->rex); } @@ -1694,7 +1694,7 @@ int process_cli(struct session *t) /* no need to go further */ txn->status = 403; /* let's log the request time */ - t->logs.t_request = tv_diff(&t->logs.tv_accept, &now); + t->logs.t_request = tv_ms_elapsed(&t->logs.tv_accept, &now); client_retnclose(t, error_message(t, HTTP_ERR_403)); goto return_prx_cond; } @@ -1888,7 +1888,7 @@ int process_cli(struct session *t) t->cli_state = CL_STDATA; req->rlim = req->data + BUFSIZE; /* no more rewrite needed */ - t->logs.t_request = tv_diff(&t->logs.tv_accept, &now); + t->logs.t_request = tv_ms_elapsed(&t->logs.tv_accept, &now); if (!t->fe->clitimeout || (t->srv_state < SV_STDATA && t->be->srvtimeout)) { @@ -1914,7 +1914,7 @@ int process_cli(struct session *t) /* flush the request so that we can drop the connection early * if the client closes first. */ - tv_delayfrom(&req->cex, &now, + tv_ms_add(&req->cex, &now, t->be->contimeout ? t->be->contimeout : 0); } @@ -1975,13 +1975,13 @@ int process_cli(struct session *t) * to shutw */ EV_FD_SET(t->cli_fd, DIR_RD); if (t->fe->clitimeout) - tv_delayfrom(&req->rex, &now, t->fe->clitimeout); + tv_ms_add(&req->rex, &now, t->fe->clitimeout); t->cli_state = CL_STSHUTW; //fprintf(stderr,"%p:%s(%d), c=%d, s=%d\n", t, __FUNCTION__, __LINE__, t->cli_state, t->cli_state); return 1; } /* read timeout */ - else if (tv_cmp2_le(&req->rex, &now)) { + else if (tv_ms_le2(&req->rex, &now)) { EV_FD_CLR(t->cli_fd, DIR_RD); tv_eternity(&req->rex); t->cli_state = CL_STSHUTR; @@ -1998,7 +1998,7 @@ int process_cli(struct session *t) return 1; } /* write timeout */ - else if (tv_cmp2_le(&rep->wex, &now)) { + else if (tv_ms_le2(&rep->wex, &now)) { EV_FD_CLR(t->cli_fd, DIR_WR); tv_eternity(&rep->wex); shutdown(t->cli_fd, SHUT_WR); @@ -2006,7 +2006,7 @@ int process_cli(struct session *t) * to shutw */ EV_FD_SET(t->cli_fd, DIR_RD); if (t->fe->clitimeout) - tv_delayfrom(&req->rex, &now, t->fe->clitimeout); + tv_ms_add(&req->rex, &now, t->fe->clitimeout); t->cli_state = CL_STSHUTW; if (!(t->flags & SN_ERR_MASK)) @@ -2040,7 +2040,7 @@ int process_cli(struct session *t) */ tv_eternity(&req->rex); else - tv_delayfrom(&req->rex, &now, t->fe->clitimeout); + tv_ms_add(&req->rex, &now, t->fe->clitimeout); } } @@ -2055,7 +2055,7 @@ int process_cli(struct session *t) if (EV_FD_COND_S(t->cli_fd, DIR_WR)) { /* restart writing */ if (t->fe->clitimeout) { - tv_delayfrom(&rep->wex, &now, t->fe->clitimeout); + tv_ms_add(&rep->wex, &now, t->fe->clitimeout); /* FIXME: to prevent the client from expiring read timeouts during writes, * we refresh it. */ req->rex = rep->wex; @@ -2090,7 +2090,7 @@ int process_cli(struct session *t) t->cli_state = CL_STCLOSE; return 1; } - else if (tv_cmp2_le(&rep->wex, &now)) { + else if (tv_ms_le2(&rep->wex, &now)) { tv_eternity(&rep->wex); fd_delete(t->cli_fd); t->cli_state = CL_STCLOSE; @@ -2128,7 +2128,7 @@ int process_cli(struct session *t) if (EV_FD_COND_S(t->cli_fd, DIR_WR)) { /* restart writing */ if (t->fe->clitimeout) { - tv_delayfrom(&rep->wex, &now, t->fe->clitimeout); + tv_ms_add(&rep->wex, &now, t->fe->clitimeout); /* FIXME: to prevent the client from expiring read timeouts during writes, * we refresh it. */ req->rex = rep->wex; @@ -2162,7 +2162,7 @@ int process_cli(struct session *t) t->cli_state = CL_STCLOSE; return 1; } - else if (tv_cmp2_le(&req->rex, &now)) { + else if (tv_ms_le2(&req->rex, &now)) { tv_eternity(&req->rex); fd_delete(t->cli_fd); t->cli_state = CL_STCLOSE; @@ -2194,7 +2194,7 @@ int process_cli(struct session *t) /* there's still some space in the buffer */ if (EV_FD_COND_S(t->cli_fd, DIR_RD)) { if (t->fe->clitimeout) - tv_delayfrom(&req->rex, &now, t->fe->clitimeout); + tv_ms_add(&req->rex, &now, t->fe->clitimeout); else tv_eternity(&req->rex); //fprintf(stderr,"%p:%s(%d), c=%d, s=%d\n", t, __FUNCTION__, __LINE__, t->cli_state, t->cli_state); @@ -2242,7 +2242,7 @@ int process_srv(struct session *t) (t->req->l == 0 || t->be->options & PR_O_ABRT_CLOSE))) { /* give up */ tv_eternity(&req->cex); if (t->pend_pos) - t->logs.t_queue = tv_diff(&t->logs.tv_accept, &now); + t->logs.t_queue = tv_ms_elapsed(&t->logs.tv_accept, &now); /* note that this must not return any error because it would be able to * overwrite the client_retnclose() output. */ @@ -2259,7 +2259,7 @@ int process_srv(struct session *t) * already set the connect expiration date to the right * timeout. We just have to check that it has not expired. */ - if (!tv_cmp2_le(&req->cex, &now)) + if (!tv_ms_le2(&req->cex, &now)) return 0; /* We will set the queue timer to the time spent, just for @@ -2269,7 +2269,7 @@ int process_srv(struct session *t) * the tarpitted connections by filtering on the 'PT' status flags. */ tv_eternity(&req->cex); - t->logs.t_queue = tv_diff(&t->logs.tv_accept, &now); + t->logs.t_queue = tv_ms_elapsed(&t->logs.tv_accept, &now); srv_close_with_err(t, SN_ERR_PRXCOND, SN_FINST_T, 500, error_message(t, HTTP_ERR_500)); return 1; @@ -2281,12 +2281,12 @@ int process_srv(struct session *t) * to any other session to release it and wake us up again. */ if (t->pend_pos) { - if (!tv_cmp2_le(&req->cex, &now)) + if (!tv_ms_le2(&req->cex, &now)) return 0; else { /* we've been waiting too long here */ tv_eternity(&req->cex); - t->logs.t_queue = tv_diff(&t->logs.tv_accept, &now); + t->logs.t_queue = tv_ms_elapsed(&t->logs.tv_accept, &now); srv_close_with_err(t, SN_ERR_SRVTO, SN_FINST_Q, 503, error_message(t, HTTP_ERR_503)); if (t->srv) @@ -2305,7 +2305,7 @@ int process_srv(struct session *t) * number of retries. */ if (srv_retryable_connect(t)) { - t->logs.t_queue = tv_diff(&t->logs.tv_accept, &now); + t->logs.t_queue = tv_ms_elapsed(&t->logs.tv_accept, &now); return t->srv_state != SV_STIDLE; } } while (1); @@ -2326,7 +2326,7 @@ int process_srv(struct session *t) srv_close_with_err(t, SN_ERR_CLICL, SN_FINST_C, 0, NULL); return 1; } - if (!(req->flags & BF_WRITE_STATUS) && !tv_cmp2_le(&req->cex, &now)) { + if (!(req->flags & BF_WRITE_STATUS) && !tv_ms_le2(&req->cex, &now)) { //fprintf(stderr,"1: c=%d, s=%d, now=%d.%06d, exp=%d.%06d\n", c, s, now.tv_sec, now.tv_usec, req->cex.tv_sec, req->cex.tv_usec); return 0; /* nothing changed */ } @@ -2375,7 +2375,7 @@ int process_srv(struct session *t) * the SV_STIDLE state. */ if (srv_retryable_connect(t)) { - t->logs.t_queue = tv_diff(&t->logs.tv_accept, &now); + t->logs.t_queue = tv_ms_elapsed(&t->logs.tv_accept, &now); return t->srv_state != SV_STCONN; } @@ -2385,7 +2385,7 @@ int process_srv(struct session *t) } while (1); } else { /* no error or write 0 */ - t->logs.t_connect = tv_diff(&t->logs.tv_accept, &now); + t->logs.t_connect = tv_ms_elapsed(&t->logs.tv_accept, &now); //fprintf(stderr,"3: c=%d, s=%d\n", c, s); if (req->l == 0) /* nothing to write */ { @@ -2394,7 +2394,7 @@ int process_srv(struct session *t) } else /* need the right to write */ { EV_FD_SET(t->srv_fd, DIR_WR); if (t->be->srvtimeout) { - tv_delayfrom(&req->wex, &now, t->be->srvtimeout); + tv_ms_add(&req->wex, &now, t->be->srvtimeout); /* FIXME: to prevent the server from expiring read timeouts during writes, * we refresh it. */ rep->rex = req->wex; @@ -2406,7 +2406,7 @@ int process_srv(struct session *t) if (t->be->mode == PR_MODE_TCP) { /* let's allow immediate data connection in this case */ EV_FD_SET(t->srv_fd, DIR_RD); if (t->be->srvtimeout) - tv_delayfrom(&rep->rex, &now, t->be->srvtimeout); + tv_ms_add(&rep->rex, &now, t->be->srvtimeout); else tv_eternity(&rep->rex); @@ -2495,7 +2495,7 @@ int process_srv(struct session *t) * rep->l == rlim-data */ if (t->be->srvtimeout) - tv_delayfrom(&rep->rex, &now, t->be->srvtimeout); + tv_ms_add(&rep->rex, &now, t->be->srvtimeout); else tv_eternity(&rep->rex); } @@ -2561,7 +2561,7 @@ int process_srv(struct session *t) /* read timeout : return a 504 to the client. */ else if (unlikely(EV_FD_ISSET(t->srv_fd, DIR_RD) && - tv_cmp2_le(&rep->rex, &now))) { + tv_ms_le2(&rep->rex, &now))) { tv_eternity(&rep->rex); tv_eternity(&req->wex); fd_delete(t->srv_fd); @@ -2602,7 +2602,7 @@ int process_srv(struct session *t) * alive when switching to shutw */ EV_FD_SET(t->srv_fd, DIR_RD); if (t->be->srvtimeout) - tv_delayfrom(&rep->rex, &now, t->be->srvtimeout); + tv_ms_add(&rep->rex, &now, t->be->srvtimeout); shutdown(t->srv_fd, SHUT_WR); t->srv_state = SV_STSHUTW; @@ -2615,7 +2615,7 @@ int process_srv(struct session *t) * some work to do on the headers. */ else if (unlikely(EV_FD_ISSET(t->srv_fd, DIR_WR) && - tv_cmp2_le(&req->wex, &now))) { + tv_ms_le2(&req->wex, &now))) { EV_FD_CLR(t->srv_fd, DIR_WR); tv_eternity(&req->wex); shutdown(t->srv_fd, SHUT_WR); @@ -2623,7 +2623,7 @@ int process_srv(struct session *t) * when switching to shutw */ EV_FD_SET(t->srv_fd, DIR_RD); if (t->be->srvtimeout) - tv_delayfrom(&rep->rex, &now, t->be->srvtimeout); + tv_ms_add(&rep->rex, &now, t->be->srvtimeout); t->srv_state = SV_STSHUTW; if (!(t->flags & SN_ERR_MASK)) @@ -2645,7 +2645,7 @@ int process_srv(struct session *t) if (EV_FD_COND_S(t->srv_fd, DIR_WR)) { /* restart writing */ if (t->be->srvtimeout) { - tv_delayfrom(&req->wex, &now, t->be->srvtimeout); + tv_ms_add(&req->wex, &now, t->be->srvtimeout); /* FIXME: to prevent the server from expiring read timeouts during writes, * we refresh it. */ rep->rex = req->wex; @@ -2925,7 +2925,7 @@ int process_srv(struct session *t) t->srv_state = SV_STDATA; rep->rlim = rep->data + BUFSIZE; /* no more rewrite needed */ - t->logs.t_data = tv_diff(&t->logs.tv_accept, &now); + t->logs.t_data = tv_ms_elapsed(&t->logs.tv_accept, &now); /* client connection already closed or option 'forceclose' required : * we close the server's outgoing connection right now. @@ -2939,7 +2939,7 @@ int process_srv(struct session *t) * to shutw */ EV_FD_SET(t->srv_fd, DIR_RD); if (t->be->srvtimeout) - tv_delayfrom(&rep->rex, &now, t->be->srvtimeout); + tv_ms_add(&rep->rex, &now, t->be->srvtimeout); shutdown(t->srv_fd, SHUT_WR); t->srv_state = SV_STSHUTW; @@ -3009,13 +3009,13 @@ int process_srv(struct session *t) * to shutw */ EV_FD_SET(t->srv_fd, DIR_RD); if (t->be->srvtimeout) - tv_delayfrom(&rep->rex, &now, t->be->srvtimeout); + tv_ms_add(&rep->rex, &now, t->be->srvtimeout); t->srv_state = SV_STSHUTW; return 1; } /* read timeout */ - else if (tv_cmp2_le(&rep->rex, &now)) { + else if (tv_ms_le2(&rep->rex, &now)) { EV_FD_CLR(t->srv_fd, DIR_RD); tv_eternity(&rep->rex); t->srv_state = SV_STSHUTR; @@ -3026,7 +3026,7 @@ int process_srv(struct session *t) return 1; } /* write timeout */ - else if (tv_cmp2_le(&req->wex, &now)) { + else if (tv_ms_le2(&req->wex, &now)) { EV_FD_CLR(t->srv_fd, DIR_WR); tv_eternity(&req->wex); shutdown(t->srv_fd, SHUT_WR); @@ -3034,7 +3034,7 @@ int process_srv(struct session *t) * to shutw */ EV_FD_SET(t->srv_fd, DIR_RD); if (t->be->srvtimeout) - tv_delayfrom(&rep->rex, &now, t->be->srvtimeout); + tv_ms_add(&rep->rex, &now, t->be->srvtimeout); t->srv_state = SV_STSHUTW; if (!(t->flags & SN_ERR_MASK)) t->flags |= SN_ERR_SRVTO; @@ -3054,7 +3054,7 @@ int process_srv(struct session *t) if (EV_FD_COND_S(t->srv_fd, DIR_WR)) { /* restart writing */ if (t->be->srvtimeout) { - tv_delayfrom(&req->wex, &now, t->be->srvtimeout); + tv_ms_add(&req->wex, &now, t->be->srvtimeout); /* FIXME: to prevent the server from expiring read timeouts during writes, * we refresh it. */ rep->rex = req->wex; @@ -3073,7 +3073,7 @@ int process_srv(struct session *t) else { if (EV_FD_COND_S(t->srv_fd, DIR_RD)) { if (t->be->srvtimeout) - tv_delayfrom(&rep->rex, &now, t->be->srvtimeout); + tv_ms_add(&rep->rex, &now, t->be->srvtimeout); else tv_eternity(&rep->rex); } @@ -3121,7 +3121,7 @@ int process_srv(struct session *t) return 1; } - else if (tv_cmp2_le(&req->wex, &now)) { + else if (tv_ms_le2(&req->wex, &now)) { //EV_FD_CLR(t->srv_fd, DIR_WR); tv_eternity(&req->wex); fd_delete(t->srv_fd); @@ -3151,7 +3151,7 @@ int process_srv(struct session *t) if (EV_FD_COND_S(t->srv_fd, DIR_WR)) { /* restart writing */ if (t->be->srvtimeout) { - tv_delayfrom(&req->wex, &now, t->be->srvtimeout); + tv_ms_add(&req->wex, &now, t->be->srvtimeout); /* FIXME: to prevent the server from expiring read timeouts during writes, * we refresh it. */ rep->rex = req->wex; @@ -3202,7 +3202,7 @@ int process_srv(struct session *t) return 1; } - else if (tv_cmp2_le(&rep->rex, &now)) { + else if (tv_ms_le2(&rep->rex, &now)) { //EV_FD_CLR(t->srv_fd, DIR_RD); tv_eternity(&rep->rex); fd_delete(t->srv_fd); @@ -3230,7 +3230,7 @@ int process_srv(struct session *t) else { if (EV_FD_COND_S(t->srv_fd, DIR_RD)) { if (t->be->srvtimeout) - tv_delayfrom(&rep->rex, &now, t->be->srvtimeout); + tv_ms_add(&rep->rex, &now, t->be->srvtimeout); else tv_eternity(&rep->rex); } @@ -4349,7 +4349,7 @@ void manage_client_side_cookies(struct session *t, struct buffer *req) }/* end while(srv) */ }/* end else if server == NULL */ - tv_delayfrom(&asession_temp->expire, &now, t->be->appsession_timeout); + tv_ms_add(&asession_temp->expire, &now, t->be->appsession_timeout); }/* end if ((t->proxy->appsession_name != NULL) ... */ } @@ -4809,7 +4809,7 @@ void manage_server_side_cookies(struct session *t, struct buffer *rtr) if (asession_temp->serverid[0] == '\0') memcpy(asession_temp->serverid, t->srv->id, server_id_len); - tv_delayfrom(&asession_temp->expire, &now, t->be->appsession_timeout); + tv_ms_add(&asession_temp->expire, &now, t->be->appsession_timeout); #if defined(DEBUG_HASH) print_table(&(t->be->htbl_proxy)); @@ -4971,7 +4971,7 @@ void get_srv_from_appsession(struct session *t, const char *begin, int len) pool_free_to(apools.sessid, local_asession.sessid); } - tv_delayfrom(&asession_temp->expire, &now, t->be->appsession_timeout); + tv_ms_add(&asession_temp->expire, &now, t->be->appsession_timeout); asession_temp->request_count++; #if defined(DEBUG_HASH) @@ -5092,7 +5092,7 @@ int stats_check_uri_auth(struct session *t, struct proxy *backend) */ t->cli_state = CL_STSHUTR; t->req->rlim = t->req->data + BUFSIZE; /* no more rewrite needed */ - t->logs.t_request = tv_diff(&t->logs.tv_accept, &now); + t->logs.t_request = tv_ms_elapsed(&t->logs.tv_accept, &now); t->data_source = DATA_SRC_STATS; t->data_state = DATA_ST_INIT; produce_content(t); diff --git a/src/proxy.c b/src/proxy.c index 9096c91f2b..3cc355a84b 100644 --- a/src/proxy.c +++ b/src/proxy.c @@ -221,7 +221,7 @@ int maintain_proxies(void) while (p) { if (p->state != PR_STSTOPPED) { int t; - t = tv_remain2(&now, &p->stop_time); + t = tv_ms_remain2(&now, &p->stop_time); if (t == 0) { Warning("Proxy %s stopped.\n", p->id); send_log(p, LOG_WARNING, "Proxy %s stopped.\n", p->id); @@ -259,7 +259,7 @@ void soft_stop(void) if (p->state != PR_STSTOPPED) { Warning("Stopping proxy %s in %d ms.\n", p->id, p->grace); send_log(p, LOG_WARNING, "Stopping proxy %s in %d ms.\n", p->id, p->grace); - tv_delayfrom(&p->stop_time, &now, p->grace); + tv_ms_add(&p->stop_time, &now, p->grace); } p = p->next; } diff --git a/src/stream_sock.c b/src/stream_sock.c index 77eda02c83..ce04672efd 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -152,7 +152,7 @@ int stream_sock_read(int fd) { if (b->flags & BF_READ_STATUS) { out_wakeup: if (b->rto && EV_FD_ISSET(fd, DIR_RD)) - tv_delayfrom(&b->rex, &now, b->rto); + tv_ms_add(&b->rex, &now, b->rto); else tv_eternity(&b->rex); @@ -278,7 +278,7 @@ int stream_sock_write(int fd) { if (b->flags & BF_WRITE_STATUS) { if (b->wto) { - tv_delayfrom(&b->wex, &now, b->wto); + tv_ms_add(&b->wex, &now, b->wto); /* FIXME: to prevent the client from expiring read timeouts during writes, * we refresh it. A solution would be to merge read+write timeouts into a * unique one, although that needs some study particularly on full-duplex diff --git a/src/task.c b/src/task.c index a2ca0404bd..2fd6efa2a9 100644 --- a/src/task.c +++ b/src/task.c @@ -96,8 +96,8 @@ int wake_expired_tasks() if (likely(timer_wq.data != NULL)) { task = LIST_ELEM(timer_wq.data, struct task *, qlist); - if (likely(tv_cmp_ge(&task->expire, &now) > 0)) - return tv_remain(&now, &task->expire); + if (likely(__tv_isge(&task->expire, &now) > 0)) + return tv_ms_remain(&now, &task->expire); } /* OK we lose. Let's scan the tree then. */ @@ -106,8 +106,8 @@ int wake_expired_tasks() tree64_foreach(&timer_wq, data, stack, slen) { task = LIST_ELEM(data, struct task *, qlist); - if (!tv_isbefore(&task->expire, &now)) { - next_time = tv_remain(&now, &task->expire); + if (__tv_isgt(&task->expire, &now)) { + next_time = tv_ms_remain(&now, &task->expire); break; } diff --git a/src/time.c b/src/time.c index c146504717..262bc44911 100644 --- a/src/time.c +++ b/src/time.c @@ -1,7 +1,7 @@ /* * Time calculation functions. * - * Copyright 2000-2006 Willy Tarreau + * Copyright 2000-2007 Willy Tarreau * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -22,12 +22,10 @@ struct timeval start_date; /* the process's start date */ /* * adds ms to , set the result to and returns a pointer */ -REGPRM3 struct timeval *tv_delayfrom(struct timeval *tv, const struct timeval *from, int ms) +REGPRM3 struct timeval *_tv_ms_add(struct timeval *tv, const struct timeval *from, int ms) { - if (!tv || !from) - return NULL; - tv->tv_usec = from->tv_usec + (ms%1000)*1000; - tv->tv_sec = from->tv_sec + (ms/1000); + tv->tv_usec = from->tv_usec + (ms % 1000) * 1000; + tv->tv_sec = from->tv_sec + (ms / 1000); while (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; tv->tv_sec++; @@ -37,90 +35,41 @@ REGPRM3 struct timeval *tv_delayfrom(struct timeval *tv, const struct timeval *f /* * compares and modulo 1ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2 - * Must not be used when either argument is eternity. Use tv_cmp2_ms() for that. + * Must not be used when either argument is eternity. Use tv_ms_cmp2() for that. */ -REGPRM2 int tv_cmp_ms(const struct timeval *tv1, const struct timeval *tv2) +REGPRM2 int _tv_ms_cmp(const struct timeval *tv1, const struct timeval *tv2) { - if ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) { - if ((unsigned)tv2->tv_usec >= (unsigned)tv1->tv_usec + 1000) - return -1; - else if ((unsigned)tv1->tv_usec >= (unsigned)tv2->tv_usec + 1000) - return 1; - else - return 0; - } - else if (((unsigned)tv2->tv_sec > (unsigned)tv1->tv_sec + 1) || - (((unsigned)tv2->tv_sec == (unsigned)tv1->tv_sec + 1) && - ((unsigned)tv2->tv_usec + 1000000 >= (unsigned)tv1->tv_usec + 1000))) - return -1; - else if (((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec + 1) || - (((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec + 1) && - ((unsigned)tv1->tv_usec + 1000000 >= (unsigned)tv2->tv_usec + 1000))) - return 1; - else - return 0; + return __tv_ms_cmp(tv1, tv2); } /* * compares and modulo 1 ms: returns 0 if equal, -1 if tv1 < tv2, 1 if tv1 > tv2, * assuming that TV_ETERNITY is greater than everything. */ -REGPRM2 int tv_cmp2_ms(const struct timeval *tv1, const struct timeval *tv2) +REGPRM2 int _tv_ms_cmp2(const struct timeval *tv1, const struct timeval *tv2) { - if (tv_iseternity(tv1)) - if (tv_iseternity(tv2)) - return 0; /* same */ - else - return 1; /* tv1 later than tv2 */ - else if (tv_iseternity(tv2)) - return -1; /* tv2 later than tv1 */ - - if ((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec) { - if ((unsigned)tv1->tv_usec >= (unsigned)tv2->tv_usec + 1000) - return 1; - else if ((unsigned)tv2->tv_usec >= (unsigned)tv1->tv_usec + 1000) - return -1; - else - return 0; - } - else if (((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec + 1) || - (((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec + 1) && - ((unsigned)tv1->tv_usec + 1000000 >= (unsigned)tv2->tv_usec + 1000))) - return 1; - else if (((unsigned)tv2->tv_sec > (unsigned)tv1->tv_sec + 1) || - (((unsigned)tv2->tv_sec == (unsigned)tv1->tv_sec + 1) && - ((unsigned)tv2->tv_usec + 1000000 >= (unsigned)tv1->tv_usec + 1000))) - return -1; - else - return 0; + return __tv_ms_cmp2(tv1, tv2); } /* * compares and modulo 1 ms: returns 1 if tv1 <= tv2, 0 if tv1 > tv2, * assuming that TV_ETERNITY is greater than everything. Returns 0 if tv1 is * TV_ETERNITY, and always assumes that tv2 != TV_ETERNITY. Designed to replace - * occurrences of (tv_cmp2_ms(tv,now) <= 0). + * occurrences of (tv_ms_cmp2(tv,now) <= 0). */ -REGPRM2 int tv_cmp2_le(const struct timeval *tv1, const struct timeval *tv2) +REGPRM2 int _tv_ms_le2(const struct timeval *tv1, const struct timeval *tv2) { - if (likely((unsigned)tv1->tv_sec > (unsigned)tv2->tv_sec + 1)) - return 0; - - if (likely((unsigned)tv1->tv_sec < (unsigned)tv2->tv_sec)) - return 1; - - if (likely((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec)) { - if ((unsigned)tv2->tv_usec >= (unsigned)tv1->tv_usec + 1000) - return 1; - else - return 0; - } + return __tv_ms_le2(tv1, tv2); +} - if (unlikely(((unsigned)tv1->tv_sec == (unsigned)tv2->tv_sec + 1) && - ((unsigned)tv1->tv_usec + 1000000 >= (unsigned)tv2->tv_usec + 1000))) - return 0; - else - return 1; +/* + * returns the remaining time between tv1=now and event=tv2 + * if tv2 is passed, 0 is returned. + * Must not be used when either argument is eternity. + */ +REGPRM2 unsigned long _tv_ms_remain(const struct timeval *tv1, const struct timeval *tv2) +{ + return __tv_ms_remain(tv1, tv2); } /* @@ -128,49 +77,21 @@ REGPRM2 int tv_cmp2_le(const struct timeval *tv1, const struct timeval *tv2) * if tv2 is passed, 0 is returned. * Returns TIME_ETERNITY if tv2 is eternity. */ -REGPRM2 unsigned long tv_remain2(const struct timeval *tv1, const struct timeval *tv2) +REGPRM2 unsigned long _tv_ms_remain2(const struct timeval *tv1, const struct timeval *tv2) { - unsigned long ret; - if (tv_iseternity(tv2)) return TIME_ETERNITY; - if (tv_cmp_ms(tv1, tv2) >= 0) - return 0; /* event elapsed */ - - ret = (tv2->tv_sec - tv1->tv_sec) * 1000; - if ((unsigned)tv2->tv_usec > (unsigned)tv1->tv_usec) - ret += (tv2->tv_usec - tv1->tv_usec) / 1000; - else - ret -= (tv1->tv_usec - tv2->tv_usec) / 1000; - return (unsigned long) ret; + return __tv_ms_remain(tv1, tv2); } - /* - * returns the absolute difference, in ms, between tv1 and tv2 + * Returns the time in ms elapsed between tv1 and tv2, assuming that tv1<=tv2. * Must not be used when either argument is eternity. */ -REGPRM2 unsigned long tv_delta(const struct timeval *tv1, const struct timeval *tv2) +REGPRM2 unsigned long _tv_ms_elapsed(const struct timeval *tv1, const struct timeval *tv2) { - int cmp; - unsigned long ret; - - - cmp = tv_cmp(tv1, tv2); - if (!cmp) - return 0; /* same dates, null diff */ - else if (cmp < 0) { - const struct timeval *tmp = tv1; - tv1 = tv2; - tv2 = tmp; - } - ret = (tv1->tv_sec - tv2->tv_sec) * 1000; - if ((unsigned)tv1->tv_usec > (unsigned)tv2->tv_usec) - ret += (tv1->tv_usec - tv2->tv_usec) / 1000; - else - ret -= (tv2->tv_usec - tv1->tv_usec) / 1000; - return (unsigned long) ret; + return __tv_ms_elapsed(tv1, tv2); } /*