Update of /usr/cvsroot/asterisk
In directory mongoose.digium.com:/tmp/cvs-serv13236

Modified Files:
        app.c asterisk.c cdr.c channel.c cli.c frame.c manager.c rtp.c 
        sched.c translate.c utils.c 
Log Message:
add a library of timeval manipulation functions, and change a large number of 
usses to use the new functions (bug #4504)


Index: app.c
===================================================================
RCS file: /usr/cvsroot/asterisk/app.c,v
retrieving revision 1.69
retrieving revision 1.70
diff -u -d -r1.69 -r1.70
--- app.c       13 Jul 2005 19:27:09 -0000      1.69
+++ app.c       15 Jul 2005 23:00:46 -0000      1.70
@@ -408,7 +408,6 @@
 
 int ast_control_streamfile(struct ast_channel *chan, const char *file, const 
char *fwd, const char *rev, const char *stop, const char *pause, int skipms) 
 {
-       struct timeval started, ended;
        long elapsed = 0,last_elapsed =0;
        char *breaks=NULL;
        char *end=NULL;
@@ -443,7 +442,7 @@
        }
 
        for (;;) {
-               gettimeofday(&started,NULL);
+               struct timeval started = ast_tvnow();
 
                if (chan)
                        ast_stopstream(chan);
@@ -468,8 +467,7 @@
                        break;
 
                if (pause != NULL && strchr(pause, res)) {
-                       gettimeofday(&ended, NULL);
-                       elapsed = (((ended.tv_sec * 1000) + ended.tv_usec / 
1000) - ((started.tv_sec * 1000) + started.tv_usec / 1000) + last_elapsed);
+                       elapsed = ast_tvdiff_ms(ast_tvnow(), started) + 
last_elapsed;
                        for(;;) {
                                if (chan)
                                        ast_stopstream(chan);

Index: asterisk.c
===================================================================
RCS file: /usr/cvsroot/asterisk/asterisk.c,v
retrieving revision 1.168
retrieving revision 1.169
diff -u -d -r1.168 -r1.169
--- asterisk.c  15 Jul 2005 22:12:55 -0000      1.168
+++ asterisk.c  15 Jul 2005 23:00:46 -0000      1.169
@@ -1199,7 +1199,7 @@
                                                break;
                                        case 'd': /* date */
                                                memset(&tm, 0, sizeof(struct 
tm));
-                                               gettimeofday(&tv, NULL);
+                                               tv = ast_tvnow();
                                                if (localtime_r(&(tv.tv_sec), 
&tm)) {
                                                        strftime(p, 
sizeof(prompt) - strlen(prompt), "%Y-%m-%d", &tm);
                                                }
@@ -1256,7 +1256,7 @@
 #endif
                                        case 't': /* time */
                                                memset(&tm, 0, sizeof(struct 
tm));
-                                               gettimeofday(&tv, NULL);
+                                               tv = ast_tvnow();
                                                if (localtime_r(&(tv.tv_sec), 
&tm)) {
                                                        strftime(p, 
sizeof(prompt) - strlen(prompt), "%H:%M:%S", &tm);
                                                }

Index: cdr.c
===================================================================
RCS file: /usr/cvsroot/asterisk/cdr.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -d -r1.49 -r1.50
--- cdr.c       8 Jul 2005 21:09:38 -0000       1.49
+++ cdr.c       15 Jul 2005 23:00:46 -0000      1.50
@@ -419,9 +419,9 @@
                chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : 
"<unknown>";
                if (!ast_test_flag(cdr, AST_CDR_FLAG_POSTED) && 
!ast_test_flag(cdr, AST_CDR_FLAG_POST_DISABLED))
                        ast_log(LOG_WARNING, "CDR on channel '%s' not 
posted\n", chan);
-               if (!cdr->end.tv_sec && !cdr->end.tv_usec)
+               if (ast_tvzero(cdr->end))
                        ast_log(LOG_WARNING, "CDR on channel '%s' lacks end\n", 
chan);
-               if (!cdr->start.tv_sec && !cdr->start.tv_usec)
+               if (ast_tvzero(cdr->start))
                        ast_log(LOG_WARNING, "CDR on channel '%s' lacks 
start\n", chan);
 
                ast_cdr_free_vars(cdr, 0);
@@ -450,9 +450,9 @@
                        chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : 
"<unknown>";
                        if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED))
                                ast_log(LOG_WARNING, "CDR on channel '%s' 
already posted\n", chan);
-                       if (cdr->start.tv_sec || cdr->start.tv_usec)
+                       if (!ast_tvzero(cdr->start))
                                ast_log(LOG_WARNING, "CDR on channel '%s' 
already started\n", chan);
-                       gettimeofday(&cdr->start, NULL);
+                       cdr->start = ast_tvnow();
                }
                cdr = cdr->next;
        }
@@ -468,9 +468,8 @@
                        ast_log(LOG_WARNING, "CDR on channel '%s' already 
posted\n", chan);
                if (cdr->disposition < AST_CDR_ANSWERED)
                        cdr->disposition = AST_CDR_ANSWERED;
-               if (!cdr->answer.tv_sec && !cdr->answer.tv_usec) {
-                       gettimeofday(&cdr->answer, NULL);
-               }
+               if (ast_tvzero(cdr->answer))
+                       cdr->answer = ast_tvnow();
                cdr = cdr->next;
        }
 }
@@ -637,10 +636,10 @@
                chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : 
"<unknown>";
                if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED))
                        ast_log(LOG_WARNING, "CDR on channel '%s' already 
posted\n", chan);
-               if (!cdr->start.tv_sec && !cdr->start.tv_usec)
+               if (ast_tvzero(cdr->start))
                        ast_log(LOG_WARNING, "CDR on channel '%s' has not 
started\n", chan);
-               if (!cdr->end.tv_sec && !cdr->end.tv_usec) 
-                       gettimeofday(&cdr->end, NULL);
+               if (ast_tvzero(cdr->end))
+                       cdr->end = ast_tvnow();
                cdr = cdr->next;
        }
 }
@@ -780,12 +779,12 @@
                chan = !ast_strlen_zero(cdr->channel) ? cdr->channel : 
"<unknown>";
                if (ast_test_flag(cdr, AST_CDR_FLAG_POSTED))
                        ast_log(LOG_WARNING, "CDR on channel '%s' already 
posted\n", chan);
-               if (!cdr->end.tv_sec && !cdr->end.tv_usec)
+               if (ast_tvzero(cdr->end))
                        ast_log(LOG_WARNING, "CDR on channel '%s' lacks end\n", 
chan);
-               if (!cdr->start.tv_sec && !cdr->start.tv_usec)
+               if (ast_tvzero(cdr->start))
                        ast_log(LOG_WARNING, "CDR on channel '%s' lacks 
start\n", chan);
                cdr->duration = cdr->end.tv_sec - cdr->start.tv_sec + 
(cdr->end.tv_usec - cdr->start.tv_usec) / 1000000;
-               if (cdr->answer.tv_sec || cdr->answer.tv_usec)
+               if (!ast_tvzero(cdr->answer))
                        cdr->billsec = cdr->end.tv_sec - cdr->answer.tv_sec + 
(cdr->end.tv_usec - cdr->answer.tv_usec) / 1000000;
                else
                        cdr->billsec = 0;
@@ -1008,13 +1007,12 @@
 
 static void *do_cdr(void *data)
 {
-       struct timeval now;
        struct timespec timeout;
        int schedms;
        int numevents = 0;
 
        for(;;) {
-               gettimeofday(&now, NULL);
+               struct timeval now = ast_tvnow();
                schedms = ast_sched_wait(sched);
                /* this shouldn't happen, but provide a 1 second default just 
in case */
                if (schedms <= 0)

Index: channel.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channel.c,v
retrieving revision 1.220
retrieving revision 1.221
diff -u -d -r1.220 -r1.221
--- channel.c   15 Jul 2005 22:06:15 -0000      1.220
+++ channel.c   15 Jul 2005 23:00:46 -0000      1.221
@@ -1120,7 +1120,7 @@
 int ast_waitfor_n_fd(int *fds, int n, int *ms, int *exception)
 {
        /* Wait for x amount of time on a file descriptor to have input.  */
-       struct timeval start, now;
+       struct timeval start;
        int res;
        int x, y;
        int winner = -1;
@@ -1133,7 +1133,7 @@
                return -1;
        }
        if (*ms > 0)
-               gettimeofday(&start, NULL);
+               start = ast_tvnow();
        y = 0;
        for (x=0;x<n;x++) {
                if (fds[x] > -1) {
@@ -1166,13 +1166,8 @@
                }
        }
        if (*ms > 0) {
-               long passed;
-               gettimeofday(&now, NULL);
-               passed = (now.tv_sec - start.tv_sec) * 1000;
-               passed += (now.tv_usec - start.tv_usec) / 1000;
-               if (passed <= *ms)
-                       *ms -= passed;
-               else
+               *ms -= ast_tvdiff_ms(ast_tvnow(), start);
+               if (*ms < 0)
                        *ms = 0;
        }
        return winner;
@@ -1182,7 +1177,7 @@
        int *exception, int *outfd, int *ms)
 {
        /* Wait for x amount of time on a file descriptor to have input.  */
-       struct timeval start, end;
+       struct timeval start;
        struct pollfd *pfds;
        int res;
        long rms;
@@ -1253,7 +1248,7 @@
                }
        }
        if (*ms > 0) 
-               gettimeofday(&start, NULL);
+               start = ast_tvnow();
        res = poll(pfds, max, rms);
        if (res < 0) {
                for (x=0;x<n;x++) 
@@ -1315,13 +1310,8 @@
                }       
        }
        if (*ms > 0) {
-               long diff;
-               gettimeofday(&end, NULL);
-               diff = (end.tv_sec - start.tv_sec) * 1000;
-               diff += (end.tv_usec - start.tv_usec) / 1000;
-               if (diff < *ms)
-                       *ms -= diff;
-               else
+               *ms -= ast_tvdiff_ms(ast_tvnow(), start);
+               if (*ms < 0)
                        *ms = 0;
        }
        return winner;
@@ -2809,15 +2799,6 @@
        return 0;
 }
 
-static long tvdiff(struct timeval *now, struct timeval *then) 
-{
-#if 0
-       return (((now->tv_sec * 1000) + now->tv_usec / 1000) - ((then->tv_sec * 
1000) + then->tv_usec / 1000));
-#else
-       return (now->tv_sec - then->tv_sec) * 1000 + (now->tv_usec - 
then->tv_usec) / 1000;     
-#endif
-}
-
 /*--- Find bridged channel */
 struct ast_channel *ast_bridged_channel(struct ast_channel *chan)
 {
@@ -2878,7 +2859,6 @@
        int res=0;
        int o0nativeformats;
        int o1nativeformats;
-       struct timeval precise_now;
        long elapsed_ms=0, time_left_ms=0;
        
        cs[0] = c0;
@@ -2899,8 +2879,7 @@
                /* timestamp */
                if (config->timelimit) {
                        /* If there is a time limit, return now */
-                       gettimeofday(&precise_now,NULL);
-                       elapsed_ms = tvdiff(&precise_now,start_time);
+                       elapsed_ms = ast_tvdiff_ms(ast_tvnow(), *start_time);
                        time_left_ms = config->timelimit - elapsed_ms;
 
                        if (*playitagain && 
((ast_test_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING)) || 
(ast_test_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING))) && 
(config->play_warning && time_left_ms <= config->play_warning)) { 
@@ -3022,7 +3001,7 @@
        int firstpass;
        int o0nativeformats;
        int o1nativeformats;
-       struct timeval start_time,precise_now;
+       struct timeval start_time;
        long elapsed_ms=0, time_left_ms=0;
        int playit=0, playitagain=1, first_time=1;
 
@@ -3031,7 +3010,7 @@
        config->firstpass = 0;
 
        /* timestamp */
-       gettimeofday(&start_time,NULL);
+       start_time = ast_tvnow();
        time_left_ms = config->timelimit;
 
        if ((ast_test_flag(&(config->features_caller), 
AST_FEATURE_PLAY_WARNING)) && config->start_sound && firstpass)
@@ -3073,8 +3052,7 @@
        for (/* ever */;;) {
                /* timestamp */
                if (config->timelimit) {
-                       gettimeofday(&precise_now,NULL);
-                       elapsed_ms = tvdiff(&precise_now,&start_time);
+                       elapsed_ms = ast_tvdiff_ms(ast_tvnow(), start_time);
                        time_left_ms = config->timelimit - elapsed_ms;
 
                        if (playitagain && 
((ast_test_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING)) || 
(ast_test_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING))) && 
(config->play_warning && time_left_ms <= config->play_warning)) { 

Index: cli.c
===================================================================
RCS file: /usr/cvsroot/asterisk/cli.c,v
retrieving revision 1.91
retrieving revision 1.92
diff -u -d -r1.91 -r1.92
--- cli.c       15 Jul 2005 22:06:15 -0000      1.91
+++ cli.c       15 Jul 2005 23:00:46 -0000      1.92
@@ -668,7 +668,7 @@
        
        if (argc != 3)
                return RESULT_SHOWUSAGE;
-       gettimeofday(&now, NULL);
+       now = ast_tvnow();
        c = ast_get_channel_by_name_locked(argv[2]);
        if (!c) {
                ast_cli(fd, "%s is not a known channel\n", argv[2]);

Index: frame.c
===================================================================
RCS file: /usr/cvsroot/asterisk/frame.c,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -d -r1.60 -r1.61
--- frame.c     12 Jul 2005 22:20:16 -0000      1.60
+++ frame.c     15 Jul 2005 23:00:46 -0000      1.61
@@ -144,8 +144,7 @@
        else
                memcpy(s->data + s->len, f->data, f->datalen);
        /* If either side is empty, reset the delivery time */
-       if (!s->len || (!f->delivery.tv_sec && !f->delivery.tv_usec) ||
-                       (!s->delivery.tv_sec && !s->delivery.tv_usec))
+       if (!s->len || ast_tvzero(f->delivery) || ast_tvzero(s->delivery))      
/* XXX really ? */
                s->delivery = f->delivery;
        s->len += f->datalen;
        return 0;
@@ -181,7 +180,7 @@
        s->f.offset = AST_FRIENDLY_OFFSET;
        s->f.datalen = len;
        /* Samples will be improper given VAD, but with VAD the concept really 
doesn't even exist */
-       s->f.samples = len * s->samplesperbyte;
+       s->f.samples = len * s->samplesperbyte; /* XXX rounding */
        s->f.delivery = s->delivery;
        /* Fill Data */
        memcpy(s->f.data, s->data, len);
@@ -191,14 +190,9 @@
                /* In principle this should all be fine because if we are 
sending
                   G.729 VAD, the next timestamp will take over anyawy */
                memmove(s->data, s->data + len, s->len);
-               if (s->delivery.tv_sec || s->delivery.tv_usec) {
+               if (!ast_tvzero(s->delivery)) {
                        /* If we have delivery time, increment it, otherwise, 
leave it at 0 */
-                       s->delivery.tv_sec += (len * s->samplesperbyte) / 
8000.0;
-                       s->delivery.tv_usec += (((int)(len * 
s->samplesperbyte)) % 8000) * 125;
-                       if (s->delivery.tv_usec > 1000000) {
-                               s->delivery.tv_usec -= 1000000;
-                               s->delivery.tv_sec += 1;
-                       }
+                       s->delivery = ast_tvadd(s->delivery, 
ast_samp2tv(s->f.samples, 8000));
                }
        }
        /* Return frame */

Index: manager.c
===================================================================
RCS file: /usr/cvsroot/asterisk/manager.c,v
retrieving revision 1.102
retrieving revision 1.103
diff -u -d -r1.102 -r1.103
--- manager.c   10 Jul 2005 22:56:21 -0000      1.102
+++ manager.c   15 Jul 2005 23:00:46 -0000      1.103
@@ -683,11 +683,10 @@
        char idText[256] = "";
        struct ast_channel *c;
        char bridge[256];
-       struct timeval now;
+       struct timeval now = ast_tvnow();
        long elapsed_seconds=0;
        int all = !name || ast_strlen_zero(name); /* set if we want all 
channels */
 
-       gettimeofday(&now, NULL);
        astman_send_ack(s, m, "Channel status will follow");
         if (id && !ast_strlen_zero(id))
                 snprintf(idText,256,"ActionID: %s\r\n",id);

Index: rtp.c
===================================================================
RCS file: /usr/cvsroot/asterisk/rtp.c,v
retrieving revision 1.138
retrieving revision 1.139
diff -u -d -r1.138 -r1.139
--- rtp.c       14 Jul 2005 23:58:36 -0000      1.138
+++ rtp.c       15 Jul 2005 23:00:46 -0000      1.139
@@ -42,6 +42,7 @@
 #include "asterisk/utils.h"
 #include "asterisk/cli.h"
 #include "asterisk/unaligned.h"
+#include "asterisk/utils.h"
 
 #define MAX_TIMESTAMP_SKEW     640
 
@@ -144,12 +145,10 @@
 
 static struct ast_frame *send_dtmf(struct ast_rtp *rtp)
 {
-       struct timeval tv;
        static struct ast_frame null_frame = { AST_FRAME_NULL, };
        char iabuf[INET_ADDRSTRLEN];
-       gettimeofday(&tv, NULL);
-       if ((tv.tv_sec < rtp->dtmfmute.tv_sec) ||
-           ((tv.tv_sec == rtp->dtmfmute.tv_sec) && (tv.tv_usec < 
rtp->dtmfmute.tv_usec))) {
+
+       if (ast_tvcmp(ast_tvnow(), rtp->dtmfmute) < 0) {
                if (option_debug)
                        ast_log(LOG_DEBUG, "Ignore potential DTMF echo from 
'%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr));
                rtp->resp = 0;
@@ -367,24 +366,13 @@
 
 static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int 
timestamp, int mark)
 {
-       if ((!rtp->rxcore.tv_sec && !rtp->rxcore.tv_usec) || mark) {
-               gettimeofday(&rtp->rxcore, NULL);
-               rtp->rxcore.tv_sec -= timestamp / 8000;
-               rtp->rxcore.tv_usec -= (timestamp % 8000) * 125;
+       struct timeval ts = ast_samp2tv( timestamp, 8000);
+       if (ast_tvzero(rtp->rxcore) || mark) {
+               rtp->rxcore = ast_tvsub(ast_tvnow(), ts);
                /* Round to 20ms for nice, pretty timestamps */
                rtp->rxcore.tv_usec -= rtp->rxcore.tv_usec % 20000;
-               if (rtp->rxcore.tv_usec < 0) {
-                       /* Adjust appropriately if necessary */
-                       rtp->rxcore.tv_usec += 1000000;
-                       rtp->rxcore.tv_sec -= 1;
-               }
-       }
-       tv->tv_sec = rtp->rxcore.tv_sec + timestamp / 8000;
-       tv->tv_usec = rtp->rxcore.tv_usec + (timestamp % 8000) * 125;
-       if (tv->tv_usec >= 1000000) {
-               tv->tv_usec -= 1000000;
-               tv->tv_sec += 1;
        }
+       *tv = ast_tvadd(rtp->rxcore, ts);
 }
 
 struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
@@ -1033,28 +1021,19 @@
 
 static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
 {
-       struct timeval now;
-       unsigned int ms;
-       if (!rtp->txcore.tv_sec && !rtp->txcore.tv_usec) {
-               gettimeofday(&rtp->txcore, NULL);
+       struct timeval t;
+       long ms;
+       if (ast_tvzero(rtp->txcore)) {
+               rtp->txcore = ast_tvnow();
                /* Round to 20ms for nice, pretty timestamps */
                rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000;
        }
-       if (delivery && (delivery->tv_sec || delivery->tv_usec)) {
-               /* Use previous txcore */
-               ms = (delivery->tv_sec - rtp->txcore.tv_sec) * 1000;
-               ms += (1000000 + delivery->tv_usec - rtp->txcore.tv_usec) / 
1000 - 1000;
-               rtp->txcore.tv_sec = delivery->tv_sec;
-               rtp->txcore.tv_usec = delivery->tv_usec;
-       } else {
-               gettimeofday(&now, NULL);
-               ms = (now.tv_sec - rtp->txcore.tv_sec) * 1000;
-               ms += (1000000 + now.tv_usec - rtp->txcore.tv_usec) / 1000 - 
1000;
-               /* Use what we just got for next time */
-               rtp->txcore.tv_sec = now.tv_sec;
-               rtp->txcore.tv_usec = now.tv_usec;
-       }
-       return ms;
+       /* Use previous txcore if available */
+       t = (delivery && !ast_tvzero(*delivery)) ? *delivery : ast_tvnow();
+       ms = ast_tvdiff_ms(t, rtp->txcore);
+       /* Use what we just got for next time */
+       rtp->txcore = t;
+       return (unsigned int) ms;
 }
 
 int ast_rtp_senddigit(struct ast_rtp *rtp, char digit)
@@ -1087,12 +1066,7 @@
        if (!rtp->them.sin_addr.s_addr)
                return 0;
 
-       gettimeofday(&rtp->dtmfmute, NULL);
-       rtp->dtmfmute.tv_usec += (500 * 1000);
-       if (rtp->dtmfmute.tv_usec > 1000000) {
-               rtp->dtmfmute.tv_usec -= 1000000;
-               rtp->dtmfmute.tv_sec += 1;
-       }
+       rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
        
        /* Get a pointer to the header */
        rtpheader = (unsigned int *)data;
@@ -1159,13 +1133,8 @@
        if (!rtp->them.sin_addr.s_addr)
                return 0;
 
-       gettimeofday(&rtp->dtmfmute, NULL);
-       rtp->dtmfmute.tv_usec += (500 * 1000);
-       if (rtp->dtmfmute.tv_usec > 1000000) {
-               rtp->dtmfmute.tv_usec -= 1000000;
-               rtp->dtmfmute.tv_sec += 1;
-       }
-       
+       rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
+
        /* Get a pointer to the header */
        rtpheader = (unsigned int *)data;
        rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | 
(rtp->seqno++));
@@ -1201,7 +1170,7 @@
 
                /* Re-calculate last TS */
                rtp->lastts = rtp->lastts + ms * 8;
-               if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
+               if (ast_tvzero(f->delivery)) {
                        /* If this isn't an absolute delivery time, Check if it 
is close to our prediction, 
                           and if so, go with our prediction */
                        if (abs(rtp->lastts - pred) < MAX_TIMESTAMP_SKEW)
@@ -1218,7 +1187,7 @@
                /* Re-calculate last TS */
                rtp->lastts = rtp->lastts + ms * 90;
                /* If it's close to our prediction, go for it */
-               if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
+               if (ast_tvzero(f->delivery)) {
                        if (abs(rtp->lastts - pred) < 7200) {
                                rtp->lastts = pred;
                                rtp->lastovidtimestamp += f->samples;

Index: sched.c
===================================================================
RCS file: /usr/cvsroot/asterisk/sched.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- sched.c     15 Jul 2005 22:21:31 -0000      1.21
+++ sched.c     15 Jul 2005 23:00:46 -0000      1.22
@@ -31,6 +31,7 @@
 #include "asterisk/logger.h"
 #include "asterisk/channel.h"
 #include "asterisk/lock.h"
+#include "asterisk/utils.h"
 
 /* Determine if a is sooner than b */
 #define SOONER(a,b) (((b).tv_sec > (a).tv_sec) || \
@@ -148,18 +149,13 @@
         * Return the number of milliseconds 
         * until the next scheduled event
         */
-       struct timeval tv;
        int ms;
        DEBUG(ast_log(LOG_DEBUG, "ast_sched_wait()\n"));
        ast_mutex_lock(&con->lock);
        if (!con->schedq) {
                ms = -1;
-       } else if (gettimeofday(&tv, NULL) < 0) {
-               /* This should never happen */
-               ms = 0;
        } else {
-               ms = (con->schedq->when.tv_sec - tv.tv_sec) * 1000;
-               ms += (con->schedq->when.tv_usec - tv.tv_usec) / 1000;
+               ms = ast_tvdiff_ms(con->schedq->when, ast_tvnow());
                if (ms < 0)
                        ms = 0;
        }
@@ -194,41 +190,21 @@
        con->schedcnt++;
 }
 
-static inline int sched_settime(struct timeval *tv, int when)
+/*
+ * given the last event *tv and the offset in milliseconds 'when',
+ * computes the next value,
+ */
+static int sched_settime(struct timeval *tv, int when)
 {
-       struct timeval tv_tmp;
-       long error_sec, error_usec;
+       struct timeval now = ast_tvnow();
 
-       if (gettimeofday(&tv_tmp, NULL) < 0) {
-               /* This shouldn't ever happen, but let's be sure */
-               ast_log(LOG_NOTICE, "gettimeofday() failed!\n");
-               return -1;
-       }
        /*ast_log(LOG_DEBUG, "TV -> %lu,%lu\n", tv->tv_sec, tv->tv_usec);*/
-       if (((unsigned long)(tv->tv_sec) > 0)||((unsigned long)(tv->tv_usec) > 
0)) {
-               if ((unsigned long)(tv_tmp.tv_usec) < (unsigned 
long)(tv->tv_usec)) {
-                       tv_tmp.tv_usec += 1000000;
-                       tv_tmp.tv_sec -= 1;
-               }
-               error_sec = (unsigned long)(tv_tmp.tv_sec) - (unsigned 
long)(tv->tv_sec);
-               error_usec = (unsigned long)(tv_tmp.tv_usec) - (unsigned 
long)(tv->tv_usec);
-       } else {
-               /*ast_log(LOG_DEBUG, "Initializing error\n");*/
-               error_sec = 0;
-               error_usec = 0;
-       }
-       /*ast_log(LOG_DEBUG, "ERROR -> %lu,%lu\n", error_sec, error_usec);*/
-       if (error_sec * 1000 + error_usec / 1000 < when) {
-               tv->tv_sec = tv_tmp.tv_sec + (when/1000 - error_sec);
-               tv->tv_usec = tv_tmp.tv_usec + ((when % 1000) * 1000 - 
error_usec);
-       } else {
+       if (ast_tvzero(*tv))    /* not supplied, default to now */
+               *tv = now;
+       *tv = ast_tvadd(*tv, ast_samp2tv(when, 1000));
+       if (ast_tvcmp(*tv, now) < 0) {
                ast_log(LOG_DEBUG, "Request to schedule in the past?!?!\n");
-               tv->tv_sec = tv_tmp.tv_sec;
-               tv->tv_usec = tv_tmp.tv_usec;
-       }
-       if (tv->tv_usec > 1000000) {
-               tv->tv_sec++;
-               tv->tv_usec-= 1000000;
+               *tv = now;
        }
        return 0;
 }
@@ -251,8 +227,7 @@
                tmp->callback = callback;
                tmp->data = data;
                tmp->resched = when;
-               tmp->when.tv_sec = 0;
-               tmp->when.tv_usec = 0;
+               tmp->when = ast_tv(0, 0);
                if (sched_settime(&tmp->when, when)) {
                        sched_release(con, tmp);
                } else {
@@ -315,9 +290,7 @@
         * stderr
         */
        struct sched *q;
-       struct timeval tv;
-       time_t s, ms;
-       gettimeofday(&tv, NULL);
+       struct timeval tv = ast_tvnow();
 #ifdef SCHED_MAX_CACHE
        ast_log(LOG_DEBUG, "Asterisk Schedule Dump (%d in Q, %d Total, %d 
Cache)\n", con->schedcnt, con->eventcnt - 1, con->schedccnt);
 #else
@@ -327,21 +300,15 @@
        ast_log(LOG_DEBUG, 
"=============================================================\n");
        ast_log(LOG_DEBUG, "|ID    Callback          Data              Time  
(sec:ms)   |\n");
        ast_log(LOG_DEBUG, 
"+-----+-----------------+-----------------+-----------------+\n");
-       q = con->schedq;
-       while(q) {
-               s =  q->when.tv_sec - tv.tv_sec;
-               ms = q->when.tv_usec - tv.tv_usec;
-               if (ms < 0) {
-                       ms += 1000000;
-                       s--;
-               }
+       for (q = con->schedq; q; q = q->next) {
+               struct timeval delta =  ast_tvsub(q->when, tv);
+
                ast_log(LOG_DEBUG, "|%.4d | %-15p | %-15p | %.6ld : %.6ld |\n", 
-                               q->id,
-                               q->callback,
-                               q->data,
-                               (long)s,
-                               (long)ms);
-               q=q->next;
+                       q->id,
+                       q->callback,
+                       q->data,
+                       delta.tv_sec,
+                       delta.tv_usec);
        }
        ast_log(LOG_DEBUG, 
"=============================================================\n");
        
@@ -362,15 +329,13 @@
        for(;;) {
                if (!con->schedq)
                        break;
-               if (gettimeofday(&tv, NULL)) {
-                       /* This should never happen */
-                       ast_log(LOG_NOTICE, "gettimeofday() failed!\n");
-                       break;
-               }
-               /* We only care about millisecond accuracy anyway, so this will
-                  help us get more than one event at one time if they are very
-                  close together. */
-               tv.tv_usec += 1000;
+               
+               /* schedule all events which are going to expire within 1ms.
+                * We only care about millisecond accuracy anyway, so this will
+                * help us get more than one event at one time if they are very
+                * close together.
+                */
+               tv = ast_tvadd(ast_tvnow(), ast_tv(0, 1000));
                if (SOONER(con->schedq->when, tv)) {
                        current = con->schedq;
                        con->schedq = con->schedq->next;
@@ -414,7 +379,6 @@
 {
        struct sched *s;
        long secs;
-       struct timeval now;
        DEBUG(ast_log(LOG_DEBUG, "ast_sched_when()\n"));
 
        ast_mutex_lock(&con->lock);
@@ -425,11 +389,8 @@
        }
        secs=-1;
        if (s!=NULL) {
-               if (gettimeofday(&now, NULL)) {
-                       ast_log(LOG_NOTICE, "gettimeofday() failed!\n");
-               } else {
-                       secs=s->when.tv_sec-now.tv_sec;
-               }
+               struct timeval now = ast_tvnow();
+               secs=s->when.tv_sec-now.tv_sec;
        }
        ast_mutex_unlock(&con->lock);
        return secs;

Index: translate.c
===================================================================
RCS file: /usr/cvsroot/asterisk/translate.c,v
retrieving revision 1.39
retrieving revision 1.40
diff -u -d -r1.39 -r1.40
--- translate.c 5 Jul 2005 14:00:03 -0000       1.39
+++ translate.c 15 Jul 2005 23:00:46 -0000      1.40
@@ -107,10 +107,7 @@
                                
                        if (tmp) {
                                tmp->next = NULL;
-                               tmp->nextin.tv_sec = 0;
-                               tmp->nextin.tv_usec = 0;
-                               tmp->nextout.tv_sec = 0;
-                               tmp->nextout.tv_usec = 0;
+                               tmp->nextin = tmp->nextout = ast_tv( 0, 0 );
                                tmp->step = tr_matrix[source][dest].step;
                                tmp->state = tmp->step->newpvt();
                                if (!tmp->state) {
@@ -147,47 +144,26 @@
        p = path;
        /* Feed the first frame into the first translator */
        p->step->framein(p->state, f);
-       if (f->delivery.tv_sec || f->delivery.tv_usec) {
-               if (path->nextin.tv_sec || path->nextin.tv_usec) {
+       if (!ast_tvzero(f->delivery)) {
+               if (!ast_tvzero(path->nextin)) {
                        /* Make sure this is in line with what we were 
expecting */
-                       if ((path->nextin.tv_sec != f->delivery.tv_sec) ||
-                           (path->nextin.tv_usec != f->delivery.tv_usec)) {
+                       if (!ast_tveq(path->nextin, f->delivery)) {
                                /* The time has changed between what we 
expected and this
                                   most recent time on the new packet.  Adjust 
our output
                                   time appropriately */
-                               long sdiff;
-                               long udiff;
-                               sdiff = f->delivery.tv_sec - 
path->nextin.tv_sec;
-                               udiff = f->delivery.tv_usec - 
path->nextin.tv_usec;
-                               path->nextin.tv_sec = f->delivery.tv_sec;
-                               path->nextin.tv_usec = f->delivery.tv_usec;
-                               path->nextout.tv_sec += sdiff;
-                               path->nextout.tv_usec += udiff;
-                               if (path->nextout.tv_usec < 0) {
-                                       path->nextout.tv_usec += 1000000;
-                                       path->nextout.tv_sec--;
-                               } else if (path->nextout.tv_usec >= 1000000) {
-                                       path->nextout.tv_usec -= 1000000;
-                                       path->nextout.tv_sec++;
-                               }
+                               path->nextout = ast_tvadd(path->nextout,
+                                       ast_tvsub(f->delivery, path->nextin));
+                               path->nextin = f->delivery;
                        }
                } else {
                        /* This is our first pass.  Make sure the timing looks 
good */
-                       path->nextin.tv_sec = f->delivery.tv_sec;
-                       path->nextin.tv_usec = f->delivery.tv_usec;
-                       path->nextout.tv_sec = f->delivery.tv_sec;
-                       path->nextout.tv_usec = f->delivery.tv_usec;
+                       path->nextin = f->delivery;
+                       path->nextout = f->delivery;
                }
                /* Predict next incoming sample */
-               path->nextin.tv_sec += (f->samples / 8000);
-               path->nextin.tv_usec += ((f->samples % 8000) * 125);
-               if (path->nextin.tv_usec >= 1000000) {
-                       path->nextin.tv_usec -= 1000000;
-                       path->nextin.tv_sec++;
-               }
+               path->nextin = ast_tvadd(path->nextin, ast_samp2tv(f->samples, 
8000));
        }
-       delivery.tv_sec = f->delivery.tv_sec;
-       delivery.tv_usec = f->delivery.tv_usec;
+       delivery = f->delivery;
        if (consume)
                ast_frfree(f);
        while(p) {
@@ -200,22 +176,15 @@
                if (p->next) 
                        p->next->step->framein(p->next->state, out);
                else {
-                       if (delivery.tv_sec || delivery.tv_usec) {
+                       if (!ast_tvzero(delivery)) {
                                /* Use next predicted outgoing timestamp */
-                               out->delivery.tv_sec = path->nextout.tv_sec;
-                               out->delivery.tv_usec = path->nextout.tv_usec;
+                               out->delivery = path->nextout;
                                
                                /* Predict next outgoing timestamp from samples 
in this
                                   frame. */
-                               path->nextout.tv_sec += (out->samples / 8000);
-                               path->nextout.tv_usec += ((out->samples % 8000) 
* 125);
-                               if (path->nextout.tv_usec >= 1000000) {
-                                       path->nextout.tv_sec++;
-                                       path->nextout.tv_usec -= 1000000;
-                               }
+                               path->nextout = ast_tvadd(path->nextout, 
ast_samp2tv( out->samples, 8000));
                        } else {
-                               out->delivery.tv_sec = 0;
-                               out->delivery.tv_usec = 0;
+                               out->delivery = ast_tv(0, 0);
                        }
                        return out;
                }
@@ -231,7 +200,7 @@
        int sofar=0;
        struct ast_translator_pvt *pvt;
        struct ast_frame *f, *out;
-       struct timeval start, finish;
+       struct timeval start;
        int cost;
        if(!samples)
          samples = 1;
@@ -248,7 +217,7 @@
                t->cost = 99999;
                return;
        }
-       gettimeofday(&start, NULL);
+       start = ast_tvnow();
        /* Call the encoder until we've processed one second of time */
        while(sofar < samples * 8000) {
                f = t->sample();
@@ -265,9 +234,8 @@
                        ast_frfree(out);
                }
        }
-       gettimeofday(&finish, NULL);
+       cost = ast_tvdiff_ms(ast_tvnow(), start);
        t->destroy(pvt);
-       cost = (finish.tv_sec - start.tv_sec) * 1000 + (finish.tv_usec - 
start.tv_usec) / 1000;
        t->cost = cost / samples;
        if (!t->cost)
                t->cost = 1;

Index: utils.c
===================================================================
RCS file: /usr/cvsroot/asterisk/utils.c,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -d -r1.57 -r1.58
--- utils.c     15 Jul 2005 22:06:15 -0000      1.57
+++ utils.c     15 Jul 2005 23:00:46 -0000      1.58
@@ -493,6 +493,55 @@
        return 0;
 }
 
+#define ONE_MILLION    1000000
+/*
+ * put timeval in a valid range. usec is 0..999999
+ * negative values are not allowed and truncated.
+ */
+static struct timeval tvfix(struct timeval a)
+{
+       if (a.tv_usec >= ONE_MILLION) {
+               ast_log(LOG_ERROR, "warning too large timestamp %ld.%ld\n",
+                       a.tv_sec, a.tv_usec);
+               a.tv_sec += a.tv_usec % ONE_MILLION;
+               a.tv_usec %= ONE_MILLION;
+       } else if (a.tv_usec < 0) {
+               ast_log(LOG_ERROR, "warning negative timestamp %ld.%ld\n",
+                       a.tv_sec, a.tv_usec);
+               a.tv_usec = 0;
+       }
+       return a;
+}
+
+struct timeval ast_tvadd(struct timeval a, struct timeval b)
+{
+       /* consistency checks to guarantee usec in 0..999999 */
+       a = tvfix(a);
+       b = tvfix(b);
+       a.tv_sec += b.tv_sec;
+       a.tv_usec += b.tv_usec;
+       if (a.tv_usec >= ONE_MILLION) {
+               a.tv_sec++;
+               a.tv_usec -= ONE_MILLION;
+       }
+       return a;
+}
+
+struct timeval ast_tvsub(struct timeval a, struct timeval b)
+{
+       /* consistency checks to guarantee usec in 0..999999 */
+       a = tvfix(a);
+       b = tvfix(b);
+       a.tv_sec -= b.tv_sec;
+       a.tv_usec -= b.tv_usec;
+       if (a.tv_usec < 0) {
+               a.tv_sec-- ;
+               a.tv_usec += ONE_MILLION;
+       }
+       return a;
+}
+#undef ONE_MILLION
+
 #ifndef HAVE_STRCASESTR
 static char *upper(const char *orig, char *buf, int bufsize)
 {

_______________________________________________
Asterisk-Cvs mailing list
[email protected]
http://lists.digium.com/mailman/listinfo/asterisk-cvs

Reply via email to