Re: [RFC - 0/9] Generic timekeeping subsystem (v. B5)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Roman Zippel wrote:


~

The thing that worries me about this function is that it does every thing in usec. We are using nsec in xtime now and I wonder if it would not be more accurate to do the math in nsecs. Even tick size (tick_nsec) does not translate well to usec, it currently being 999849 nsecs.

George
---

 kernel/time.c  |    3 ++-
 kernel/timer.c |   53 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 1 deletion(-)

Index: linux-2.6/kernel/time.c
===================================================================
--- linux-2.6.orig/kernel/time.c	2005-07-13 03:18:04.000000000 +0200
+++ linux-2.6/kernel/time.c	2005-08-16 01:37:20.000000000 +0200
@@ -366,8 +366,9 @@ int do_adjtimex(struct timex *txc)
 	    } /* txc->modes & ADJ_OFFSET */
 	    if (txc->modes & ADJ_TICK) {
 		tick_usec = txc->tick;
-		tick_nsec = TICK_USEC_TO_NSEC(tick_usec);
 	    }
+	    if (txc->modes & (ADJ_FREQUENCY|ADJ_OFFSET|ADJ_TICK))
+		    time_recalc();
 	} /* txc->modes */
 leave:	if ((time_status & (STA_UNSYNC|STA_CLOCKERR)) != 0
 	    || ((time_status & (STA_PPSFREQ|STA_PPSTIME)) != 0
Index: linux-2.6/kernel/timer.c
===================================================================
--- linux-2.6.orig/kernel/timer.c	2005-07-13 03:18:04.000000000 +0200
+++ linux-2.6/kernel/timer.c	2005-08-16 23:10:53.000000000 +0200
@@ -559,6 +559,7 @@ found:
  */
 unsigned long tick_usec = TICK_USEC; 		/* USER_HZ period (usec) */
 unsigned long tick_nsec = TICK_NSEC;		/* ACTHZ period (nsec) */
+unsigned long tick_nsec2 = TICK_NSEC;
/* * The current time @@ -569,6 +570,7 @@ unsigned long tick_nsec = TICK_NSEC; /*
  * the usual normalization.
  */
 struct timespec xtime __attribute__ ((aligned (16)));
+struct timespec xtime2 __attribute__ ((aligned (16)));
 struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
EXPORT_SYMBOL(xtime);
@@ -596,6 +598,33 @@ static long time_adj;			/* tick adjust (
 long time_reftime;			/* time at last adjustment (s)	*/
 long time_adjust;
 long time_next_adjust;
+static long time_adj2, time_adj2_cur, time_freq_adj2, time_freq_phase2, time_phase2;
+
+void time_recalc(void)
+{
+	long f, t;
+	tick_nsec = TICK_USEC_TO_NSEC(tick_usec);

This leaves bits on the floor. Is it not possible to do this whole calculation in nano seconds? Currently, for example, tick_nsec is 999849...
+
+	t = time_freq >> (SHIFT_USEC + 8);
+	if (t) {
+		time_freq -= t << (SHIFT_USEC + 8);
+		t *= 1000 << 8;
+	}
+	f = time_freq * 125;
+	t += tick_usec * USER_HZ * 1000 + (f >> (SHIFT_USEC - 3));
+	f &= (1 << (SHIFT_USEC - 3)) - 1;
+	tick_nsec2 = t / HZ;
+	f += (t % HZ) << (SHIFT_USEC - 3);
+	f <<= 5;
+	time_adj2 = f / HZ;
+	time_freq_adj2 = f % HZ;
+
+	printk("tr: %ld.%09ld(%ld,%ld,%ld,%ld) - %ld.%09ld(%ld,%ld,%ld)\n",
+		xtime.tv_sec, xtime.tv_sec,
+		tick_nsec, time_freq, time_offset, time_next_adjust,
+		xtime2.tv_sec, xtime2.tv_nsec,
+		tick_nsec2, time_adj2, time_freq_adj2);
+}
/*
  * this routine handles the overflow of the microsecond field
@@ -739,6 +768,16 @@ static void second_overflow(void)
 #endif
 }
+static void second_overflow2(void)
+{
+	time_adj2_cur = time_adj2;
+	time_freq_phase2 += time_freq_adj2;
+	if (time_freq_phase2 > HZ) {
+		time_freq_phase2 -= HZ;
+		time_adj2_cur++;
+	}
+}
+
 /* in the NTP reference this is called "hardclock()" */
 static void update_wall_time_one_tick(void)
 {
@@ -786,6 +825,20 @@ static void update_wall_time_one_tick(vo
 		time_adjust = time_next_adjust;
 		time_next_adjust = 0;
 	}
+
+	delta_nsec = tick_nsec2;
+	time_phase2 += time_adj2_cur;
+	if (time_phase2 >= (1 << (SHIFT_USEC + 2))) {
+		long ltemp = time_phase2 >> (SHIFT_USEC + 2);
+		time_phase2 -= ltemp << (SHIFT_USEC + 2);
+		delta_nsec += ltemp;
+	}
+	xtime2.tv_nsec += delta_nsec;
+	if (xtime2.tv_nsec >= NSEC_PER_SEC) {
+		xtime2.tv_nsec -= NSEC_PER_SEC;
+		xtime2.tv_sec++;
+		second_overflow2();
+	}
 }
/*
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


--
George Anzinger   [email protected]
HRT (High-res-timers):  http://sourceforge.net/projects/high-res-timers/
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]
  Powered by Linux