]> AND Private Git Repository - loba.git/blob - timer.h
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
Use static instead of volatile for variables that may be clobbered by a TRY..CATCH.
[loba.git] / timer.h
1 #ifndef TIMER_H
2 #define TIMER_H
3
4 #include <sys/time.h>
5 #include <sys/resource.h>
6
7 #ifdef _BSD_SOURCE
8 #  define HAVE_TIMERADD
9 #  define HAVE_TIMERSUB
10 #  define HAVE_TIMERCLEAR
11 #else
12 #  warning _BSD_SOURCE not defined
13 #  undef HAVE_TIMERADD
14 #  undef HAVE_TIMERSUB
15 #  undef HAVE_TIMERCLEAR
16 #endif
17
18 inline
19 struct timeval operator+(const struct timeval& a, const struct timeval& b)
20 {
21     struct timeval result;
22 #ifdef HAVE_TIMERADD
23     timeradd(&a, &b, &result);
24 #else
25     result.tv_sec = a.tv_sec + b.tv_sec;
26     result.tv_usec = a.tv_usec + b.tv_usec;
27     if (result.tv_usec >= 1000000) {
28         ++result.tv_sec;
29         result.tv_usec -= 1000000;
30     }
31 #endif
32     return result;
33 }
34
35 inline
36 struct timeval operator-(const struct timeval& a, const struct timeval& b)
37 {
38     struct timeval result;
39 #ifdef HAVE_TIMERSUB
40     timersub(&a, &b, &result);
41 #else
42     result.tv_sec = a.tv_sec - b.tv_sec;
43     result.tv_usec = a.tv_usec - b.tv_usec;
44     if (result.tv_usec < 0) {
45         --result.tv_sec;
46         result.tv_usec += 1000000;
47     }
48 #endif
49     return result;
50 }
51
52 class timestamp {
53 public:
54     enum clock_type { wallclock_time, cpu_time };
55
56     timestamp(clock_type ct);
57     ~timestamp();
58     void reset();
59
60     void start();
61     void stop();
62
63     struct timeval tv_duration() const;
64     double duration() const;
65
66 private:
67     clock_type clk;
68     struct timeval before;
69     struct timeval after;
70     struct timeval difference;
71
72     void get_time(struct timeval& tv);
73
74     static void tv_clear(struct timeval& a);
75     static double timertod(const struct timeval& a);
76 };
77
78 inline
79 timestamp::timestamp(clock_type ct): clk(ct)
80 {
81     reset();
82 }
83
84 inline
85 timestamp::~timestamp()
86 {
87 }
88
89 inline
90 void timestamp::reset()
91 {
92     tv_clear(before);
93     tv_clear(after);
94     tv_clear(difference);
95 }
96
97 inline
98 void timestamp::start()
99 {
100     get_time(before);
101 }
102
103 inline
104 void timestamp::stop()
105 {
106     get_time(after);
107     difference = difference + (after - before);
108 }
109
110 inline
111 struct timeval timestamp::tv_duration() const
112 {
113     return difference;
114 }
115
116 inline
117 double timestamp::duration() const
118 {
119     return timertod(difference);
120 }
121
122 inline
123 void timestamp::get_time(struct timeval& tv)
124 {
125     switch (clk) {
126     case cpu_time: {
127         struct rusage usage;
128         getrusage(RUSAGE_SELF, &usage);
129         tv = usage.ru_utime + usage.ru_stime;
130         break;
131     }
132     case wallclock_time:
133         gettimeofday(&tv, NULL);
134         break;
135     }
136 }
137
138 inline
139 void timestamp::tv_clear(struct timeval& a)
140 {
141 #ifdef HAVE_TIMERCLEAR
142     timerclear(&a);
143 #else
144     tv.sec = tv.usec = 0;
145 #endif
146 }
147
148 inline
149 double timestamp::timertod(const struct timeval& a)
150 {
151     return a.tv_sec + a.tv_usec / 1e6;
152 }
153
154 #endif // !TIMER_H
155
156 // Local variables:
157 // mode: c++
158 // End: