This source file includes following definitions.
- set_to_current_time
- get_current_time
- timevar_accumulate
- timevar_init
- timevar_push
- timevar_pop
- timevar_start
- timevar_stop
- timevar_get
- timevar_print
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 #include <config.h>
22
23
24 #include "timevar.h"
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <sys/resource.h>
30 #include <sys/time.h>
31 #include <sys/times.h>
32
33 #include "gethrxtime.h"
34 #include "gettext.h"
35 #define _(msgid) gettext (msgid)
36 #include "xalloc.h"
37
38
39
40 int timevar_enabled = 0;
41
42
43
44 struct timevar_def
45 {
46
47 struct timevar_time_def elapsed;
48
49
50
51 struct timevar_time_def start_time;
52
53
54 const char *name;
55
56
57
58 unsigned standalone : 1;
59
60
61
62 unsigned used : 1;
63 };
64
65
66
67
68 struct timevar_stack_def
69 {
70
71 struct timevar_def *timevar;
72
73
74 struct timevar_stack_def *next;
75 };
76
77
78
79 static struct timevar_def timevars[TIMEVAR_LAST];
80
81
82 static struct timevar_stack_def *stack;
83
84
85
86 static struct timevar_stack_def *unused_stack_instances;
87
88
89
90
91 static struct timevar_time_def start_time;
92
93
94
95 static void
96 set_to_current_time (struct timevar_time_def *now)
97 {
98 now->user = 0;
99 now->sys = 0;
100 now->wall = 0;
101
102 if (!timevar_enabled)
103 return;
104
105 struct rusage self;
106 getrusage (RUSAGE_SELF, &self);
107 struct rusage chld;
108 getrusage (RUSAGE_CHILDREN, &chld);
109
110 now->user =
111 xtime_make (self.ru_utime.tv_sec + chld.ru_utime.tv_sec,
112 (self.ru_utime.tv_usec + chld.ru_utime.tv_usec) * 1000);
113
114 now->sys =
115 xtime_make (self.ru_stime.tv_sec + chld.ru_stime.tv_sec,
116 (self.ru_stime.tv_usec + chld.ru_stime.tv_usec) * 1000);
117
118 now->wall = gethrxtime();
119 }
120
121
122
123 static struct timevar_time_def
124 get_current_time (void)
125 {
126 struct timevar_time_def now;
127 set_to_current_time (&now);
128 return now;
129 }
130
131
132
133 static void
134 timevar_accumulate (struct timevar_time_def *timer,
135 const struct timevar_time_def *start,
136 const struct timevar_time_def *stop)
137 {
138 timer->user += stop->user - start->user;
139 timer->sys += stop->sys - start->sys;
140 timer->wall += stop->wall - start->wall;
141 }
142
143 void
144 timevar_init ()
145 {
146 if (!timevar_enabled)
147 return;
148
149
150 memset ((void *) timevars, 0, sizeof (timevars));
151
152
153 #define DEFTIMEVAR(identifier__, name__) \
154 timevars[identifier__].name = name__;
155 #include "timevar.def"
156 #undef DEFTIMEVAR
157 }
158
159 void
160 timevar_push (timevar_id_t timevar)
161 {
162 if (!timevar_enabled)
163 return;
164
165 struct timevar_def *tv = &timevars[timevar];
166
167
168 tv->used = 1;
169
170
171 if (tv->standalone)
172 abort ();
173
174
175 struct timevar_time_def const now = get_current_time ();
176
177
178
179 if (stack)
180 timevar_accumulate (&stack->timevar->elapsed, &start_time, &now);
181
182
183
184 start_time = now;
185
186
187
188 struct timevar_stack_def *context = NULL;
189 if (unused_stack_instances != NULL)
190 {
191 context = unused_stack_instances;
192 unused_stack_instances = unused_stack_instances->next;
193 }
194 else
195 context = (struct timevar_stack_def *)
196 xmalloc (sizeof (struct timevar_stack_def));
197
198
199 context->timevar = tv;
200 context->next = stack;
201 stack = context;
202 }
203
204 void
205 timevar_pop (timevar_id_t timevar)
206 {
207 if (!timevar_enabled)
208 return;
209
210 if (&timevars[timevar] != stack->timevar)
211 abort ();
212
213
214 struct timevar_time_def const now = get_current_time ();
215
216
217 struct timevar_stack_def *popped = stack;
218 timevar_accumulate (&popped->timevar->elapsed, &start_time, &now);
219
220
221
222 start_time = now;
223
224
225 stack = stack->next;
226
227
228
229 popped->next = unused_stack_instances;
230 unused_stack_instances = popped;
231 }
232
233 void
234 timevar_start (timevar_id_t timevar)
235 {
236 if (!timevar_enabled)
237 return;
238
239 struct timevar_def *tv = &timevars[timevar];
240
241
242 tv->used = 1;
243
244
245
246 if (tv->standalone)
247 abort ();
248 tv->standalone = 1;
249
250 set_to_current_time (&tv->start_time);
251 }
252
253 void
254 timevar_stop (timevar_id_t timevar)
255 {
256 if (!timevar_enabled)
257 return;
258
259 struct timevar_def *tv = &timevars[timevar];
260
261
262 if (!tv->standalone)
263 abort ();
264
265 struct timevar_time_def const now = get_current_time ();
266 timevar_accumulate (&tv->elapsed, &tv->start_time, &now);
267 }
268
269 void
270 timevar_get (timevar_id_t timevar,
271 struct timevar_time_def *elapsed)
272 {
273 struct timevar_def *tv = &timevars[timevar];
274 *elapsed = tv->elapsed;
275
276
277 if (tv->standalone)
278 {
279 struct timevar_time_def const now = get_current_time ();
280 timevar_accumulate (elapsed, &tv->start_time, &now);
281 }
282
283 else if (stack->timevar == tv)
284 {
285 struct timevar_time_def const now = get_current_time ();
286 timevar_accumulate (elapsed, &start_time, &now);
287 }
288 }
289
290 void
291 timevar_print (FILE *fp)
292 {
293 if (!timevar_enabled)
294 return;
295
296
297
298 if (fp == 0)
299 fp = stderr;
300
301
302 struct timevar_time_def const now = get_current_time ();
303
304
305
306 if (stack)
307 timevar_accumulate (&stack->timevar->elapsed, &start_time, &now);
308
309
310
311 start_time = now;
312
313 struct timevar_time_def const* total = &timevars[tv_total].elapsed;
314
315 fprintf (fp, "%-22s\n",
316 _("Execution times (seconds)"));
317 fprintf (fp, " %-22s %-13s %-13s %-16s\n",
318 "", _("CPU user"), _("CPU system"), _("wall clock"));
319 for (unsigned id = 0; id < (unsigned) TIMEVAR_LAST; ++id)
320 {
321
322
323 if ((timevar_id_t) id == tv_total)
324 continue;
325
326
327 struct timevar_def *tv = &timevars[(timevar_id_t) id];
328 if (!tv->used)
329 continue;
330
331
332 const int usr = total->user ? tv->elapsed.user * 100 / total->user : 0;
333 const int sys = total->sys ? tv->elapsed.sys * 100 / total->sys : 0;
334 const int wall = total->wall ? tv->elapsed.wall * 100 / total->wall : 0;
335
336
337 if (!usr && !sys && !wall)
338 continue;
339
340 fprintf (fp, " %-22s", tv->name);
341 fprintf (fp, "%8.3f (%2d%%)", tv->elapsed.user * 1e-9, usr);
342 fprintf (fp, "%8.3f (%2d%%)", tv->elapsed.sys * 1e-9, sys);
343 fprintf (fp, "%11.6f (%2d%%)\n", tv->elapsed.wall * 1e-9, wall);
344 }
345
346
347 fprintf (fp, " %-22s", timevars[tv_total].name);
348 fprintf (fp, "%8.3f ", total->user * 1e-9);
349 fprintf (fp, "%8.3f ", total->sys * 1e-9);
350 fprintf (fp, "%11.6f\n", total->wall * 1e-9);
351 }