Blame SOURCES/ntp-4.2.6p5-nanoshm.patch

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