[Asterisk-cvs] asterisk app.c, 1.69, 1.70 asterisk.c, 1.168, 1.169 cdr.c, 1.49, 1.50 channel.c, 1.220, 1.221 cli.c, 1.91, 1.92 frame.c, 1.60, 1.61 manager.c, 1.102, 1.103 rtp.c, 1.138, 1.139 sched.c, 1.21, 1.22 translate.c, 1.39, 1.40 utils.c, 1.57, 1.58

kpfleming at lists.digium.com kpfleming at lists.digium.com
Fri Jul 15 18:52:57 CDT 2005


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)
 {




More information about the svn-commits mailing list