2 * sht.c - Testprogram for shared memory refclock
3 * read/write shared memory segment; see usage
21 #define sleep(x) Sleep(x*1000)
26 int mode; /* 0 - if valid set
30 * if count before and after read of values is equal,
35 time_t clockTimeStampSec;
36 int clockTimeStampUSec;
37 time_t receiveTimeStampSec;
38 int receiveTimeStampUSec;
43 unsigned clockTimeStampNSec; /* Unsigned ns timestamps */
44 unsigned receiveTimeStampNSec; /* Unsigned ns timestamps */
47 static struct shmTime *
53 int shmid=shmget (0x4e545030+unit, sizeof (struct shmTime), IPC_CREAT|0777);
59 struct shmTime *p=(struct shmTime *)shmat (shmid, 0, 0);
60 if ((int)(long)p==-1) {
69 LPSECURITY_ATTRIBUTES psec=0;
70 snprintf (buf, sizeof(buf), "NTP%d", unit);
71 SECURITY_DESCRIPTOR sd;
72 SECURITY_ATTRIBUTES sa;
75 assert (InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION));
76 assert (SetSecurityDescriptorDacl(&sd,1,0,0));
77 sa.nLength=sizeof (SECURITY_ATTRIBUTES);
78 sa.lpSecurityDescriptor=&sd;
80 shmid=CreateFileMapping ((HANDLE)0xffffffff, 0, PAGE_READWRITE,
81 psec, sizeof (struct shmTime),buf);
83 shmid=CreateFileMapping ((HANDLE)0xffffffff, 0, PAGE_READWRITE,
84 0, sizeof (struct shmTime),buf);
85 cout <<"CreateFileMapping with psec!=0 failed"<<endl;
90 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM,
91 0, GetLastError (), 0, mbuf, sizeof (mbuf), 0);
92 int x=GetLastError ();
93 cout <<"CreateFileMapping "<<buf<<":"<<mbuf<<endl;
97 struct shmTime *p=(struct shmTime *) MapViewOfFile (shmid,
98 FILE_MAP_WRITE, 0, 0, sizeof (struct shmTime));
101 FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM,
102 0, GetLastError (), 0, mbuf, sizeof (mbuf), 0);
103 cout <<"MapViewOfFile "<<buf<<":"<<mbuf<<endl;
119 volatile struct shmTime *p;
125 printf ("usage: %s [uu:]{r[c][l]|w|snnn}\n",argv[0]);
126 printf (" uu use clock unit uu (default: 2)\n");
127 printf (" r read shared memory\n");
128 printf (" c clear valid-flag\n");
129 printf (" l loop (so, rcl will read and clear in a loop\n");
130 printf (" w write shared memory with current time\n");
131 printf (" snnnn set nsamples to nnn\n");
132 printf (" lnnnn set leap to nnn\n");
133 printf (" pnnnn set precision to -nnn\n");
139 unit = strtoul(argv[1], &argp, 10);
142 else if (*argp == ':')
150 p->nsamples=atoi(argp+1);
154 p->leap=atoi(argp+1);
158 p->precision=-atoi(argp+1);
167 case 'l': loop=1; break;
168 case 'c': clear=1; break;
169 default : goto usage;
173 printf ("mode=%d, count=%d, clock=%ld.%09u, rec=%ld.%09u,\n",
175 (long)p->clockTimeStampSec,p->clockTimeStampNSec,
176 (long)p->receiveTimeStampSec,p->receiveTimeStampNSec);
177 printf (" leap=%d, precision=%d, nsamples=%d, valid=%d\n",
178 p->leap, p->precision, p->nsamples, p->valid);
183 printf ("cleared\n");
193 /* To show some life action, we read the system
194 * clock and use a bit of fuzz from 'random()' to get a
195 * bit of wobbling into the values (so we can observe a
198 time_t clk_sec, rcv_sec;
199 uint clk_frc, rcv_frc;
201 #if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)
203 /* Here we have a high-resolution system clock, and
204 * we're not afraid to use it!
206 struct timespec tmptime;
207 if (0 == clock_gettime(CLOCK_REALTIME, &tmptime)) {
208 rcv_sec = tmptime.tv_sec;
209 rcv_frc = (uint)tmptime.tv_nsec;
215 rcv_frc = (uint)random() % 1000000000u;
217 /* add a wobble of ~3.5msec to the clock time */
219 clk_frc = rcv_frc + (uint)(random()%7094713 - 3547356);
220 /* normalise result -- the SHM driver is picky! */
221 while ((int)clk_frc < 0) {
222 clk_frc += 1000000000;
225 while ((int)clk_frc >= 1000000000) {
226 clk_frc -= 1000000000;
230 /* Most 'real' time sources would create a clock
231 * (reference) time stamp where the fraction is zero,
232 * but that's not an actual requirement. So we show how
233 * to deal with the time stamps in general; changing the
234 * behaviour for cases where the fraction of the
235 * clock time is zero should be trivial.
240 p->clockTimeStampSec = clk_sec;
241 p->clockTimeStampUSec = clk_frc / 1000; /* truncate! */
242 p->clockTimeStampNSec = clk_frc;
243 p->receiveTimeStampSec = rcv_sec;
244 p->receiveTimeStampUSec = rcv_frc / 1000; /* truncate! */
245 p->receiveTimeStampNSec = rcv_frc;
246 printf ("%ld.%09u %ld.%09u\n",
247 (long)p->clockTimeStampSec , p->clockTimeStampNSec ,
248 (long)p->receiveTimeStampSec, p->receiveTimeStampNSec);
252 printf ("p->valid still set\n"); /* not an error! */