Blame SOURCES/ntp-4.2.6p5-nanoshm.patch

6e16f6
diff -up ntp-4.2.6p5/ntpd/refclock_shm.c.nanoshm ntp-4.2.6p5/ntpd/refclock_shm.c
6e16f6
--- ntp-4.2.6p5/ntpd/refclock_shm.c.nanoshm	2010-02-04 08:26:55.000000000 +0100
6e16f6
+++ ntp-4.2.6p5/ntpd/refclock_shm.c	2014-08-25 15:43:45.608698816 +0200
6e16f6
@@ -83,16 +83,18 @@ struct shmTime {
6e16f6
 		      *         use values 
6e16f6
 		      *       clear valid
6e16f6
 		      */
6e16f6
-	int    count;
6e16f6
-	time_t clockTimeStampSec;
6e16f6
-	int    clockTimeStampUSec;
6e16f6
-	time_t receiveTimeStampSec;
6e16f6
-	int    receiveTimeStampUSec;
6e16f6
-	int    leap;
6e16f6
-	int    precision;
6e16f6
-	int    nsamples;
6e16f6
-	int    valid;
6e16f6
-	int    dummy[10]; 
6e16f6
+	volatile int    count;
6e16f6
+	time_t		clockTimeStampSec;
6e16f6
+	int		clockTimeStampUSec;
6e16f6
+	time_t		receiveTimeStampSec;
6e16f6
+	int		receiveTimeStampUSec;
6e16f6
+	int		leap;
6e16f6
+	int		precision;
6e16f6
+	int		nsamples;
6e16f6
+	volatile int    valid;
6e16f6
+	unsigned	clockTimeStampNSec;	/* Unsigned ns timestamps */
6e16f6
+	unsigned	receiveTimeStampNSec;	/* Unsigned ns timestamps */
6e16f6
+	int		dummy[8];
6e16f6
 };
6e16f6
 
