clock_gettime大约每秒发生一次故障

时间:2019-03-27 22:44:37

标签: c macos time.h

我正在Mac上使用C进行基准测试。这里的代码可以编译并运行,但是输出中会出现一种毛刺,发生频率约为1Hz。程序“应该”每2毫秒中断一次,并报告上次中断时间的数据。默认设置是将以下内容打印到终端上

eventCounter \t elapsedTime \t jitter \t sumJitter

eventCounter很明显,每次中断发生时都会计数

elapsedTime以美国为单位

经过抖动时间减去2000(2mS)

sumJitter是抖动+抖动

大约每秒精确地一次,经过时间的结果崩溃到大约-1,000,000,这很疯狂,因为这意味着我做了一个时光机...现在我过去了...大约16分钟... 我觉得没什么不同。

这是代码



#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>

#define OPT_R_MIN 0
#define OPT_R_MAX 5000
#define OPT_R_DEF 100
#define OPT_U_MIN 100
#define OPT_U_MAX 2000000000 // 2K seconds
#define OPT_U_DEF 2000
#define OPT_O_ELAPSED 0
#define OPT_O_JITTER 1
#define OPT_O_SUMJITTER 2
#define OPT_O_DEVIATION 3
#define OPT_O_DEVIATION_MAX 256
#define OPT_C_MIN 100
#define OPT_C_MAX 2000000000
#define OPT_C_DEF 1000

#define TIME_OUT_PERIOD 5000000
#define MILLION 1000000
#define BILLION 1000000000

int opt_o_min = OPT_O_ELAPSED;
int opt_o_max = OPT_O_SUMJITTER;

int opt_r = OPT_R_DEF;
unsigned int opt_u = OPT_U_DEF;
int opt_o = OPT_O_JITTER;
int opt_c = OPT_C_DEF;
int editOutput = 0;

volatile unsigned int  elapsedTime, jitter;
struct timespec thisTime, lastTime, timeOutStart, timeOutTest;
volatile unsigned int sampleFlag = 0;
volatile int eventCounter, sumJitter, firstTime, secondTime;

void alarmWakeup(int sig_num);
void startTimer(int r, unsigned int u);
void handler(int sig_num);
char filename [100];
struct tm *timenow;


void usage()
{
   fprintf
   (stderr,
      "\n" \
      "Usage: sudo ./timerTest ... [OPTION] ...\n" \
      "   -r value, sets the allowed lag between alarm and callback   default: %d\n"
      "   -u value, sets microsecond alarm setting   default: %d\n" \
      "         %d < VALID < %d ONLY (under test)\n"\
      "   -o value, sets the output type     default: %d\n"\
      "         %d elapsed time in microseconds\n"\
      "         %d jitter (elapsed time / -u value)\n"\
      "         %d cumulative jitter (jitter + jitter)\n"\
      "   -t value, sets duration of test cycles in event counter    default: %d\n"\
      "         %d < VALID < %d ONLY (under test)\n"\
      "\n",
      OPT_R_DEF,OPT_U_DEF, OPT_U_MIN, OPT_U_MAX, OPT_O_JITTER,
      OPT_O_ELAPSED, OPT_O_JITTER, OPT_O_SUMJITTER, OPT_O_DEVIATION,
      OPT_O_DEVIATION_MAX, OPT_C_DEF, OPT_C_MIN, OPT_C_MAX
   );
}

void fatal(int show_usage, char *fmt, ...)
{
   char buf[128];
   va_list ap;

   va_start(ap, fmt);
   vsnprintf(buf, sizeof(buf), fmt, ap);
   va_end(ap);

   fprintf(stderr, "%s\n", buf);

   if (show_usage) usage();

   fflush(stderr);

   exit(EXIT_FAILURE);
}

static int initOpts(int argc, char *argv[])
{
   int i, opt;
   unsigned int u;

   while ((opt = getopt(argc, argv, "r:u:o:t:")) != -1)
   {
      i = -1;
      switch (opt)
      {
         case 'r':
            i = atoi(optarg);
            if ((i >= OPT_R_MIN) && (i <= OPT_R_MAX))
               opt_r = i;
            else fatal(1, "invalid -r option (%d)", i);
            break;

         case 'u':
            u = atol(optarg);
            if ((u >= OPT_U_MIN) && (u <= OPT_U_MAX))
               opt_u = u;
            else fatal(1, "invalid -u option (%d)", u);
            break;

         case 'o':
            i = atoi(optarg);
            opt_o = i;  // probably fatal
            break;

        case 't':
            i = atoi(optarg);
            opt_c = i;  // probably fatal
            break;

        default: /* '?' */
           usage();
        }
    }
   return optind;
}


int main(int argc, char *argv[])
{
    int settings = 0;
    // command line settings
    settings = initOpts(argc, argv);
    time_t now = time(NULL);
    timenow = gmtime(&now);

    // FILE *data;
    // strftime(filename, sizeof(filename),
    // "/home/pi/Documents/_C_/WiringPiAlarm/protoPulse_%Y-%m-%d_%H:%M:%S.dat", timenow);
    // data = fopen(filename, "w+");
    // fprintf(data,"# Sample count: %d option(s)\n", opt_c);
    // fprintf(data,"# Running with %d latency at %duS sample rate\n",opt_r,opt_u);
    // fprintf(data,"# Output Type is %d\n\n" , opt_o);

    printf("User selects %d option(s)\n", settings-1);
    printf("Running with %d latency at %duS sample rate\n",opt_r,opt_u);
    printf("Output Type is %d\n" , opt_o);
    printf("    Use -o value to select output type\n");
    printf("        0: elapsed time between interrutps\n");
    printf("        1: jitter (elapsed time / -u)\n");
    printf("        2: cumulative jitter (jitter + jitter)\n");
    printf("Sample count: %d\n", opt_c);
    printf("Starting alarm timer for %dmS...\n", opt_u);


    eventCounter = 0;
    firstTime = secondTime = 1;
        clock_gettime(CLOCK_MONOTONIC, &lastTime);
    // lastTime = micros();
    timeOutStart = lastTime;
    startTimer(opt_r, opt_u);


    while(1)
    {
        if(sampleFlag){
            sampleFlag = 0;
            timeOutStart = lastTime;
            int metaDataOutput;
            switch(opt_o){  // ALL OUTPUTS DISCARD THE FIRST CALLBACK
                case OPT_O_JITTER:
                    metaDataOutput = jitter;
                    break;
                case OPT_O_SUMJITTER:
                    metaDataOutput = sumJitter;
                    break;
                default:
                    metaDataOutput = elapsedTime;
                    break;
            }
             printf("%d\t%d\t%d\t%d\n",eventCounter,elapsedTime,jitter, sumJitter);
             // fprintf(data,"%d\t%d\n",eventCounter,metaDataOutput);
         }
                 clock_gettime(CLOCK_MONOTONIC, &timeOutTest);
         if((MILLION * (timeOutTest.tv_sec - timeOutStart.tv_sec) + timeOutTest.tv_nsec - timeOutStart.tv_nsec)/1000>TIME_OUT_PERIOD){
            fatal(0,"program timed out",0);
         }
         if(eventCounter >= opt_c){
            fatal(0,"counted %d events", eventCounter, 0);
         }
    }

    return 0;

}//int main(int argc, char *argv[])

