Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1096)

Side by Side Diff: net/quic/congestion_control/tcp_cubic_sender.cc

Issue 12334063: Land recent QUIC changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: more EXPECT_FALSE Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/quic/congestion_control/tcp_cubic_sender.h" 5 #include "net/quic/congestion_control/tcp_cubic_sender.h"
6 6
7 namespace net {
8
7 namespace { 9 namespace {
8 // Constants based on TCP defaults. 10 // Constants based on TCP defaults.
9 const int64 kHybridStartLowWindow = 16; 11 const int64 kHybridStartLowWindow = 16;
10 const net::QuicByteCount kMaxSegmentSize = net::kMaxPacketSize; 12 const QuicByteCount kMaxSegmentSize = kMaxPacketSize;
11 const net::QuicByteCount kDefaultReceiveWindow = 64000; 13 const QuicByteCount kDefaultReceiveWindow = 64000;
12 const int64 kInitialCongestionWindow = 10; 14 const int64 kInitialCongestionWindow = 10;
13 const int64 kMaxCongestionWindow = 10000; 15 const int64 kMaxCongestionWindow = 10000;
14 const int kMaxBurstLength = 3; 16 const int kMaxBurstLength = 3;
15 }; 17 };
16 18
17 namespace net {
18
19 TcpCubicSender::TcpCubicSender(const QuicClock* clock, bool reno) 19 TcpCubicSender::TcpCubicSender(const QuicClock* clock, bool reno)
20 : hybrid_slow_start_(clock), 20 : hybrid_slow_start_(clock),
21 cubic_(clock), 21 cubic_(clock),
22 reno_(reno), 22 reno_(reno),
23 congestion_window_count_(0), 23 congestion_window_count_(0),
24 receiver_congestion_window_(kDefaultReceiveWindow), 24 receiver_congestion_window_(kDefaultReceiveWindow),
25 last_received_accumulated_number_of_lost_packets_(0), 25 last_received_accumulated_number_of_lost_packets_(0),
26 bytes_in_flight_(0), 26 bytes_in_flight_(0),
27 update_end_sequence_number_(true), 27 update_end_sequence_number_(true),
28 end_sequence_number_(0), 28 end_sequence_number_(0),
29 congestion_window_(kInitialCongestionWindow), 29 congestion_window_(kInitialCongestionWindow),
30 slowstart_threshold_(kMaxCongestionWindow), 30 slowstart_threshold_(kMaxCongestionWindow),
31 delay_min_(QuicTime::Delta::Zero()) { 31 delay_min_(QuicTime::Delta::Zero()) {
32 } 32 }
33 33
34 void TcpCubicSender::OnIncomingQuicCongestionFeedbackFrame( 34 void TcpCubicSender::OnIncomingQuicCongestionFeedbackFrame(
35 const QuicCongestionFeedbackFrame& feedback, 35 const QuicCongestionFeedbackFrame& feedback,
36 QuicTime feedback_receive_time,
37 QuicBandwidth /*sent_bandwidth*/,
36 const SentPacketsMap& /*sent_packets*/) { 38 const SentPacketsMap& /*sent_packets*/) {
37 if (last_received_accumulated_number_of_lost_packets_ != 39 if (last_received_accumulated_number_of_lost_packets_ !=
38 feedback.tcp.accumulated_number_of_lost_packets) { 40 feedback.tcp.accumulated_number_of_lost_packets) {
39 int recovered_lost_packets = 41 int recovered_lost_packets =
40 last_received_accumulated_number_of_lost_packets_ - 42 last_received_accumulated_number_of_lost_packets_ -
41 feedback.tcp.accumulated_number_of_lost_packets; 43 feedback.tcp.accumulated_number_of_lost_packets;
42 last_received_accumulated_number_of_lost_packets_ = 44 last_received_accumulated_number_of_lost_packets_ =
43 feedback.tcp.accumulated_number_of_lost_packets; 45 feedback.tcp.accumulated_number_of_lost_packets;
44 if (recovered_lost_packets > 0) { 46 if (recovered_lost_packets > 0) {
45 OnIncomingLoss(recovered_lost_packets); 47 OnIncomingLoss(feedback_receive_time);
46 } 48 }
47 } 49 }
48 receiver_congestion_window_ = feedback.tcp.receive_window; 50 receiver_congestion_window_ = feedback.tcp.receive_window;
49 } 51 }
50 52
51 void TcpCubicSender::OnIncomingAck( 53 void TcpCubicSender::OnIncomingAck(
52 QuicPacketSequenceNumber acked_sequence_number, QuicByteCount acked_bytes, 54 QuicPacketSequenceNumber acked_sequence_number, QuicByteCount acked_bytes,
53 QuicTime::Delta rtt) { 55 QuicTime::Delta rtt) {
54 bytes_in_flight_ -= acked_bytes; 56 bytes_in_flight_ -= acked_bytes;
55 CongestionAvoidance(acked_sequence_number); 57 CongestionAvoidance(acked_sequence_number);
56 AckAccounting(rtt); 58 AckAccounting(rtt);
57 if (end_sequence_number_ == acked_sequence_number) { 59 if (end_sequence_number_ == acked_sequence_number) {
58 DLOG(INFO) << "Start update end sequence number @" << acked_sequence_number; 60 DLOG(INFO) << "Start update end sequence number @" << acked_sequence_number;
59 update_end_sequence_number_ = true; 61 update_end_sequence_number_ = true;
60 } 62 }
61 } 63 }
62 64
63 void TcpCubicSender::OnIncomingLoss(int /*number_of_lost_packets*/) { 65 void TcpCubicSender::OnIncomingLoss(QuicTime /*ack_receive_time*/) {
64 // In a normal TCP we would need to know the lowest missing packet to detect 66 // In a normal TCP we would need to know the lowest missing packet to detect
65 // if we receive 3 missing packets. Here we get a missing packet for which we 67 // if we receive 3 missing packets. Here we get a missing packet for which we
66 // enter TCP Fast Retransmit immediately. 68 // enter TCP Fast Retransmit immediately.
67 if (reno_) { 69 if (reno_) {
68 congestion_window_ = congestion_window_ >> 1; 70 congestion_window_ = congestion_window_ >> 1;
69 slowstart_threshold_ = congestion_window_; 71 slowstart_threshold_ = congestion_window_;
70 } else { 72 } else {
71 congestion_window_ = 73 congestion_window_ =
72 cubic_.CongestionWindowAfterPacketLoss(congestion_window_); 74 cubic_.CongestionWindowAfterPacketLoss(congestion_window_);
73 slowstart_threshold_ = congestion_window_; 75 slowstart_threshold_ = congestion_window_;
74 } 76 }
75 // Sanity, make sure that we don't end up with an empty window. 77 // Sanity, make sure that we don't end up with an empty window.
76 if (congestion_window_ == 0) { 78 if (congestion_window_ == 0) {
77 congestion_window_ = 1; 79 congestion_window_ = 1;
78 } 80 }
81 DLOG(INFO) << "Incoming loss; congestion window:" << congestion_window_;
79 } 82 }
80 83
81 void TcpCubicSender::SentPacket(QuicPacketSequenceNumber sequence_number, 84 void TcpCubicSender::SentPacket(QuicTime /*sent_time*/,
85 QuicPacketSequenceNumber sequence_number,
82 QuicByteCount bytes, 86 QuicByteCount bytes,
83 bool is_retransmission) { 87 bool is_retransmission) {
84 if (!is_retransmission) { 88 if (!is_retransmission) {
85 bytes_in_flight_ += bytes; 89 bytes_in_flight_ += bytes;
86 } 90 }
87 if (!is_retransmission && update_end_sequence_number_) { 91 if (!is_retransmission && update_end_sequence_number_) {
88 end_sequence_number_ = sequence_number; 92 end_sequence_number_ = sequence_number;
89 if (AvailableCongestionWindow() == 0) { 93 if (AvailableCongestionWindow() == 0) {
90 update_end_sequence_number_ = false; 94 update_end_sequence_number_ = false;
91 DLOG(INFO) << "Stop update end sequence number @" << sequence_number; 95 DLOG(INFO) << "Stop update end sequence number @" << sequence_number;
92 } 96 }
93 } 97 }
94 } 98 }
95 99
96 QuicTime::Delta TcpCubicSender::TimeUntilSend(bool is_retransmission) { 100 QuicTime::Delta TcpCubicSender::TimeUntilSend(QuicTime now,
101 bool is_retransmission) {
97 if (is_retransmission) { 102 if (is_retransmission) {
98 // For TCP we can always send a retransmission immediately. 103 // For TCP we can always send a retransmission immediately.
99 return QuicTime::Delta::Zero(); 104 return QuicTime::Delta::Zero();
100 } 105 }
101 if (AvailableCongestionWindow() == 0) { 106 if (AvailableCongestionWindow() == 0) {
102 return QuicTime::Delta::Infinite(); 107 return QuicTime::Delta::Infinite();
103 } 108 }
104 return QuicTime::Delta::Zero(); 109 return QuicTime::Delta::Zero();
105 } 110 }
106 111
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 const QuicByteCount left = congestion_window_bytes - bytes_in_flight_; 144 const QuicByteCount left = congestion_window_bytes - bytes_in_flight_;
140 return left <= tcp_max_burst; 145 return left <= tcp_max_burst;
141 } 146 }
142 147
143 // Called when we receive and ack. Normal TCP tracks how many packets one ack 148 // Called when we receive and ack. Normal TCP tracks how many packets one ack
144 // represents, but quic has a separate ack for each packet. 149 // represents, but quic has a separate ack for each packet.
145 void TcpCubicSender::CongestionAvoidance(QuicPacketSequenceNumber ack) { 150 void TcpCubicSender::CongestionAvoidance(QuicPacketSequenceNumber ack) {
146 if (!IsCwndLimited()) { 151 if (!IsCwndLimited()) {
147 // We don't update the congestion window unless we are close to using the 152 // We don't update the congestion window unless we are close to using the
148 // window we have available. 153 // window we have available.
149 DLOG(INFO) << "Congestion avoidance window not limited";
150 return; 154 return;
151 } 155 }
152 if (congestion_window_ < slowstart_threshold_) { 156 if (congestion_window_ < slowstart_threshold_) {
153 // Slow start. 157 // Slow start.
154 if (hybrid_slow_start_.EndOfRound(ack)) { 158 if (hybrid_slow_start_.EndOfRound(ack)) {
155 hybrid_slow_start_.Reset(end_sequence_number_); 159 hybrid_slow_start_.Reset(end_sequence_number_);
156 } 160 }
157 // congestion_window_cnt is the number of acks since last change of snd_cwnd 161 // congestion_window_cnt is the number of acks since last change of snd_cwnd
158 if (congestion_window_ < kMaxCongestionWindow) { 162 if (congestion_window_ < kMaxCongestionWindow) {
159 // TCP slow start, exponentail growth, increase by one for each ACK. 163 // TCP slow start, exponentail growth, increase by one for each ACK.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 hybrid_slow_start_.Reset(end_sequence_number_); 210 hybrid_slow_start_.Reset(end_sequence_number_);
207 } 211 }
208 hybrid_slow_start_.Update(rtt, delay_min_); 212 hybrid_slow_start_.Update(rtt, delay_min_);
209 if (hybrid_slow_start_.Exit()) { 213 if (hybrid_slow_start_.Exit()) {
210 slowstart_threshold_ = congestion_window_; 214 slowstart_threshold_ = congestion_window_;
211 } 215 }
212 } 216 }
213 } 217 }
214 218
215 } // namespace net 219 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/congestion_control/tcp_cubic_sender.h ('k') | net/quic/congestion_control/tcp_cubic_sender_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698