Switch to unified view

a b/src/chrono.cpp
1
#ifndef TEST_CHRONO
2
/* Copyright (C) 2014 J.F.Dockes
3
 *   This program is free software; you can redistribute it and/or modify
4
 *   it under the terms of the GNU General Public License as published by
5
 *   the Free Software Foundation; either version 2 of the License, or
6
 *   (at your option) any later version.
7
 *
8
 *   This program is distributed in the hope that it will be useful,
9
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 *   GNU General Public License for more details.
12
 *
13
 *   You should have received a copy of the GNU General Public License
14
 *   along with this program; if not, write to the
15
 *   Free Software Foundation, Inc.,
16
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17
 */
18
19
// Measure and display time intervals.
20
21
#include <stdio.h>
22
#include <stdlib.h>
23
#include <time.h>
24
#include <sys/time.h>
25
#include <iostream>
26
27
#include "chrono.h"
28
29
using namespace std;
30
31
////////////////////
32
33
#ifndef CLOCK_REALTIME
34
#define CLOCK_REALTIME 1
35
#endif
36
37
#define MILLIS(TS1, TS2)                                \
38
    ((long long)((TS2).tv_sec - (TS1).tv_sec) * 1000LL +  \
39
     ((TS2).tv_nsec - (TS1).tv_nsec) / 1000000)
40
41
#define MICROS(TS1, TS2)                                        \
42
    ((long long)((TS2).tv_sec - (TS1).tv_sec) * 1000000LL +       \
43
     ((TS2).tv_nsec - (TS1).tv_nsec) / 1000)
44
45
#define SECONDS(TS1, TS2)                             \
46
    (float((TS2).tv_sec - (TS1).tv_sec) +             \
47
     float((TS2).tv_nsec - (TS1).tv_nsec) * 1e-9)
48
49
// We use gettimeofday instead of clock_gettime for now and get only
50
// uS resolution, because clock_gettime is more configuration trouble
51
// than it's worth
52
static void gettime(int, Chrono::TimeSpec *ts)
53
{
54
    struct timeval tv;
55
    gettimeofday(&tv, 0);
56
    ts->tv_sec = tv.tv_sec;
57
    ts->tv_nsec = tv.tv_usec * 1000;
58
}
59
///// End system interface (used to be much more complicated in the 199xs...)
60
61
Chrono::TimeSpec Chrono::o_now;
62
63
void Chrono::refnow()
64
{
65
    gettime(CLOCK_REALTIME, &o_now);
66
}
67
68
long long Chrono::amicros() const
69
{
70
    TimeSpec ts;
71
    ts.tv_sec = 0;
72
    ts.tv_nsec = 0;
73
    return MICROS(ts, m_orig);
74
}
75
76
Chrono::Chrono()
77
{
78
    restart();
79
}
80
81
// Reset and return value before rest in milliseconds
82
long Chrono::restart()
83
{
84
    TimeSpec now;
85
    gettime(CLOCK_REALTIME, &now);
86
    long ret = MILLIS(m_orig, now);
87
    m_orig = now;
88
    return ret;
89
}
90
long Chrono::urestart()
91
{
92
    TimeSpec now;
93
    gettime(CLOCK_REALTIME, &now);
94
    long ret = MICROS(m_orig, now);
95
    m_orig = now;
96
    return ret;
97
}
98
99
// Get current timer value, milliseconds
100
long Chrono::millis(bool frozen)
101
{
102
    if (frozen) {
103
        return MILLIS(m_orig, o_now);
104
    } else {
105
        TimeSpec now;
106
        gettime(CLOCK_REALTIME, &now);
107
        return MILLIS(m_orig, now);
108
    }
109
}
110
111
//
112
long Chrono::micros(bool frozen)
113
{
114
    if (frozen) {
115
        return MICROS(m_orig, o_now);
116
    } else {
117
        TimeSpec now;
118
        gettime(CLOCK_REALTIME, &now);
119
        return MICROS(m_orig, now);
120
    }
121
}
122
123
float Chrono::secs(bool frozen)
124
{
125
    if (frozen) {
126
        return SECONDS(m_orig, o_now);
127
    } else {
128
        TimeSpec now;
129
        gettime(CLOCK_REALTIME, &now);
130
        return SECONDS(m_orig, now);
131
    }
132
}
133
134
#else
135
136
///////////////////// test driver
137
138
139
#include <stdio.h>
140
#include <signal.h>
141
#include <unistd.h>
142
#include <stdlib.h>
143
144
#include <iostream>
145
146
#include "chrono.h"
147
148
using namespace std;
149
150
static char *thisprog;
151
static void
152
Usage(void)
153
{
154
    fprintf(stderr, "Usage : %s \n", thisprog);
155
    exit(1);
156
}
157
158
Chrono achrono;
159
Chrono rchrono;
160
161
void
162
showsecs(long msecs)
163
{
164
    fprintf(stderr, "%3.5f S", ((float)msecs) / 1000.0);
165
}
166
167
void
168
sigint(int sig)
169
{
170
    signal(SIGINT, sigint);
171
    signal(SIGQUIT, sigint);
172
173
    fprintf(stderr, "Absolute interval: ");
174
    showsecs(achrono.millis());
175
    fprintf(stderr, ". Relative interval: ");
176
    showsecs(rchrono.restart());
177
    cerr <<  " Abs micros: " << rchrono.amicros() <<
178
        " Relabs micros: " << rchrono.amicros() - 1430477861905884LL
179
         << endl;
180
    fprintf(stderr, ".\n");
181
    if (sig == SIGQUIT) {
182
        exit(0);
183
    }
184
}
185
186
int main(int argc, char **argv)
187
{
188
189
    thisprog = argv[0];
190
    argc--;
191
    argv++;
192
193
    if (argc != 0) {
194
        Usage();
195
    }
196
197
    for (int i = 0; i < 50000000; i++);
198
    fprintf(stderr, "Start secs: %.2f\n", achrono.secs());
199
200
201
    fprintf(stderr, "Type ^C for intermediate result, ^\\ to stop\n");
202
    signal(SIGINT, sigint);
203
    signal(SIGQUIT, sigint);
204
    achrono.restart();
205
    rchrono.restart();
206
    while (1) {
207
        pause();
208
    }
209
}
210
211
#endif /*TEST_CHRONO*/