void startTimer(int r, unsigned int u){
    int latency = r;
    unsigned int micros = u;

    signal(SIGALRM, alarmWakeup);
    ualarm(latency, micros);

}

void alarmWakeup(int sig_num)
{

    if(sig_num == SIGALRM)
    {
                clock_gettime(CLOCK_MONOTONIC, &thisTime);
        // thisTime = micros();
        elapsedTime = (MILLION * (thisTime.tv_sec - lastTime.tv_sec) + thisTime.tv_nsec - lastTime.tv_nsec)/1000;
        lastTime = thisTime;
        if(firstTime){
            firstTime = 0;
            return;
        }
        if(secondTime){
            secondTime = 0;
            return;
        }
        jitter = elapsedTime - opt_u;
        sumJitter += jitter;
        eventCounter++;
        sampleFlag = 1;



    }

}

这是我得到的数据的一个样本

User selects 0 option(s)
Running with 100 latency at 2000uS sample rate
Output Type is 1
    Use -o value to select output type
        0: elapsed time between interrutps
        1: jitter (elapsed time / -u)
        2: cumulative jitter (jitter + jitter)
Sample count: 1000
Starting alarm timer for 2000mS...
1   1928    -72 -72
2   2031    31  -41
3   1989    -11 -52
4   1975    -25 -77
5   2032    32  -45
6   1971    -29 -74
7   2027    27  -47
8   2012    12  -35
9   2051    51  16
10  1920    -80 -64
11  1998    -2  -66
12  1994    -6  -72
13  2027    27  -45
14  1998    -2  -47
15  2000    0   -47
16  1986    -14 -61
17  1906    -94 -155
18  2126    126 -29
19  1978    -22 -51
20  2047    47  -4
21  1924    -76 -80
22  2038    38  -42
23  1963    -37 -79
24  2045    45  -34
25  1863    -137    -171
26  2169    169 -2
27  1921    -79 -81
28  2040    40  -41
29  1997    -3  -44
30  2021    21  -23
31  1995    -5  -28
32  1984    -16 -44
33  1927    -73 -117
34  2059    59  -58
35  1990    -10 -68
36  1963    -37 -105
37  1836    -164    -269
38  2250    250 -19
39  1978    -22 -41
40  1962    -38 -79
41  1898    -102    -181
42  2124    124 -57
43  1997    -3  -60
44  2009    9   -51
45  2019    19  -32
46  1986    -14 -46
47  2006    6   -40
48  1999    -1  -41
49  1985    -15 -56
50  2013    13  -43
51  2001    1   -42
52  2000    0   -42
53  2169    169 127
54  1815    -185    -58
55  2007    7   -51
56  1990    -10 -61
57  1783    -217    -278
58  2269    269 -9
59  1964    -36 -45
60  2020    20  -25
61  2021    21  -4
62  1992    -8  -12
63  1996    -4  -16
64  1937    -63 -79
65  2009    9   -70
66  2061    61  -9
67  1731    -269    -278
68  2271    271 -7
69  1993    -7  -14
70  1958    -42 -56
71  1769    -231    -287
72  2303    303 16
73  1931    -69 -53
74  1810    -190    -243
75  1998    -2  -245
76  2221    221 -24
77  1998    -2  -26
78  1955    -45 -71
79  2150    150 79
80  1895    -105    -26
81  2013    13  -13
82  1852    -148    -161
83  2116    116 -45
84  1979    -21 -66
85  2004    4   -62
86  1902    -98 -160
87  1981    -19 -179
88  2203    203 24
89  1955    -45 -21
90  1970    -30 -51
91  1832    -168    -219
92  1939    -61 -280
93  2326    326 46
94  1940    -60 -14
95  2000    0   -14
96  1988    -12 -26
97  1979    -21 -47
98  2020    20  -27
99  1859    -141    -168
100 2113    113 -55
101 2028    28  -27
102 1958    -42 -69
103 1922    -78 -147
104 2134    134 -13
105 1969    -31 -44
106 2049    49  5
107 1846    -154    -149
108 2127    127 -22
109 2019    19  -3
110 1985    -15 -18
111 1994    -6  -24
112 2017    17  -7
113 1975    -25 -32
114 1957    -43 -75
115 2057    57  -18
116 1981    -19 -37
117 2011    11  -26
118 1760    -240    -266
119 2226    226 -40
120 1969    -31 -71
121 2011    11  -60
122 2293    293 233
123 1719    -281    -48
124 1980    -20 -68
125 2053    53  -15
126 1992    -8  -23
127 1955    -45 -68
128 2064    64  -4
129 1951    -49 -53
130 2045    45  -8
131 1931    -69 -77
132 1861    -139    -216
133 2220    220 4
134 1980    -20 -16
135 1827    -173    -189
136 2138    138 -51
137 2010    10  -41
138 1994    -6  -47
139 2038    38  -9
140 1987    -13 -22
141 2061    61  39
142 1921    -79 -40
143 1799    -201    -241
144 2244    244 3
145 1971    -29 -26
146 1749    -251    -277
147 2239    239 -38
148 2017    17  -21
149 1994    -6  -27
150 1920    -80 -107
151 2077    77  -30
152 1944    -56 -86
153 2085    85  -1
154 1985    -15 -16
155 1981    -19 -35
156 1985    -15 -50
157 2059    59  9
158 1929    -71 -62
159 2005    5   -57
160 2035    35  -22
161 1986    -14 -36
162 1977    -23 -59
163 2000    0   -59
164 2036    36  -23
165 3912    1912    1889
166 42  -1958   -69
167 2072    72  3
168 1754    -246    -243
169 1957    -43 -286
170 2284    284 -2
171 1993    -7  -9
172 1958    -42 -51
173 2043    43  -8
174 1762    -238    -246
175 2235    235 -11
176 1965    -35 -46
177 2049    49  3
178 1992    -8  -5
179 1982    -18 -23
180 2006    6   -17
181 1968    -32 -49
182 1790    -210    -259
183 2019    19  -240
184 2194    194 -46
185 1916    -84 -130
186 2079    79  -51
187 1849    -151    -202
188 2213    213 11
189 1944    -56 -45
190 2022    22  -23
191 2001    1   -22
192 2000    0   -22
193 2003    3   -19
194 1930    -70 -89
195 2081    81  -8
196 1946    -54 -62
197 2058    58  -4
198 1997    -3  -7
199 1932    -68 -75
200 2068    68  -7
201 1929    -71 -78
202 2034    34  -44
203 2038    38  -6
204 1998    -2  -8
205 1950    -50 -58
206 1990    -10 -68
207 1880    -120    -188
208 2368    368 180
209 1825    -175    5
210 1709    -291    -286
211 2102    102 -184
212 2110    110 -74
213 2041    41  -33
214 2027    27  -6
215 1963    -37 -43
216 1841    -159    -202
217 2215    215 13
218 1800    -200    -187
219 2195    195 8
220 1984    -16 -8
221 1988    -12 -20
222 1966    -34 -54
223 2086    86  32
224 1858    -142    -110
225 2161    161 51
226 1806    -194    -143
227 2091    91  -52
228 1990    -10 -62
229 1995    -5  -67
230 1995    -5  -72
231 2039    39  -33
232 1996    -4  -37
233 2019    19  -18
234 1990    -10 -28
235 1777    -223    -251
236 2005    5   -246
237 2308    308 62
238 1903    -97 -35
239 1783    -217    -252
240 2064    64  -188
241 1943    -57 -245
242 1963    -37 -282
243 2216    216 -66
244 1889    -111    -177
245 2125    125 -52
246 1777    -223    -275
247 2306    306 31
248 1907    -93 -62
249 1991    -9  -71
250 2016    16  -55
251 1984    -16 -71
252 2002    2   -69
253 2029    29  -40
254 2027    27  -13
255 1993    -7  -20
256 2016    16  -4
257 1814    -186    -190
258 1953    -47 -237
259 2063    63  -174
260 2117    117 -57
261 1990    -10 -67
262 1863    -137    -204
263 2207    207 3
264 1987    -13 -10
265 1992    -8  -18
266 1970    -30 -48
267 2067    67  19
268 1976    -24 -5
269 1987    -13 -18
270 1963    -37 -55
271 1992    -8  -63
272 1996    -4  -67
273 2059    59  -8
274 1986    -14 -22
275 2011    11  -11
276 1956    -44 -55
277 1990    -10 -65
278 2002    2   -63
279 2051    51  -12
280 1989    -11 -23
281 1742    -258    -281
282 2297    297 16
283 1960    -40 -24
284 1902    -98 -122
285 2053    53  -69
286 1804    -196    -265
287 2025    25  -240
288 2201    201 -39
289 1992    -8  -47
290 1996    -4  -51
291 1981    -19 -70
292 1997    -3  -73
293 2005    5   -68
294 1876    -124    -192
295 2161    161 -31
296 1913    -87 -118
297 2052    52  -66
298 2027    27  -39
299 1899    -101    -140
300 2105    105 -35
301 1849    -151    -186
302 1996    -4  -190
303 2152    152 -38
304 1945    -55 -93
305 2087    87  -6
306 1979    -21 -27
307 1971    -29 -56
308 2050    50  -6
309 1988    -12 -18
310 1998    -2  -20
311 2068    68  48
312 1890    -110    -62
313 1998    -2  -64
314 1994    -6  -70
315 2000    0   -70
316 2023    23  -47
317 1987    -13 -60
318 2055    55  -5
319 1942    -58 -63
320 1901    -99 -162
321 2144    144 -18
322 2007    7   -11
323 2010    10  -1
324 1929    -71 -72
325 2063    63  -9
326 1956    -44 -53
327 1992    -8  -61
328 2028    28  -33
329 2026    26  -7
330 1976    -24 -31
331 2005    5   -26
332 1873    -127    -153
333 2126    126 -27
334 1955    -45 -72
335 2153    153 81
336 1854    -146    -65
337 1879    -121    -186
338 2140    140 -46
339 1898    -102    -148
340 2132    132 -16
341 1983    -17 -33
342 1998    -2  -35
343 2022    22  -13
344 1942    -58 -71
345 1893    -107    -178
346 2171    171 -7
347 2067    67  60
348 1905    -95 -35
349 1867    -133    -168
350 1941    -59 -227
351 2240    240 13
352 1972    -28 -15
353 1966    -34 -49
354 2044    44  -5
355 1958    -42 -47
356 1981    -19 -66
357 -997000 -999000 -999066
358 1997    -3  -999069
359 1999    -1  -999070
360 2011    11  -999059
361 2057    57  -999002
362 1987    -13 -999015
363 1971    -29 -999044
364 2037    37  -999007
365 1845    -155    -999162
366 2173    173 -998989
367 1986    -14 -999003
368 1974    -26 -999029
369 2016    16  -999013
370 1998    -2  -999015
371 2009    9   -999006
372 1822    -178    -999184
373 1939    -61 -999245
374 2206    206 -999039
375 1923    -77 -999116
376 1917    -83 -999199
377 2202    202 -998997
378 1929    -71 -999068
379 1882    -118    -999186
380 2191    191 -998995
381 1918    -82 -999077
382 2037    37  -999040
383 2025    25  -999015
384 1917    -83 -999098
385 2052    52  -999046
386 1799    -201    -999247
387 2202    202 -999045
388 2013    13  -999032
389 1964    -36 -999068
390 2023    23  -999045
391 2050    50  -998995
392 1924    -76 -999071
393 2043    43  -999028
394 2027    27  -999001
395 1986    -14 -999015
396 1983    -17 -999032
397 1855    -145    -999177
398 2133    133 -999044
399 1976    -24 -999068
400 1781    -219    -999287
401 2179    179 -999108
402 1966    -34 -999142
403 2086    86  -999056
404 2047    47  -999009
405 2002    2   -999007
406 1971    -29 -999036
407 1995    -5  -999041
408 2041    41  -999000
409 1989    -11 -999011
410 2011    11  -999000
411 1985    -15 -999015
412 1949    -51 -999066
413 2061    61  -999005
414 1982    -18 -999023
415 1997    -3  -999026
416 2012    12  -999014
417 1979    -21 -999035
418 2029    29  -999006
419 1978    -22 -999028
420 1978    -22 -999050
421 1993    -7  -999057
422 1834    -166        -999223
423 1970    -30 -999253
424 2146    146 -999107
425 2100    100 -999007
426 1962    -38 -999045
427 1908    -92 -999137
428 2155    155 -998982
429 1753    -247    -999229
430 2198    198 -999031
431 2025    25  -999006
432 1827    -173    -999179
433 2152    152 -999027
434 2033    33  -998994
435 1880    -120    -999114
436 1898    -102    -999216
437 2225    225 -998991
438 1985    -15 -999006
439 1870    -130    -999136
440 2101    101 -999035
441 1968    -32 -999067
442 2040    40  -999027
443 1956    -44 -999071
444 2008    8   -999063
445 2046    46  -999017
446 1946    -54 -999071
447 2029    29  -999042
448 2029    29  -999013
449 1996    -4  -999017
450 2002    2   -999015
451 1976    -24 -999039
452 1972    -28 -999067
453 2031    31  -999036
454 2009    9   -999027
455 2024    24  -999003
456 1987    -13 -999016
457 2000    0   -999016
458 1851    -149    -999165
459 2167    167 -998998
460 1933    -67 -999065
461 2029    29  -999036
462 1982    -18 -999054
463 1989    -11 -999065
464 2001    1   -999064
465 1994    -6  -999070
466 2058    58  -999012
467 1993    -7  -999019
468 1945    -55 -999074
469 2011    11  -999063
470 2020    20  -999043
471 2030    30  -999013
472 2002    2   -999011
473 1729    -271    -999282
474 2217    217 -999065
475 2015    15  -999050
476 2078    78  -998972
477 2003    3   -998969
478 1937    -63 -999032
479 1963    -37 -999069
480 2050    50  -999019
481 2030    30  -998989
482 1948    -52 -999041
483 1991    -9  -999050
484 2195    195 -998855
485 1790    -210    -999065
486 1993    -7  -999072
487 2005    5   -999067
488 2064    64  -999003
489 1970    -30 -999033
490 1921    -79 -999112
491 2100    100 -999012
492 1975    -25 -999037
493 2060    60  -998977
494 1790    -210    -999187
495 1985    -15 -999202
496 2217    217 -998985
497 1829    -171    -999156
498 2167    167 -998989
499 1823    -177    -999166
500 2151    151 -999015
501 2032    32  -998983
502 1991    -9  -998992
503 1984    -16 -999008
504 1817    -183    -999191
505 2156    156 -999035
506 1963    -37 -999072
507 2013    13  -999059
508 1835    -165    -999224
509 2230    230 -998994
510 1966    -34 -999028
511 1949    -51 -999079
512 2012    12  -999067
513 2064    64  -999003
514 1780    -220    -999223
515 2173    173 -999050
516 1972    -28 -999078
517 2048    48  -999030
518 1991    -9  -999039
519 2072    72  -998967
520 1931    -69 -999036
521 2031    31  -999005
522 1991    -9  -999014
523 2005    5   -999009
524 1995    -5  -999014
525 1994    -6  -999020
526 1957    -43 -999063
527 1833    -167    -999230
528 2186    186 -999044
529 1973    -27 -999071
530 2005    5   -999066
531 2053    53  -999013
532 1970    -30 -999043
533 1891    -109    -999152
534 2086    86  -999066
535 2005    5   -999061
536 2054    54  -999007
537 1872    -128    -999135
538 2141    141 -998994
539 1991    -9  -999003
540 1729    -271    -999274
541 2284    284 -998990
542 1984    -16 -999006
543 1932    -68 -999074
544 2060    60  -999014
545 1819    -181    -999195
546 2201    201 -998994
547 1927    -73 -999067
548 2034    34  -999033
549 1774    -226    -999259
550 2219    219 -999040
551 1973    -27 -999067
552 1997    -3  -999070
553 1875    -125    -999195
554 2167    167 -999028
555 2013    13  -999015
556 1997    -3  -999018
557 1860    -140    -999158
558 2162    162 -998996
559 1792    -208    -999204
560 2004    4   -999200
561 2015    15  -999185
562 2194    194 -998991
563 1971    -29 -999020
564 1987    -13 -999033
565 1997    -3  -999036
566 1998    -2  -999038
567 2030    30  -999008
568 1769    -231    -999239
569 2259    259 -998980
570 1767    -233    -999213
571 2000    0   -999213
572 2168    168 -999045
573 1978    -22 -999067
574 1810    -190    -999257
575 2218    218 -999039
576 2039    39  -999000
577 1933    -67 -999067
578 2027    27  -999040
579 2022    22  -999018
580 2011    11  -999007
581 1997    -3  -999010
582 1845    -155    -999165
583 2152    152 -999013
584 2020    20  -998993
585 1818    -182    -999175
586 1980    -20 -999195
587 2084    84  -999111
588 1920    -80 -999191
589 2178    178 -999013
590 1998    -2  -999015
591 1930    -70 -999085
592 2038    38  -999047
593 1909    -91 -999138
594 2079    79  -999059
595 1992    -8  -999067
596 2006    6   -999061
597 1996    -4  -999065
598 2046    46  -999019
599 2011    11  -999008
600 1999    -1  -999009
601 2000    0   -999009
602 1907    -93 -999102
603 2103    103 -998999
604 1984    -16 -999015
605 1988    -12 -999027
606 2019    19  -999008
607 1985    -15 -999023
608 1952    -48 -999071
609 2045    45  -999026
610 1992    -8  -999034
611 2014    14  -999020
612 2014    14  -999006
613 1750    -250    -999256
614 2271    271 -998985
615 1959    -41 -999026
616 1958    -42 -999068
617 1997    -3  -999071
618 2011    11  -999060
619 1974    -26 -999086
620 2058    58  -999028
621 1965    -35 -999063
622 2105    105 -998958
623 1889    -111    -999069
624 2071    71  -998998
625 1989    -11 -999009
626 1734    -266    -999275
627 2307    307 -998968
628 1943    -57 -999025
629 2156    156 -998869
630 1872    -128    -998997
631 1985    -15 -999012
632 1848    -152    -999164
633 2167    167 -998997
634 1960    -40 -999037
635 2012    12  -999025
636 1737    -263    -999288
637 2256    256 -999032
638 1968    -32 -999064
639 2047    47  -999017
640 1983    -17 -999034
641 1791    -209    -999243
642 2251    251 -998992
643 1973    -27 -999019
644 1954    -46 -999065
645 1864    -136    -999201
646 2169    169 -999032
647 1969    -31 -999063
648 2023    23  -999040
649 2031    31  -999009
650 1988    -12 -999021
651 2027    27  -998994
652 1998    -2  -998996
653 1988    -12 -999008
654 1954    -46 -999054
655 2046    46  -999008
656 1997    -3  -999011
657 1955    -45 -999056
658 1880    -120    -999176
659 2153    153 -999023
660 2463    463 -998560
661 1500    -500    -999060
662 2067    67  -998993
663 2010    10  -998983
664 1940    -60 -999043
665 1778    -222    -999265
666 2220    220 -999045
667 1789    -211    -999256
668 2233    233 -999023
669 1964    -36 -999059
670 1899    -101    -999160
671 2175    175 -998985
672 1962    -38 -999023
673 2016    16  -999007
674 1894    -106    -999113
675 2118    118 -998995
676 1984    -16 -999011
677 2008    8   -999003
678 1972    -28 -999031
679 1963    -37 -999068
680 2001    1   -999067
681 1869    -131    -999198
682 2090    90  -999108
683 2072    72  -999036
684 1782    -218    -999254
685 2276    276 -998978
686 1702    -298    -999276
687 2302    302 -998974
688 1936    -64 -999038
689 2034    34  -999004
690 1988    -12 -999016
691 1963    -37 -999053
692 2048    48  -999005
693 1973    -27 -999032
694 2022    22  -999010
695 1984    -16 -999026
696 2022    22  -999004
697 1989    -11 -999015
698 2134    134 -998881
699 1820    -180    -999061
700 1996    -4  -999065
701 2002    2   -999063
702 1999    -1  -999064
703 1830    -170    -999234
704 2061    61  -999173
705 2158    158 -999015
706 1997    -3  -999018
707 1827    -173    -999191
708 1938    -62 -999253
709 2277    277 -998976
710 1990    -10 -998986
711 1720    -280    -999266
712 2293    293 -998973
713 1960    -40 -999013
714 2002    2   -999011
715 1886    -114    -999125
716 2154    154 -998971
717 1956    -44 -999015
718 2010    10  -999005
719 1841    -159    -999164
720 2175    175 -998989
721 1728    -272    -999261
722 2218    218 -999043
723 1985    -15 -999058
724 1867    -133    -999191
725 1948    -52 -999243
726 2257    257 -998986
727 1865    -135    -999121
728 2065    65  -999056
729 2049    49  -999007
730 1955    -45 -999052
731 2046    46  -999006
732 2003    3   -999003
733 1744    -256    -999259
734 2281    281 -998978
735 1992    -8  -998986
736 1922    -78 -999064
737 2055    55  -999009
738 1999    -1  -999010
739 1807    -193    -999203
740 2158    158 -999045
741 1901    -99 -999144
742 1971    -29 -999173
743 2128    128 -999045
744 1975    -25 -999070
745 2015    15  -999055
746 2041    41  -999014
747 1986    -14 -999028
748 1959    -41 -999069
749 2073    73  -998996
750 1941    -59 -999055
751 2080    80  -998975
752 1907    -93 -999068
753 2045    45  -999023
754 1851    -149    -999172
755 2200    200 -998972
756 1953    -47 -999019
757 1840    -160    -999179
758 2190    190 -998989
759 1732    -268    -999257
760 2295    295 -998962
761 1952    -48 -999010
762 1998    -2  -999012
763 1966    -34 -999046
764 1993    -7  -999053
765 1992    -8  -999061
766 1994    -6  -999067
767 1892    -108    -999175
768 2180    180 -998995
769 1718    -282    -999277
770 2262    262 -999015
771 2023    23  -998992
772 1981    -19 -999011
773 1894    -106    -999117
774 2122    122 -998995
775 1965    -35 -999030
776 2033    33  -998997
777 1936    -64 -999061
778 2056    56  -999005
779 1750    -250    -999255
780 2274    274 -998981
781 1959    -41 -999022
782 2015    15  -999007
783 1997    -3  -999010
784 1993    -7  -999017
785 1810    -190    -999207
786 2042    42  -999165
787 1912    -88 -999253
788 2214    214 -999039
789 1827    -173    -999212
790 2096    96  -999116
791 2127    127 -998989
792 1919    -81 -999070
793 2056    56  -999014
794 1953    -47 -999061
795 2052    52  -999009
796 1980    -20 -999029
797 2026    26  -999003
798 2003    3   -999000
799 1725    -275    -999275
800 2277    277 -998998
801 1952    -48 -999046
802 1906    -94 -999140
803 2141    141 -998999
804 1984    -16 -999015
805 2009    9   -999006
806 2007    7   -998999
807 1945    -55 -999054
808 1992    -8  -999062
809 1997    -3  -999065
810 1998    -2  -999067
811 2012    12  -999055
812 2038    38  -999017
813 1947    -53 -999070
814 2060    60  -999010
815 1999    -1  -999011
816 1990    -10 -999021
817 1999    -1  -999022
818 2035    35  -998987
819 1951    -49 -999036
820 1978    -22 -999058
821 2018    18  -999040
822 2014    14  -999026
823 2019    19  -999007
824 1982    -18 -999025
825 2017    17  -999008
826 2029    29  -998979
827 1980    -20 -998999
828 1941    -59 -999058
829 2017    17  -999041
830 1979    -21 -999062
831 1894    -106    -999168
832 1914    -86 -999254
833 2239    239 -999015
834 2003    3   -999012
835 1897    -103    -999115
836 1935    -65 -999180
837 2193    193 -998987
838 1982    -18 -999005
839 1987    -13 -999018
840 1946    -54 -999072
841 2070    70  -999002
842 1893    -107    -999109
843 1946    -54 -999163
844 2176    176 -998987
845 1973    -27 -999014
846 2002    2   -999012
847 1990    -10 -999022
848 2015    15  -999007
849 2003    3   -999004
850 1742    -258    -999262
851 2412    412 -998850
852 1782    -218    -999068
853 2034    34  -999034
854 1970    -30 -999064
855 2033    33  -999031
856 1996    -4  -999035
857 -996970 -998970 -1998005
858 1957    -43 -1998048
859 1871    -129    -1998177
860 2142    142 -1998035
861 1796    -204    -1998239
862 2287    287 -1997952
863 1924    -76 -1998028
864 2019    19  -1998009
865 2063    63  -1997946
866 1935    -65 -1998011
867 1999    -1  -1998012
868 2007    7   -1998005
869 1996    -4  -1998009
870 1984    -16 -1998025
871 1957    -43 -1998068
872 2037    37  -1998031
873 1763    -237    -1998268
874 2242    242 -1998026
875 1961    -39 -1998065
876 2020    20  -1998045
877 1984    -16 -1998061
878 2062    62  -1997999
879 1980    -20 -1998019
880 1754    -246    -1998265
881 2284    284 -1997981
882 1836    -164    -1998145
883 2221    221 -1997924
884 1936    -64 -1997988
885 1978    -22 -1998010
886 1853    -147    -1998157
887 2146    146 -1998011
888 2005    5   -1998006
889 1993    -7  -1998013
890 1866    -134    -1998147
891 2164    164 -1997983
892 1742    -258    -1998241
893 2147    147 -1998094
894 2081    81  -1998013
895 1955    -45 -1998058
896 1997    -3  -1998061
897 2054    54  -1998007
898 1964    -36 -1998043
899 2032    32  -1998011
900 1999    -1  -1998012
901 1996    -4  -1998016
902 1988    -12 -1998028
903 1836    -164    -1998192
904 2212    212 -1997980
905 2033    33  -1997947
906 1825    -175    -1998122
907 2142    142 -1997980
908 1983    -17 -1997997
909 1925    -75 -1998072
910 2075    75  -1997997
911 1995    -5  -1998002
912 1759    -241    -1998243
913 2268    268 -1997975
914 1828    -172    -1998147
915 2101    101 -1998046
916 1894    -106    -1998152
917 2115    115 -1998037
918 1993    -7  -1998044
919 1934    -66 -1998110
920 2100    100 -1998010
921 1995    -5  -1998015
922 1980    -20 -1998035
923 2110    110 -1997925
924 1945    -55 -1997980
925 1731    -269    -1998249
926 2305    305 -1997944
927 1870    -130    -1998074
928 1904    -96 -1998170
929 2179    179 -1997991
930 1894    -106    -1998097
931 2090    90  -1998007
932 2225    225 -1997782
933 1791    -209    -1997991
934 1954    -46 -1998037
935 2010    10  -1998027
936 1754    -246    -1998273
937 2245    245 -1998028
938 1962    -38 -1998066
939 2001    1   -1998065
940 2064    64  -1998001
941 1969    -31 -1998032
942 2060    60  -1997972
943 2042    42  -1997930
944 1669    -331    -1998261
945 2292    292 -1997969
946 1959    -41 -1998010
947 2012    12  -1997998
948 1931    -69 -1998067
949 2057    57  -1998010
950 2009    9   -1998001
951 1825    -175    -1998176
952 2203    203 -1997973
953 1964    -36 -1998009
954 2077    77  -1997932
955 1941    -59 -1997991
956 1988    -12 -1998003
957 1970    -30 -1998033
958 1980    -20 -1998053
959 1992    -8  -1998061
960 2001    1   -1998060
961 2221    221 -1997839
962 1834    -166    -1998005
963 1993    -7  -1998012
964 1987    -13 -1998025
965 2026    26  -1997999
966 1987    -13 -1998012
967 2001    1   -1998011
968 2004    4   -1998007
969 1944    -56 -1998063
970 1885    -115    -1998178
971 2203    203 -1997975
972 1965    -35 -1998010
973 2049    49  -1997961
974 1967    -33 -1997994
975 1784    -216    -1998210
976 2219    219 -1997991
977 1976    -24 -1998015
978 1973    -27 -1998042
979 2025    25  -1998017
980 1981    -19 -1998036
981 1981    -19 -1998055
982 2058    58  -1997997
983 1969    -31 -1998028
984 2023    23  -1998005
985 2006    6   -1997999
986 1810    -190    -1998189
987 2206    206 -1997983
988 1990    -10 -1997993
989 1952    -48 -1998041
990 1983    -17 -1998058
991 2033    33  -1998025
992 2000    0   -1998025
993 2011    11  -1998014
994 1864    -136    -1998150
995 1893    -107    -1998257
996 2287    287 -1997970
997 1957    -43 -1998013
998 2006    6   -1998007
999 1957    -43 -1998050
counted 1000 events

