Move the implementation of GetReleaseTime from QuicBatchWriterBase to QuicGsoBatchWriter. No behavior change. This makes it easier to modify the GetReleaseTime function in multi release mode. PiperOrigin-RevId: 327089872 Change-Id: I6d52a40324290017657eef3f2d9bef4e54b8e914
diff --git a/quic/core/batch_writer/quic_batch_writer_base.cc b/quic/core/batch_writer/quic_batch_writer_base.cc index 51b6188..ade94a7 100644 --- a/quic/core/batch_writer/quic_batch_writer_base.cc +++ b/quic/core/batch_writer/quic_batch_writer_base.cc
@@ -8,7 +8,6 @@ #include "net/third_party/quiche/src/quic/platform/api/quic_export.h" #include "net/third_party/quiche/src/quic/platform/api/quic_flags.h" #include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h" -#include "net/third_party/quiche/src/quic/platform/api/quic_server_stats.h" namespace quic { @@ -30,52 +29,6 @@ return result; } -QuicBatchWriterBase::ReleaseTime QuicBatchWriterBase::GetReleaseTime( - const PerPacketOptions* options) const { - DCHECK(SupportsReleaseTime()); - - if (options == nullptr) { - return {0, QuicTime::Delta::Zero()}; - } - - const uint64_t now = NowInNanosForReleaseTime(); - const uint64_t ideal_release_time = - now + options->release_time_delay.ToMicroseconds() * 1000; - - if ((options->release_time_delay.IsZero() || options->allow_burst) && - !buffered_writes().empty() && - // If release time of buffered packets is in the past, flush buffered - // packets and buffer this packet at the ideal release time. - (buffered_writes().back().release_time >= now)) { - // Send as soon as possible, but no sooner than the last buffered packet. - const uint64_t actual_release_time = buffered_writes().back().release_time; - - const int64_t offset_ns = actual_release_time - ideal_release_time; - if (offset_ns >= 0) { - QUIC_SERVER_HISTOGRAM_TIMES("batch_writer_positive_release_time_offset", - offset_ns / 1000, 1, 100000, 50, - "Duration from ideal release time to actual " - "release time, in microseconds."); - } else { - QUIC_SERVER_HISTOGRAM_TIMES("batch_writer_negative_release_time_offset", - -offset_ns / 1000, 1, 100000, 50, - "Duration from actual release time to ideal " - "release time, in microseconds."); - } - - ReleaseTime result{actual_release_time, - QuicTime::Delta::FromMicroseconds(offset_ns / 1000)}; - - QUIC_DVLOG(1) << "ideal_release_time:" << ideal_release_time - << ", actual_release_time:" << actual_release_time - << ", offset:" << result.release_time_offset; - return result; - } - - // Send according to the release time delay. - return {ideal_release_time, QuicTime::Delta::Zero()}; -} - WriteResult QuicBatchWriterBase::InternalWritePacket( const char* buffer, size_t buf_len,
diff --git a/quic/core/batch_writer/quic_batch_writer_base.h b/quic/core/batch_writer/quic_batch_writer_base.h index b902677..30e1af4 100644 --- a/quic/core/batch_writer/quic_batch_writer_base.h +++ b/quic/core/batch_writer/quic_batch_writer_base.h
@@ -64,13 +64,6 @@ return batch_buffer_->buffered_writes(); } - // Get the current time in nanos which is understood by the sending api for - // releasing packets in the future. - virtual uint64_t NowInNanosForReleaseTime() const { - DCHECK(false) << "Should not be called since release time is unsupported."; - return 0; - } - // Given the release delay in |options| and the state of |batch_buffer_|, get // the absolute release time. struct QUIC_NO_EXPORT ReleaseTime { @@ -80,7 +73,11 @@ // which is (now + |options->release_time_delay|). QuicTime::Delta release_time_offset = QuicTime::Delta::Zero(); }; - ReleaseTime GetReleaseTime(const PerPacketOptions* options) const; + virtual ReleaseTime GetReleaseTime( + const PerPacketOptions* /*options*/) const { + DCHECK(false) << "Should not be called since release time is unsupported."; + return ReleaseTime{0, QuicTime::Delta::Zero()}; + } struct QUIC_EXPORT_PRIVATE CanBatchResult { CanBatchResult(bool can_batch, bool must_flush)
diff --git a/quic/core/batch_writer/quic_gso_batch_writer.cc b/quic/core/batch_writer/quic_gso_batch_writer.cc index 95db178..5feb595 100644 --- a/quic/core/batch_writer/quic_gso_batch_writer.cc +++ b/quic/core/batch_writer/quic_gso_batch_writer.cc
@@ -8,6 +8,7 @@ #include <ctime> #include "net/third_party/quiche/src/quic/core/quic_linux_socket_utils.h" +#include "net/third_party/quiche/src/quic/platform/api/quic_server_stats.h" namespace quic { @@ -96,6 +97,52 @@ return CanBatchResult(can_batch, must_flush); } +QuicGsoBatchWriter::ReleaseTime QuicGsoBatchWriter::GetReleaseTime( + const PerPacketOptions* options) const { + DCHECK(SupportsReleaseTime()); + + if (options == nullptr) { + return {0, QuicTime::Delta::Zero()}; + } + + const uint64_t now = NowInNanosForReleaseTime(); + const uint64_t ideal_release_time = + now + options->release_time_delay.ToMicroseconds() * 1000; + + if ((options->release_time_delay.IsZero() || options->allow_burst) && + !buffered_writes().empty() && + // If release time of buffered packets is in the past, flush buffered + // packets and buffer this packet at the ideal release time. + (buffered_writes().back().release_time >= now)) { + // Send as soon as possible, but no sooner than the last buffered packet. + const uint64_t actual_release_time = buffered_writes().back().release_time; + + const int64_t offset_ns = actual_release_time - ideal_release_time; + if (offset_ns >= 0) { + QUIC_SERVER_HISTOGRAM_TIMES("gso_writer_positive_release_time_offset", + offset_ns / 1000, 1, 100000, 50, + "Duration from ideal release time to actual " + "release time, in microseconds."); + } else { + QUIC_SERVER_HISTOGRAM_TIMES("gso_writer_negative_release_time_offset", + -offset_ns / 1000, 1, 100000, 50, + "Duration from actual release time to ideal " + "release time, in microseconds."); + } + + ReleaseTime result{actual_release_time, + QuicTime::Delta::FromMicroseconds(offset_ns / 1000)}; + + QUIC_DVLOG(1) << "ideal_release_time:" << ideal_release_time + << ", actual_release_time:" << actual_release_time + << ", offset:" << result.release_time_offset; + return result; + } + + // Send according to the release time delay. + return {ideal_release_time, QuicTime::Delta::Zero()}; +} + uint64_t QuicGsoBatchWriter::NowInNanosForReleaseTime() const { struct timespec ts;
diff --git a/quic/core/batch_writer/quic_gso_batch_writer.h b/quic/core/batch_writer/quic_gso_batch_writer.h index d210cf7..ce8a71d 100644 --- a/quic/core/batch_writer/quic_gso_batch_writer.h +++ b/quic/core/batch_writer/quic_gso_batch_writer.h
@@ -41,7 +41,10 @@ clockid_t clockid_for_release_time, ReleaseTimeForceEnabler enabler); - uint64_t NowInNanosForReleaseTime() const override; + ReleaseTime GetReleaseTime(const PerPacketOptions* options) const override; + + // Get the current time in nanos from |clockid_for_release_time_|. + virtual uint64_t NowInNanosForReleaseTime() const; static size_t MaxSegments(size_t gso_size) { // Max segments should be the min of UDP_MAX_SEGMENTS(64) and