Index: net/quic/congestion_control/tcp_cubic_sender.cc |
diff --git a/net/quic/congestion_control/tcp_cubic_sender.cc b/net/quic/congestion_control/tcp_cubic_sender.cc |
index 03cf38baa7f09faed12994c204ca9c2a63e47205..9ea96aed5f5b171c0c6e60ecb4c9d02b76897f51 100644 |
--- a/net/quic/congestion_control/tcp_cubic_sender.cc |
+++ b/net/quic/congestion_control/tcp_cubic_sender.cc |
@@ -7,6 +7,7 @@ |
#include <algorithm> |
#include "base/metrics/histogram.h" |
+#include "net/quic/congestion_control/prr_sender.h" |
#include "net/quic/congestion_control/rtt_stats.h" |
#include "net/quic/crypto/crypto_protocol.h" |
@@ -23,7 +24,7 @@ const QuicPacketCount kMinimumCongestionWindow = 2; |
const QuicByteCount kMaxSegmentSize = kDefaultTCPMSS; |
const int64 kInitialCongestionWindow = 10; |
const int kMaxBurstLength = 3; |
-}; // namespace |
+} // namespace |
TcpCubicSender::TcpCubicSender( |
const QuicClock* clock, |
@@ -38,10 +39,6 @@ TcpCubicSender::TcpCubicSender( |
reno_(reno), |
num_connections_(2), |
congestion_window_count_(0), |
- prr_out_(0), |
- prr_delivered_(0), |
- ack_count_since_loss_(0), |
- bytes_in_flight_before_loss_(0), |
largest_sent_sequence_number_(0), |
largest_acked_sequence_number_(0), |
largest_sent_at_last_cutback_(0), |
@@ -106,7 +103,8 @@ void TcpCubicSender::OnPacketAcked( |
largest_acked_sequence_number_ = max(acked_sequence_number, |
largest_acked_sequence_number_); |
if (InRecovery()) { |
- PrrOnPacketAcked(acked_bytes); |
+ // PRR is used when in recovery. |
+ prr_.OnPacketAcked(acked_bytes); |
return; |
} |
MaybeIncreaseCwnd(acked_sequence_number, bytes_in_flight); |
@@ -131,7 +129,8 @@ void TcpCubicSender::OnPacketLost(QuicPacketSequenceNumber sequence_number, |
if (InSlowStart()) { |
++stats_->slowstart_packets_lost; |
} |
- PrrOnPacketLost(bytes_in_flight); |
+ |
+ prr_.OnPacketLost(bytes_in_flight); |
if (reno_) { |
congestion_window_ = congestion_window_ >> 1; |
@@ -161,8 +160,10 @@ bool TcpCubicSender::OnPacketSent(QuicTime /*sent_time*/, |
if (is_retransmittable != HAS_RETRANSMITTABLE_DATA) { |
return false; |
} |
- |
- prr_out_ += bytes; |
+ if (InRecovery()) { |
+ // PRR is used when in recovery. |
+ prr_.OnPacketSent(bytes); |
+ } |
DCHECK_LT(largest_sent_sequence_number_, sequence_number); |
largest_sent_sequence_number_ = sequence_number; |
hybrid_slow_start_.OnPacketSent(sequence_number); |
@@ -178,7 +179,9 @@ QuicTime::Delta TcpCubicSender::TimeUntilSend( |
return QuicTime::Delta::Zero(); |
} |
if (InRecovery()) { |
- return PrrTimeUntilSend(bytes_in_flight); |
+ // PRR is used when in recovery. |
+ return prr_.TimeUntilSend(GetCongestionWindow(), bytes_in_flight, |
+ slowstart_threshold_); |
} |
if (GetCongestionWindow() > bytes_in_flight) { |
return QuicTime::Delta::Zero(); |
@@ -315,46 +318,6 @@ void TcpCubicSender::RevertRetransmissionTimeout() { |
previous_congestion_window_ = 0; |
} |
-void TcpCubicSender::PrrOnPacketLost(QuicByteCount bytes_in_flight) { |
- prr_out_ = 0; |
- bytes_in_flight_before_loss_ = bytes_in_flight; |
- prr_delivered_ = 0; |
- ack_count_since_loss_ = 0; |
-} |
- |
-void TcpCubicSender::PrrOnPacketAcked(QuicByteCount acked_bytes) { |
- prr_delivered_ += acked_bytes; |
- ++ack_count_since_loss_; |
-} |
- |
-QuicTime::Delta TcpCubicSender::PrrTimeUntilSend( |
- QuicByteCount bytes_in_flight) const { |
- DCHECK(InRecovery()); |
- // Return QuicTime::Zero In order to ensure limited transmit always works. |
- if (prr_out_ == 0 || bytes_in_flight < kMaxSegmentSize) { |
- return QuicTime::Delta::Zero(); |
- } |
- if (GetCongestionWindow() > bytes_in_flight) { |
- // During PRR-SSRB, limit outgoing packets to 1 extra MSS per ack, instead |
- // of sending the entire available window. This prevents burst retransmits |
- // when more packets are lost than the CWND reduction. |
- // limit = MAX(prr_delivered - prr_out, DeliveredData) + MSS |
- if (prr_delivered_ + ack_count_since_loss_ * kMaxSegmentSize <= prr_out_) { |
- return QuicTime::Delta::Infinite(); |
- } |
- return QuicTime::Delta::Zero(); |
- } |
- // Implement Proportional Rate Reduction (RFC6937) |
- // Checks a simplified version of the PRR formula that doesn't use division: |
- // AvailableSendWindow = |
- // CEIL(prr_delivered * ssthresh / BytesInFlightAtLoss) - prr_sent |
- if (prr_delivered_ * slowstart_threshold_ * kMaxSegmentSize > |
- prr_out_ * bytes_in_flight_before_loss_) { |
- return QuicTime::Delta::Zero(); |
- } |
- return QuicTime::Delta::Infinite(); |
-} |
- |
CongestionControlType TcpCubicSender::GetCongestionControlType() const { |
return reno_ ? kReno : kCubic; |
} |