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

Side by Side Diff: net/quic/congestion_control/quic_congestion_manager.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, 9 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/quic_congestion_manager.h" 5 #include "net/quic/congestion_control/quic_congestion_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 9
10 #include "base/stl_util.h" 10 #include "base/stl_util.h"
11 #include "net/quic/congestion_control/receive_algorithm_interface.h" 11 #include "net/quic/congestion_control/receive_algorithm_interface.h"
12 #include "net/quic/congestion_control/send_algorithm_interface.h" 12 #include "net/quic/congestion_control/send_algorithm_interface.h"
13 13
14 namespace { 14 namespace {
15 const int kBitrateSmoothingPeriodMs = 3000; 15 const int kBitrateSmoothingPeriodMs = 1000;
16 const int kMinBitrateSmoothingPeriodMs = 500; 16 const int kMinBitrateSmoothingPeriodMs = 500;
17 const int kHistoryPeriodMs = 5000; 17 const int kHistoryPeriodMs = 5000;
18 18
19 const int kDefaultRetransmissionTimeMs = 500; 19 const int kDefaultRetransmissionTimeMs = 500;
20 const size_t kMaxRetransmissions = 15; 20 const size_t kMaxRetransmissions = 10;
21 const size_t kTailDropWindowSize = 5;
21 22
22 COMPILE_ASSERT(kHistoryPeriodMs >= kBitrateSmoothingPeriodMs, 23 COMPILE_ASSERT(kHistoryPeriodMs >= kBitrateSmoothingPeriodMs,
23 history_must_be_longer_or_equal_to_the_smoothing_period); 24 history_must_be_longer_or_equal_to_the_smoothing_period);
24 } // namespace 25 } // namespace
25 26
26 using std::map; 27 using std::map;
27 using std::min; 28 using std::min;
28 29
29 namespace net { 30 namespace net {
30 31
31 QuicCongestionManager::QuicCongestionManager( 32 QuicCongestionManager::QuicCongestionManager(
32 const QuicClock* clock, 33 const QuicClock* clock,
33 CongestionFeedbackType type) 34 CongestionFeedbackType type)
34 : clock_(clock), 35 : clock_(clock),
35 receive_algorithm_(ReceiveAlgorithmInterface::Create(clock, type)), 36 receive_algorithm_(ReceiveAlgorithmInterface::Create(clock, type)),
36 send_algorithm_(SendAlgorithmInterface::Create(clock, type)) { 37 send_algorithm_(SendAlgorithmInterface::Create(clock, type)),
38 largest_missing_(0) {
37 } 39 }
38 40
39 QuicCongestionManager::~QuicCongestionManager() { 41 QuicCongestionManager::~QuicCongestionManager() {
40 STLDeleteValues(&packet_history_map_); 42 STLDeleteValues(&packet_history_map_);
41 } 43 }
42 44
43 void QuicCongestionManager::SentPacket(QuicPacketSequenceNumber sequence_number, 45 void QuicCongestionManager::SentPacket(QuicPacketSequenceNumber sequence_number,
46 QuicTime sent_time,
44 QuicByteCount bytes, 47 QuicByteCount bytes,
45 bool is_retransmission) { 48 bool is_retransmission) {
46 DCHECK(!ContainsKey(pending_packets_, sequence_number)); 49 DCHECK(!ContainsKey(pending_packets_, sequence_number));
47 send_algorithm_->SentPacket(sequence_number, bytes, is_retransmission); 50 send_algorithm_->SentPacket(sent_time, sequence_number, bytes,
51 is_retransmission);
48 52
49 packet_history_map_[sequence_number] = 53 packet_history_map_[sequence_number] =
50 new class SendAlgorithmInterface::SentPacket(bytes, clock_->Now()); 54 new class SendAlgorithmInterface::SentPacket(bytes, sent_time);
51 pending_packets_[sequence_number] = bytes; 55 pending_packets_[sequence_number] = bytes;
52 CleanupPacketHistory(); 56 CleanupPacketHistory();
53 DLOG(INFO) << "Sent sequence number:" << sequence_number;
54 } 57 }
55 58
56 void QuicCongestionManager::OnIncomingQuicCongestionFeedbackFrame( 59 void QuicCongestionManager::OnIncomingQuicCongestionFeedbackFrame(
57 const QuicCongestionFeedbackFrame& frame) { 60 const QuicCongestionFeedbackFrame& frame, QuicTime feedback_receive_time) {
58 send_algorithm_->OnIncomingQuicCongestionFeedbackFrame(frame, 61 QuicBandwidth sent_bandwidth = SentBandwidth(feedback_receive_time);
59 packet_history_map_); 62 send_algorithm_->OnIncomingQuicCongestionFeedbackFrame(
63 frame, feedback_receive_time, sent_bandwidth, packet_history_map_);
60 } 64 }
61 65
62 void QuicCongestionManager::OnIncomingAckFrame(const QuicAckFrame& frame) { 66 void QuicCongestionManager::OnIncomingAckFrame(const QuicAckFrame& frame,
67 QuicTime ack_receive_time) {
63 // We calculate the RTT based on the highest ACKed sequence number, the lower 68 // We calculate the RTT based on the highest ACKed sequence number, the lower
64 // sequence numbers will include the ACK aggregation delay. 69 // sequence numbers will include the ACK aggregation delay.
65 QuicTime::Delta rtt = QuicTime::Delta::Zero(); 70 QuicTime::Delta rtt = QuicTime::Delta::Zero();
66 SendAlgorithmInterface::SentPacketsMap::iterator history_it = 71 SendAlgorithmInterface::SentPacketsMap::iterator history_it =
67 packet_history_map_.find(frame.received_info.largest_observed); 72 packet_history_map_.find(frame.received_info.largest_observed);
68 if (history_it != packet_history_map_.end()) { 73 if (history_it != packet_history_map_.end()) {
69 rtt = clock_->Now().Subtract(history_it->second->SendTimestamp()); 74 // TODO(pwestin): we need to add the delta to the feedback message.
75 rtt = ack_receive_time.Subtract(history_it->second->SendTimestamp());
70 } 76 }
71 // We want to. 77 // We want to.
72 // * Get all packets lower(including) than largest_observed 78 // * Get all packets lower(including) than largest_observed
73 // from pending_packets_. 79 // from pending_packets_.
74 // * Remove all missing packets. 80 // * Remove all missing packets.
75 // * Send each ACK in the list to send_algorithm_. 81 // * Send each ACK in the list to send_algorithm_.
76 PendingPacketsMap::iterator it, it_upper; 82 PendingPacketsMap::iterator it, it_upper;
77 it = pending_packets_.begin(); 83 it = pending_packets_.begin();
78 it_upper = pending_packets_.upper_bound(frame.received_info.largest_observed); 84 it_upper = pending_packets_.upper_bound(frame.received_info.largest_observed);
79 85
86 bool new_packet_loss_reported = false;
80 while (it != it_upper) { 87 while (it != it_upper) {
81 QuicPacketSequenceNumber sequence_number = it->first; 88 QuicPacketSequenceNumber sequence_number = it->first;
82 if (!frame.received_info.IsAwaitingPacket(sequence_number)) { 89 if (!IsAwaitingPacket(frame.received_info, sequence_number)) {
83 // Not missing, hence implicitly acked. 90 // Not missing, hence implicitly acked.
84 send_algorithm_->OnIncomingAck(sequence_number, 91 send_algorithm_->OnIncomingAck(sequence_number,
85 it->second, 92 it->second,
86 rtt); 93 rtt);
87 DLOG(INFO) << "ACKed sequence number:" << sequence_number;
88 pending_packets_.erase(it++); // Must be incremented post to work. 94 pending_packets_.erase(it++); // Must be incremented post to work.
89 } else { 95 } else {
96 if (sequence_number > largest_missing_) {
97 // We have a new loss reported.
98 new_packet_loss_reported = true;
99 largest_missing_ = sequence_number;
100 }
90 ++it; 101 ++it;
91 } 102 }
92 } 103 }
104 if (new_packet_loss_reported) {
105 send_algorithm_->OnIncomingLoss(ack_receive_time);
106 }
93 } 107 }
94 108
95 QuicTime::Delta QuicCongestionManager::TimeUntilSend(bool is_retransmission) { 109 QuicTime::Delta QuicCongestionManager::TimeUntilSend(QuicTime now,
96 return send_algorithm_->TimeUntilSend(is_retransmission); 110 bool is_retransmission) {
111 return send_algorithm_->TimeUntilSend(now, is_retransmission);
97 } 112 }
98 113
99 bool QuicCongestionManager::GenerateCongestionFeedback( 114 bool QuicCongestionManager::GenerateCongestionFeedback(
100 QuicCongestionFeedbackFrame* feedback) { 115 QuicCongestionFeedbackFrame* feedback) {
101 return receive_algorithm_->GenerateCongestionFeedback(feedback); 116 return receive_algorithm_->GenerateCongestionFeedback(feedback);
102 } 117 }
103 118
104 void QuicCongestionManager::RecordIncomingPacket( 119 void QuicCongestionManager::RecordIncomingPacket(
105 QuicByteCount bytes, 120 QuicByteCount bytes,
106 QuicPacketSequenceNumber sequence_number, 121 QuicPacketSequenceNumber sequence_number,
107 QuicTime timestamp, 122 QuicTime timestamp,
108 bool revived) { 123 bool revived) {
109 receive_algorithm_->RecordIncomingPacket(bytes, sequence_number, timestamp, 124 receive_algorithm_->RecordIncomingPacket(bytes, sequence_number, timestamp,
110 revived); 125 revived);
111 } 126 }
112 127
113 // static 128 // static
114 const QuicTime::Delta QuicCongestionManager::DefaultRetransmissionTime() { 129 const QuicTime::Delta QuicCongestionManager::DefaultRetransmissionTime() {
115 return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs); 130 return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
116 } 131 }
117 132
118 // static 133 // static
119 const QuicTime::Delta QuicCongestionManager::GetRetransmissionDelay( 134 const QuicTime::Delta QuicCongestionManager::GetRetransmissionDelay(
135 size_t unacked_packets_count,
120 size_t number_retransmissions) { 136 size_t number_retransmissions) {
137 if (unacked_packets_count <= kTailDropWindowSize) {
138 return QuicTime::Delta::FromMilliseconds(kDefaultRetransmissionTimeMs);
139 }
140
121 return QuicTime::Delta::FromMilliseconds( 141 return QuicTime::Delta::FromMilliseconds(
122 kDefaultRetransmissionTimeMs * 142 kDefaultRetransmissionTimeMs *
123 (1 << min<size_t>(number_retransmissions, kMaxRetransmissions))); 143 (1 << min<size_t>(number_retransmissions, kMaxRetransmissions)));
124 } 144 }
125 145
126 QuicBandwidth QuicCongestionManager::SentBandwidth() const { 146 QuicBandwidth QuicCongestionManager::SentBandwidth(
147 QuicTime feedback_receive_time) const {
127 const QuicTime::Delta kBitrateSmoothingPeriod = 148 const QuicTime::Delta kBitrateSmoothingPeriod =
128 QuicTime::Delta::FromMilliseconds(kBitrateSmoothingPeriodMs); 149 QuicTime::Delta::FromMilliseconds(kBitrateSmoothingPeriodMs);
129 const QuicTime::Delta kMinBitrateSmoothingPeriod = 150 const QuicTime::Delta kMinBitrateSmoothingPeriod =
130 QuicTime::Delta::FromMilliseconds(kMinBitrateSmoothingPeriodMs); 151 QuicTime::Delta::FromMilliseconds(kMinBitrateSmoothingPeriodMs);
131 152
132 QuicTime now = clock_->Now();
133 QuicByteCount sum_bytes_sent = 0; 153 QuicByteCount sum_bytes_sent = 0;
134 154
135 // Sum packet from new until they are kBitrateSmoothingPeriod old. 155 // Sum packet from new until they are kBitrateSmoothingPeriod old.
136 SendAlgorithmInterface::SentPacketsMap::const_reverse_iterator history_rit = 156 SendAlgorithmInterface::SentPacketsMap::const_reverse_iterator history_rit =
137 packet_history_map_.rbegin(); 157 packet_history_map_.rbegin();
138 158
139 QuicTime::Delta max_diff = QuicTime::Delta::Zero(); 159 QuicTime::Delta max_diff = QuicTime::Delta::Zero();
140 for (; history_rit != packet_history_map_.rend(); ++history_rit) { 160 for (; history_rit != packet_history_map_.rend(); ++history_rit) {
141 QuicTime::Delta diff = now.Subtract(history_rit->second->SendTimestamp()); 161 QuicTime::Delta diff =
162 feedback_receive_time.Subtract(history_rit->second->SendTimestamp());
142 if (diff > kBitrateSmoothingPeriod) { 163 if (diff > kBitrateSmoothingPeriod) {
143 break; 164 break;
144 } 165 }
145 sum_bytes_sent += history_rit->second->BytesSent(); 166 sum_bytes_sent += history_rit->second->BytesSent();
146 max_diff = diff; 167 max_diff = diff;
147 } 168 }
148 if (max_diff < kMinBitrateSmoothingPeriod) { 169 if (max_diff < kMinBitrateSmoothingPeriod) {
149 // No estimate. 170 // No estimate.
150 return QuicBandwidth::Zero(); 171 return QuicBandwidth::Zero();
151 } 172 }
152 return QuicBandwidth::FromBytesAndTimeDelta(sum_bytes_sent, max_diff); 173 return QuicBandwidth::FromBytesAndTimeDelta(sum_bytes_sent, max_diff);
153 } 174 }
154 175
155 QuicBandwidth QuicCongestionManager::BandwidthEstimate() { 176 QuicBandwidth QuicCongestionManager::BandwidthEstimate() {
156 return send_algorithm_->BandwidthEstimate(); 177 return send_algorithm_->BandwidthEstimate();
157 } 178 }
158 179
159 void QuicCongestionManager::CleanupPacketHistory() { 180 void QuicCongestionManager::CleanupPacketHistory() {
160 const QuicTime::Delta kHistoryPeriod = 181 const QuicTime::Delta kHistoryPeriod =
161 QuicTime::Delta::FromMilliseconds(kHistoryPeriodMs); 182 QuicTime::Delta::FromMilliseconds(kHistoryPeriodMs);
162 QuicTime Now = clock_->Now(); 183 QuicTime now = clock_->ApproximateNow();
163 184
164 SendAlgorithmInterface::SentPacketsMap::iterator history_it = 185 SendAlgorithmInterface::SentPacketsMap::iterator history_it =
165 packet_history_map_.begin(); 186 packet_history_map_.begin();
166 for (; history_it != packet_history_map_.end(); ++history_it) { 187 for (; history_it != packet_history_map_.end(); ++history_it) {
167 if (Now.Subtract(history_it->second->SendTimestamp()) <= kHistoryPeriod) { 188 if (now.Subtract(history_it->second->SendTimestamp()) <= kHistoryPeriod) {
168 return; 189 return;
169 } 190 }
170 DLOG(INFO) << "Clear sequence number:" << history_it->first
171 << "from history";
172 delete history_it->second; 191 delete history_it->second;
173 packet_history_map_.erase(history_it); 192 packet_history_map_.erase(history_it);
174 history_it = packet_history_map_.begin(); 193 history_it = packet_history_map_.begin();
175 } 194 }
176 } 195 }
177 196
178 } // namespace net 197 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/congestion_control/quic_congestion_manager.h ('k') | net/quic/congestion_control/send_algorithm_interface.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698