[chrony-dev] SOCK refclock system time resolution

[ Thread Index | Date Index | More chrony.tuxfamily.org/chrony-dev Archives ]


I'm playing with feeding data to the SOCK refclock with GPS time myself
(without using gpsd, etc.).  I saw that the samples contain the host/system
timestamp as a struct timeval.  I changed it to allow nanosecond time of
measurements but before I try to polish it and send it for inclusion, I
wanted to check if there would there be interest in that?  The current diff
is below, but it needs a bit more cleanup and testing.

Thanks,

Jeff.

---

diff --git a/refclock_sock.c b/refclock_sock.c
index 2da57ef..add17e2 100644
--- a/refclock_sock.c
+++ b/refclock_sock.c
@@ -35,11 +35,13 @@
 #include "sched.h"
 #include "socket.h"
 
-#define SOCK_MAGIC 0x534f434b
+#define SOCK_MAGIC_TV 0x534f434b
+#define SOCK_MAGIC_TS 0x534f434c
 
-struct sock_sample {
+struct sock_sample_tv64 {
   /* Time of the measurement (system time) */
-  struct timeval tv;
+  int64_t time_sec;
+  int64_t time_usec;
 
   /* Offset between the true time and the system time (in seconds) */
   double offset;
@@ -54,36 +56,54 @@ struct sock_sample {
   /* Padding, ignored */
   int _pad;
 
-  /* Protocol identifier (0x534f434b) */
+  /* Protocol identifier (SOCK_MAGIC_TV) */
   int magic;
 };
 
-/* On 32-bit glibc-based systems enable conversion between timevals using
-   32-bit and 64-bit time_t to support SOCK clients compiled with different
-   time_t size than chrony */
-#ifdef __GLIBC_PREREQ
-#if __GLIBC_PREREQ(2, 34) && __TIMESIZE == 32
-#define CONVERT_TIMEVAL 1
-#if defined(_TIME_BITS) && _TIME_BITS == 64
-typedef int32_t alt_time_t;
-typedef int32_t alt_suseconds_t;
-#else
-typedef int64_t alt_time_t;
-typedef int64_t alt_suseconds_t;
-#endif
-struct alt_timeval {
-  alt_time_t tv_sec;
-  alt_suseconds_t tv_usec;
+struct sock_sample_tv32 {
+  int32_t time_sec;
+  int32_t time_usec;
+  double offset;
+  int pulse;
+  int leap;
+  int _pad;
+  int magic;
+};
+
+struct sock_sample_ts {
+  uint64_t time_sec;
+  uint64_t time_nsec;
+  double offset;
+  uint32_t pulse;
+  uint32_t leap;
+  uint32_t _pad;
+
+  /* Protocol identifier (SOCK_MAGIC_TS) */
+  uint32_t magic;
+};
+
+_Static_assert(sizeof (struct sock_sample_tv64) == 40,
+	       "Size of sock_sample_tv64 changed");
+_Static_assert(sizeof (struct sock_sample_tv32) == 32,
+	       "Size of sock_sample_tv32 changed");
+_Static_assert(sizeof (struct sock_sample_ts) == 40,
+	       "Size of sock_sample_ts changed");
+
+union sock_sample {
+  struct sock_sample_tv32 tv32;
+  struct sock_sample_tv64 tv64;
+  struct sock_sample_ts ts;
 };
-#endif
-#endif
 
 static void read_sample(int sockfd, int event, void *anything)
 {
-  char buf[sizeof (struct sock_sample) + 16];
+  char buf[sizeof (union sock_sample) + 1];
   struct timespec sys_ts, ref_ts;
-  struct sock_sample sample;
+  union sock_sample sample;
   RCL_Instance instance;
+  double offset;
+  int pulse;
+  int leap;
   int s;
 
   instance = (RCL_Instance)anything;
@@ -95,49 +115,65 @@ static void read_sample(int sockfd, int event, void *anything)
     return;
   }
 
-  if (s == sizeof (sample)) {
-    memcpy(&sample, buf, sizeof (sample));
-#ifdef CONVERT_TIMEVAL
-  } else if (s == sizeof (sample) - sizeof (struct timeval) + sizeof (struct alt_timeval)) {
-    struct alt_timeval atv;
-    memcpy(&atv, buf, sizeof (atv));
-#ifndef HAVE_LONG_TIME_T
-    if (atv.tv_sec > INT32_MAX || atv.tv_sec < INT32_MIN ||
-        atv.tv_usec > INT32_MAX || atv.tv_usec < INT32_MIN) {
-      DEBUG_LOG("Could not convert 64-bit timeval");
-      return;
-    }
-#endif
-    sample.tv.tv_sec = atv.tv_sec;
-    sample.tv.tv_usec = atv.tv_usec;
-    DEBUG_LOG("Converted %d-bit timeval", 8 * (int)sizeof (alt_time_t));
-    memcpy((char *)&sample + sizeof (struct timeval), buf + sizeof (struct alt_timeval),
-           sizeof (sample) - sizeof (struct timeval));
-#endif
-  } else {
-    DEBUG_LOG("Unexpected length of SOCK sample : %d != %ld",
+  if (s > sizeof (sample)) {
+    DEBUG_LOG("Unexpected length of SOCK sample : %d > %ld",
               s, (long)sizeof (sample));
     return;
   }
 
-  if (sample.magic != SOCK_MAGIC) {
-    DEBUG_LOG("Unexpected magic number in SOCK sample : %x != %x",
-              (unsigned int)sample.magic, (unsigned int)SOCK_MAGIC);
+  memcpy(&sample, buf, sizeof (sample.ts));
+
+  _Static_assert(sizeof (struct sock_sample_ts) == sizeof (struct sock_sample_tv64),
+		 "sock_sample_ts and sock_sample_tv64 mismatch in size");
+  if (s == sizeof (sample.ts) || s == sizeof (sample.tv64)) {
+    if (sample.ts.magic == SOCK_MAGIC_TS) {
+      sys_ts.tv_sec = sample.ts.time_sec;
+      sys_ts.tv_nsec = sample.ts.time_nsec;
+      offset = sample.ts.offset;
+      pulse = sample.ts.pulse;
+      leap = sample.ts.leap;
+    } else if (sample.tv64.magic == SOCK_MAGIC_TV) {
+      sys_ts.tv_sec = sample.tv64.time_sec;
+      sys_ts.tv_nsec = sample.tv64.time_usec * 1000;
+      offset = sample.tv64.offset;
+      pulse = sample.tv64.pulse;
+      leap = sample.tv64.leap;
+    } else {
+      DEBUG_LOG("Unexpected magic number in SOCK sample : %x != %x or %x != %x",
+                (unsigned int)sample.ts.magic, (unsigned int)SOCK_MAGIC_TS,
+		(unsigned int)sample.tv64.magic, (unsigned int)SOCK_MAGIC_TV);
+      return;
+    }
+  } else if (s == sizeof (sample.tv32) && sample.tv32.magic == SOCK_MAGIC_TV) {
+    if (sample.tv32.magic != SOCK_MAGIC_TV) {
+      DEBUG_LOG("Unexpected magic number in SOCK sample : %x != %x",
+                (unsigned int)sample.tv32.magic, (unsigned int)SOCK_MAGIC_TV);
+      return;
+    }
+
+    sys_ts.tv_sec = sample.tv32.time_sec;
+    sys_ts.tv_nsec = sample.tv32.time_usec * 1000;
+    offset = sample.tv32.offset;
+    pulse = sample.tv32.pulse;
+    leap = sample.tv32.leap;
+  } else {
+    DEBUG_LOG("Unexpected length of SOCK sample : %d != %ld or %ld or %ld",
+              s, (long)sizeof (sample.ts), (long)sizeof (sample.tv64),
+	      (long)sizeof (sample.tv32));
     return;
   }
 
-  UTI_TimevalToTimespec(&sample.tv, &sys_ts);
   UTI_NormaliseTimespec(&sys_ts);
 
-  if (!UTI_IsTimeOffsetSane(&sys_ts, sample.offset))
+  if (!UTI_IsTimeOffsetSane(&sys_ts, offset))
     return;
 
-  UTI_AddDoubleToTimespec(&sys_ts, sample.offset, &ref_ts);
+  UTI_AddDoubleToTimespec(&sys_ts, offset, &ref_ts);
 
-  if (sample.pulse) {
-    RCL_AddPulse(instance, &sys_ts, sample.offset);
+  if (pulse) {
+    RCL_AddPulse(instance, &sys_ts, offset);
   } else {
-    RCL_AddSample(instance, &sys_ts, &ref_ts, sample.leap);
+    RCL_AddSample(instance, &sys_ts, &ref_ts, leap);
   }
 }
 

-- 
To unsubscribe email chrony-dev-request@xxxxxxxxxxxxxxxxxxxx with "unsubscribe" in the subject.
For help email chrony-dev-request@xxxxxxxxxxxxxxxxxxxx with "help" in the subject.
Trouble?  Email listmaster@xxxxxxxxxxxxxxxxxxxx.


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/