Browse code

- ser equivalents to time(2) and gettimeofday(2), using internal ser time (faster then making a syscall, but at least in the gettimeofday case more imprecise, can be about 0.1-0.2 s off)

Andrei Pelinescu-Onciul authored on 17/07/2008 07:51:34
Showing 2 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,38 @@
0
+/* 
1
+ * $Id$
2
+ * 
3
+ * time related functions
4
+ *
5
+ * Copyright (C) 2006 iptelorg GmbH
6
+ *
7
+ * Permission to use, copy, modify, and distribute this software for any
8
+ * purpose with or without fee is hereby granted, provided that the above
9
+ * copyright notice and this permission notice appear in all copies.
10
+ *
11
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
+ */
19
+/* History:
20
+ * --------
21
+ *  2008-07-16  initial version (andrei)
22
+ */
23
+#ifndef _ser_time_h
24
+#define _ser_time_h
25
+
26
+#include <sys/time.h>
27
+#include <time.h>
28
+
29
+/* time(2) equivalent, using ser internal timers (faster then a syscall) */
30
+time_t ser_time(time_t* t);
31
+
32
+/* gettimeofday(2) equivalent, faster but much more imprecise
33
+ * (in normal conditions should be within 0.1 s of the real time)
34
+ * WARNING: ignores tz (it's obsolete anyway) */
35
+int ser_gettimeofday(struct timeval* tv, const struct timezone *tz);
36
+
37
+#endif /* _ser_time_h */
... ...
@@ -394,6 +394,13 @@ int arm_timer()
394 394
 
395 395
 
396 396
 
397
+#ifdef DBG_ser_time
398
+/* debugging  only */
399
+void check_ser_drift();
400
+#endif /* DBG_set_time */
401
+
402
+
403
+
397 404
 /* adjust the timer using the "real" time, each TIMER_RESYNC_TICKS, but only
398 405
  * if timer drift > TIMER_MAX_DRIFT
399 406
  * NOTES: - it will adjust time within  TIMER_MAX_DRIFT from the "real"
... ...
@@ -412,6 +419,9 @@ inline static void adjust_ticks()
412 412
 	
413 413
 	/* fix ticks if necessary */
414 414
 	if ((*ticks-last_adj_check)>=(ticks_t)TIMER_RESYNC_TICKS){
415
+#ifdef DBG_ser_time
416
+		check_ser_drift();
417
+#endif /* DBG_ser_time */
415 418
 		last_adj_check=*ticks;
416 419
 		if (gettimeofday(&crt_time, 0)<0){
417 420
 			LOG(L_ERR, "ERROR: adjust_ticks: gettimeofday failed: %s [%d]\n",
... ...
@@ -461,6 +471,62 @@ inline static void adjust_ticks()
461 461
 
462 462
 
463 463
 
464
+/* time(2) equivalent, using ser internal timers (faster then a syscall) */
465
+time_t ser_time(time_t *t)
466
+{
467
+	if (likely(t==0))
468
+		return last_time.tv_sec+TICKS_TO_S(*ticks-last_ticks);
469
+	*t=last_time.tv_sec+TICKS_TO_S(*ticks-last_ticks);
470
+	return *t;
471
+}
472
+
473
+
474
+
475
+/* gettimeofday(2) equivalent, using ser internal timers (faster 
476
+ * but more imprecise)
477
+ * WARNING: ignores tz (it's obsolete anyway)*/
478
+int ser_gettimeofday(struct timeval* tv, struct timezone* tz)
479
+{
480
+	if (likely(tv!=0)){
481
+		tv->tv_sec=last_time.tv_sec+TICKS_TO_S(*ticks-last_ticks);
482
+		tv->tv_usec=last_time.tv_usec+
483
+					(TICKS_TO_MS(*ticks-last_ticks)%1000)*1000;
484
+	}
485
+	return 0;
486
+}
487
+
488
+
489
+
490
+#ifdef DBG_ser_time
491
+/* debugging  only, remove */
492
+void check_ser_drift()
493
+{
494
+	time_t t1, t2;
495
+	struct timeval tv1, tv2;
496
+	int r;
497
+	
498
+	t1=time(0);
499
+	t2=ser_time(0);
500
+	if (t1!=t2)
501
+		BUG("time(0)!=ser_time(0) : %d != %d \n", (unsigned)t1, (unsigned)t2);
502
+	
503
+	r=gettimeofday(&tv1, 0);
504
+	ser_gettimeofday(&tv2, 0);
505
+	if (tv1.tv_sec!=tv2.tv_sec)
506
+		BUG("gettimeofday seconds!=ser_gettimeofday seconds : %d != %d \n",
507
+				(unsigned)tv1.tv_sec, (unsigned)tv2.tv_sec);
508
+	else if ((tv1.tv_usec > tv2.tv_usec) && 
509
+				(unsigned)(tv1.tv_usec-tv2.tv_usec)>100000)
510
+		BUG("gettimeofday usecs > ser_gettimeofday with > 0.1s : %d ms\n",
511
+			(unsigned)(tv1.tv_usec-tv2.tv_usec)/1000);
512
+	else if ((tv1.tv_usec < tv2.tv_usec) && 
513
+				(unsigned)(tv2.tv_usec-tv1.tv_usec)>100000)
514
+		BUG("gettimeofday usecs < ser_gettimeofday with > 0.1s : %d ms\n",
515
+			(unsigned)(tv2.tv_usec-tv1.tv_usec)/1000);
516
+}
517
+#endif /* DBG_ser_time */
518
+
519
+
464 520
 
465 521
 struct timer_ln* timer_alloc()
466 522
 {