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 |