Use faster clock_gettime() instead of sysctl() to get current ticks on iOS10

BUG=724546

Review-Url: https://codereview.chromium.org/2894173002
Cr-Commit-Position: refs/heads/master@{#474336}
diff --git a/base/time/time_mac.cc b/base/time/time_mac.cc
index 0ae3a30..52800a83 100644
--- a/base/time/time_mac.cc
+++ b/base/time/time_mac.cc
@@ -23,6 +23,11 @@
 #include "base/numerics/safe_conversions.h"
 #include "build/build_config.h"
 
+#if defined(OS_IOS)
+#include <time.h>
+#include "base/ios/ios_util.h"
+#endif
+
 namespace {
 
 #if defined(OS_MACOSX) && !defined(OS_IOS)
@@ -52,8 +57,20 @@
 }
 #endif  // defined(OS_MACOSX) && !defined(OS_IOS)
 
+// Returns monotonically growing number of ticks in microseconds since some
+// unspecified starting point.
 int64_t ComputeCurrentTicks() {
 #if defined(OS_IOS)
+  // iOS 10 supports clock_gettime(CLOCK_MONOTONIC, ...), which is
+  // around 15 times faster than sysctl() call. Use it if possible;
+  // otherwise, fall back to sysctl().
+  if (base::ios::IsRunningOnIOS10OrLater()) {
+    struct timespec tp;
+    if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
+      return (int64_t)tp.tv_sec * 1000000 + tp.tv_nsec / 1000;
+    }
+  }
+
   // On iOS mach_absolute_time stops while the device is sleeping. Instead use
   // now - KERN_BOOTTIME to get a time difference that is not impacted by clock
   // changes. KERN_BOOTTIME will be updated by the system whenever the system
diff --git a/net/quic/platform/impl/quic_chromium_clock.cc b/net/quic/platform/impl/quic_chromium_clock.cc
index fb591f84..78ca26e 100644
--- a/net/quic/platform/impl/quic_chromium_clock.cc
+++ b/net/quic/platform/impl/quic_chromium_clock.cc
@@ -4,12 +4,6 @@
 
 #include "net/quic/platform/impl/quic_chromium_clock.h"
 
-#if defined(OS_IOS)
-#include <time.h>
-
-#include "base/ios/ios_util.h"
-#endif
-
 #include "base/memory/singleton.h"
 #include "base/time/time.h"
 
@@ -29,21 +23,17 @@
 }
 
 QuicTime QuicChromiumClock::Now() const {
-#if defined(OS_IOS)
-  if (base::ios::IsRunningOnIOS10OrLater()) {
-    struct timespec tp;
-    if (clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
-      return CreateTimeFromMicroseconds(tp.tv_sec * 1000000 +
-                                        tp.tv_nsec / 1000);
-    }
-  }
-#endif
-  return CreateTimeFromMicroseconds(base::TimeTicks::Now().ToInternalValue());
+  int64_t ticks = (base::TimeTicks::Now() - base::TimeTicks()).InMicroseconds();
+  DCHECK_GE(ticks, 0);
+  return CreateTimeFromMicroseconds(ticks);
 }
 
 QuicWallTime QuicChromiumClock::WallNow() const {
-  return QuicWallTime::FromUNIXMicroseconds(base::Time::Now().ToJavaTime() *
-                                            1000);
+  const base::TimeDelta time_since_unix_epoch =
+      base::Time::Now() - base::Time::UnixEpoch();
+  int64_t time_since_unix_epoch_micro = time_since_unix_epoch.InMicroseconds();
+  DCHECK_GE(time_since_unix_epoch_micro, 0);
+  return QuicWallTime::FromUNIXMicroseconds(time_since_unix_epoch_micro);
 }
 
 }  // namespace net