Index: usr.bin/time/time.1 =================================================================== --- usr.bin/time/time.1 +++ usr.bin/time/time.1 @@ -28,7 +28,7 @@ .\" @(#)time.1 8.1 (Berkeley) 6/6/93 .\" $FreeBSD$ .\" -.Dd May 14, 2006 +.Dd Jan 24, 2018 .Dt TIME 1 .Os .Sh NAME @@ -37,7 +37,7 @@ .Sh SYNOPSIS .Nm .Op Fl al -.Op Fl h | Fl p +.Op Fl hm | Fl p .Op Fl o Ar file .Ar utility Op Ar argument ... .Sh DESCRIPTION @@ -74,6 +74,10 @@ The contents of the .Em rusage structure are printed as well. +.It Fl m +Report elapsed time time using the monotonic clock, rather than the realtime clock. +Using this option will give more reliable measurements when measuring short +intervals of time. .It Fl o Ar file Write the output to .Ar file Index: usr.bin/time/time.c =================================================================== --- usr.bin/time/time.c +++ usr.bin/time/time.c @@ -62,6 +62,7 @@ #include static int getstathz(void); +static void gettime(struct timespec *, int); static void humantime(FILE *, long, long); static void showtime(FILE *, struct timespec *, struct timespec *, struct rusage *); @@ -76,7 +77,7 @@ int main(int argc, char **argv) { - int aflag, ch, lflag, status; + int aflag, ch, lflag, mflag, status; int exitonsig; pid_t pid; struct rlimit rl; @@ -88,8 +89,8 @@ (void) setlocale(LC_NUMERIC, ""); decimal_point = localeconv()->decimal_point[0]; - aflag = hflag = lflag = pflag = 0; - while ((ch = getopt(argc, argv, "ahlo:p")) != -1) + aflag = hflag = lflag = mflag = pflag = 0; + while ((ch = getopt(argc, argv, "ahlo:mp")) != -1) switch((char)ch) { case 'a': aflag = 1; @@ -100,6 +101,9 @@ case 'l': lflag = 1; break; + case 'm': + mflag = 1; + break; case 'o': ofn = optarg; break; @@ -111,6 +115,9 @@ usage(); } + if (mflag && pflag) + errx(2, "monotonic output and posix output are incompatible"); + if (!(argc -= optind)) exit(0); argv += optind; @@ -121,8 +128,7 @@ setvbuf(out, (char *)NULL, _IONBF, (size_t)0); } - if (clock_gettime(CLOCK_REALTIME, &before_ts)) - err(1, "clock_gettime"); + gettime(&before_ts, mflag); switch(pid = fork()) { case -1: /* error */ err(1, "time"); @@ -141,14 +147,12 @@ while (wait4(pid, &status, 0, &ru) != pid) { if (siginfo_recvd) { siginfo_recvd = 0; - if (clock_gettime(CLOCK_REALTIME, &after)) - err(1, "clock_gettime"); + gettime(&after, mflag); getrusage(RUSAGE_CHILDREN, &ru); showtime(stdout, &before_ts, &after, &ru); } } - if (clock_gettime(CLOCK_REALTIME, &after)) - err(1, "clock_gettime"); + gettime(&after, mflag); if ( ! WIFEXITED(status)) warnx("command terminated abnormally"); exitonsig = WIFSIGNALED(status) ? WTERMSIG(status) : 0; @@ -238,6 +242,15 @@ if (sysctl(mib, 2, &clockrate, &size, NULL, 0) == -1) err(1, "sysctl kern.clockrate"); return clockrate.stathz; +} + +static void +gettime(struct timespec *ts, int monotonic) +{ + clockid_t clock = monotonic ? CLOCK_MONOTONIC : CLOCK_REALTIME; + + if (clock_gettime(clock, ts)) + err(1, "clock_gettime"); } static void