]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 2503] sht utility outdated
authorJuergen Perlinger <perlinger@ntp.org>
Sat, 4 Oct 2014 09:53:31 +0000 (11:53 +0200)
committerJuergen Perlinger <perlinger@ntp.org>
Sat, 4 Oct 2014 09:53:31 +0000 (11:53 +0200)
bk: 542fc39bbO1NSojV4y5MzJ3UHPg5kA

ChangeLog
util/sht.c

index 8b1ac687c762d5c6c5b990f8219b357b7a00fbb4..8c403f785496e41c85c4932468b314657b59dbfe 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,4 @@
+* [Bug 2503] SHT utility outdated
 (4.2.7p475) 2014/09/11 Released by Harlan Stenn <stenn@ntp.org>
 * [Bug 2654] refclock_true.c doesn't identify the Mk III.
 (4.2.7p474) 2014/09/10 Released by Harlan Stenn <stenn@ntp.org>
index 2a83f401c5d21b65e49187b008e26f11b9d40f83..dfd97ffb9f1f554367d8aea728127538da996de3 100644 (file)
@@ -2,6 +2,8 @@
  * sht.c - Testprogram for shared memory refclock
  * read/write shared memory segment; see usage
  */
+#include "config.h"
+
 #ifndef SYS_WINNT
 #include <sys/types.h>
 #include <sys/ipc.h>
@@ -19,6 +21,7 @@
 #define sleep(x) Sleep(x*1000)
 #endif
 #include <assert.h>
+
 struct shmTime {
        int    mode; /* 0 - if valid set
                      *       use values, 
@@ -28,18 +31,20 @@ struct shmTime {
                      *         use values 
                      *       clear valid
                      */
-       int    count;
-       time_t clockTimeStampSec;
-       int    clockTimeStampUSec;
-       time_t receiveTimeStampSec;
-       int    receiveTimeStampUSec;
-       int    leap;
-       int    precision;
-       int    nsamples;
-       int    valid;
+       volatile int    count;
+       time_t          clockTimeStampSec;
+       int             clockTimeStampUSec;
+       time_t          receiveTimeStampSec;
+       int             receiveTimeStampUSec;
+       int             leap;
+       int             precision;
+       int             nsamples;
+       volatile int    valid;
+       unsigned        clockTimeStampNSec;     /* Unsigned ns timestamps */
+       unsigned        receiveTimeStampNSec;   /* Unsigned ns timestamps */
 };
 
-struct shmTime *
+static struct shmTime *
 getShmTime (
        int unit
        )
