From: Juergen Perlinger Date: Sat, 4 Oct 2014 09:53:31 +0000 (+0200) Subject: [Bug 2503] sht utility outdated X-Git-Tag: NTP_4_2_7P476~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f780d2ab983ef913d0876bc937b5d74e965847ce;p=thirdparty%2Fntp.git [Bug 2503] sht utility outdated bk: 542fc39bbO1NSojV4y5MzJ3UHPg5kA --- diff --git a/ChangeLog b/ChangeLog index 8b1ac687c..8c403f785 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ +* [Bug 2503] SHT utility outdated (4.2.7p475) 2014/09/11 Released by Harlan Stenn * [Bug 2654] refclock_true.c doesn't identify the Mk III. (4.2.7p474) 2014/09/10 Released by Harlan Stenn diff --git a/util/sht.c b/util/sht.c index 2a83f401c..dfd97ffb9 100644 --- a/util/sht.c +++ b/util/sht.c @@ -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 #include @@ -19,6 +21,7 @@ #define sleep(x) Sleep(x*1000) #endif #include + 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; }