Fix int overflow GetClockTimeMicros() on macOS On macOS mach_timespec_t.tv_sec is only 4 bytes and we were converting to micros before moving to a bigger var. This would cause all the wall times obtained on a mac (through GetClockTimeMicros() to be wrong.
This was likely the cause of KUDU-2435 and KUDU-2408 too, since the time would easily wrap, causing us to a update the clock with a value that was seemingly from the future. Posix just requires it to be an integer (see: https://en.wikipedia.org/w/index.php?title=Time_t&oldid=450752800) so also fixed it on the non-macOS path. Testing this is likely not worth it since the only real change was on macOS where the overlow doesn't happen anymore. Change-Id: Ie0eaa548f61352be529755a732566613cfa72098 Reviewed-on: http://gerrit.cloudera.org:8080/10371 Reviewed-by: Todd Lipcon <t...@apache.org> Reviewed-by: Dan Burkert <danburk...@apache.org> Reviewed-by: Grant Henke <granthe...@apache.org> Tested-by: Kudu Jenkins Project: http://git-wip-us.apache.org/repos/asf/kudu/repo Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/07d6b5f2 Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/07d6b5f2 Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/07d6b5f2 Branch: refs/heads/master Commit: 07d6b5f2ba384e10288d5926af93933f0a74185d Parents: 525943f Author: David Alves <dral...@apache.org> Authored: Thu May 10 13:52:14 2018 -0700 Committer: David Ribeiro Alves <davidral...@gmail.com> Committed: Thu May 10 22:38:23 2018 +0000 ---------------------------------------------------------------------- src/kudu/gutil/walltime.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/kudu/blob/07d6b5f2/src/kudu/gutil/walltime.h ---------------------------------------------------------------------- diff --git a/src/kudu/gutil/walltime.h b/src/kudu/gutil/walltime.h index e9cab67..4b15f42 100644 --- a/src/kudu/gutil/walltime.h +++ b/src/kudu/gutil/walltime.h @@ -81,7 +81,12 @@ inline void GetCurrentTime(mach_timespec_t* ts) { inline MicrosecondsInt64 GetCurrentTimeMicros() { mach_timespec_t ts; GetCurrentTime(&ts); - return ts.tv_sec * 1000000 + ts.tv_nsec / 1000; + // 'tv_sec' is just 4 bytes on macOS, need to be careful not + // to convert to nanos until we've moved to a larger int. + MicrosecondsInt64 micros_from_secs = ts.tv_sec; + micros_from_secs *= 1000 * 1000; + micros_from_secs += ts.tv_nsec / 1000; + return micros_from_secs; } inline int64_t GetMonoTimeNanos() { @@ -130,7 +135,13 @@ inline MicrosecondsInt64 GetThreadCpuTimeMicros() { inline MicrosecondsInt64 GetClockTimeMicros(clockid_t clock) { timespec ts; clock_gettime(clock, &ts); - return ts.tv_sec * 1000000 + ts.tv_nsec / 1000; + // 'tv_sec' is usually 8 bytes, but the spec says it only + // needs to be 'a signed int'. Moved to a 64 bit var before + // converting to micros to be safe. + MicrosecondsInt64 micros_from_secs = ts.tv_sec; + micros_from_secs *= 1000 * 1000; + micros_from_secs += ts.tv_nsec / 1000; + return micros_from_secs; } #endif // defined(__APPLE__)