我使用clock_gettime函数错误吗? 我应该使用其他计时器吗? 看起来像翻车。如果将其放入计时器读取功能中,是否有人知道如何解决该问题?

是的,我知道我正在使用ualarm() 此代码的最终目标是树莓派。我只是在玩我制作的基准测试工具,以为可以在笔记本电脑上运行。我在RPi上没有得到类似的问题...虽然我一次运行它的时间不超过10秒...

2 个答案:

答案 0 :(得分:2)

即使对于生产代码来说这是不好的做法,我还是在信号处理程序中添加了printf()语句来记录输出:

/* SO 5538-7600 */

#include "time_math.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>

#define OPT_R_MIN 0
#define OPT_R_MAX 5000
#define OPT_R_DEF 100
#define OPT_U_MIN 100
#define OPT_U_MAX 2000000000 // 2K seconds
#define OPT_U_DEF 2000
#define OPT_O_ELAPSED 0
#define OPT_O_JITTER 1
#define OPT_O_SUMJITTER 2
#define OPT_O_DEVIATION 3
#define OPT_O_DEVIATION_MAX 256
#define OPT_C_MIN 100
#define OPT_C_MAX 2000000000
#define OPT_C_DEF 1000

#define TIME_OUT_PERIOD 5000000
#define MILLION 1000000
#define BILLION 1000000000

