[PATCH 2/10] NTP: normalize time_adj

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

 



This normalizes the calculated value time_adj in second_overflow() to be
always positive. The difference is added to tick_nsec and stored in
tick_nsec_curr. This simplifies the work needed in
update_wall_time_one_tick() as time_phase is always positive.

Signed-off-by: Roman Zippel <[email protected]>

---

 include/linux/timex.h |    2 +-
 kernel/timer.c        |   24 ++++++++++++++----------
 2 files changed, 15 insertions(+), 11 deletions(-)

Index: linux-2.6-mm/include/linux/timex.h
===================================================================
--- linux-2.6-mm.orig/include/linux/timex.h	2005-12-21 12:11:48.000000000 +0100
+++ linux-2.6-mm/include/linux/timex.h	2005-12-21 12:11:56.000000000 +0100
@@ -93,7 +93,7 @@
 #define SHIFT_SCALE 22		/* phase scale (shift) */
 #define SHIFT_UPDATE (SHIFT_KG + MAXTC) /* time offset scale (shift) */
 #define SHIFT_USEC 16		/* frequency offset scale (shift) */
-#define FINENSEC (1L << (SHIFT_SCALE - 10)) /* ~1 ns in phase units */
+#define FINENSEC (1L << SHIFT_SCALE) /* ~1 ns in phase units */
 
 #define MAXPHASE 512000L        /* max phase error (us) */
 #define MAXFREQ (512L << SHIFT_USEC)  /* max frequency error (ppm) */
Index: linux-2.6-mm/kernel/timer.c
===================================================================
--- linux-2.6-mm.orig/kernel/timer.c	2005-12-21 12:11:48.000000000 +0100
+++ linux-2.6-mm/kernel/timer.c	2005-12-21 12:11:56.000000000 +0100
@@ -552,6 +552,7 @@ found:
  */
 unsigned long tick_usec = TICK_USEC; 		/* USER_HZ period (usec) */
 unsigned long tick_nsec = TICK_NSEC;		/* ACTHZ period (nsec) */
+static unsigned long tick_nsec_curr = TICK_NSEC;
 
 /* 
  * The current time 
@@ -601,7 +602,7 @@ long time_next_adjust;
  */
 static void second_overflow(void)
 {
-	long ltemp;
+	long ltemp, adj;
 
 	/* Bump the maxerror field */
 	time_maxerror += time_tolerance >> SHIFT_USEC;
@@ -662,6 +663,7 @@ static void second_overflow(void)
 		time_state = TIME_OK;
 	}
 
+	tick_nsec_curr = tick_nsec;
 	/*
 	 * Compute the phase adjustment for the next second. In PLL mode, the
 	 * offset is reduced by a fixed factor times the time constant. In FLL
@@ -675,36 +677,38 @@ static void second_overflow(void)
 	ltemp = min(ltemp, (MAXPHASE / MINSEC) << SHIFT_UPDATE);
 	ltemp = max(ltemp, -(MAXPHASE / MINSEC) << SHIFT_UPDATE);
 	time_offset -= ltemp;
-	time_adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
+	adj = ltemp << (SHIFT_SCALE - SHIFT_HZ - SHIFT_UPDATE);
 
 	/*
 	 * Compute the frequency estimate and additional phase adjustment due
 	 * to frequency error for the next second.
 	 */
 	ltemp = time_freq;
-	time_adj += shift_right(ltemp,(SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE));
+	adj += shift_right(ltemp,(SHIFT_USEC + SHIFT_HZ - SHIFT_SCALE));
 
 #if HZ == 100
 	/*
 	 * Compensate for (HZ==100) != (1 << SHIFT_HZ).  Add 25% and 3.125% to
 	 * get 128.125; => only 0.125% error (p. 14)
 	 */
-	time_adj += shift_right(time_adj, 2) + shift_right(time_adj, 5);
+	adj += shift_right(adj, 2) + shift_right(adj, 5);
 #endif
 #if HZ == 250
 	/*
 	 * Compensate for (HZ==250) != (1 << SHIFT_HZ).  Add 1.5625% and
 	 * 0.78125% to get 255.85938; => only 0.05% error (p. 14)
 	 */
-	time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7);
+	adj += shift_right(adj, 6) + shift_right(adj, 7);
 #endif
 #if HZ == 1000
 	/*
 	 * Compensate for (HZ==1000) != (1 << SHIFT_HZ).  Add 1.5625% and
 	 * 0.78125% to get 1023.4375; => only 0.05% error (p. 14)
 	 */
-	time_adj += shift_right(time_adj, 6) + shift_right(time_adj, 7);
+	adj += shift_right(adj, 6) + shift_right(adj, 7);
 #endif
+	tick_nsec_curr += adj >> (SHIFT_SCALE - 10);
+	time_adj = (adj << 10) & (FINENSEC - 1);
 }
 
 /* in the NTP reference this is called "hardclock()" */
@@ -727,15 +731,15 @@ static void update_wall_time_one_tick(vo
 		/* Reduce by this step the amount of time left  */
 		time_adjust -= time_adjust_step;
 	}
-	delta_nsec = tick_nsec + time_adjust_step * 1000;
+	delta_nsec = tick_nsec_curr + time_adjust_step * 1000;
 	/*
 	 * Advance the phase, once it gets to one microsecond, then
 	 * advance the tick more.
 	 */
 	time_phase += time_adj;
-	if ((time_phase >= FINENSEC) || (time_phase <= -FINENSEC)) {
-		long ltemp = shift_right(time_phase, (SHIFT_SCALE - 10));
-		time_phase -= ltemp << (SHIFT_SCALE - 10);
+	if (time_phase >= FINENSEC) {
+		long ltemp = time_phase >> SHIFT_SCALE;
+		time_phase -= ltemp << SHIFT_SCALE;
 		delta_nsec += ltemp;
 	}
 	xtime.tv_nsec += delta_nsec;
-
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]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux