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