int opt_o_min = OPT_O_ELAPSED;
int opt_o_max = OPT_O_SUMJITTER;

int opt_r = OPT_R_DEF;
unsigned int opt_u = OPT_U_DEF;
int opt_o = OPT_O_JITTER;
int opt_c = OPT_C_DEF;
int editOutput = 0;

volatile unsigned int elapsedTime, jitter;
struct timespec thisTime, lastTime, timeOutStart, timeOutTest;
volatile unsigned int sampleFlag = 0;
volatile int eventCounter, sumJitter, firstTime, secondTime;

void alarmWakeup(int sig_num);
void startTimer(int r, unsigned int u);
void handler(int sig_num);

char filename[100];
struct tm *timenow;


static void usage(void)
{
    fprintf(stderr,
        "Usage: sudo ./timerTest ... [OPTION] ...\n"
        "   -r value, sets the allowed lag between alarm and callback   default: %d\n"
        "   -u value, sets microsecond alarm setting   default: %d\n"
        "         %d < VALID < %d ONLY (under test)\n"
        "   -o value, sets the output type     default: %d\n"
        "         %d elapsed time in microseconds\n"
        "         %d jitter (elapsed time / -u value)\n"
        "         %d cumulative jitter (jitter + jitter)\n"
        "   -t value, sets duration of test cycles in event counter    default: %d\n"
        "         %d < VALID < %d ONLY (under test)\n"
        "\n",
        OPT_R_DEF, OPT_U_DEF, OPT_U_MIN, OPT_U_MAX, OPT_O_JITTER,
        OPT_O_ELAPSED, OPT_O_JITTER, OPT_O_SUMJITTER, OPT_O_DEVIATION,
        OPT_O_DEVIATION_MAX, OPT_C_DEF//, OPT_C_MIN, OPT_C_MAX
        );
}

