Mercurial > illumos > illumos-gate
changeset 4058:8fe48e2ebe43
6451790 timex gives garbage when the real time overflows
6524847 printt() limitation in timex
author | as158974 |
---|---|
date | Wed, 18 Apr 2007 03:07:55 -0700 |
parents | c3c51c446c6e |
children | bad304cb4af7 |
files | usr/src/cmd/sa/timex.c |
diffstat | 1 files changed, 74 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/sa/timex.c Tue Apr 17 17:52:16 2007 -0700 +++ b/usr/src/cmd/sa/timex.c Wed Apr 18 03:07:55 2007 -0700 @@ -18,20 +18,19 @@ * * CDDL HEADER END */ - /* - * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ - +/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ #pragma ident "%Z%%M% %I% %E% SMI" #include <sys/types.h> #include <sys/times.h> +#include <sys/time.h> #include <sys/param.h> #include <sys/wait.h> #include <unistd.h> @@ -43,14 +42,15 @@ #include <errno.h> #include <pwd.h> -char fname[20]; +#define NSEC_TO_TICK(nsec) ((nsec) / nsec_per_tick) +#define NSEC_TO_TICK_ROUNDUP(nsec) NSEC_TO_TICK((nsec) + \ + nsec_per_tick/2) -/* - * Quant[0] will get set to HZ/10 later. - */ -int quant[] = { 10, 10, 10, 6, 10, 6, 10, 10, 10, 10, 10 }; +char fname[20]; +static int hz; +static int nsec_per_tick; -void printt(char *, time_t); +void printt(char *, hrtime_t); void hmstime(char[]); void diag(char *); @@ -61,7 +61,7 @@ int status; register pid_t p; int c; - time_t before, after; + hrtime_t before, after, timediff; char stime[9], etime[9]; char cmd[80]; int pflg = 0, sflg = 0, oflg = 0; @@ -74,10 +74,11 @@ int ichar, iblok; long chars = 0, bloks = 0; - /* initalize quant array using the sysconf() */ - quant[0] = ((int)sysconf(_SC_CLK_TCK))/10; + aopt[0] = '\0'; - aopt[0] = '\0'; /* terminate the string #1245107 */ + hz = sysconf(_SC_CLK_TCK); + nsec_per_tick = NANOSEC / hz; + /* check options; */ while ((c = getopt(argc, argv, "sopfhkmrt")) != EOF) switch (c) { @@ -116,13 +117,18 @@ system(cmd); } if (pflg + oflg) hmstime(stime); - before = times(&obuffer); - if ((p = fork()) == (pid_t)-1) diag("Try again.\n"); + before = gethrtime(); + (void) times(&obuffer); + if ((p = fork()) == (pid_t)-1) { + perror("Fork Failed"); + (void) unlink(fname); + exit(EXIT_FAILURE); + } if (p == 0) { setgid(getgid()); execvp(*(argv+optind), (argv+optind)); fprintf(stderr, "%s: %s\n", *(argv+optind), strerror(errno)); - exit(1); + exit(EXIT_FAILURE); } signal(SIGINT, SIG_IGN); signal(SIGQUIT, SIG_IGN); @@ -132,12 +138,14 @@ fprintf(stderr, "Command terminated abnormally.\n"); signal(SIGINT, SIG_DFL); signal(SIGQUIT, SIG_DFL); - after = times(&buffer); + (void) times(&buffer); + after = gethrtime(); + timediff = after - before; if (pflg + oflg) hmstime(etime); if (sflg) system(cmd); fprintf(stderr, "\n"); - printt("real", (after-before)); + printt("real", NSEC_TO_TICK_ROUNDUP(timediff)); printt("user", buffer.tms_cutime - obuffer.tms_cutime); printt("sys ", buffer.tms_cstime - obuffer.tms_cstime); fprintf(stderr, "\n"); @@ -191,38 +199,58 @@ system(cmd); unlink(fname); } - exit(status>>8); + exit(WEXITSTATUS(status)); } -char *pad = "000 "; -char *sep = "\0\0.\0:\0:\0\0"; -char *nsep = "\0\0.\0 \0 \0\0"; - void -printt(char *s, time_t a) +printt(char *label, hrtime_t ticks) { - int digit[11]; - int i; - char c; - int nonzero; + long tk; /* number of leftover ticks */ + long ss; /* number of seconds */ + long mm; /* number of minutes */ + long hh; /* number of hours */ + longlong_t total = ticks; - for (i = 0; i < 11; i++) { - digit[i] = a % quant[i]; - a /= quant[i]; + tk = total % hz; /* ticks % hz */ + total /= hz; + ss = total % 60; /* ticks / hz % 60 */ + total /= 60; + mm = total % 60; /* ticks / hz / 60 % 60 */ + hh = total / 60; /* ticks / hz / 60 / 60 */ + + (void) fprintf(stderr, "%s ", label); + + /* Display either padding or the elapsed hours */ + if (hh == 0L) { + (void) fprintf(stderr, "%6c", ' '); + } else { + (void) fprintf(stderr, "%5ld:", hh); } - fprintf(stderr, s); - nonzero = 0; - while (--i > 0) { - c = digit[i] != 0 ? digit[i] + '0': - nonzero ? '0': - pad[i]; - if (c != '\0') putc(c, stderr); - nonzero |= digit[i]; - c = nonzero?sep[i]:nsep[i]; - if (c != '\0') putc(c, stderr); + + /* + * Display either nothing or the elapsed minutes, zero + * padding (if hours > 0) or space padding (if not). + */ + if (mm == 0L && hh == 0L) { + (void) fprintf(stderr, "%3c", ' '); + } else if (mm != 0L && hh == 0L) { + (void) fprintf(stderr, "%2ld:", mm); + } else { + (void) fprintf(stderr, "%02ld:", mm); } - fprintf(stderr, "%c", digit[0] * 100/HZ + '0'); - fprintf(stderr, "\n"); + + /* + * Display the elapsed seconds; seconds are always + * zero padded. + */ + if (hh == 0L && mm == 0L) { + (void) fprintf(stderr, "%2ld.", ss); + } else { + (void) fprintf(stderr, "%02ld.", ss); + } + + /* Display hundredths of a second. */ + (void) fprintf(stderr, "%02ld\n", tk * 100/hz); } /* @@ -246,5 +274,5 @@ { fprintf(stderr, "%s\n", s); unlink(fname); - exit(1); + exit(EXIT_FAILURE); }