| 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 <stdint.h> |
| 8 |
| 7 #include <limits> | 9 #include <limits> |
| 8 | 10 |
| 9 #include "base/logging.h" | 11 #include "base/logging.h" |
| 10 #include "base/rand_util.h" | 12 #include "base/rand_util.h" |
| 11 #include "net/quic/crypto/quic_random.h" | 13 #include "net/quic/crypto/quic_random.h" |
| 12 | 14 |
| 13 using std::list; | 15 using std::list; |
| 14 using std::max; | 16 using std::max; |
| 15 using std::min; | 17 using std::min; |
| 16 using std::string; | 18 using std::string; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 QuicTime::Delta rtt) | 64 QuicTime::Delta rtt) |
| 63 : clock_(clock), | 65 : clock_(clock), |
| 64 lose_next_ack_(false), | 66 lose_next_ack_(false), |
| 65 forward_loss_rate_(0), | 67 forward_loss_rate_(0), |
| 66 reverse_loss_rate_(0), | 68 reverse_loss_rate_(0), |
| 67 loss_correlation_(0), | 69 loss_correlation_(0), |
| 68 bandwidth_(bandwidth), | 70 bandwidth_(bandwidth), |
| 69 rtt_(rtt), | 71 rtt_(rtt), |
| 70 buffer_size_(1000000), | 72 buffer_size_(1000000), |
| 71 delayed_ack_timer_(QuicTime::Delta::FromMilliseconds(100)) { | 73 delayed_ack_timer_(QuicTime::Delta::FromMilliseconds(100)) { |
| 72 uint32 seed = base::RandInt(0, std::numeric_limits<int32>::max()); | 74 uint32_t seed = base::RandInt(0, std::numeric_limits<int32_t>::max()); |
| 73 DVLOG(1) << "Seeding SendAlgorithmSimulator with " << seed; | 75 DVLOG(1) << "Seeding SendAlgorithmSimulator with " << seed; |
| 74 simple_random_.set_seed(seed); | 76 simple_random_.set_seed(seed); |
| 75 } | 77 } |
| 76 | 78 |
| 77 SendAlgorithmSimulator::~SendAlgorithmSimulator() {} | 79 SendAlgorithmSimulator::~SendAlgorithmSimulator() {} |
| 78 | 80 |
| 79 void SendAlgorithmSimulator::AddTransfer(Sender* sender, size_t num_bytes) { | 81 void SendAlgorithmSimulator::AddTransfer(Sender* sender, size_t num_bytes) { |
| 80 AddTransfer(sender, num_bytes, clock_->Now(), | 82 AddTransfer(sender, num_bytes, clock_->Now(), |
| 81 StringPrintf("#%zu", pending_transfers_.size())); | 83 StringPrintf("#%zu", pending_transfers_.size())); |
| 82 } | 84 } |
| 83 | 85 |
| 84 void SendAlgorithmSimulator::AddTransfer( | 86 void SendAlgorithmSimulator::AddTransfer( |
| 85 Sender* sender, size_t num_bytes, QuicTime start_time, string name) { | 87 Sender* sender, size_t num_bytes, QuicTime start_time, string name) { |
| 86 pending_transfers_.push_back(Transfer(sender, num_bytes, start_time, name)); | 88 pending_transfers_.push_back(Transfer(sender, num_bytes, start_time, name)); |
| 87 // Record initial stats from when the transfer begins. | 89 // Record initial stats from when the transfer begins. |
| 88 pending_transfers_.back().sender->RecordStats(); | 90 pending_transfers_.back().sender->RecordStats(); |
| 89 } | 91 } |
| 90 | 92 |
| 91 void SendAlgorithmSimulator::TransferBytes() { | 93 void SendAlgorithmSimulator::TransferBytes() { |
| 92 TransferBytes(kuint64max, QuicTime::Delta::Infinite()); | 94 TransferBytes(std::numeric_limits<uint64_t>::max(), |
| 95 QuicTime::Delta::Infinite()); |
| 93 } | 96 } |
| 94 | 97 |
| 95 void SendAlgorithmSimulator::TransferBytes(QuicByteCount max_bytes, | 98 void SendAlgorithmSimulator::TransferBytes(QuicByteCount max_bytes, |
| 96 QuicTime::Delta max_time) { | 99 QuicTime::Delta max_time) { |
| 97 const QuicTime end_time = max_time.IsInfinite() ? | 100 const QuicTime end_time = max_time.IsInfinite() ? |
| 98 QuicTime::Zero().Add(QuicTime::Delta::Infinite()) : | 101 QuicTime::Zero().Add(QuicTime::Delta::Infinite()) : |
| 99 clock_->Now().Add(max_time); | 102 clock_->Now().Add(max_time); |
| 100 QuicByteCount bytes_sent = 0; | 103 QuicByteCount bytes_sent = 0; |
| 101 while (!pending_transfers_.empty() && | 104 while (!pending_transfers_.empty() && |
| 102 clock_->Now() < end_time && | 105 clock_->Now() < end_time && |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 } | 182 } |
| 180 } | 183 } |
| 181 | 184 |
| 182 return PacketEvent(ack_time, transfer); | 185 return PacketEvent(ack_time, transfer); |
| 183 } | 186 } |
| 184 | 187 |
| 185 QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) { | 188 QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) { |
| 186 Sender* sender = transfer->sender; | 189 Sender* sender = transfer->sender; |
| 187 if (sender->next_acked == sender->last_acked) { | 190 if (sender->next_acked == sender->last_acked) { |
| 188 // Determine if the next ack is lost only once, to ensure determinism. | 191 // Determine if the next ack is lost only once, to ensure determinism. |
| 189 lose_next_ack_ = | 192 lose_next_ack_ = reverse_loss_rate_ * std::numeric_limits<uint64_t>::max() > |
| 190 reverse_loss_rate_ * kuint64max > simple_random_.RandUint64(); | 193 simple_random_.RandUint64(); |
| 191 } | 194 } |
| 192 | 195 |
| 193 QuicPacketNumber next_acked = sender->last_acked; | 196 QuicPacketNumber next_acked = sender->last_acked; |
| 194 QuicTime::Delta next_ack_delay = | 197 QuicTime::Delta next_ack_delay = |
| 195 FindNextAck(transfer, sender->last_acked, &next_acked); | 198 FindNextAck(transfer, sender->last_acked, &next_acked); |
| 196 if (lose_next_ack_) { | 199 if (lose_next_ack_) { |
| 197 next_ack_delay = FindNextAck(transfer, next_acked, &next_acked); | 200 next_ack_delay = FindNextAck(transfer, next_acked, &next_acked); |
| 198 } | 201 } |
| 199 sender->next_acked = next_acked; | 202 sender->next_acked = next_acked; |
| 200 return next_ack_delay; | 203 return next_ack_delay; |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 << " cwnd:" << sender->send_algorithm->GetCongestionWindow() | 353 << " cwnd:" << sender->send_algorithm->GetCongestionWindow() |
| 351 << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms"; | 354 << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms"; |
| 352 sender->send_algorithm->OnPacketSent( | 355 sender->send_algorithm->OnPacketSent( |
| 353 clock_->Now(), transfer->bytes_in_flight, | 356 clock_->Now(), transfer->bytes_in_flight, |
| 354 sender->last_sent, kPacketSize, HAS_RETRANSMITTABLE_DATA); | 357 sender->last_sent, kPacketSize, HAS_RETRANSMITTABLE_DATA); |
| 355 // Lose the packet immediately if the buffer is full. | 358 // Lose the packet immediately if the buffer is full. |
| 356 if (sent_packets_.size() * kPacketSize < buffer_size_) { | 359 if (sent_packets_.size() * kPacketSize < buffer_size_) { |
| 357 // TODO(ianswett): This buffer simulation is an approximation. | 360 // TODO(ianswett): This buffer simulation is an approximation. |
| 358 // An ack time of zero means loss. | 361 // An ack time of zero means loss. |
| 359 bool packet_lost = | 362 bool packet_lost = |
| 360 forward_loss_rate_ * kuint64max > simple_random_.RandUint64(); | 363 forward_loss_rate_ * std::numeric_limits<uint64_t>::max() > |
| 364 simple_random_.RandUint64(); |
| 361 // Handle correlated loss. | 365 // Handle correlated loss. |
| 362 if (!sent_packets_.empty() && sent_packets_.back().lost && | 366 if (!sent_packets_.empty() && sent_packets_.back().lost && |
| 363 loss_correlation_ * kuint64max > simple_random_.RandUint64()) { | 367 loss_correlation_ * std::numeric_limits<uint64_t>::max() > |
| 368 simple_random_.RandUint64()) { |
| 364 packet_lost = true; | 369 packet_lost = true; |
| 365 } | 370 } |
| 366 DVLOG(1) << "losing packet:" << sender->last_sent | 371 DVLOG(1) << "losing packet:" << sender->last_sent |
| 367 << " name:" << transfer->name << " due to random loss."; | 372 << " name:" << transfer->name << " due to random loss."; |
| 368 | 373 |
| 369 // If the number of bytes in flight are less than the bdp, there's | 374 // If the number of bytes in flight are less than the bdp, there's |
| 370 // no buffering delay. Bytes lost from the buffer are not counted. | 375 // no buffering delay. Bytes lost from the buffer are not counted. |
| 371 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_); | 376 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_); |
| 372 QuicTime ack_time = clock_->Now().Add(rtt_).Add(sender->additional_rtt); | 377 QuicTime ack_time = clock_->Now().Add(rtt_).Add(sender->additional_rtt); |
| 373 if (kPacketSize > bdp) { | 378 if (kPacketSize > bdp) { |
| 374 ack_time = ack_time.Add(bandwidth_.TransferTime(kPacketSize - bdp)); | 379 ack_time = ack_time.Add(bandwidth_.TransferTime(kPacketSize - bdp)); |
| 375 } | 380 } |
| 376 QuicTime queue_ack_time = sent_packets_.empty() ? QuicTime::Zero() : | 381 QuicTime queue_ack_time = sent_packets_.empty() ? QuicTime::Zero() : |
| 377 sent_packets_.back().ack_time.Add(bandwidth_.TransferTime(kPacketSize)); | 382 sent_packets_.back().ack_time.Add(bandwidth_.TransferTime(kPacketSize)); |
| 378 ack_time = QuicTime::Max(ack_time, queue_ack_time); | 383 ack_time = QuicTime::Max(ack_time, queue_ack_time); |
| 379 sent_packets_.push_back(SentPacket( | 384 sent_packets_.push_back(SentPacket( |
| 380 sender->last_sent, clock_->Now(), ack_time, packet_lost, transfer)); | 385 sender->last_sent, clock_->Now(), ack_time, packet_lost, transfer)); |
| 381 } else { | 386 } else { |
| 382 DVLOG(1) << "losing packet:" << sender->last_sent | 387 DVLOG(1) << "losing packet:" << sender->last_sent |
| 383 << " name:" << transfer->name << " because the buffer was full."; | 388 << " name:" << transfer->name << " because the buffer was full."; |
| 384 } | 389 } |
| 385 transfer->bytes_in_flight += kPacketSize; | 390 transfer->bytes_in_flight += kPacketSize; |
| 386 } | 391 } |
| 387 | 392 |
| 388 } // namespace net | 393 } // namespace net |
| OLD | NEW |