static void fatal(int show_usage, char *fmt, ...)
{
    char buf[128];
    va_list ap;

    va_start(ap, fmt);
    vsnprintf(buf, sizeof(buf), fmt, ap);
    va_end(ap);

    fprintf(stderr, "%s\n", buf);

    if (show_usage)
        usage();

    fflush(stderr);

    exit(EXIT_FAILURE);
}

static int initOpts(int argc, char *argv[])
{
    int i, opt;
    unsigned int u;

    while ((opt = getopt(argc, argv, "r:u:o:t:")) != -1)
    {
        i = -1;
        switch (opt)
        {
        case 'r':
            i = atoi(optarg);
            if ((i >= OPT_R_MIN) && (i <= OPT_R_MAX))
                opt_r = i;
            else
                fatal(1, "invalid -r option (%d)", i);
            break;

        case 'u':
            u = atol(optarg);
            if ((u >= OPT_U_MIN) && (u <= OPT_U_MAX))
                opt_u = u;
            else
                fatal(1, "invalid -u option (%d)", u);
            break;

        case 'o':
            i = atoi(optarg);
            opt_o = i;  // probably fatal
            break;

        case 't':
            i = atoi(optarg);
            opt_c = i;  // probably fatal
            break;

        default: /* '?' */
            usage();
        }
    }
    return optind;
}

