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

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

Issue 447093004: Land Recent QUIC Changes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fixed indenation in QuicFramer.cc Created 6 years, 4 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
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 30 matching lines...) Expand all
41 MockClock* clock, 41 MockClock* clock,
42 QuicBandwidth bandwidth, 42 QuicBandwidth bandwidth,
43 QuicTime::Delta rtt) 43 QuicTime::Delta rtt)
44 : clock_(clock), 44 : clock_(clock),
45 lose_next_ack_(false), 45 lose_next_ack_(false),
46 forward_loss_rate_(0), 46 forward_loss_rate_(0),
47 reverse_loss_rate_(0), 47 reverse_loss_rate_(0),
48 loss_correlation_(0), 48 loss_correlation_(0),
49 bandwidth_(bandwidth), 49 bandwidth_(bandwidth),
50 rtt_(rtt), 50 rtt_(rtt),
51 buffer_size_(1000000) { 51 buffer_size_(1000000),
52 delayed_ack_timer_(QuicTime::Delta::FromMilliseconds(100)) {
52 uint32 seed = base::RandInt(0, std::numeric_limits<int32>::max()); 53 uint32 seed = base::RandInt(0, std::numeric_limits<int32>::max());
53 DVLOG(1) << "Seeding SendAlgorithmSimulator with " << seed; 54 DVLOG(1) << "Seeding SendAlgorithmSimulator with " << seed;
54 simple_random_.set_seed(seed); 55 simple_random_.set_seed(seed);
55 } 56 }
56 57
57 SendAlgorithmSimulator::~SendAlgorithmSimulator() {} 58 SendAlgorithmSimulator::~SendAlgorithmSimulator() {}
58 59
59 void SendAlgorithmSimulator::AddTransfer(Sender* sender, size_t num_bytes) { 60 void SendAlgorithmSimulator::AddTransfer(Sender* sender, size_t num_bytes) {
60 AddTransfer(sender, num_bytes, clock_->Now()); 61 AddTransfer(sender, num_bytes, clock_->Now());
61 } 62 }
(...skipping 23 matching lines...) Expand all
85 PacketEvent ack_event = NextAckEvent(); 86 PacketEvent ack_event = NextAckEvent();
86 // If both times are infinite, fire a TLP. 87 // If both times are infinite, fire a TLP.
87 if (ack_event.time_delta.IsInfinite() && 88 if (ack_event.time_delta.IsInfinite() &&
88 send_event.time_delta.IsInfinite()) { 89 send_event.time_delta.IsInfinite()) {
89 DVLOG(1) << "Both times are infinite, simulating a TLP."; 90 DVLOG(1) << "Both times are infinite, simulating a TLP.";
90 // TODO(ianswett): Use a more sophisticated TLP timer or never lose 91 // TODO(ianswett): Use a more sophisticated TLP timer or never lose
91 // the last ack? 92 // the last ack?
92 clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(100)); 93 clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
93 SendDataNow(&pending_transfers_.front()); 94 SendDataNow(&pending_transfers_.front());
94 } else if (ack_event.time_delta < send_event.time_delta) { 95 } else if (ack_event.time_delta < send_event.time_delta) {
95 DVLOG(1) << "Handling ack, advancing time:" 96 DVLOG(1) << "Handling ack of largest observed:"
97 << ack_event.transfer->sender->next_acked << ", advancing time:"
96 << ack_event.time_delta.ToMicroseconds() << "us"; 98 << ack_event.time_delta.ToMicroseconds() << "us";
97 // Ack data all the data up to ack time and lose any missing sequence 99 // Ack data all the data up to ack time and lose any missing sequence
98 // numbers. 100 // numbers.
99 clock_->AdvanceTime(ack_event.time_delta); 101 clock_->AdvanceTime(ack_event.time_delta);
100 HandlePendingAck(ack_event.transfer); 102 HandlePendingAck(ack_event.transfer);
101 } else { 103 } else {
102 DVLOG(1) << "Sending, advancing time:" 104 DVLOG(1) << "Sending, advancing time:"
103 << send_event.time_delta.ToMicroseconds() << "us"; 105 << send_event.time_delta.ToMicroseconds() << "us";
104 clock_->AdvanceTime(send_event.time_delta); 106 clock_->AdvanceTime(send_event.time_delta);
105 SendDataNow(send_event.transfer); 107 SendDataNow(send_event.transfer);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 return PacketEvent(ack_time, transfer); 160 return PacketEvent(ack_time, transfer);
159 } 161 }
160 162
161 QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) { 163 QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) {
162 Sender* sender = transfer->sender; 164 Sender* sender = transfer->sender;
163 if (sender->next_acked == sender->last_acked) { 165 if (sender->next_acked == sender->last_acked) {
164 // Determine if the next ack is lost only once, to ensure determinism. 166 // Determine if the next ack is lost only once, to ensure determinism.
165 lose_next_ack_ = 167 lose_next_ack_ =
166 reverse_loss_rate_ * kuint64max > simple_random_.RandUint64(); 168 reverse_loss_rate_ * kuint64max > simple_random_.RandUint64();
167 } 169 }
168 bool two_acks_remaining = lose_next_ack_; 170
169 sender->next_acked = sender->last_acked; 171 QuicPacketSequenceNumber next_acked = sender->last_acked;
170 bool packets_lost = false; 172 QuicTime::Delta next_ack_delay =
173 FindNextAck(transfer, sender->last_acked, &next_acked);
174 if (lose_next_ack_) {
175 next_ack_delay = FindNextAck(transfer, next_acked, &next_acked);
176 }
177 sender->next_acked = next_acked;
178 return next_ack_delay;
179 }
180
181 QuicTime::Delta SendAlgorithmSimulator::FindNextAck(
182 const Transfer* transfer,
183 QuicPacketSequenceNumber last_acked,
184 QuicPacketSequenceNumber* next_acked) const {
185 *next_acked = last_acked;
186 QuicTime::Delta ack_delay = QuicTime::Delta::Infinite();
171 // Remove any packets that are simulated as lost. 187 // Remove any packets that are simulated as lost.
172 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); 188 for (list<SentPacket>::const_iterator it = sent_packets_.begin();
173 it != sent_packets_.end(); ++it) { 189 it != sent_packets_.end(); ++it) {
174 if (transfer != it->transfer) { 190 if (transfer != it->transfer) {
175 continue; 191 continue;
176 } 192 }
177 193 // Skip over any packets less than or equal to last_acked.
194 if (it->sequence_number <= last_acked) {
195 continue;
196 }
178 // Lost packets don't trigger an ack. 197 // Lost packets don't trigger an ack.
179 if (it->ack_time == QuicTime::Zero()) { 198 if (it->ack_time == QuicTime::Zero()) {
180 packets_lost = true;
181 continue; 199 continue;
182 } 200 }
201 DCHECK_LT(*next_acked, it->sequence_number);
202 // Consider a delayed ack for the current next_acked.
203 if (ack_delay < it->ack_time.Subtract(clock_->Now())) {
204 break;
205 }
206 *next_acked = it->sequence_number;
207 ack_delay = it->ack_time.Subtract(clock_->Now());
208 if (HasRecentLostPackets(transfer, *next_acked) ||
209 (*next_acked - last_acked) >= 2) {
210 break;
211 }
212 ack_delay = ack_delay.Add(delayed_ack_timer_);
213 }
214
215 DVLOG(1) << "FindNextAcked found next_acked_:"
216 << transfer->sender->next_acked
217 << " last_acked:" << transfer->sender->last_acked
218 << " ack_delay(ms):" << ack_delay.ToMilliseconds();
219 return ack_delay;
220 }
221
222 bool SendAlgorithmSimulator::HasRecentLostPackets(
223 const Transfer* transfer, QuicPacketSequenceNumber next_acked) const {
224 QuicPacketSequenceNumber last_packet = transfer->sender->last_acked;
225 for (list<SentPacket>::const_iterator it = sent_packets_.begin();
226 it != sent_packets_.end() && it->sequence_number < next_acked; ++it) {
227 if (transfer != it->transfer) {
228 continue;
229 }
230 // Lost packets don't trigger an ack.
231 if (it->ack_time == QuicTime::Zero()) {
232 return true;
233 }
183 // Buffer dropped packets are skipped automatically, but still end up 234 // Buffer dropped packets are skipped automatically, but still end up
184 // being lost and cause acks to be sent immediately. 235 // being lost and cause acks to be sent immediately.
185 if (sender->next_acked < it->sequence_number - 1) { 236 if (it->sequence_number > last_packet + 1) {
186 packets_lost = true; 237 return true;
187 } 238 }
188 DCHECK_LT(sender->next_acked, it->sequence_number); 239 last_packet = it->sequence_number;
189 sender->next_acked = it->sequence_number;
190 if (packets_lost || (sender->next_acked - sender->last_acked) % 2 == 0) {
191 if (two_acks_remaining) {
192 two_acks_remaining = false;
193 } else {
194 break;
195 }
196 }
197 } 240 }
198 // If the connection has no packets to be acked, return Infinite. 241 return false;
199 if (sender->next_acked == sender->last_acked) {
200 return QuicTime::Delta::Infinite();
201 }
202
203 QuicTime::Delta ack_time = QuicTime::Delta::Infinite();
204 for (list<SentPacket>::const_iterator it = sent_packets_.begin();
205 it != sent_packets_.end(); ++it) {
206 if (transfer == it->transfer && sender->next_acked == it->sequence_number) {
207 ack_time = it->ack_time.Subtract(clock_->Now());
208 }
209 }
210 // If only one packet is acked, simulate a delayed ack.
211 if (!ack_time.IsInfinite() && transfer->bytes_in_flight == kPacketSize) {
212 ack_time = ack_time.Add(QuicTime::Delta::FromMilliseconds(100));
213 }
214 DVLOG(1) << "FindNextAcked found next_acked_:"
215 << transfer->sender->next_acked
216 << " last_acked:" << transfer->sender->last_acked
217 << " ack_time(ms):" << ack_time.ToMilliseconds();
218 return ack_time;
219 } 242 }
220 243
221 void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) { 244 void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) {
222 Sender* sender = transfer->sender; 245 Sender* sender = transfer->sender;
223 DCHECK_LT(sender->last_acked, sender->next_acked); 246 DCHECK_LT(sender->last_acked, sender->next_acked);
224 SendAlgorithmInterface::CongestionMap acked_packets; 247 SendAlgorithmInterface::CongestionMap acked_packets;
225 SendAlgorithmInterface::CongestionMap lost_packets; 248 SendAlgorithmInterface::CongestionMap lost_packets;
249 DVLOG(1) << "Acking packets from:" << sender->last_acked
250 << " to " << sender->next_acked
251 << " bytes_in_flight:" << transfer->bytes_in_flight
252 << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms";
226 // Some entries may be missing from the sent_packets_ array, if they were 253 // Some entries may be missing from the sent_packets_ array, if they were
227 // dropped due to buffer overruns. 254 // dropped due to buffer overruns.
228 SentPacket largest_observed(0, QuicTime::Zero(), QuicTime::Zero(), NULL); 255 SentPacket largest_observed(0, QuicTime::Zero(), QuicTime::Zero(), NULL);
229 list<SentPacket>::iterator it = sent_packets_.begin(); 256 list<SentPacket>::iterator it = sent_packets_.begin();
230 while (sender->last_acked < sender->next_acked) { 257 while (sender->last_acked < sender->next_acked) {
231 ++sender->last_acked; 258 ++sender->last_acked;
232 TransmissionInfo info = TransmissionInfo(); 259 TransmissionInfo info = TransmissionInfo();
233 info.bytes_sent = kPacketSize; 260 info.bytes_sent = kPacketSize;
234 info.in_flight = true; 261 info.in_flight = true;
235 // Find the next SentPacket for this transfer. 262 // Find the next SentPacket for this transfer.
(...skipping 15 matching lines...) Expand all
251 } 278 }
252 // This packet has been acked or lost, remove it from sent_packets_. 279 // This packet has been acked or lost, remove it from sent_packets_.
253 largest_observed = *it; 280 largest_observed = *it;
254 sent_packets_.erase(it++); 281 sent_packets_.erase(it++);
255 } 282 }
256 283
257 DCHECK(largest_observed.ack_time.IsInitialized()); 284 DCHECK(largest_observed.ack_time.IsInitialized());
258 DVLOG(1) << "Updating RTT from send_time:" 285 DVLOG(1) << "Updating RTT from send_time:"
259 << largest_observed.send_time.ToDebuggingValue() << " to ack_time:" 286 << largest_observed.send_time.ToDebuggingValue() << " to ack_time:"
260 << largest_observed.ack_time.ToDebuggingValue(); 287 << largest_observed.ack_time.ToDebuggingValue();
261 sender->rtt_stats->UpdateRtt( 288 QuicTime::Delta measured_rtt =
262 largest_observed.ack_time.Subtract(largest_observed.send_time), 289 largest_observed.ack_time.Subtract(largest_observed.send_time);
263 QuicTime::Delta::Zero(), 290 DCHECK_GE(measured_rtt.ToMicroseconds(), rtt_.ToMicroseconds());
264 clock_->Now()); 291 sender->rtt_stats->UpdateRtt(measured_rtt,
292 QuicTime::Delta::Zero(),
293 clock_->Now());
265 sender->send_algorithm->OnCongestionEvent( 294 sender->send_algorithm->OnCongestionEvent(
266 true, transfer->bytes_in_flight, acked_packets, lost_packets); 295 true, transfer->bytes_in_flight, acked_packets, lost_packets);
267 DCHECK_LE(kPacketSize * (acked_packets.size() + lost_packets.size()), 296 DCHECK_LE(kPacketSize * (acked_packets.size() + lost_packets.size()),
268 transfer->bytes_in_flight); 297 transfer->bytes_in_flight);
269 transfer->bytes_in_flight -= 298 transfer->bytes_in_flight -=
270 kPacketSize * (acked_packets.size() + lost_packets.size()); 299 kPacketSize * (acked_packets.size() + lost_packets.size());
271 300
272 sender->RecordStats(); 301 sender->RecordStats();
273 transfer->bytes_acked += acked_packets.size() * kPacketSize; 302 transfer->bytes_acked += acked_packets.size() * kPacketSize;
274 transfer->bytes_lost += lost_packets.size() * kPacketSize; 303 transfer->bytes_lost += lost_packets.size() * kPacketSize;
(...skipping 13 matching lines...) Expand all
288 break; 317 break;
289 } 318 }
290 } 319 }
291 } 320 }
292 } 321 }
293 322
294 void SendAlgorithmSimulator::SendDataNow(Transfer* transfer) { 323 void SendAlgorithmSimulator::SendDataNow(Transfer* transfer) {
295 Sender* sender = transfer->sender; 324 Sender* sender = transfer->sender;
296 ++sender->last_sent; 325 ++sender->last_sent;
297 DVLOG(1) << "Sending packet:" << sender->last_sent 326 DVLOG(1) << "Sending packet:" << sender->last_sent
298 << " bytes_in_flight:" << transfer->bytes_in_flight; 327 << " bytes_in_flight:" << transfer->bytes_in_flight
328 << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms";
299 sender->send_algorithm->OnPacketSent( 329 sender->send_algorithm->OnPacketSent(
300 clock_->Now(), transfer->bytes_in_flight, 330 clock_->Now(), transfer->bytes_in_flight,
301 sender->last_sent, kPacketSize, HAS_RETRANSMITTABLE_DATA); 331 sender->last_sent, kPacketSize, HAS_RETRANSMITTABLE_DATA);
302 // Lose the packet immediately if the buffer is full. 332 // Lose the packet immediately if the buffer is full.
303 if (sent_packets_.size() * kPacketSize < buffer_size_) { 333 if (sent_packets_.size() * kPacketSize < buffer_size_) {
304 // TODO(ianswett): This buffer simulation is an approximation. 334 // TODO(ianswett): This buffer simulation is an approximation.
305 // An ack time of zero means loss. 335 // An ack time of zero means loss.
306 bool packet_lost = 336 bool packet_lost =
307 forward_loss_rate_ * kuint64max > simple_random_.RandUint64(); 337 forward_loss_rate_ * kuint64max > simple_random_.RandUint64();
308 // Handle correlated loss. 338 // Handle correlated loss.
309 if (!sent_packets_.empty() && 339 if (!sent_packets_.empty() &&
310 !sent_packets_.back().ack_time.IsInitialized() && 340 !sent_packets_.back().ack_time.IsInitialized() &&
311 loss_correlation_ * kuint64max > simple_random_.RandUint64()) { 341 loss_correlation_ * kuint64max > simple_random_.RandUint64()) {
312 packet_lost = true; 342 packet_lost = true;
313 } 343 }
314 DVLOG(1) << "losing packet:" << sender->last_sent 344 DVLOG(1) << "losing packet:" << sender->last_sent
315 << " due to random loss."; 345 << " due to random loss.";
316 346
317 QuicTime ack_time = clock_->Now().Add(rtt_);
318 // If the number of bytes in flight are less than the bdp, there's 347 // If the number of bytes in flight are less than the bdp, there's
319 // no buffering delay. Bytes lost from the buffer are not counted. 348 // no buffering delay. Bytes lost from the buffer are not counted.
320 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_); 349 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_);
321 if ((sent_packets_.size() + 1) * kPacketSize > bdp) { 350 QuicTime ack_time = clock_->Now().Add(rtt_);
322 QuicByteCount qsize = (sent_packets_.size() + 1) * kPacketSize - bdp; 351 if (kPacketSize > bdp) {
323 ack_time = ack_time.Add(bandwidth_.TransferTime(qsize)); 352 ack_time = ack_time.Add(bandwidth_.TransferTime(kPacketSize - bdp));
324 DVLOG(1) << "Increasing transfer time:"
325 << bandwidth_.TransferTime(qsize).ToMilliseconds()
326 << "ms due to qsize:" << qsize;
327 } 353 }
354 QuicTime queue_ack_time = sent_packets_.empty() ? QuicTime::Zero() :
355 sent_packets_.back().ack_time.Add(bandwidth_.TransferTime(kPacketSize));
356 ack_time = QuicTime::Max(ack_time, queue_ack_time);
328 // If the packet is lost, give it an ack time of Zero. 357 // If the packet is lost, give it an ack time of Zero.
329 sent_packets_.push_back(SentPacket( 358 sent_packets_.push_back(SentPacket(
330 sender->last_sent, clock_->Now(), 359 sender->last_sent, clock_->Now(),
331 packet_lost ? QuicTime::Zero() : ack_time, transfer)); 360 packet_lost ? QuicTime::Zero() : ack_time, transfer));
332 } else { 361 } else {
333 DVLOG(1) << "losing packet:" << sender->last_sent 362 DVLOG(1) << "losing packet:" << sender->last_sent
334 << " because the buffer was full."; 363 << " because the buffer was full.";
335 } 364 }
336 transfer->bytes_in_flight += kPacketSize; 365 transfer->bytes_in_flight += kPacketSize;
337 } 366 }
338 367
339 // Advance the time by |delta| without sending anything. 368 // Advance the time by |delta| without sending anything.
340 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) { 369 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) {
341 clock_->AdvanceTime(delta); 370 clock_->AdvanceTime(delta);
342 } 371 }
343 372
344 } // namespace net 373 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/congestion_control/send_algorithm_simulator.h ('k') | net/quic/congestion_control/tcp_cubic_sender.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698