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

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

Issue 399153003: Land Recent QUIC Changes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added NET_EXPORT_PRIVATE Created 6 years, 5 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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/send_algorithm_simulator.h" 5 #include "net/quic/congestion_control/send_algorithm_simulator.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/rand_util.h" 10 #include "base/rand_util.h"
(...skipping 16 matching lines...) Expand all
27 RttStats* rtt_stats) 27 RttStats* rtt_stats)
28 : send_algorithm(send_algorithm), 28 : send_algorithm(send_algorithm),
29 rtt_stats(rtt_stats), 29 rtt_stats(rtt_stats),
30 last_sent(0), 30 last_sent(0),
31 last_acked(0), 31 last_acked(0),
32 next_acked(1), 32 next_acked(1),
33 max_cwnd(0), 33 max_cwnd(0),
34 min_cwnd(100000), 34 min_cwnd(100000),
35 max_cwnd_drop(0), 35 max_cwnd_drop(0),
36 last_cwnd(0), 36 last_cwnd(0),
37 last_transfer_bandwidth(QuicBandwidth::Zero()) {} 37 last_transfer_bandwidth(QuicBandwidth::Zero()),
38 last_transfer_loss_rate(0) {}
38 39
39 SendAlgorithmSimulator::SendAlgorithmSimulator( 40 SendAlgorithmSimulator::SendAlgorithmSimulator(
40 MockClock* clock, 41 MockClock* clock,
41 QuicBandwidth bandwidth, 42 QuicBandwidth bandwidth,
42 QuicTime::Delta rtt) 43 QuicTime::Delta rtt)
43 : clock_(clock), 44 : clock_(clock),
44 lose_next_ack_(false), 45 lose_next_ack_(false),
45 forward_loss_rate_(0), 46 forward_loss_rate_(0),
46 reverse_loss_rate_(0), 47 reverse_loss_rate_(0),
47 loss_correlation_(0), 48 loss_correlation_(0),
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 DVLOG(1) << "Sending, advancing time:" 100 DVLOG(1) << "Sending, advancing time:"
100 << send_event.time_delta.ToMicroseconds() << "us"; 101 << send_event.time_delta.ToMicroseconds() << "us";
101 clock_->AdvanceTime(send_event.time_delta); 102 clock_->AdvanceTime(send_event.time_delta);
102 SendDataNow(send_event.transfer); 103 SendDataNow(send_event.transfer);
103 bytes_sent += kPacketSize; 104 bytes_sent += kPacketSize;
104 } 105 }
105 } 106 }
106 } 107 }
107 108
108 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextSendEvent() { 109 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextSendEvent() {
109 QuicTime::Delta send_time = QuicTime::Delta::Infinite(); 110 QuicTime::Delta next_send_time = QuicTime::Delta::Infinite();
110 Transfer* transfer = NULL; 111 Transfer* transfer = NULL;
111 for (vector<Transfer>::iterator it = pending_transfers_.begin(); 112 for (vector<Transfer>::iterator it = pending_transfers_.begin();
112 it != pending_transfers_.end(); ++it) { 113 it != pending_transfers_.end(); ++it) {
113 // If the flow hasn't started, return the start time.
114 if (clock_->Now() < it->start_time) {
115 send_time = it->start_time.Subtract(clock_->Now());
116 transfer = &(*it);
117 continue;
118 }
119 // If we've already sent enough bytes, wait for them to be acked. 114 // If we've already sent enough bytes, wait for them to be acked.
120 if (it->bytes_acked + it->bytes_in_flight >= it->num_bytes) { 115 if (it->bytes_acked + it->bytes_in_flight >= it->num_bytes) {
121 continue; 116 continue;
122 } 117 }
123 QuicTime::Delta transfer_send_time = 118 // If the flow hasn't started, use the start time.
124 it->sender->send_algorithm->TimeUntilSend( 119 QuicTime::Delta transfer_send_time = it->start_time.Subtract(clock_->Now());
125 clock_->Now(), it->bytes_in_flight, HAS_RETRANSMITTABLE_DATA); 120 if (clock_->Now() >= it->start_time) {
126 if (transfer_send_time < send_time) { 121 transfer_send_time =
127 send_time = transfer_send_time; 122 it->sender->send_algorithm->TimeUntilSend(
123 clock_->Now(), it->bytes_in_flight, HAS_RETRANSMITTABLE_DATA);
124 }
125 if (transfer_send_time < next_send_time) {
126 next_send_time = transfer_send_time;
128 transfer = &(*it); 127 transfer = &(*it);
129 } 128 }
130 } 129 }
131 DVLOG(1) << "NextSendTime returning delta(ms):" << send_time.ToMilliseconds(); 130 DVLOG(1) << "NextSendTime returning delta(ms):"
132 return PacketEvent(send_time, transfer); 131 << next_send_time.ToMilliseconds();
132 return PacketEvent(next_send_time, transfer);
133 } 133 }
134 134
135 // NextAck takes into account packet loss in both forward and reverse 135 // NextAck takes into account packet loss in both forward and reverse
136 // direction, as well as correlated losses. And it assumes the receiver acks 136 // direction, as well as correlated losses. And it assumes the receiver acks
137 // every other packet when there is no loss. 137 // every other packet when there is no loss.
138 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextAckEvent() { 138 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextAckEvent() {
139 if (sent_packets_.empty()) { 139 if (sent_packets_.empty()) {
140 DVLOG(1) << "No outstanding packets to ack for any transfer."; 140 DVLOG(1) << "No outstanding packets to ack for any transfer.";
141 return PacketEvent(QuicTime::Delta::Infinite(), NULL); 141 return PacketEvent(QuicTime::Delta::Infinite(), NULL);
142 } 142 }
143 143
144 // For each connection, find the next acked packet. 144 // For each connection, find the next acked packet.
145 QuicTime::Delta ack_time = QuicTime::Delta::Infinite(); 145 QuicTime::Delta ack_time = QuicTime::Delta::Infinite();
146 Transfer* transfer = NULL; 146 Transfer* transfer = NULL;
147 for (vector<Transfer>::iterator it = pending_transfers_.begin(); 147 for (vector<Transfer>::iterator it = pending_transfers_.begin();
148 it != pending_transfers_.end(); ++it) { 148 it != pending_transfers_.end(); ++it) {
149 // If necessary, determine next_acked_.
150 // This is only done once to ensure multiple calls return the same time.
151 QuicTime::Delta transfer_ack_time = FindNextAcked(&(*it)); 149 QuicTime::Delta transfer_ack_time = FindNextAcked(&(*it));
152 if (transfer_ack_time < ack_time) { 150 if (transfer_ack_time < ack_time) {
153 ack_time = transfer_ack_time; 151 ack_time = transfer_ack_time;
154 transfer = &(*it); 152 transfer = &(*it);
155 } 153 }
156 } 154 }
157 155
158 return PacketEvent(ack_time, transfer); 156 return PacketEvent(ack_time, transfer);
159 } 157 }
160 158
161 QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) { 159 QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) {
162 Sender* sender = transfer->sender; 160 Sender* sender = transfer->sender;
163 if (sender->next_acked == sender->last_acked) { 161 if (sender->next_acked == sender->last_acked) {
164 // Determine if the next ack is lost only once, to ensure determinism. 162 // Determine if the next ack is lost only once, to ensure determinism.
165 lose_next_ack_ = 163 lose_next_ack_ =
166 reverse_loss_rate_ * kuint64max > simple_random_.RandUint64(); 164 reverse_loss_rate_ * kuint64max > simple_random_.RandUint64();
167 } 165 }
168 bool two_acks_remaining = lose_next_ack_; 166 bool two_acks_remaining = lose_next_ack_;
169 sender->next_acked = sender->last_acked; 167 sender->next_acked = sender->last_acked;
170 bool packets_lost = false; 168 bool packets_lost = false;
171 // Remove any packets that are simulated as lost. 169 // Remove any packets that are simulated as lost.
172 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); 170 for (list<SentPacket>::const_iterator it = sent_packets_.begin();
173 it != sent_packets_.end(); ++it) { 171 it != sent_packets_.end(); ++it) {
174 if (transfer != it->transfer) { 172 if (transfer != it->transfer) {
175 continue; 173 continue;
176 } 174 }
177 175
178 // Lost packets don't trigger an ack. 176 // Lost packets don't trigger an ack.
179 if (it->ack_time == QuicTime::Zero()) { 177 if (it->ack_time == QuicTime::Zero()) {
180 packets_lost = true; 178 packets_lost = true;
181 continue; 179 continue;
182 } 180 }
183 // Buffer dropped packets are skipped automatically, but still end up 181 // Buffer dropped packets are skipped automatically, but still end up
184 // being lost and cause acks to be sent immediately. 182 // being lost and cause acks to be sent immediately.
185 if (sender->next_acked < it->sequence_number - 1) { 183 if (sender->next_acked < it->sequence_number - 1) {
186 packets_lost = true; 184 packets_lost = true;
187 } 185 }
186 DCHECK_LT(sender->next_acked, it->sequence_number);
188 sender->next_acked = it->sequence_number; 187 sender->next_acked = it->sequence_number;
189 if (packets_lost || (sender->next_acked - sender->last_acked) % 2 == 0) { 188 if (packets_lost || (sender->next_acked - sender->last_acked) % 2 == 0) {
190 if (two_acks_remaining) { 189 if (two_acks_remaining) {
191 two_acks_remaining = false; 190 two_acks_remaining = false;
192 } else { 191 } else {
193 break; 192 break;
194 } 193 }
195 } 194 }
196 } 195 }
196 // If the connection has no packets to be acked, return Infinite.
197 if (sender->next_acked == sender->last_acked) {
198 return QuicTime::Delta::Infinite();
199 }
197 200
198 QuicTime::Delta ack_time = QuicTime::Delta::Infinite(); 201 QuicTime::Delta ack_time = QuicTime::Delta::Infinite();
199 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); 202 for (list<SentPacket>::const_iterator it = sent_packets_.begin();
200 it != sent_packets_.end(); ++it) { 203 it != sent_packets_.end(); ++it) {
201 if (transfer == it->transfer && sender->next_acked == it->sequence_number) { 204 if (transfer == it->transfer && sender->next_acked == it->sequence_number) {
202 ack_time = it->ack_time.Subtract(clock_->Now()); 205 ack_time = it->ack_time.Subtract(clock_->Now());
203 } 206 }
204 } 207 }
205 // If only one packet is acked, simulate a delayed ack. 208 // If only one packet is acked, simulate a delayed ack.
206 if (!ack_time.IsInfinite() && transfer->bytes_in_flight == kPacketSize) { 209 if (!ack_time.IsInfinite() && transfer->bytes_in_flight == kPacketSize) {
207 ack_time = ack_time.Add(QuicTime::Delta::FromMilliseconds(100)); 210 ack_time = ack_time.Add(QuicTime::Delta::FromMilliseconds(100));
208 } 211 }
209 DVLOG(1) << "FindNextAcked found next_acked_:" 212 DVLOG(1) << "FindNextAcked found next_acked_:"
210 << transfer->sender->next_acked 213 << transfer->sender->next_acked
211 << " last_acked:" << transfer->sender->last_acked 214 << " last_acked:" << transfer->sender->last_acked
212 << " ack_time(ms):" << ack_time.ToMilliseconds(); 215 << " ack_time(ms):" << ack_time.ToMilliseconds();
213 return ack_time; 216 return ack_time;
214 } 217 }
215 218
216 void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) { 219 void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) {
217 Sender* sender = transfer->sender; 220 Sender* sender = transfer->sender;
218 DCHECK_LT(sender->last_acked, sender->next_acked); 221 DCHECK_LT(sender->last_acked, sender->next_acked);
219 SendAlgorithmInterface::CongestionMap acked_packets; 222 SendAlgorithmInterface::CongestionMap acked_packets;
220 SendAlgorithmInterface::CongestionMap lost_packets; 223 SendAlgorithmInterface::CongestionMap lost_packets;
221 // Some entries may be missing from the sent_packets_ array, if they were 224 // Some entries may be missing from the sent_packets_ array, if they were
222 // dropped due to buffer overruns. 225 // dropped due to buffer overruns.
223 SentPacket largest_observed = sent_packets_.front(); 226 SentPacket largest_observed(0, QuicTime::Zero(), QuicTime::Zero(), NULL);
227 list<SentPacket>::iterator it = sent_packets_.begin();
224 while (sender->last_acked < sender->next_acked) { 228 while (sender->last_acked < sender->next_acked) {
225 ++sender->last_acked; 229 ++sender->last_acked;
226 TransmissionInfo info = TransmissionInfo(); 230 TransmissionInfo info = TransmissionInfo();
227 info.bytes_sent = kPacketSize; 231 info.bytes_sent = kPacketSize;
228 info.in_flight = true; 232 info.in_flight = true;
233 // Find the next SentPacket for this transfer.
234 while (it->transfer != transfer) {
235 DCHECK(it != sent_packets_.end());
236 ++it;
237 }
229 // If it's missing from the array, it's a loss. 238 // If it's missing from the array, it's a loss.
230 if (sent_packets_.front().sequence_number > sender->last_acked) { 239 if (it->sequence_number > sender->last_acked) {
231 DVLOG(1) << "Lost packet:" << sender->last_acked 240 DVLOG(1) << "Lost packet:" << sender->last_acked
232 << " dropped by buffer overflow."; 241 << " dropped by buffer overflow.";
233 lost_packets[sender->last_acked] = info; 242 lost_packets[sender->last_acked] = info;
234 continue; 243 continue;
235 } 244 }
236 if (sent_packets_.front().ack_time.IsInitialized()) { 245 if (it->ack_time.IsInitialized()) {
237 acked_packets[sender->last_acked] = info; 246 acked_packets[sender->last_acked] = info;
238 } else { 247 } else {
239 lost_packets[sender->last_acked] = info; 248 lost_packets[sender->last_acked] = info;
240 } 249 }
241 // Remove all packets from the front to next_acked_. 250 // This packet has been acked or lost, remove it from sent_packets_.
242 largest_observed = sent_packets_.front(); 251 largest_observed = *it;
243 sent_packets_.pop_front(); 252 sent_packets_.erase(it++);
244 } 253 }
245 254
246 DCHECK(largest_observed.ack_time.IsInitialized()); 255 DCHECK(largest_observed.ack_time.IsInitialized());
256 DVLOG(1) << "Updating RTT from send_time:"
257 << largest_observed.send_time.ToDebuggingValue() << " to ack_time:"
258 << largest_observed.ack_time.ToDebuggingValue();
247 sender->rtt_stats->UpdateRtt( 259 sender->rtt_stats->UpdateRtt(
248 largest_observed.ack_time.Subtract(largest_observed.send_time), 260 largest_observed.ack_time.Subtract(largest_observed.send_time),
249 QuicTime::Delta::Zero(), 261 QuicTime::Delta::Zero(),
250 clock_->Now()); 262 clock_->Now());
251 sender->send_algorithm->OnCongestionEvent( 263 sender->send_algorithm->OnCongestionEvent(
252 true, transfer->bytes_in_flight, acked_packets, lost_packets); 264 true, transfer->bytes_in_flight, acked_packets, lost_packets);
253 DCHECK_LE(kPacketSize * (acked_packets.size() + lost_packets.size()), 265 DCHECK_LE(kPacketSize * (acked_packets.size() + lost_packets.size()),
254 transfer->bytes_in_flight); 266 transfer->bytes_in_flight);
255 transfer->bytes_in_flight -= 267 transfer->bytes_in_flight -=
256 kPacketSize * (acked_packets.size() + lost_packets.size()); 268 kPacketSize * (acked_packets.size() + lost_packets.size());
257 269
258 sender->RecordStats(); 270 sender->RecordStats();
259 transfer->bytes_acked += acked_packets.size() * kPacketSize; 271 transfer->bytes_acked += acked_packets.size() * kPacketSize;
272 transfer->bytes_lost += lost_packets.size() * kPacketSize;
260 if (transfer->bytes_acked >= transfer->num_bytes) { 273 if (transfer->bytes_acked >= transfer->num_bytes) {
261 // Remove completed transfers and record transfer bandwidth. 274 // Remove completed transfers and record transfer bandwidth.
262 QuicTime::Delta transfer_time = 275 QuicTime::Delta transfer_time =
263 clock_->Now().Subtract(transfer->start_time); 276 clock_->Now().Subtract(transfer->start_time);
277 sender->last_transfer_loss_rate = static_cast<float>(transfer->bytes_lost) /
278 (transfer->bytes_lost + transfer->bytes_acked);
264 sender->last_transfer_bandwidth = 279 sender->last_transfer_bandwidth =
265 QuicBandwidth::FromBytesAndTimeDelta(transfer->num_bytes, 280 QuicBandwidth::FromBytesAndTimeDelta(transfer->num_bytes,
266 transfer_time); 281 transfer_time);
267 for (vector<Transfer>::iterator it = pending_transfers_.begin(); 282 for (vector<Transfer>::iterator it = pending_transfers_.begin();
268 it != pending_transfers_.end(); ++it) { 283 it != pending_transfers_.end(); ++it) {
269 if (transfer == &(*it)) { 284 if (transfer == &(*it)) {
270 pending_transfers_.erase(it); 285 pending_transfers_.erase(it);
271 break; 286 break;
272 } 287 }
273 } 288 }
(...skipping 23 matching lines...) Expand all
297 DVLOG(1) << "losing packet:" << sender->last_sent 312 DVLOG(1) << "losing packet:" << sender->last_sent
298 << " due to random loss."; 313 << " due to random loss.";
299 314
300 QuicTime ack_time = clock_->Now().Add(rtt_); 315 QuicTime ack_time = clock_->Now().Add(rtt_);
301 // If the number of bytes in flight are less than the bdp, there's 316 // If the number of bytes in flight are less than the bdp, there's
302 // no buffering delay. Bytes lost from the buffer are not counted. 317 // no buffering delay. Bytes lost from the buffer are not counted.
303 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_); 318 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_);
304 if ((sent_packets_.size() + 1) * kPacketSize > bdp) { 319 if ((sent_packets_.size() + 1) * kPacketSize > bdp) {
305 QuicByteCount qsize = (sent_packets_.size() + 1) * kPacketSize - bdp; 320 QuicByteCount qsize = (sent_packets_.size() + 1) * kPacketSize - bdp;
306 ack_time = ack_time.Add(bandwidth_.TransferTime(qsize)); 321 ack_time = ack_time.Add(bandwidth_.TransferTime(qsize));
322 DVLOG(1) << "Increasing transfer time:"
323 << bandwidth_.TransferTime(qsize).ToMilliseconds()
324 << "ms due to qsize:" << qsize;
307 } 325 }
308 // If the packet is lost, give it an ack time of Zero. 326 // If the packet is lost, give it an ack time of Zero.
309 sent_packets_.push_back(SentPacket( 327 sent_packets_.push_back(SentPacket(
310 sender->last_sent, clock_->Now(), 328 sender->last_sent, clock_->Now(),
311 packet_lost ? QuicTime::Zero() : ack_time, transfer)); 329 packet_lost ? QuicTime::Zero() : ack_time, transfer));
312 } else { 330 } else {
313 DVLOG(1) << "losing packet:" << sender->last_sent 331 DVLOG(1) << "losing packet:" << sender->last_sent
314 << " because the buffer was full."; 332 << " because the buffer was full.";
315 } 333 }
316 transfer->bytes_in_flight += kPacketSize; 334 transfer->bytes_in_flight += kPacketSize;
317 } 335 }
318 336
319 // Advance the time by |delta| without sending anything. 337 // Advance the time by |delta| without sending anything.
320 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) { 338 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) {
321 clock_->AdvanceTime(delta); 339 clock_->AdvanceTime(delta);
322 } 340 }
323 341
324 } // namespace net 342 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/congestion_control/send_algorithm_simulator.h ('k') | net/quic/congestion_control/tcp_cubic_sender.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698