int main(int argc, char *argv[])
{
    int settings = 0;
    // command line settings
    settings = initOpts(argc, argv);
    time_t now = time(NULL);
    timenow = gmtime(&now);

    // FILE *data;
    // strftime(filename, sizeof(filename),
    // "/home/pi/Documents/_C_/WiringPiAlarm/protoPulse_%Y-%m-%d_%H:%M:%S.dat", timenow);
    // data = fopen(filename, "w+");
    // fprintf(data,"# Sample count: %d option(s)\n", opt_c);
    // fprintf(data,"# Running with %d latency at %duS sample rate\n",opt_r,opt_u);
    // fprintf(data,"# Output Type is %d\n\n" , opt_o);

    printf("User selects %d option(s)\n", settings - 1);
    printf("Running with %d latency at %duS sample rate\n", opt_r, opt_u);
    printf("Output Type is %d\n", opt_o);
    printf("    Use -o value to select output type\n");
    printf("        0: elapsed time between interrutps\n");
    printf("        1: jitter (elapsed time / -u)\n");
    printf("        2: cumulative jitter (jitter + jitter)\n");
    printf("Sample count: %d\n", opt_c);
    printf("Starting alarm timer for %dmS...\n", opt_u);


    eventCounter = 0;
    firstTime = secondTime = 1;
    clock_gettime(CLOCK_MONOTONIC, &lastTime);
    // lastTime = micros();
    timeOutStart = lastTime;
    startTimer(opt_r, opt_u);


    while (1)
    {
        if (sampleFlag)
        {
            sampleFlag = 0;
            timeOutStart = lastTime;
            // int metaDataOutput;
            // switch(opt_o){  // ALL OUTPUTS DISCARD THE FIRST CALLBACK
            //    case OPT_O_JITTER:
            //        metaDataOutput = jitter;
            //        break;
            //    case OPT_O_SUMJITTER:
            //        metaDataOutput = sumJitter;
            //        break;
            //    default:
            //        metaDataOutput = elapsedTime;
            //        break;
            // }
            printf("%d\t%d\t%d\t%d\n", eventCounter, elapsedTime, jitter, sumJitter);
            // fprintf(data,"%d\t%d\n",eventCounter,metaDataOutput);
        }
        clock_gettime(CLOCK_MONOTONIC, &timeOutTest);
        if ((MILLION * (timeOutTest.tv_sec - timeOutStart.tv_sec) + timeOutTest.tv_nsec - timeOutStart.tv_nsec) / 1000 > TIME_OUT_PERIOD)
        {
            fatal(0, "program timed out", 0);
        }
        if (eventCounter >= opt_c)
        {
            fatal(0, "counted %d events", eventCounter, 0);
        }
    }

    return 0;
}

