VirtualBox

source: kBuild/trunk/src/misc/kmk_time.c@ 2421

Last change on this file since 2421 was 2413, checked in by bird, 14 years ago

copyright year update.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.4 KB
Line 
1/* $Id: kmk_time.c 2413 2010-09-11 17:43:04Z bird $ */
2/** @file
3 * kmk_time - Time program execution.
4 *
5 * This is based on kmk/kmkbuiltin/redirect.c.
6 */
7
8/*
9 * Copyright (c) 2007-2010 knut st. osmundsen <[email protected]>
10 *
11 * This file is part of kBuild.
12 *
13 * kBuild is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * kBuild is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with kBuild. If not, see <http://www.gnu.org/licenses/>
25 *
26 */
27
28/*******************************************************************************
29* Header Files *
30*******************************************************************************/
31#include <stdio.h>
32#include <stdlib.h>
33#include <string.h>
34#include <errno.h>
35#include <fcntl.h>
36#include <time.h>
37#if defined(_MSC_VER)
38# include <io.h>
39# include <direct.h>
40# include <process.h>
41# include <Windows.h>
42#else
43# include <unistd.h>
44# include <sys/time.h>
45# include <sys/wait.h>
46# include <signal.h>
47#endif
48
49#ifdef __OS2__
50# define INCL_BASE
51# include <os2.h>
52# ifndef LIBPATHSTRICT
53# define LIBPATHSTRICT 3
54# endif
55#endif
56
57#ifndef _MSC_VER
58static const char *my_strsignal(int signo)
59{
60#define CASE_SIG_RET_STR(sig) if (signo == SIG##sig) return #sig
61#ifdef SIGHUP
62 CASE_SIG_RET_STR(HUP);
63#endif
64#ifdef SIGINT
65 CASE_SIG_RET_STR(INT);
66#endif
67#ifdef SIGQUIT
68 CASE_SIG_RET_STR(QUIT);
69#endif
70#ifdef SIGILL
71 CASE_SIG_RET_STR(ILL);
72#endif
73#ifdef SIGTRAP
74 CASE_SIG_RET_STR(TRAP);
75#endif
76#ifdef SIGABRT
77 CASE_SIG_RET_STR(ABRT);
78#endif
79#ifdef SIGIOT
80 CASE_SIG_RET_STR(IOT);
81#endif
82#ifdef SIGBUS
83 CASE_SIG_RET_STR(BUS);
84#endif
85#ifdef SIGFPE
86 CASE_SIG_RET_STR(FPE);
87#endif
88#ifdef SIGKILL
89 CASE_SIG_RET_STR(KILL);
90#endif
91#ifdef SIGUSR1
92 CASE_SIG_RET_STR(USR1);
93#endif
94#ifdef SIGSEGV
95 CASE_SIG_RET_STR(SEGV);
96#endif
97#ifdef SIGUSR2
98 CASE_SIG_RET_STR(USR2);
99#endif
100#ifdef SIGPIPE
101 CASE_SIG_RET_STR(PIPE);
102#endif
103#ifdef SIGALRM
104 CASE_SIG_RET_STR(ALRM);
105#endif
106#ifdef SIGTERM
107 CASE_SIG_RET_STR(TERM);
108#endif
109#ifdef SIGSTKFLT
110 CASE_SIG_RET_STR(STKFLT);
111#endif
112#ifdef SIGCHLD
113 CASE_SIG_RET_STR(CHLD);
114#endif
115#ifdef SIGCONT
116 CASE_SIG_RET_STR(CONT);
117#endif
118#ifdef SIGSTOP
119 CASE_SIG_RET_STR(STOP);
120#endif
121#ifdef SIGTSTP
122 CASE_SIG_RET_STR(TSTP);
123#endif
124#ifdef SIGTTIN
125 CASE_SIG_RET_STR(TTIN);
126#endif
127#ifdef SIGTTOU
128 CASE_SIG_RET_STR(TTOU);
129#endif
130#ifdef SIGURG
131 CASE_SIG_RET_STR(URG);
132#endif
133#ifdef SIGXCPU
134 CASE_SIG_RET_STR(XCPU);
135#endif
136#ifdef SIGXFSZ
137 CASE_SIG_RET_STR(XFSZ);
138#endif
139#ifdef SIGVTALRM
140 CASE_SIG_RET_STR(VTALRM);
141#endif
142#ifdef SIGPROF
143 CASE_SIG_RET_STR(PROF);
144#endif
145#ifdef SIGWINCH
146 CASE_SIG_RET_STR(WINCH);
147#endif
148#ifdef SIGIO
149 CASE_SIG_RET_STR(IO);
150#endif
151#ifdef SIGPWR
152 CASE_SIG_RET_STR(PWR);
153#endif
154#ifdef SIGSYS
155 CASE_SIG_RET_STR(SYS);
156#endif
157#ifdef SIGBREAK
158 CASE_SIG_RET_STR(BREAK);
159#endif
160#undef CASE_SIG_RET_STR
161 return "???";
162}
163#endif /* unix */
164
165static const char *name(const char *pszName)
166{
167 const char *psz = strrchr(pszName, '/');
168#if defined(_MSC_VER) || defined(__OS2__)
169 const char *psz2 = strrchr(pszName, '\\');
170 if (!psz2)
171 psz2 = strrchr(pszName, ':');
172 if (psz2 && (!psz || psz2 > psz))
173 psz = psz2;
174#endif
175 return psz ? psz + 1 : pszName;
176}
177
178
179static int usage(FILE *pOut, const char *argv0)
180{
181 fprintf(pOut,
182 "usage: %s <program> [args]\n"
183 " or: %s --help\n"
184 " or: %s --version\n"
185 ,
186 argv0, argv0, argv0);
187 return 1;
188}
189
190
191int main(int argc, char **argv)
192{
193 int i, j;
194 int cTimes = 1;
195#if defined(_MSC_VER)
196 FILETIME ftStart, ft;
197 unsigned _int64 usMin, usMax, usAvg, usTotal, usCur;
198 unsigned _int64 iStart;
199 intptr_t rc;
200#else
201 struct timeval tvStart, tv;
202 unsigned long long usMin, usMax, usAvg, usTotal, usCur;
203 pid_t pid;
204 int rc;
205#endif
206 int rcExit = 0;
207
208 /*
209 * Parse arguments.
210 */
211 if (argc <= 1)
212 return usage(stderr, name(argv[0]));
213 for (i = 1; i < argc; i++)
214 {
215 char *psz = &argv[i][0];
216 if (*psz++ != '-')
217 break;
218
219 if (*psz == '-')
220 {
221 /* '--' ? */
222 if (!psz[1])
223 {
224 i++;
225 break;
226 }
227
228 /* convert to short. */
229 if (!strcmp(psz, "-help"))
230 psz = "h";
231 else if (!strcmp(psz, "-version"))
232 psz = "V";
233 else if (!strcmp(psz, "-iterations"))
234 psz = "i";
235 }
236
237 switch (*psz)
238 {
239 case 'h':
240 usage(stdout, name(argv[0]));
241 return 0;
242
243 case 'V':
244 printf("kmk_time - kBuild version %d.%d.%d (r%u)\n"
245 "Copyright (C) 2007-2009 knut st. osmundsen\n",
246 KBUILD_VERSION_MAJOR, KBUILD_VERSION_MINOR, KBUILD_VERSION_PATCH,
247 KBUILD_SVN_REV);
248 return 0;
249
250 case 'i':
251 if (i + 1 >= argc)
252 {
253 fprintf(stderr, "%s: syntax error: missing iteration count\n", name(argv[0]));
254 return 1;
255 }
256 cTimes = atoi(argv[++i]);
257 if (cTimes <= 0)
258 {
259 fprintf(stderr, "%s: error: invalid interation count '%s'.\n", name(argv[0]), argv[i]);
260 return 1;
261 }
262 break;
263
264 default:
265 fprintf(stderr, "%s: error: syntax error '%s'\n", name(argv[0]), argv[i]);
266 return 1;
267 }
268 }
269
270 /*
271 * Make sure there's something to execute.
272 */
273 if (i >= argc)
274 {
275 fprintf(stderr, "%s: syntax error: nothing to execute!\n", name(argv[0]));
276 return usage(stderr, name(argv[0]));
277 }
278
279 /*
280 * Execute the program the specified number of times.
281 */
282 usMax = usMin = usTotal = 0;
283 usMin--; /* wraps to max value */
284 for (j = 0; j < cTimes; j++)
285 {
286 /*
287 * Execute the program (it's actually supposed to be a command I think, but wtf).
288 */
289
290#if defined(_MSC_VER)
291 /** @todo
292 * We'll have to find the '--' in the commandline and pass that
293 * on to CreateProcess or spawn. Otherwise, the argument qouting
294 * is gonna be messed up.
295 */
296 GetSystemTimeAsFileTime(&ftStart);
297 rc = _spawnvp(_P_WAIT, argv[i], &argv[i]);
298 if (rc == -1)
299 {
300 fprintf(stderr, "%s: error: _spawnvp(_P_WAIT, \"%s\", ...) failed: %s\n", name(argv[0]), argv[i], strerror(errno));
301 return 8;
302 }
303
304 GetSystemTimeAsFileTime(&ft);
305
306 iStart = ftStart.dwLowDateTime | ((unsigned _int64)ftStart.dwHighDateTime << 32);
307 usCur = ft.dwLowDateTime | ((unsigned _int64)ft.dwHighDateTime << 32);
308 usCur -= iStart;
309 usCur /= 10; /* to usecs */
310
311 printf("%s: ", name(argv[0]));
312 if (cTimes != 1)
313 printf("#%02u ", j + 1);
314 printf("%um%u.%06us - exit code: %d\n",
315 (unsigned)(usCur / (60 * 1000000)),
316 (unsigned)(usCur % (60 * 1000000)) / 1000000,
317 (unsigned)(usCur % 1000000),
318 rc);
319
320#else /* unix: */
321 gettimeofday(&tvStart, NULL);
322 pid = fork();
323 if (!pid)
324 {
325 /* child */
326 execvp(argv[i], &argv[i]);
327 fprintf(stderr, "%s: error: _execvp(\"%s\", ...) failed: %s\n", name(argv[0]), argv[i], strerror(errno));
328 return 8;
329 }
330 if (pid < 0)
331 {
332 fprintf(stderr, "%s: error: fork() failed: %s\n", name(argv[0]), strerror(errno));
333 return 9;
334 }
335
336 /* parent, wait for child. */
337 rc = 9;
338 while (waitpid(pid, &rc, 0) == -1 && errno == EINTR)
339 /* nothing */;
340 gettimeofday(&tv, NULL);
341
342 /* calc elapsed time */
343 tv.tv_sec -= tvStart.tv_sec;
344 if (tv.tv_usec > tvStart.tv_usec)
345 tv.tv_usec -= tvStart.tv_usec;
346 else
347 {
348 tv.tv_sec--;
349 tv.tv_usec = tv.tv_usec + 1000000 - tvStart.tv_usec;
350 }
351 usCur = tv.tv_sec * 1000000ULL
352 + tv.tv_usec;
353
354 printf("%s: ", name(argv[0]));
355 if (cTimes != 1)
356 printf("#%02u ", j + 1);
357 printf("%um%u.%06us",
358 (unsigned)(tv.tv_sec / 60),
359 (unsigned)(tv.tv_sec % 60),
360 (unsigned)tv.tv_usec);
361 if (WIFEXITED(rc))
362 {
363 printf(" - normal exit: %d\n", WEXITSTATUS(rc));
364 rc = WEXITSTATUS(rc);
365 }
366 else if (WIFSIGNALED(rc) && WCOREDUMP(rc))
367 {
368 printf(" - dumped core: %s (%d)\n", my_strsignal(WTERMSIG(rc)), WTERMSIG(rc));
369 rc = 10;
370 }
371 else if (WIFSIGNALED(rc))
372 {
373 printf(" - killed by: %s (%d)\n", my_strsignal(WTERMSIG(rc)), WTERMSIG(rc));
374 rc = 11;
375 }
376 else if (WIFSTOPPED(rc))
377 {
378 printf(" - stopped by: %s (%d)\n", my_strsignal(WSTOPSIG(rc)), WSTOPSIG(rc));
379 rc = 12;
380 }
381 else
382 {
383 printf(" unknown exit status %#x (%d)\n", rc, rc);
384 rc = 13;
385 }
386#endif /* unix */
387 if (rc && !rcExit)
388 rcExit = (int)rc;
389
390 /* calc min/max/avg */
391 usTotal += usCur;
392 if (usMax < usCur)
393 usMax = usCur;
394 if (usMin > usCur)
395 usMin = usCur;
396 }
397
398 /*
399 * Summary if more than one run.
400 */
401 if (cTimes != 1)
402 {
403 usAvg = usTotal / cTimes;
404
405 printf("%s: avg %um%u.%06us\n", name(argv[0]), (unsigned)(usAvg / 60000000), (unsigned)(usAvg % 60000000) / 1000000, (unsigned)(usAvg % 1000000));
406 printf("%s: min %um%u.%06us\n", name(argv[0]), (unsigned)(usMin / 60000000), (unsigned)(usMin % 60000000) / 1000000, (unsigned)(usMin % 1000000));
407 printf("%s: max %um%u.%06us\n", name(argv[0]), (unsigned)(usMax / 60000000), (unsigned)(usMax % 60000000) / 1000000, (unsigned)(usMax % 1000000));
408 }
409
410 return rcExit;
411}
412
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette