| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |