From ea9800e98598c71fe76c4e2a0d0498b6bd490a83 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Fri, 12 Sep 2014 16:33:37 -0700 Subject: [PATCH 1/2] Explain why clock(3) isn't broken. Bug: 17441123 Bug: 17814435 (cherry picked from commit f83c208b82c78dad07f4065f63bdd354f5ef9951) Change-Id: I2065afe73b79a8d86404edee16e983625d902cdc --- libc/bionic/clock.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libc/bionic/clock.cpp b/libc/bionic/clock.cpp index 98f71afc3..a2636c67c 100644 --- a/libc/bionic/clock.cpp +++ b/libc/bionic/clock.cpp @@ -34,5 +34,8 @@ clock_t clock() { tms t; times(&t); + // Although times(2) and clock(3) both use the type clock_t, the units are + // different. For times(2) it's pure clock ticks, but for clock(3) the unit + // is CLOCKS_PER_SEC, so we need to scale appropriately. return (t.tms_utime + t.tms_stime) * (CLOCKS_PER_SEC / sysconf(_SC_CLK_TCK)); } From a508714800242b294291060641ed35d719bdc857 Mon Sep 17 00:00:00 2001 From: Alex Van Brunt Date: Fri, 26 Sep 2014 13:32:47 -0700 Subject: [PATCH 2/2] Reimplement clock(3) using clock_gettime(3) Unlike times(), clock_gettime() is implemented as a vDSO on many architectures. So, using clock_gettime() will return a more accurate time and do so with less overhead because it does have the overhead of calling into the kernel. It is also significantly more accurate because it measures the actual time in nanoseconds rather than the number of ticks (typically 1 millisecond or more). Bug: 17814435 (cherry picked from commit 8d0b2dbf2154d5da17ff09b1d4f864d281362ad2) Change-Id: Id4945d9f387330518f78669809639952e9227ed9 --- libc/bionic/clock.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libc/bionic/clock.cpp b/libc/bionic/clock.cpp index a2636c67c..5bd32f9c9 100644 --- a/libc/bionic/clock.cpp +++ b/libc/bionic/clock.cpp @@ -30,12 +30,13 @@ #include #include +#define NS_PER_S 1000000000 // No "private/bionic_constants.h" in lmp-dev. + // http://pubs.opengroup.org/onlinepubs/9699919799/functions/clock.html clock_t clock() { - tms t; - times(&t); - // Although times(2) and clock(3) both use the type clock_t, the units are - // different. For times(2) it's pure clock ticks, but for clock(3) the unit - // is CLOCKS_PER_SEC, so we need to scale appropriately. - return (t.tms_utime + t.tms_stime) * (CLOCKS_PER_SEC / sysconf(_SC_CLK_TCK)); + timespec ts; + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == -1) { + return -1; + } + return (ts.tv_sec * CLOCKS_PER_SEC) + (ts.tv_nsec / (NS_PER_S / CLOCKS_PER_SEC)); }