Move QuicEpollClock to quic/core.

It does not need to be platformized.

PiperOrigin-RevId: 434781337
diff --git a/quic/core/quic_epoll_alarm_factory_test.cc b/quic/core/quic_epoll_alarm_factory_test.cc
index d815fae..c59f2be 100644
--- a/quic/core/quic_epoll_alarm_factory_test.cc
+++ b/quic/core/quic_epoll_alarm_factory_test.cc
@@ -4,9 +4,9 @@
 
 #include "quic/core/quic_epoll_alarm_factory.h"
 
+#include "quic/core/quic_epoll_clock.h"
 #include "quic/platform/api/quic_epoll_test_tools.h"
 #include "quic/platform/api/quic_test.h"
-#include "net/quic/platform/impl/quic_epoll_clock.h"
 
 namespace quic {
 namespace test {
diff --git a/quic/core/quic_epoll_clock.cc b/quic/core/quic_epoll_clock.cc
new file mode 100644
index 0000000..2c2e5e0
--- /dev/null
+++ b/quic/core/quic_epoll_clock.cc
@@ -0,0 +1,46 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quic/core/quic_epoll_clock.h"
+
+#include "common/platform/api/quiche_flag_utils.h"
+
+namespace quic {
+
+QuicEpollClock::QuicEpollClock(QuicEpollServer* epoll_server)
+    : epoll_server_(epoll_server), largest_time_(QuicTime::Zero()) {}
+
+QuicEpollClock::~QuicEpollClock() {}
+
+QuicTime QuicEpollClock::ApproximateNow() const {
+  return CreateTimeFromMicroseconds(epoll_server_->ApproximateNowInUsec());
+}
+
+QuicTime QuicEpollClock::Now() const {
+  QuicTime now = CreateTimeFromMicroseconds(epoll_server_->NowInUsec());
+
+  if (now <= largest_time_) {
+    if (now < largest_time_) {
+      QUICHE_CODE_COUNT(quic_epoll_clock_step_backward);
+    }
+    // Time not increasing, return |largest_time_|.
+    return largest_time_;
+  }
+
+  largest_time_ = now;
+  return largest_time_;
+}
+
+QuicWallTime QuicEpollClock::WallNow() const {
+  return QuicWallTime::FromUNIXMicroseconds(
+      epoll_server_->ApproximateNowInUsec());
+}
+
+QuicTime QuicEpollClock::ConvertWallTimeToQuicTime(
+    const QuicWallTime& walltime) const {
+  return QuicTime::Zero() +
+         QuicTime::Delta::FromMicroseconds(walltime.ToUNIXMicroseconds());
+}
+
+}  // namespace quic
diff --git a/quic/core/quic_epoll_clock.h b/quic/core/quic_epoll_clock.h
new file mode 100644
index 0000000..282b1ca
--- /dev/null
+++ b/quic/core/quic_epoll_clock.h
@@ -0,0 +1,48 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef QUICHE_QUIC_CORE_QUIC_EPOLL_CLOCK_H_
+#define QUICHE_QUIC_CORE_QUIC_EPOLL_CLOCK_H_
+
+#include "quic/core/quic_clock.h"
+#include "quic/core/quic_time.h"
+#include "quic/platform/api/quic_epoll.h"
+#include "quic/platform/api/quic_export.h"
+
+namespace quic {
+
+// Clock to efficiently retrieve an approximately accurate time from an
+// EpollServer.
+class QUIC_EXPORT_PRIVATE QuicEpollClock : public QuicClock {
+ public:
+  explicit QuicEpollClock(QuicEpollServer* epoll_server);
+  QuicEpollClock(const QuicEpollClock&) = delete;
+  QuicEpollClock& operator=(const QuicEpollClock&) = delete;
+  ~QuicEpollClock() override;
+
+  // Returns the approximate current time as a QuicTime object.
+  QuicTime ApproximateNow() const override;
+
+  // Returns the current time as a QuicTime object.
+  // Note: this use significant resources please use only if needed.
+  QuicTime Now() const override;
+
+  // WallNow returns the current wall-time - a time that is consistent across
+  // different clocks.
+  QuicWallTime WallNow() const override;
+
+  // Override to do less work in this implementation.  The epoll clock is
+  // already based on system (unix epoch) time, no conversion required.
+  QuicTime ConvertWallTimeToQuicTime(
+      const QuicWallTime& walltime) const override;
+
+ protected:
+  QuicEpollServer* epoll_server_;
+  // Largest time returned from Now() so far.
+  mutable QuicTime largest_time_;
+};
+
+}  // namespace quic
+
+#endif  // QUICHE_QUIC_CORE_QUIC_EPOLL_CLOCK_H_
diff --git a/quic/core/quic_epoll_clock_test.cc b/quic/core/quic_epoll_clock_test.cc
new file mode 100644
index 0000000..2964dfb
--- /dev/null
+++ b/quic/core/quic_epoll_clock_test.cc
@@ -0,0 +1,139 @@
+// Copyright 2022 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "quic/core/quic_epoll_clock.h"
+
+#include "quic/platform/api/quic_epoll_test_tools.h"
+#include "quic/platform/api/quic_test.h"
+
+namespace quic {
+namespace test {
+
+class QuicEpollClockTest : public QuicTest {};
+
+TEST_F(QuicEpollClockTest, ApproximateNowInUsec) {
+  QuicFakeEpollServer epoll_server;
+  QuicEpollClock clock(&epoll_server);
+
+  epoll_server.set_now_in_usec(1000000);
+  EXPECT_EQ(1000000,
+            (clock.ApproximateNow() - QuicTime::Zero()).ToMicroseconds());
+  EXPECT_EQ(1u, clock.WallNow().ToUNIXSeconds());
+  EXPECT_EQ(1000000u, clock.WallNow().ToUNIXMicroseconds());
+
+  epoll_server.AdvanceBy(5);
+  EXPECT_EQ(1000005,
+            (clock.ApproximateNow() - QuicTime::Zero()).ToMicroseconds());
+  EXPECT_EQ(1u, clock.WallNow().ToUNIXSeconds());
+  EXPECT_EQ(1000005u, clock.WallNow().ToUNIXMicroseconds());
+
+  epoll_server.AdvanceBy(10 * 1000000);
+  EXPECT_EQ(11u, clock.WallNow().ToUNIXSeconds());
+  EXPECT_EQ(11000005u, clock.WallNow().ToUNIXMicroseconds());
+}
+
+TEST_F(QuicEpollClockTest, NowInUsec) {
+  QuicFakeEpollServer epoll_server;
+  QuicEpollClock clock(&epoll_server);
+
+  epoll_server.set_now_in_usec(1000000);
+  EXPECT_EQ(1000000, (clock.Now() - QuicTime::Zero()).ToMicroseconds());
+
+  epoll_server.AdvanceBy(5);
+  EXPECT_EQ(1000005, (clock.Now() - QuicTime::Zero()).ToMicroseconds());
+}
+
+TEST_F(QuicEpollClockTest, CalibrateRealEpollClock) {
+  QuicEpollServer epoll_server;
+
+  QuicEpollClock uncalibrated_clock(&epoll_server);
+  QuicEpollClock calibrated_clock(&epoll_server);
+  EXPECT_TRUE(calibrated_clock.ComputeCalibrationOffset().IsZero());
+
+  for (int i = 0; i < 100; ++i) {
+    QuicWallTime wallnow = uncalibrated_clock.WallNow();
+    EXPECT_EQ(uncalibrated_clock.ConvertWallTimeToQuicTime(wallnow),
+              calibrated_clock.ConvertWallTimeToQuicTime(wallnow));
+  }
+}
+
+// ClockWithOffset is a clock whose offset(WallNow() - Now() at any instant) is
+// given at construction time.
+class ClockWithOffset : public QuicEpollClock {
+ public:
+  ClockWithOffset(QuicEpollServer* epoll_server, QuicTime::Delta offset)
+      : QuicEpollClock(epoll_server), offset_(offset) {}
+
+  QuicTime Now() const override { return QuicEpollClock::Now() - offset_; }
+
+  // QuicEpollClock disables ConvertWallTimeToQuicTime since it always have a
+  // zero offset. We need to re-enable it here in order to test the calibration
+  // and conversion code in QuicClock.
+  QuicTime ConvertWallTimeToQuicTime(
+      const QuicWallTime& walltime) const override {
+    return QuicClock::ConvertWallTimeToQuicTime(walltime);
+  }
+
+ private:
+  QuicTime::Delta offset_;
+};
+
+TEST_F(QuicEpollClockTest, CalibrateClockWithOffset) {
+  QuicEpollServer epoll_server;
+
+  for (const QuicTime::Delta& offset : {QuicTime::Delta::FromSeconds(5000),
+                                        QuicTime::Delta::FromSeconds(-8000)}) {
+    ClockWithOffset clock(&epoll_server, offset);
+    ASSERT_EQ(offset, clock.ComputeCalibrationOffset())
+        << "offset (us): " << offset.ToMicroseconds();
+    // Test fails without this.
+    clock.SetCalibrationOffset(offset);
+
+    QuicWallTime last_walltime = clock.WallNow();
+    QuicTime last_time = clock.ConvertWallTimeToQuicTime(last_walltime);
+
+    for (int i = 0; i < 1e5; ++i) {
+      QuicWallTime wallnow = clock.WallNow();
+      QuicTime now = clock.ConvertWallTimeToQuicTime(wallnow);
+
+      if (wallnow.IsAfter(last_walltime)) {
+        ASSERT_LT(0, (now - last_time).ToMicroseconds())
+            << "offset (us): " << offset.ToMicroseconds();
+
+        last_walltime = wallnow;
+        last_time = now;
+      }
+    }
+  }
+}
+
+TEST_F(QuicEpollClockTest, MonotonicityWithRealEpollClock) {
+  QuicEpollServer epoll_server;
+  QuicEpollClock clock(&epoll_server);
+
+  QuicTime last_now = clock.Now();
+  for (int i = 0; i < 1e5; ++i) {
+    QuicTime now = clock.Now();
+
+    ASSERT_LE(last_now, now);
+
+    last_now = now;
+  }
+}
+
+TEST_F(QuicEpollClockTest, MonotonicityWithFakeEpollClock) {
+  QuicFakeEpollServer epoll_server;
+  QuicEpollClock clock(&epoll_server);
+
+  epoll_server.set_now_in_usec(100);
+  QuicTime last_now = clock.Now();
+
+  epoll_server.set_now_in_usec(90);
+  QuicTime now = clock.Now();
+
+  ASSERT_EQ(last_now, now);
+}
+
+}  // namespace test
+}  // namespace quic
diff --git a/quic/core/quic_epoll_connection_helper.h b/quic/core/quic_epoll_connection_helper.h
index e433ff5..d944c0e 100644
--- a/quic/core/quic_epoll_connection_helper.h
+++ b/quic/core/quic_epoll_connection_helper.h
@@ -14,12 +14,12 @@
 
 #include "quic/core/quic_connection.h"
 #include "quic/core/quic_default_packet_writer.h"
+#include "quic/core/quic_epoll_clock.h"
 #include "quic/core/quic_packet_writer.h"
 #include "quic/core/quic_packets.h"
 #include "quic/core/quic_time.h"
 #include "quic/platform/api/quic_epoll.h"
 #include "quic/platform/api/quic_stream_buffer_allocator.h"
-#include "net/quic/platform/impl/quic_epoll_clock.h"
 #include "common/simple_buffer_allocator.h"
 
 namespace quic {
diff --git a/quic/test_tools/server_thread.h b/quic/test_tools/server_thread.h
index 81d0bf2..1baa6e5 100644
--- a/quic/test_tools/server_thread.h
+++ b/quic/test_tools/server_thread.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "quic/core/quic_config.h"
+#include "quic/core/quic_epoll_clock.h"
 #include "quic/platform/api/quic_containers.h"
 #include "quic/platform/api/quic_mutex.h"
 #include "quic/platform/api/quic_socket_address.h"
diff --git a/quic/tools/quic_client_interop_test_bin.cc b/quic/tools/quic_client_interop_test_bin.cc
index 6c14cc3..5dcd95c 100644
--- a/quic/tools/quic_client_interop_test_bin.cc
+++ b/quic/tools/quic_client_interop_test_bin.cc
@@ -9,11 +9,11 @@
 
 #include "absl/strings/str_cat.h"
 #include "quic/core/crypto/quic_client_session_cache.h"
+#include "quic/core/quic_epoll_clock.h"
 #include "quic/core/quic_types.h"
 #include "quic/core/quic_versions.h"
 #include "quic/platform/api/quic_epoll.h"
 #include "quic/platform/api/quic_system_event_loop.h"
-#include "net/quic/platform/impl/quic_epoll_clock.h"
 #include "quic/test_tools/quic_connection_peer.h"
 #include "quic/test_tools/quic_session_peer.h"
 #include "quic/tools/fake_proof_verifier.h"
diff --git a/quic/tools/quic_server.cc b/quic/tools/quic_server.cc
index fe10d12..743eaaf 100644
--- a/quic/tools/quic_server.cc
+++ b/quic/tools/quic_server.cc
@@ -22,12 +22,12 @@
 #include "quic/core/quic_default_packet_writer.h"
 #include "quic/core/quic_dispatcher.h"
 #include "quic/core/quic_epoll_alarm_factory.h"
+#include "quic/core/quic_epoll_clock.h"
 #include "quic/core/quic_epoll_connection_helper.h"
 #include "quic/core/quic_packet_reader.h"
 #include "quic/core/quic_packets.h"
 #include "quic/platform/api/quic_flags.h"
 #include "quic/platform/api/quic_logging.h"
-#include "net/quic/platform/impl/quic_epoll_clock.h"
 #include "quic/tools/quic_simple_crypto_server_stream_helper.h"
 #include "quic/tools/quic_simple_dispatcher.h"
 #include "quic/tools/quic_simple_server_backend.h"