void startTimer(int r, unsigned int u)
{
    int latency = r;
    unsigned int micros = u;

    signal(SIGALRM, alarmWakeup);
    ualarm(latency, micros);
}

void alarmWakeup(int sig_num)
{
    if (sig_num == SIGALRM)
    {
        clock_gettime(CLOCK_MONOTONIC, &thisTime);
        // thisTime = micros();
        elapsedTime = (MILLION * (thisTime.tv_sec - lastTime.tv_sec) + thisTime.tv_nsec - lastTime.tv_nsec) / 1000;
        struct timespec diff;
        sub_timespec(lastTime, thisTime, &diff);
        /* Not good practice! */
        printf("%10u : %ld.%.9ld - %ld.%.9ld (%ld.%.9ld)  - ",
               elapsedTime,
               thisTime.tv_sec, thisTime.tv_nsec,
               lastTime.tv_sec, lastTime.tv_nsec,
               diff.tv_sec, diff.tv_nsec);
        lastTime = thisTime;
        if (firstTime)
        {
            firstTime = 0;
            return;
        }
        if (secondTime)
        {
            secondTime = 0;
            return;
        }
        jitter = elapsedTime - opt_u;
        sumJitter += jitter;
        eventCounter++;
        sampleFlag = 1;
    }
}

time_math.h标头包含:

#include <time.h>

extern void sub_timespec(struct timespec t1, struct timespec t2, struct timespec *td);

sub_timespec()代码如下(如注释所示):

enum { NS_PER_SECOND = 1000000000 };

void sub_timespec(struct timespec t1, struct timespec t2, struct timespec *td)
{
    td->tv_nsec = t2.tv_nsec - t1.tv_nsec;
    td->tv_sec  = t2.tv_sec - t1.tv_sec;
    if (td->tv_sec > 0 && td->tv_nsec < 0)
    {
        td->tv_nsec += NS_PER_SECOND;
        td->tv_sec--;
    }
    else if (td->tv_sec < 0 && td->tv_nsec > 0)
    {
        td->tv_nsec -= NS_PER_SECOND;
        td->tv_sec++;
    }
}

在问题的关键时刻,输出为:

      1896 : 169978.995568000 - 169978.993672000 (0.001896000)  - 97    1896    -104    64
      1978 : 169978.997546000 - 169978.995568000 (0.001978000)  - 98    1978    -22 42
      2136 : 169978.999682000 - 169978.997546000 (0.002136000)  - 99    2136    136 178
4293970278 : 169979.001664000 - 169978.999682000 (0.001982000)  - 100   -997018 -999018 -998840
      2019 : 169979.003683000 - 169979.001664000 (0.002019000)  - 101   2019    19  -998821
      2041 : 169979.005724000 - 169979.003683000 (0.002041000)  - 102   2041    41  -998780

如您所见,数字正好是tv_nsec值从999418000001406000的转折点。 (在macOS上,尽管clock_gettime()报告的是纳秒,但最后三位数字始终为零,因此它有效地报告了微秒。)您还可能会看到,带括号的数字(sub_timespec()的输出)没有在那个时候走干草。

答案 1 :(得分:0)

乔纳森发布的时间数学解决了该问题。 现在,我想我必须替换对ualarm()的使用了……据我所知,替代方法非常繁琐。

这是工作代码。我没有使用time_math库。刚刚加入了sub_timespec()函数。 谢谢!



#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>

#define OPT_R_MIN 0
#define OPT_R_MAX 5000
#define OPT_R_DEF 100
#define OPT_U_MIN 100
#define OPT_U_MAX 2000000000 // 2K seconds
#define OPT_U_DEF 2000
#define OPT_O_ELAPSED 0
#define OPT_O_JITTER 1
#define OPT_O_SUMJITTER 2
#define OPT_O_DEVIATION 3
#define OPT_O_DEVIATION_MAX 256
#define OPT_C_MIN 100
#define OPT_C_MAX 2000000000
#define OPT_C_DEF 1000

#define TIME_OUT_PERIOD 5000000
#define MILLION 1000000
#define BILLION 1000000000