6e16f6
 struct shmunit {
6e16f6
@@ -320,31 +322,68 @@ int shm_peek(
6e16f6
 		return(0);
6e16f6
 	}
6e16f6
 	if (shm->valid) {
6e16f6
-		struct timeval tvr;
6e16f6
-		struct timeval tvt;
6e16f6
+		struct timespec tvr;
6e16f6
+		struct timespec tvt;
6e16f6
 		struct tm *t;
6e16f6
 		int ok=1;
6e16f6
+		unsigned cns_new, rns_new;
6e16f6
+		int cnt;
6e16f6
 		tvr.tv_sec = 0;
6e16f6
-		tvr.tv_usec = 0;
6e16f6
+		tvr.tv_nsec = 0;
6e16f6
 		tvt.tv_sec = 0;
6e16f6
-		tvt.tv_usec = 0;
6e16f6
+		tvt.tv_nsec = 0;
6e16f6
 		switch (shm->mode) {
6e16f6
-		    case 0: {
6e16f6
-			    tvr.tv_sec=shm->receiveTimeStampSec;
6e16f6
-			    tvr.tv_usec=shm->receiveTimeStampUSec;
6e16f6
-			    tvt.tv_sec=shm->clockTimeStampSec;
6e16f6
-			    tvt.tv_usec=shm->clockTimeStampUSec;
6e16f6
-		    }
6e16f6
-		    break;
6e16f6
-		    case 1: {
6e16f6
-			    int cnt=shm->count;
6e16f6
-			    tvr.tv_sec=shm->receiveTimeStampSec;
6e16f6
-			    tvr.tv_usec=shm->receiveTimeStampUSec;
6e16f6
-			    tvt.tv_sec=shm->clockTimeStampSec;
6e16f6
-			    tvt.tv_usec=shm->clockTimeStampUSec;
6e16f6
-			    ok=(cnt==shm->count);
6e16f6
-		    }
6e16f6
-		    break;
6e16f6
+		    case 0:
6e16f6
+			tvr.tv_sec	= shm->receiveTimeStampSec;
6e16f6
+			tvr.tv_nsec	= shm->receiveTimeStampUSec * 1000;
6e16f6
+			rns_new		= shm->receiveTimeStampNSec;
6e16f6
+			tvt.tv_sec	= shm->clockTimeStampSec;
6e16f6
+			tvt.tv_nsec	= shm->clockTimeStampUSec * 1000;
6e16f6
+			cns_new		= shm->clockTimeStampNSec;
6e16f6
+
6e16f6
+			/* Since these comparisons are between unsigned
6e16f6
+			** variables they are always well defined, and any
6e16f6
+			** (signed) underflow will turn into very large
6e16f6
+			** unsigned values, well above the 1000 cutoff
6e16f6
+			*/
6e16f6
+			if (   ((cns_new - (unsigned)tvt.tv_nsec) < 1000)
6e16f6
+			    && ((rns_new - (unsigned)tvr.tv_nsec) < 1000)) {
6e16f6
+				tvt.tv_nsec = cns_new;
6e16f6
+				tvr.tv_nsec = rns_new;
6e16f6
+			}
6e16f6
+			// At this point tvr and tvt contains valid ns-level
6e16f6
+			// timestamps, possibly generated by extending the
6e16f6
+			// old us-level timestamps
6e16f6
+
6e16f6
+			break;
6e16f6
+
6e16f6
+		    case 1:
6e16f6
+			cnt = shm->count;
6e16f6
+
6e16f6
+			tvr.tv_sec	= shm->receiveTimeStampSec;
6e16f6
+			tvr.tv_nsec	= shm->receiveTimeStampUSec * 1000;
6e16f6
+			rns_new		= shm->receiveTimeStampNSec;
6e16f6
+			tvt.tv_sec	= shm->clockTimeStampSec;
6e16f6
+			tvt.tv_nsec	= shm->clockTimeStampUSec * 1000;
6e16f6
+			cns_new		= shm->clockTimeStampNSec;
6e16f6
+			ok = (cnt == shm->count);
6e16f6
+
6e16f6
+			/* Since these comparisons are between unsigned
6e16f6
+			** variables they are always well defined, and any
6e16f6
+			** (signed) underflow will turn into very large
6e16f6
+			** unsigned values, well above the 1000 cutoff
6e16f6
+			*/
6e16f6
+			if (   ((cns_new - (unsigned)tvt.tv_nsec) < 1000)
6e16f6
+			    && ((rns_new - (unsigned)tvr.tv_nsec) < 1000)) {
6e16f6
+				tvt.tv_nsec = cns_new;
6e16f6
+				tvr.tv_nsec = rns_new;
6e16f6
+			}
6e16f6
+			// At this point tvr and tvt contains valid ns-level
6e16f6
+			// timestamps, possibly generated by extending the
6e16f6
+			// old us-level timestamps
6e16f6
+
6e16f6
+			break;
6e16f6
+
6e16f6
 		    default:
6e16f6
 			msyslog (LOG_ERR, "SHM: bad mode found in shared memory: %d",shm->mode);
6e16f6
 		}
6e16f6
@@ -352,8 +391,8 @@ int shm_peek(
6e16f6
 		if (ok) {
6e16f6
 			time_t help;	/* XXX NetBSD has incompatible tv_sec */
6e16f6
 
6e16f6
-			TVTOTS(&tvr,&pp->lastrec);
6e16f6
-			pp->lastrec.l_ui += JAN_1970;
6e16f6
+			pp->lastrec.l_ui = (u_long)tvr.tv_sec + JAN_1970;
6e16f6
+			pp->lastrec.l_uf = tvr.tv_nsec * 4.294967296;
6e16f6
 			/* pp->lasttime = current_time; */
6e16f6
 			pp->polls++;
6e16f6
 			help = tvt.tv_sec;
6e16f6
@@ -362,7 +401,7 @@ int shm_peek(
6e16f6
 			pp->hour=t->tm_hour;
6e16f6
 			pp->minute=t->tm_min;
6e16f6
 			pp->second=t->tm_sec;
6e16f6
-			pp->nsec=tvt.tv_usec * 1000;
6e16f6
+			pp->nsec = tvt.tv_nsec;
6e16f6
 			peer->precision=shm->precision;
6e16f6
 			pp->leap=shm->leap;
6e16f6
 		}