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" |
11 #include "net/quic/crypto/quic_random.h" | 11 #include "net/quic/crypto/quic_random.h" |
12 | 12 |
13 using std::list; | 13 using std::list; |
14 using std::max; | 14 using std::max; |
15 using std::min; | 15 using std::min; |
| 16 using std::vector; |
16 | 17 |
17 namespace net { | 18 namespace net { |
18 | 19 |
19 namespace { | 20 namespace { |
20 | 21 |
21 const QuicByteCount kPacketSize = 1200; | 22 const QuicByteCount kPacketSize = 1200; |
22 | 23 |
23 } // namespace | 24 } // namespace |
24 | 25 |
| 26 SendAlgorithmSimulator::Sender::Sender(SendAlgorithmInterface* send_algorithm, |
| 27 RttStats* rtt_stats) |
| 28 : send_algorithm(send_algorithm), |
| 29 rtt_stats(rtt_stats), |
| 30 last_sent(0), |
| 31 last_acked(0), |
| 32 next_acked(1), |
| 33 max_cwnd(0), |
| 34 min_cwnd(100000), |
| 35 max_cwnd_drop(0), |
| 36 last_cwnd(0), |
| 37 last_transfer_bandwidth(QuicBandwidth::Zero()) {} |
| 38 |
25 SendAlgorithmSimulator::SendAlgorithmSimulator( | 39 SendAlgorithmSimulator::SendAlgorithmSimulator( |
26 SendAlgorithmInterface* send_algorithm, | |
27 MockClock* clock, | 40 MockClock* clock, |
28 RttStats* rtt_stats, | |
29 QuicBandwidth bandwidth, | 41 QuicBandwidth bandwidth, |
30 QuicTime::Delta rtt) | 42 QuicTime::Delta rtt) |
31 : send_algorithm_(send_algorithm), | 43 : clock_(clock), |
32 clock_(clock), | |
33 rtt_stats_(rtt_stats), | |
34 next_sent_(1), | |
35 last_acked_(0), | |
36 next_acked_(1), | |
37 lose_next_ack_(false), | 44 lose_next_ack_(false), |
38 bytes_in_flight_(0), | |
39 forward_loss_rate_(0), | 45 forward_loss_rate_(0), |
40 reverse_loss_rate_(0), | 46 reverse_loss_rate_(0), |
41 loss_correlation_(0), | 47 loss_correlation_(0), |
42 bandwidth_(bandwidth), | 48 bandwidth_(bandwidth), |
43 rtt_(rtt), | 49 rtt_(rtt), |
44 buffer_size_(1000000), | 50 buffer_size_(1000000) { |
45 max_cwnd_(0), | |
46 min_cwnd_(100000), | |
47 max_cwnd_drop_(0), | |
48 last_cwnd_(0) { | |
49 uint32 seed = base::RandInt(0, std::numeric_limits<int32>::max()); | 51 uint32 seed = base::RandInt(0, std::numeric_limits<int32>::max()); |
50 DVLOG(1) << "Seeding SendAlgorithmSimulator with " << seed; | 52 DVLOG(1) << "Seeding SendAlgorithmSimulator with " << seed; |
51 simple_random_.set_seed(seed); | 53 simple_random_.set_seed(seed); |
52 } | 54 } |
53 | 55 |
54 SendAlgorithmSimulator::~SendAlgorithmSimulator() {} | 56 SendAlgorithmSimulator::~SendAlgorithmSimulator() {} |
55 | 57 |
56 // Sends the specified number of bytes as quickly as possible and returns the | 58 void SendAlgorithmSimulator::AddTransfer(Sender* sender, size_t num_bytes) { |
57 // average bandwidth in bytes per second. The time elapsed is based on | 59 AddTransfer(sender, num_bytes, clock_->Now()); |
58 // waiting for all acks to arrive. | 60 } |
59 QuicBandwidth SendAlgorithmSimulator::SendBytes(size_t num_bytes) { | 61 |
60 const QuicTime start_time = clock_->Now(); | 62 void SendAlgorithmSimulator::AddTransfer( |
61 size_t bytes_acked = 0; | 63 Sender* sender, size_t num_bytes, QuicTime start_time) { |
62 while (bytes_acked < num_bytes) { | 64 pending_transfers_.push_back(Transfer(sender, num_bytes, start_time)); |
63 DVLOG(1) << "bytes_acked:" << bytes_acked << " bytes_in_flight_:" | 65 // Record initial stats from when the transfer begins. |
64 << bytes_in_flight_ << " CWND(bytes):" | 66 pending_transfers_.back().sender->RecordStats(); |
65 << send_algorithm_->GetCongestionWindow(); | 67 } |
| 68 |
| 69 void SendAlgorithmSimulator::TransferBytes() { |
| 70 TransferBytes(kuint64max, QuicTime::Delta::Infinite()); |
| 71 } |
| 72 |
| 73 void SendAlgorithmSimulator::TransferBytes(QuicByteCount max_bytes, |
| 74 QuicTime::Delta max_time) { |
| 75 const QuicTime end_time = clock_->Now().Add(max_time); |
| 76 QuicByteCount bytes_sent = 0; |
| 77 while (!pending_transfers_.empty() && |
| 78 clock_->Now() < end_time && |
| 79 bytes_sent < max_bytes) { |
66 // Determine the times of next send and of the next ack arrival. | 80 // Determine the times of next send and of the next ack arrival. |
67 QuicTime::Delta send_delta = send_algorithm_->TimeUntilSend( | 81 PacketEvent send_event = NextSendEvent(); |
68 clock_->Now(), bytes_in_flight_, HAS_RETRANSMITTABLE_DATA); | 82 PacketEvent ack_event = NextAckEvent(); |
69 // If we've already sent enough bytes, wait for them to be acked. | |
70 if (bytes_acked + bytes_in_flight_ >= num_bytes) { | |
71 send_delta = QuicTime::Delta::Infinite(); | |
72 } | |
73 QuicTime::Delta ack_delta = NextAckDelta(); | |
74 // If both times are infinite, fire a TLP. | 83 // If both times are infinite, fire a TLP. |
75 if (ack_delta.IsInfinite() && send_delta.IsInfinite()) { | 84 if (ack_event.time_delta.IsInfinite() && |
| 85 send_event.time_delta.IsInfinite()) { |
76 DVLOG(1) << "Both times are infinite, simulating a TLP."; | 86 DVLOG(1) << "Both times are infinite, simulating a TLP."; |
77 // TODO(ianswett): Use a more sophisticated TLP timer. | 87 // TODO(ianswett): Use a more sophisticated TLP timer or never lose |
| 88 // the last ack? |
78 clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(100)); | 89 clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(100)); |
79 SendDataNow(); | 90 SendDataNow(&pending_transfers_.front()); |
80 } else if (ack_delta < send_delta) { | 91 } else if (ack_event.time_delta < send_event.time_delta) { |
81 DVLOG(1) << "Handling ack, advancing time:" | 92 DVLOG(1) << "Handling ack, advancing time:" |
82 << ack_delta.ToMicroseconds() << "us"; | 93 << ack_event.time_delta.ToMicroseconds() << "us"; |
83 // Ack data all the data up to ack time and lose any missing sequence | 94 // Ack data all the data up to ack time and lose any missing sequence |
84 // numbers. | 95 // numbers. |
85 clock_->AdvanceTime(ack_delta); | 96 clock_->AdvanceTime(ack_event.time_delta); |
86 bytes_acked += HandlePendingAck(); | 97 HandlePendingAck(ack_event.transfer); |
87 } else { | 98 } else { |
88 DVLOG(1) << "Sending, advancing time:" | 99 DVLOG(1) << "Sending, advancing time:" |
89 << send_delta.ToMicroseconds() << "us"; | 100 << send_event.time_delta.ToMicroseconds() << "us"; |
90 clock_->AdvanceTime(send_delta); | 101 clock_->AdvanceTime(send_event.time_delta); |
91 SendDataNow(); | 102 SendDataNow(send_event.transfer); |
| 103 bytes_sent += kPacketSize; |
92 } | 104 } |
93 RecordStats(); | |
94 } | 105 } |
95 return QuicBandwidth::FromBytesAndTimeDelta( | 106 } |
96 num_bytes, clock_->Now().Subtract(start_time)); | 107 |
| 108 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextSendEvent() { |
| 109 QuicTime::Delta send_time = QuicTime::Delta::Infinite(); |
| 110 Transfer* transfer = NULL; |
| 111 for (vector<Transfer>::iterator it = pending_transfers_.begin(); |
| 112 it != pending_transfers_.end(); ++it) { |
| 113 // If the flow hasn't started, return the start time. |
| 114 if (clock_->Now() < it->start_time) { |
| 115 send_time = it->start_time.Subtract(clock_->Now()); |
| 116 transfer = &(*it); |
| 117 continue; |
| 118 } |
| 119 // If we've already sent enough bytes, wait for them to be acked. |
| 120 if (it->bytes_acked + it->bytes_in_flight >= it->num_bytes) { |
| 121 continue; |
| 122 } |
| 123 QuicTime::Delta transfer_send_time = |
| 124 it->sender->send_algorithm->TimeUntilSend( |
| 125 clock_->Now(), it->bytes_in_flight, HAS_RETRANSMITTABLE_DATA); |
| 126 if (transfer_send_time < send_time) { |
| 127 send_time = transfer_send_time; |
| 128 transfer = &(*it); |
| 129 } |
| 130 } |
| 131 DVLOG(1) << "NextSendTime returning delta(ms):" << send_time.ToMilliseconds(); |
| 132 return PacketEvent(send_time, transfer); |
97 } | 133 } |
98 | 134 |
99 // NextAck takes into account packet loss in both forward and reverse | 135 // NextAck takes into account packet loss in both forward and reverse |
100 // direction, as well as correlated losses. And it assumes the receiver acks | 136 // direction, as well as correlated losses. And it assumes the receiver acks |
101 // every other packet when there is no loss. | 137 // every other packet when there is no loss. |
102 QuicTime::Delta SendAlgorithmSimulator::NextAckDelta() { | 138 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextAckEvent() { |
103 if (sent_packets_.empty() || AllPacketsLost()) { | 139 if (sent_packets_.empty()) { |
104 DVLOG(1) << "No outstanding packets to cause acks. sent_packets_.size():" | 140 DVLOG(1) << "No outstanding packets to ack for any transfer."; |
105 << sent_packets_.size(); | 141 return PacketEvent(QuicTime::Delta::Infinite(), NULL); |
106 return QuicTime::Delta::Infinite(); | |
107 } | 142 } |
108 | 143 |
109 // If necessary, determine next_acked_. | 144 // For each connection, find the next acked packet. |
110 // This is only done once to ensure multiple calls return the same time. | 145 QuicTime::Delta ack_time = QuicTime::Delta::Infinite(); |
111 FindNextAcked(); | 146 Transfer* transfer = NULL; |
112 | 147 for (vector<Transfer>::iterator it = pending_transfers_.begin(); |
113 // If only one packet is acked, simulate a delayed ack. | 148 it != pending_transfers_.end(); ++it) { |
114 if (next_acked_ - last_acked_ == 1) { | 149 // If necessary, determine next_acked_. |
115 return sent_packets_.front().ack_time.Add( | 150 // This is only done once to ensure multiple calls return the same time. |
116 QuicTime::Delta::FromMilliseconds(100)).Subtract(clock_->Now()); | 151 QuicTime::Delta transfer_ack_time = FindNextAcked(&(*it)); |
117 } | 152 if (transfer_ack_time < ack_time) { |
118 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); | 153 ack_time = transfer_ack_time; |
119 it != sent_packets_.end(); ++it) { | 154 transfer = &(*it); |
120 if (next_acked_ == it->sequence_number) { | |
121 return it->ack_time.Subtract(clock_->Now()); | |
122 } | 155 } |
123 } | 156 } |
124 LOG(DFATAL) << "Error, next_acked_: " << next_acked_ | 157 |
125 << " should have been found in sent_packets_"; | 158 return PacketEvent(ack_time, transfer); |
126 return QuicTime::Delta::Infinite(); | |
127 } | 159 } |
128 | 160 |
129 bool SendAlgorithmSimulator::AllPacketsLost() { | 161 QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) { |
130 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); | 162 Sender* sender = transfer->sender; |
131 it != sent_packets_.end(); ++it) { | 163 if (sender->next_acked == sender->last_acked) { |
132 if (it->ack_time.IsInitialized()) { | |
133 return false; | |
134 } | |
135 } | |
136 return true; | |
137 } | |
138 | |
139 void SendAlgorithmSimulator::FindNextAcked() { | |
140 // TODO(ianswett): Add a simpler mode which acks every packet. | |
141 bool packets_lost = false; | |
142 if (next_acked_ == last_acked_) { | |
143 // Determine if the next ack is lost only once, to ensure determinism. | 164 // Determine if the next ack is lost only once, to ensure determinism. |
144 lose_next_ack_ = | 165 lose_next_ack_ = |
145 reverse_loss_rate_ * kuint64max > simple_random_.RandUint64(); | 166 reverse_loss_rate_ * kuint64max > simple_random_.RandUint64(); |
146 } | 167 } |
147 bool two_acks_remaining = lose_next_ack_; | 168 bool two_acks_remaining = lose_next_ack_; |
148 next_acked_ = last_acked_; | 169 sender->next_acked = sender->last_acked; |
| 170 bool packets_lost = false; |
149 // Remove any packets that are simulated as lost. | 171 // Remove any packets that are simulated as lost. |
150 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); | 172 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); |
151 it != sent_packets_.end(); ++it) { | 173 it != sent_packets_.end(); ++it) { |
| 174 if (transfer != it->transfer) { |
| 175 continue; |
| 176 } |
| 177 |
152 // Lost packets don't trigger an ack. | 178 // Lost packets don't trigger an ack. |
153 if (it->ack_time == QuicTime::Zero()) { | 179 if (it->ack_time == QuicTime::Zero()) { |
154 packets_lost = true; | 180 packets_lost = true; |
155 continue; | 181 continue; |
156 } | 182 } |
157 // Buffer dropped packets are skipped automatically, but still end up | 183 // Buffer dropped packets are skipped automatically, but still end up |
158 // being lost and cause acks to be sent immediately. | 184 // being lost and cause acks to be sent immediately. |
159 if (next_acked_ < it->sequence_number - 1) { | 185 if (sender->next_acked < it->sequence_number - 1) { |
160 packets_lost = true; | 186 packets_lost = true; |
161 } | 187 } |
162 next_acked_ = it->sequence_number; | 188 sender->next_acked = it->sequence_number; |
163 if (packets_lost || (next_acked_ - last_acked_) % 2 == 0) { | 189 if (packets_lost || (sender->next_acked - sender->last_acked) % 2 == 0) { |
164 if (two_acks_remaining) { | 190 if (two_acks_remaining) { |
165 two_acks_remaining = false; | 191 two_acks_remaining = false; |
166 } else { | 192 } else { |
167 break; | 193 break; |
168 } | 194 } |
169 } | 195 } |
170 } | 196 } |
171 DVLOG(1) << "FindNextAcked found next_acked_:" << next_acked_ | 197 |
172 << " last_acked:" << last_acked_; | 198 QuicTime::Delta ack_time = QuicTime::Delta::Infinite(); |
| 199 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); |
| 200 it != sent_packets_.end(); ++it) { |
| 201 if (transfer == it->transfer && sender->next_acked == it->sequence_number) { |
| 202 ack_time = it->ack_time.Subtract(clock_->Now()); |
| 203 } |
| 204 } |
| 205 // If only one packet is acked, simulate a delayed ack. |
| 206 if (!ack_time.IsInfinite() && transfer->bytes_in_flight == kPacketSize) { |
| 207 ack_time = ack_time.Add(QuicTime::Delta::FromMilliseconds(100)); |
| 208 } |
| 209 DVLOG(1) << "FindNextAcked found next_acked_:" |
| 210 << transfer->sender->next_acked |
| 211 << " last_acked:" << transfer->sender->last_acked |
| 212 << " ack_time(ms):" << ack_time.ToMilliseconds(); |
| 213 return ack_time; |
173 } | 214 } |
174 | 215 |
175 int SendAlgorithmSimulator::HandlePendingAck() { | 216 void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) { |
176 DCHECK_LT(last_acked_, next_acked_); | 217 Sender* sender = transfer->sender; |
| 218 DCHECK_LT(sender->last_acked, sender->next_acked); |
177 SendAlgorithmInterface::CongestionMap acked_packets; | 219 SendAlgorithmInterface::CongestionMap acked_packets; |
178 SendAlgorithmInterface::CongestionMap lost_packets; | 220 SendAlgorithmInterface::CongestionMap lost_packets; |
179 // Some entries may be missing from the sent_packets_ array, if they were | 221 // Some entries may be missing from the sent_packets_ array, if they were |
180 // dropped due to buffer overruns. | 222 // dropped due to buffer overruns. |
181 SentPacket largest_observed = sent_packets_.front(); | 223 SentPacket largest_observed = sent_packets_.front(); |
182 while (last_acked_ < next_acked_) { | 224 while (sender->last_acked < sender->next_acked) { |
183 ++last_acked_; | 225 ++sender->last_acked; |
184 TransmissionInfo info = TransmissionInfo(); | 226 TransmissionInfo info = TransmissionInfo(); |
185 info.bytes_sent = kPacketSize; | 227 info.bytes_sent = kPacketSize; |
186 info.in_flight = true; | 228 info.in_flight = true; |
187 // If it's missing from the array, it's a loss. | 229 // If it's missing from the array, it's a loss. |
188 if (sent_packets_.front().sequence_number > last_acked_) { | 230 if (sent_packets_.front().sequence_number > sender->last_acked) { |
189 DVLOG(1) << "Lost packet:" << last_acked_ | 231 DVLOG(1) << "Lost packet:" << sender->last_acked |
190 << " dropped by buffer overflow."; | 232 << " dropped by buffer overflow."; |
191 lost_packets[last_acked_] = info; | 233 lost_packets[sender->last_acked] = info; |
192 continue; | 234 continue; |
193 } | 235 } |
194 if (sent_packets_.front().ack_time.IsInitialized()) { | 236 if (sent_packets_.front().ack_time.IsInitialized()) { |
195 acked_packets[last_acked_] = info; | 237 acked_packets[sender->last_acked] = info; |
196 } else { | 238 } else { |
197 lost_packets[last_acked_] = info; | 239 lost_packets[sender->last_acked] = info; |
198 } | 240 } |
199 // Remove all packets from the front to next_acked_. | 241 // Remove all packets from the front to next_acked_. |
200 largest_observed = sent_packets_.front(); | 242 largest_observed = sent_packets_.front(); |
201 sent_packets_.pop_front(); | 243 sent_packets_.pop_front(); |
202 } | 244 } |
203 | 245 |
204 DCHECK(largest_observed.ack_time.IsInitialized()); | 246 DCHECK(largest_observed.ack_time.IsInitialized()); |
205 rtt_stats_->UpdateRtt( | 247 sender->rtt_stats->UpdateRtt( |
206 largest_observed.ack_time.Subtract(largest_observed.send_time), | 248 largest_observed.ack_time.Subtract(largest_observed.send_time), |
207 QuicTime::Delta::Zero(), | 249 QuicTime::Delta::Zero(), |
208 clock_->Now()); | 250 clock_->Now()); |
209 send_algorithm_->OnCongestionEvent( | 251 sender->send_algorithm->OnCongestionEvent( |
210 true, bytes_in_flight_, acked_packets, lost_packets); | 252 true, transfer->bytes_in_flight, acked_packets, lost_packets); |
211 DCHECK_LE(kPacketSize * (acked_packets.size() + lost_packets.size()), | 253 DCHECK_LE(kPacketSize * (acked_packets.size() + lost_packets.size()), |
212 bytes_in_flight_); | 254 transfer->bytes_in_flight); |
213 bytes_in_flight_ -= | 255 transfer->bytes_in_flight -= |
214 kPacketSize * (acked_packets.size() + lost_packets.size()); | 256 kPacketSize * (acked_packets.size() + lost_packets.size()); |
215 return acked_packets.size() * kPacketSize; | 257 |
| 258 sender->RecordStats(); |
| 259 transfer->bytes_acked += acked_packets.size() * kPacketSize; |
| 260 if (transfer->bytes_acked >= transfer->num_bytes) { |
| 261 // Remove completed transfers and record transfer bandwidth. |
| 262 QuicTime::Delta transfer_time = |
| 263 clock_->Now().Subtract(transfer->start_time); |
| 264 sender->last_transfer_bandwidth = |
| 265 QuicBandwidth::FromBytesAndTimeDelta(transfer->num_bytes, |
| 266 transfer_time); |
| 267 for (vector<Transfer>::iterator it = pending_transfers_.begin(); |
| 268 it != pending_transfers_.end(); ++it) { |
| 269 if (transfer == &(*it)) { |
| 270 pending_transfers_.erase(it); |
| 271 break; |
| 272 } |
| 273 } |
| 274 } |
216 } | 275 } |
217 | 276 |
218 void SendAlgorithmSimulator::SendDataNow() { | 277 void SendAlgorithmSimulator::SendDataNow(Transfer* transfer) { |
219 DVLOG(1) << "Sending packet:" << next_sent_ << " bytes_in_flight:" | 278 Sender* sender = transfer->sender; |
220 << bytes_in_flight_; | 279 ++sender->last_sent; |
221 send_algorithm_->OnPacketSent( | 280 DVLOG(1) << "Sending packet:" << sender->last_sent |
222 clock_->Now(), bytes_in_flight_, | 281 << " bytes_in_flight:" << transfer->bytes_in_flight; |
223 next_sent_, kPacketSize, HAS_RETRANSMITTABLE_DATA); | 282 sender->send_algorithm->OnPacketSent( |
| 283 clock_->Now(), transfer->bytes_in_flight, |
| 284 sender->last_sent, kPacketSize, HAS_RETRANSMITTABLE_DATA); |
224 // Lose the packet immediately if the buffer is full. | 285 // Lose the packet immediately if the buffer is full. |
225 if (sent_packets_.size() * kPacketSize < buffer_size_) { | 286 if (sent_packets_.size() * kPacketSize < buffer_size_) { |
226 // TODO(ianswett): This buffer simulation is an approximation. | 287 // TODO(ianswett): This buffer simulation is an approximation. |
227 // An ack time of zero means loss. | 288 // An ack time of zero means loss. |
228 bool packet_lost = | 289 bool packet_lost = |
229 forward_loss_rate_ * kuint64max > simple_random_.RandUint64(); | 290 forward_loss_rate_ * kuint64max > simple_random_.RandUint64(); |
230 // Handle correlated loss. | 291 // Handle correlated loss. |
231 if (!sent_packets_.empty() && | 292 if (!sent_packets_.empty() && |
232 !sent_packets_.back().ack_time.IsInitialized() && | 293 !sent_packets_.back().ack_time.IsInitialized() && |
233 loss_correlation_ * kuint64max > simple_random_.RandUint64()) { | 294 loss_correlation_ * kuint64max > simple_random_.RandUint64()) { |
234 packet_lost = true; | 295 packet_lost = true; |
235 } | 296 } |
| 297 DVLOG(1) << "losing packet:" << sender->last_sent |
| 298 << " due to random loss."; |
236 | 299 |
237 QuicTime ack_time = clock_->Now().Add(rtt_); | 300 QuicTime ack_time = clock_->Now().Add(rtt_); |
238 // If the number of bytes in flight are less than the bdp, there's | 301 // If the number of bytes in flight are less than the bdp, there's |
239 // no buffering delay. Bytes lost from the buffer are not counted. | 302 // no buffering delay. Bytes lost from the buffer are not counted. |
240 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_); | 303 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_); |
241 if ((sent_packets_.size() + 1) * kPacketSize > bdp) { | 304 if ((sent_packets_.size() + 1) * kPacketSize > bdp) { |
242 QuicByteCount qsize = (sent_packets_.size() + 1) * kPacketSize - bdp; | 305 QuicByteCount qsize = (sent_packets_.size() + 1) * kPacketSize - bdp; |
243 ack_time = ack_time.Add(bandwidth_.TransferTime(qsize)); | 306 ack_time = ack_time.Add(bandwidth_.TransferTime(qsize)); |
244 } | 307 } |
245 // If the packet is lost, give it an ack time of Zero. | 308 // If the packet is lost, give it an ack time of Zero. |
246 sent_packets_.push_back(SentPacket( | 309 sent_packets_.push_back(SentPacket( |
247 next_sent_, clock_->Now(), packet_lost ? QuicTime::Zero() : ack_time)); | 310 sender->last_sent, clock_->Now(), |
| 311 packet_lost ? QuicTime::Zero() : ack_time, transfer)); |
| 312 } else { |
| 313 DVLOG(1) << "losing packet:" << sender->last_sent |
| 314 << " because the buffer was full."; |
248 } | 315 } |
249 ++next_sent_; | 316 transfer->bytes_in_flight += kPacketSize; |
250 bytes_in_flight_ += kPacketSize; | |
251 } | |
252 | |
253 void SendAlgorithmSimulator::RecordStats() { | |
254 QuicByteCount cwnd = send_algorithm_->GetCongestionWindow(); | |
255 max_cwnd_ = max(max_cwnd_, cwnd); | |
256 min_cwnd_ = min(min_cwnd_, cwnd); | |
257 if (last_cwnd_ > cwnd) { | |
258 max_cwnd_drop_ = max(max_cwnd_drop_, last_cwnd_ - cwnd); | |
259 } | |
260 last_cwnd_ = cwnd; | |
261 } | 317 } |
262 | 318 |
263 // Advance the time by |delta| without sending anything. | 319 // Advance the time by |delta| without sending anything. |
264 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) { | 320 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) { |
265 clock_->AdvanceTime(delta); | 321 clock_->AdvanceTime(delta); |
266 } | 322 } |
267 | 323 |
268 // Elapsed time from the start of the connection. | |
269 QuicTime SendAlgorithmSimulator::ElapsedTime() { | |
270 return clock_->Now(); | |
271 } | |
272 | |
273 } // namespace net | 324 } // namespace net |
OLD | NEW |