]>
git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gprofng/testsuite/gprofng.display/synprog/stopwatch.c
1 /* Copyright (C) 2021-2024 Free Software Foundation, Inc.
4 This file is part of GNU Binutils.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
26 #include <sys/types.h>
30 #include "stopwatch.h"
32 static char *prhrdelta (hrtime_t
);
33 static char *prhrvdelta (hrtime_t
);
34 void init_micro_acct ();
36 /* stopwatch routines */
43 (void) gettimeofday (&ttime
, NULL
);
44 time_t secs
= (time_t) ttime
.tv_sec
;
45 sprintf (buf
, "%s Stopwatch calibration", prtime (&secs
));
49 stopwatch_t
*inner
= stpwtch_alloc ("inner", 0);
50 stopwatch_t
*outer
= stpwtch_alloc ("outer", 0);
51 for (int i
= 0; i
< 1000; i
++)
53 stpwtch_start (outer
);
54 stpwtch_start (inner
);
58 stpwtch_print (inner
);
59 stpwtch_print (outer
);
60 free ((void *) inner
);
61 free ((void *) outer
);
65 stpwtch_alloc (char *name
, int histo
)
67 stopwatch_t
*w
= (stopwatch_t
*) malloc (sizeof (stopwatch_t
));
70 fprintf (stderr
, "stpwtch_alloc(%s, %d): malloc failed\n", name
, histo
);
78 w
->name
= strdup (name
);
86 stpwtch_start (stopwatch_t
*w
)
88 w
->start
= gethrtime ();
92 stpwtch_stop (stopwatch_t
*w
)
94 if (w
->start
== 0) /* if never started, ignore the call */
97 /* get stopping high-res time */
98 w
->tempus
= gethrtime ();
100 /* bump count of stops */
103 /* compute the delta for this call */
104 w
->delta
= w
->tempus
- w
->start
;
106 /* add in this one */
107 w
->last
= (double) (w
->delta
);
108 w
->sum
= w
->sum
+ w
->last
;
109 w
->sumsq
= w
->sumsq
+ w
->last
* w
->last
;
113 else if (w
->max
< w
->last
)
117 else if (w
->min
> w
->last
)
120 /* show stopwatch stopped */
125 stpwtch_print (stopwatch_t
*w
)
129 /* get stopping high-res time */
130 w
->tempus
= gethrtime ();
131 double duration
= (double) (w
->tempus
- w
->begin
);
134 sprintf (cvdbuf
, " 0. s. ( 0. %% of %12.6f s.) -- %s\n",
135 (duration
/ 1000000000.), w
->name
);
136 else if (w
->count
== 1)
137 sprintf (cvdbuf
, " %12.6f s. (%4.1f %%%% of %.6f s.) -- %s\n",
138 w
->sum
/ 1000000000., (100. * w
->sum
) / duration
,
139 duration
/ 1000000000., w
->name
);
142 " %12.6f s. (%4.1f %%%% of %.6f s.) -- %s\n\tN = %d,"
143 " avg = %.3f us., min = %.3f, max = %.3f\n",
144 w
->sum
/ 1000000000., (100. * w
->sum
) / duration
,
145 duration
/ 1000000000., w
->name
, w
->count
,
146 w
->sum
/ 1000. / ((double) (w
->count
> 0 ? w
->count
: 1)),
147 ((double) w
->min
/ 1000.), ((double) w
->max
/ 1000.));
148 fprintf (stderr
, cvdbuf
);
151 /* hrtime routines */
153 whrlog (hrtime_t delta
, char *event
, char *string
)
157 sprintf (buf
, " %s secs. in %s\n", prhrdelta (delta
), event
);
159 sprintf (buf
, " %s secs. in %s\n\t%s\n", prhrdelta (delta
), event
, string
);
160 int bytes
= fprintf (stderr
, "%s", buf
);
164 /* hrtime routines */
166 whrvlog (hrtime_t delta
, hrtime_t vdelta
, char *event
, char *string
)
170 sprintf (buf
, " %s wall-secs., %s CPU-secs., in %s\n",
171 prhrdelta (delta
), prhrvdelta (vdelta
), event
);
173 sprintf (buf
, " %s wall-secs., %s CPU-secs., in %s\n\t%s\n",
174 prhrdelta (delta
), prhrvdelta (vdelta
), event
, string
);
175 int bytes
= fprintf (stderr
, "%s", buf
);
179 /* prhrdelta (hrtime_t delta)
180 * returns a pointer to a static string in the form:
185 * prhrvdelta is the same, but uses a different static buffer
188 prhrdelta (hrtime_t delta
)
190 static char cvdbuf
[26];
192 /* convert to seconds */
193 double tempus
= ((double) delta
) / (double) 1000000000.;
194 sprintf (cvdbuf
, "%10.6f", tempus
);
199 prhrvdelta (hrtime_t delta
)
201 static char cvdbuf
[26];
203 /* convert to seconds */
204 double tempus
= ((double) delta
) / (double) 1000000000.;
205 sprintf (cvdbuf
, "%10.6f", tempus
);
209 /* time of day routines */
211 /* starting time - first timestamp; initialized on first call */
212 static struct timeval starttime
= {0, 0};
213 static struct timeval ttime
; /* last-recorded timestamp */
214 static struct timeval deltatime
; /* delta of last-rec'd timestamp */
219 (void) gettimeofday (&ttime
, NULL
);
220 if (starttime
.tv_sec
== 0)
223 deltatime
.tv_sec
= ttime
.tv_sec
- starttime
.tv_sec
;
224 deltatime
.tv_usec
= ttime
.tv_usec
- starttime
.tv_usec
;
225 while (deltatime
.tv_usec
< 0)
228 deltatime
.tv_usec
+= 1000000;
233 wlog (char *event
, char *string
)
239 sprintf (buf
, "%s ===== (%d) %s\n", prdelta (deltatime
),
240 (int) getpid (), event
);
242 sprintf (buf
, "%s ===== (%d) %s\n\t%s\n", prdelta (deltatime
),
243 (int) getpid (), event
, string
);
244 int bytes
= fprintf (stderr
, "%s", buf
);
249 * returns a pointer to a static string in the form:
250 * Thu 01 Jan 90 00:00:00\0
251 * 01234567890122345678901234
253 * ttime is a pointer to a UNIX time in seconds since epoch
254 * library routine localtime() is used
257 prtime (time_t *ttime
)
259 static char *days
[] = {
260 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
262 static char *months
[] = {
263 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
264 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
266 static char cvbuf
[26];
268 /* get the date and time */
269 struct tm
*tp
= localtime (ttime
);
271 /* convert to string */
272 sprintf (cvbuf
, "%3s %02d %s %02d %02d:%02d:%02d", days
[tp
->tm_wday
],
273 tp
->tm_mday
, months
[tp
->tm_mon
], tp
->tm_year
% 100,
274 tp
->tm_hour
, tp
->tm_min
, tp
->tm_sec
);
279 prdelta (struct timeval tempus
)
281 static char cvdbuf
[26];
282 while (tempus
.tv_usec
< 0)
285 tempus
.tv_usec
+= 1000000;
287 long seconds
= tempus
.tv_sec
% 60;
288 long minutes
= tempus
.tv_sec
/ 60;
289 long hours
= minutes
/ 60;
290 minutes
= minutes
% 60;
291 sprintf (cvdbuf
, "%02ld:%02ld:%02ld.%03ld ",
292 hours
, minutes
, seconds
, (long) tempus
.tv_usec
/ 1000);