@@ -111,75 +116,145 @@ main (
        char *argv[]
        )
 {
-       volatile struct shmTime *p=getShmTime(2);
+       volatile struct shmTime *p;
+       int unit;
+       char *argp;
+
        if (argc<=1) {
-               printf ("usage: %s r[c][l]|w|snnn\n",argv[0]);
+         usage:
+               printf ("usage: %s [uu:]{r[c][l]|w|snnn}\n",argv[0]);
+               printf ("       uu use clock unit uu (default: 2)\n");
                printf ("       r read shared memory\n");
-               printf ("        c clear valid-flag\n");
-               printf ("        l loop (so, rcl will read and clear in a loop\n");
+               printf ("       c clear valid-flag\n");
+               printf ("       l loop (so, rcl will read and clear in a loop\n");
                printf ("       w write shared memory with current time\n");
                printf ("       snnnn set nsamples to nnn\n");
                printf ("       lnnnn set leap to nnn\n");
                printf ("       pnnnn set precision to -nnn\n");
                exit (0);
        }
-       switch (argv[1][0]) {
-           case 's': {
-                   p->nsamples=atoi(&argv[1][1]);
-           }
-           break;
-           case 'l': {
-                   p->leap=atoi(&argv[1][1]);
-           }
-           break;
-           case 'p': {
-                   p->precision=-atoi(&argv[1][1]);
-           }
-           break;
-           case 'r': {
-                   char *ap=&argv[1][1];
-                   int clear=0;
-                   int loop=0;
-                   printf ("reader\n");
-                   while (*ap) {
-                           switch (*ap) {
-                               case 'l' : loop=1; break;
-                               case 'c' : clear=1; break;
-                           }
-                           ap++;
-                   }
-                   do {
-                           printf ("mode=%d, count=%d, clock=%d.%d, rec=%d.%d,\n",
-                                   p->mode,p->count,p->clockTimeStampSec,p->clockTimeStampUSec,
-                                   p->receiveTimeStampSec,p->receiveTimeStampUSec);
-                           printf ("  leap=%d, precision=%d, nsamples=%d, valid=%d\n",
-                                   p->leap, p->precision, p->nsamples, p->valid);
-                           if (!p->valid)
-                               printf ("***\n");
-                           if (clear) {
-                                   p->valid=0;
-                                   printf ("cleared\n");
-                           }
-                           if (loop)
-                               sleep (1);
-                   } while (loop);
-           }
-           break;
-           case 'w': {
-                   printf ("writer\n");
-                   p->mode=0;
-                   if (!p->valid) {
-                           p->clockTimeStampSec=time(0)-20;
-                           p->clockTimeStampUSec=0;
-                           p->receiveTimeStampSec=time(0)-1;
-                           p->receiveTimeStampUSec=0;
-                           printf ("%d %d\n",p->clockTimeStampSec, p->receiveTimeStampSec);
-                           p->valid=1;
-                   }
-                   else {
-                           printf ("p->valid still set\n"); /* not an error! */
-                   }
-           }
-           break;
+
+       srand(time(NULL));
+               
+       unit = strtoul(argv[1], &argp, 10);
+       if (argp == argv[1])
+               unit = 2;
+       else if (*argp == ':')
+               argp++;
+       else
+               goto usage;
+
+       p=getShmTime(unit);
+       switch (*argp) {
+       case 's':
+               p->nsamples=atoi(argp+1);
+               break;
+
+       case 'l':
+               p->leap=atoi(argp+1);
+               break;
+
+       case 'p':
+               p->precision=-atoi(argp+1);
+               break;
+
+       case 'r': {
+               int clear=0;
+               int loop=0;
+               printf ("reader\n");            
+               while (*++argp) {
+                       switch (*argp) {
+                       case 'l': loop=1; break;
+                       case 'c': clear=1; break;
+                       default : goto usage;
+                       }
+               }
+again:
+               printf ("mode=%d, count=%d, clock=%ld.%09u, rec=%ld.%09u,\n",
+                       p->mode,p->count,
+                       (long)p->clockTimeStampSec,p->clockTimeStampNSec,
+                       (long)p->receiveTimeStampSec,p->receiveTimeStampNSec);
+               printf ("  leap=%d, precision=%d, nsamples=%d, valid=%d\n",
+                       p->leap, p->precision, p->nsamples, p->valid);
+               if (!p->valid)
+                       printf ("***\n");
+               if (clear) {
+                       p->valid=0;
+                       printf ("cleared\n");
+               }
+               if (loop) {
+                       sleep (1);
+                       goto again;
+               }
+               break;
        }
+
+       case 'w': {
+               /* To show some life action, we read the system
+                * clock and use a bit of fuzz from 'random()' to get a
+                * bit of wobbling into the values (so we can observe a
+                * certain jitter!)
+                */
+               time_t clk_sec, rcv_sec;
+               uint   clk_frc, rcv_frc;
+
+#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
+               
+               /* Here we have a high-resolution system clock, and
+                * we're not afraid to use it!
+                */
+               struct timespec tmptime;
+               if (0 == clock_gettime(CLOCK_REALTIME, &tmptime)) {
+                       rcv_sec = tmptime.tv_sec;
+                       rcv_frc = (uint)tmptime.tv_nsec;
+               }
+               else
+#endif
+               {
+                       time(&rcv_sec);
+                       rcv_frc = (uint)random() % 1000000000u;
+               }
+               /* add a wobble of ~3.5msec to the clock time */
+               clk_sec = rcv_sec;
+               clk_frc = rcv_frc + (uint)(random()%7094713 - 3547356);
+               /* normalise result -- the SHM driver is picky! */
+               while ((int)clk_frc < 0) {
+                       clk_frc += 1000000000;
+                       clk_sec -= 1;
+               }
+               while ((int)clk_frc >= 1000000000) {
+                       clk_frc -= 1000000000;
+                       clk_sec += 1;
+               }
+               
+               /* Most 'real' time sources would create a clock
+                * (reference) time stamp where the fraction is zero,
+                * but that's not an actual requirement. So we show how
+                * to deal with the time stamps in general; changing the
+                * behaviour for cases where the fraction of the
+                * clock time is zero should be trivial.
+                */ 
+               printf ("writer\n");
+               p->mode=0;
+               if (!p->valid) {
+                       p->clockTimeStampSec    = clk_sec;
+                       p->clockTimeStampUSec   = clk_frc / 1000; /* truncate! */
+                       p->clockTimeStampNSec   = clk_frc;
+                       p->receiveTimeStampSec  = rcv_sec;
+                       p->receiveTimeStampUSec = rcv_frc / 1000; /* truncate! */
+                       p->receiveTimeStampNSec = rcv_frc;
+                       printf ("%ld.%09u %ld.%09u\n",
+                               (long)p->clockTimeStampSec  , p->clockTimeStampNSec  ,
+                               (long)p->receiveTimeStampSec, p->receiveTimeStampNSec);
+                       p->valid=1;
+               }
+               else {
+                       printf ("p->valid still set\n"); /* not an error! */
+               }
+               break;
+       }
+       default:
+               break;
+       }
+       return 0;
 }