int opt_o_min = OPT_O_ELAPSED;
int opt_o_max = OPT_O_SUMJITTER;

int opt_r = OPT_R_DEF;
unsigned int opt_u = OPT_U_DEF;
int opt_o = OPT_O_JITTER;
int opt_c = OPT_C_DEF;
int editOutput = 0;

volatile unsigned int elapsedTime, jitter;
struct timespec thisTime, lastTime, diff, timeOutStart, timeOutTest;
volatile unsigned int sampleFlag = 0;
volatile int eventCounter, sumJitter, firstTime, secondTime;

void alarmWakeup(int sig_num);
void startTimer(int r, unsigned int u);
void handler(int sig_num);
void sub_timespec(struct timespec t1, struct timespec t2, struct timespec *td);
char filename [100];
struct tm *timenow;


void usage()
{
   fprintf
   (stderr,
      "\n" \
      "Usage: sudo ./timerTest ... [OPTION] ...\n" \
      "   -r value, sets the allowed lag between alarm and callback   default: %d\n"
      "   -u value, sets microsecond alarm setting   default: %d\n" \
      "         %d < VALID < %d ONLY (under test)\n"\
      "   -o value, sets the output type     default: %d\n"\
      "         %d elapsed time in microseconds\n"\
      "         %d jitter (elapsed time / -u value)\n"\
      "         %d cumulative jitter (jitter + jitter)\n"\
      "   -t value, sets duration of test cycles in event counter    default: %d\n"\
      "         %d < VALID < %d ONLY (under test)\n"\
      "\n",
      OPT_R_DEF,OPT_U_DEF, OPT_U_MIN, OPT_U_MAX, OPT_O_JITTER,
      OPT_O_ELAPSED, OPT_O_JITTER, OPT_O_SUMJITTER, OPT_O_DEVIATION,
      OPT_O_DEVIATION_MAX, OPT_C_DEF, OPT_C_MIN, OPT_C_MAX
   );
}

void fatal(int show_usage, char *fmt, ...)
{
   char buf[128];
   va_list ap;

   va_start(ap, fmt);
   vsnprintf(buf, sizeof(buf), fmt, ap);
   va_end(ap);

   fprintf(stderr, "%s\n", buf);

   if (show_usage) usage();

   fflush(stderr);

   exit(EXIT_FAILURE);
}

static int initOpts(int argc, char *argv[])
{
   int i, opt;
   unsigned int u;

   while ((opt = getopt(argc, argv, "r:u:o:t:")) != -1)
   {
      i = -1;
      switch (opt)
      {
         case 'r':
            i = atoi(optarg);
            if ((i >= OPT_R_MIN) && (i <= OPT_R_MAX))
               opt_r = i;
            else fatal(1, "invalid -r option (%d)", i);
            break;

         case 'u':
            u = atol(optarg);
            if ((u >= OPT_U_MIN) && (u <= OPT_U_MAX))
               opt_u = u;
            else fatal(1, "invalid -u option (%d)", u);
            break;

         case 'o':
            i = atoi(optarg);
            opt_o = i;  // probably fatal
            break;

        case 't':
            i = atoi(optarg);
            opt_c = i;  // probably fatal
            break;

        default: /* '?' */
           usage();
        }
    }
   return optind;
}


int main(int argc, char *argv[])
{
    int settings = 0;
    // command line settings
    settings = initOpts(argc, argv);
    time_t now = time(NULL);
    timenow = gmtime(&now);

    // FILE *data;
    // strftime(filename, sizeof(filename),
    // "/home/pi/Documents/_C_/WiringPiAlarm/protoPulse_%Y-%m-%d_%H:%M:%S.dat", timenow);
    // data = fopen(filename, "w+");
    // fprintf(data,"# Sample count: %d option(s)\n", opt_c);
    // fprintf(data,"# Running with %d latency at %duS sample rate\n",opt_r,opt_u);
    // fprintf(data,"# Output Type is %d\n\n" , opt_o);

    printf("User selects %d option(s)\n", settings-1);
    printf("Running with %d latency at %duS sample rate\n",opt_r,opt_u);
    printf("Output Type is %d\n" , opt_o);
    printf("    Use -o value to select output type\n");
    printf("        0: elapsed time between interrutps\n");
    printf("        1: jitter (elapsed time / -u)\n");
    printf("        2: cumulative jitter (jitter + jitter)\n");
    printf("Sample count: %d\n", opt_c);
    printf("Starting alarm timer for %dmS...\n", opt_u);


    eventCounter = 0;
    firstTime = secondTime = 1;
        clock_gettime(CLOCK_MONOTONIC, &lastTime);
    // lastTime = micros();
    timeOutStart = lastTime;
    startTimer(opt_r, opt_u);


    while(1)
    {
        if(sampleFlag){
            sampleFlag = 0;
            timeOutStart = lastTime;
            int metaDataOutput;
                        printf("%d\t%d\t%d\t%d\n",eventCounter,elapsedTime,jitter, sumJitter);
             // fprintf(data,"%d\t%d\n",eventCounter,metaDataOutput);
         }
                 clock_gettime(CLOCK_MONOTONIC, &timeOutTest);
         if((MILLION * (timeOutTest.tv_sec - timeOutStart.tv_sec) + timeOutTest.tv_nsec - timeOutStart.tv_nsec)/1000>TIME_OUT_PERIOD){
            fatal(0,"program timed out",0);
         }
         if(eventCounter >= opt_c){
            fatal(0,"counted %d events", eventCounter, 0);
         }
    }

    return 0;

}//int main(int argc, char *argv[])

void startTimer(int r, unsigned int u){
    int latency = r;
    unsigned int micros = u;

    signal(SIGALRM, alarmWakeup);
    ualarm(latency, micros);

}

void alarmWakeup(int sig_num)
{

    if(sig_num == SIGALRM)
    {
                clock_gettime(CLOCK_MONOTONIC, &thisTime);
                sub_timespec(lastTime,thisTime,&diff);
                elapsedTime = diff.tv_nsec / 1000;
        lastTime = thisTime;
        if(firstTime){
            firstTime = 0;
            return;
        }
        if(secondTime){
            secondTime = 0;
            return;
        }
        jitter = elapsedTime - opt_u;
        sumJitter += jitter;
        eventCounter++;
        sampleFlag = 1;

    }

}


void sub_timespec(struct timespec t1, struct timespec t2, struct timespec *td)
{
    td->tv_nsec = t2.tv_nsec - t1.tv_nsec;
    td->tv_sec  = t2.tv_sec - t1.tv_sec;
    if (td->tv_sec > 0 && td->tv_nsec < 0)
    {
        td->tv_nsec += BILLION;
        td->tv_sec--;
    }
    else if (td->tv_sec < 0 && td->tv_nsec > 0)
    {
        td->tv_nsec -= BILLION;
        td->tv_sec++;
    }
}