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"