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 |