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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); | 188 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); |
189 it != sent_packets_.end(); ++it) { | 189 it != sent_packets_.end(); ++it) { |
190 if (transfer != it->transfer) { | 190 if (transfer != it->transfer) { |
191 continue; | 191 continue; |
192 } | 192 } |
193 // Skip over any packets less than or equal to last_acked. | 193 // Skip over any packets less than or equal to last_acked. |
194 if (it->sequence_number <= last_acked) { | 194 if (it->sequence_number <= last_acked) { |
195 continue; | 195 continue; |
196 } | 196 } |
197 // Lost packets don't trigger an ack. | 197 // Lost packets don't trigger an ack. |
198 if (it->ack_time == QuicTime::Zero()) { | 198 if (it->lost) { |
199 continue; | 199 continue; |
200 } | 200 } |
201 DCHECK_LT(*next_acked, it->sequence_number); | 201 DCHECK_LT(*next_acked, it->sequence_number); |
202 // Consider a delayed ack for the current next_acked. | 202 // Consider a delayed ack for the current next_acked. |
203 if (ack_delay < it->ack_time.Subtract(clock_->Now())) { | 203 if (ack_delay < it->ack_time.Subtract(clock_->Now())) { |
204 break; | 204 break; |
205 } | 205 } |
206 *next_acked = it->sequence_number; | 206 *next_acked = it->sequence_number; |
207 ack_delay = it->ack_time.Subtract(clock_->Now()); | 207 ack_delay = it->ack_time.Subtract(clock_->Now()); |
208 if (HasRecentLostPackets(transfer, *next_acked) || | 208 if (HasRecentLostPackets(transfer, *next_acked) || |
(...skipping 12 matching lines...) Expand all Loading... |
221 | 221 |
222 bool SendAlgorithmSimulator::HasRecentLostPackets( | 222 bool SendAlgorithmSimulator::HasRecentLostPackets( |
223 const Transfer* transfer, QuicPacketSequenceNumber next_acked) const { | 223 const Transfer* transfer, QuicPacketSequenceNumber next_acked) const { |
224 QuicPacketSequenceNumber last_packet = transfer->sender->last_acked; | 224 QuicPacketSequenceNumber last_packet = transfer->sender->last_acked; |
225 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); | 225 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); |
226 it != sent_packets_.end() && it->sequence_number < next_acked; ++it) { | 226 it != sent_packets_.end() && it->sequence_number < next_acked; ++it) { |
227 if (transfer != it->transfer) { | 227 if (transfer != it->transfer) { |
228 continue; | 228 continue; |
229 } | 229 } |
230 // Lost packets don't trigger an ack. | 230 // Lost packets don't trigger an ack. |
231 if (it->ack_time == QuicTime::Zero()) { | 231 if (it->lost) { |
232 return true; | 232 return true; |
233 } | 233 } |
234 // Buffer dropped packets are skipped automatically, but still end up | 234 // Buffer dropped packets are skipped automatically, but still end up |
235 // being lost and cause acks to be sent immediately. | 235 // being lost and cause acks to be sent immediately. |
236 if (it->sequence_number > last_packet + 1) { | 236 if (it->sequence_number > last_packet + 1) { |
237 return true; | 237 return true; |
238 } | 238 } |
239 last_packet = it->sequence_number; | 239 last_packet = it->sequence_number; |
240 } | 240 } |
241 return false; | 241 return false; |
242 } | 242 } |
243 | 243 |
244 void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) { | 244 void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) { |
245 Sender* sender = transfer->sender; | 245 Sender* sender = transfer->sender; |
246 DCHECK_LT(sender->last_acked, sender->next_acked); | 246 DCHECK_LT(sender->last_acked, sender->next_acked); |
247 SendAlgorithmInterface::CongestionMap acked_packets; | 247 SendAlgorithmInterface::CongestionMap acked_packets; |
248 SendAlgorithmInterface::CongestionMap lost_packets; | 248 SendAlgorithmInterface::CongestionMap lost_packets; |
249 DVLOG(1) << "Acking packets from:" << sender->last_acked | 249 DVLOG(1) << "Acking packets from:" << sender->last_acked |
250 << " to " << sender->next_acked | 250 << " to " << sender->next_acked |
251 << " bytes_in_flight:" << transfer->bytes_in_flight | 251 << " bytes_in_flight:" << transfer->bytes_in_flight |
252 << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms"; | 252 << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms"; |
253 // 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 |
254 // dropped due to buffer overruns. | 254 // dropped due to buffer overruns. |
255 SentPacket largest_observed(0, QuicTime::Zero(), QuicTime::Zero(), NULL); | 255 SentPacket largest_observed; |
256 list<SentPacket>::iterator it = sent_packets_.begin(); | 256 list<SentPacket>::iterator it = sent_packets_.begin(); |
257 while (sender->last_acked < sender->next_acked) { | 257 while (sender->last_acked < sender->next_acked) { |
258 ++sender->last_acked; | 258 ++sender->last_acked; |
259 TransmissionInfo info = TransmissionInfo(); | 259 TransmissionInfo info = TransmissionInfo(); |
260 info.bytes_sent = kPacketSize; | 260 info.bytes_sent = kPacketSize; |
261 info.in_flight = true; | 261 info.in_flight = true; |
262 // Find the next SentPacket for this transfer. | 262 // Find the next SentPacket for this transfer. |
263 while (it->transfer != transfer) { | 263 while (it->transfer != transfer) { |
264 DCHECK(it != sent_packets_.end()); | 264 DCHECK(it != sent_packets_.end()); |
265 ++it; | 265 ++it; |
266 } | 266 } |
267 // If it's missing from the array, it's a loss. | 267 // If it's missing from the array, it's a loss. |
268 if (it->sequence_number > sender->last_acked) { | 268 if (it->sequence_number > sender->last_acked) { |
269 DVLOG(1) << "Lost packet:" << sender->last_acked | 269 DVLOG(1) << "Lost packet:" << sender->last_acked |
270 << " dropped by buffer overflow."; | 270 << " dropped by buffer overflow."; |
271 lost_packets[sender->last_acked] = info; | 271 lost_packets[sender->last_acked] = info; |
272 continue; | 272 continue; |
273 } | 273 } |
274 if (it->ack_time.IsInitialized()) { | 274 if (it->lost) { |
| 275 lost_packets[sender->last_acked] = info; |
| 276 } else { |
275 acked_packets[sender->last_acked] = info; | 277 acked_packets[sender->last_acked] = info; |
276 } else { | |
277 lost_packets[sender->last_acked] = info; | |
278 } | 278 } |
279 // 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_. |
280 largest_observed = *it; | 280 largest_observed = *it; |
281 sent_packets_.erase(it++); | 281 sent_packets_.erase(it++); |
282 } | 282 } |
283 | 283 |
284 DCHECK(largest_observed.ack_time.IsInitialized()); | 284 DCHECK(largest_observed.ack_time.IsInitialized()); |
285 DVLOG(1) << "Updating RTT from send_time:" | 285 DVLOG(1) << "Updating RTT from send_time:" |
286 << largest_observed.send_time.ToDebuggingValue() << " to ack_time:" | 286 << largest_observed.send_time.ToDebuggingValue() << " to ack_time:" |
287 << largest_observed.ack_time.ToDebuggingValue(); | 287 << largest_observed.ack_time.ToDebuggingValue(); |
(...skipping 15 matching lines...) Expand all Loading... |
303 transfer->bytes_lost += lost_packets.size() * kPacketSize; | 303 transfer->bytes_lost += lost_packets.size() * kPacketSize; |
304 if (transfer->bytes_acked >= transfer->num_bytes) { | 304 if (transfer->bytes_acked >= transfer->num_bytes) { |
305 // Remove completed transfers and record transfer bandwidth. | 305 // Remove completed transfers and record transfer bandwidth. |
306 QuicTime::Delta transfer_time = | 306 QuicTime::Delta transfer_time = |
307 clock_->Now().Subtract(transfer->start_time); | 307 clock_->Now().Subtract(transfer->start_time); |
308 sender->last_transfer_loss_rate = static_cast<float>(transfer->bytes_lost) / | 308 sender->last_transfer_loss_rate = static_cast<float>(transfer->bytes_lost) / |
309 (transfer->bytes_lost + transfer->bytes_acked); | 309 (transfer->bytes_lost + transfer->bytes_acked); |
310 sender->last_transfer_bandwidth = | 310 sender->last_transfer_bandwidth = |
311 QuicBandwidth::FromBytesAndTimeDelta(transfer->num_bytes, | 311 QuicBandwidth::FromBytesAndTimeDelta(transfer->num_bytes, |
312 transfer_time); | 312 transfer_time); |
| 313 DCHECK_GE(bandwidth_.ToBitsPerSecond(), |
| 314 sender->last_transfer_bandwidth.ToBitsPerSecond()); |
313 for (vector<Transfer>::iterator it = pending_transfers_.begin(); | 315 for (vector<Transfer>::iterator it = pending_transfers_.begin(); |
314 it != pending_transfers_.end(); ++it) { | 316 it != pending_transfers_.end(); ++it) { |
315 if (transfer == &(*it)) { | 317 if (transfer == &(*it)) { |
316 pending_transfers_.erase(it); | 318 pending_transfers_.erase(it); |
317 break; | 319 break; |
318 } | 320 } |
319 } | 321 } |
320 } | 322 } |
321 } | 323 } |
322 | 324 |
323 void SendAlgorithmSimulator::SendDataNow(Transfer* transfer) { | 325 void SendAlgorithmSimulator::SendDataNow(Transfer* transfer) { |
324 Sender* sender = transfer->sender; | 326 Sender* sender = transfer->sender; |
325 ++sender->last_sent; | 327 ++sender->last_sent; |
326 DVLOG(1) << "Sending packet:" << sender->last_sent | 328 DVLOG(1) << "Sending packet:" << sender->last_sent |
327 << " bytes_in_flight:" << transfer->bytes_in_flight | 329 << " bytes_in_flight:" << transfer->bytes_in_flight |
328 << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms"; | 330 << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms"; |
329 sender->send_algorithm->OnPacketSent( | 331 sender->send_algorithm->OnPacketSent( |
330 clock_->Now(), transfer->bytes_in_flight, | 332 clock_->Now(), transfer->bytes_in_flight, |
331 sender->last_sent, kPacketSize, HAS_RETRANSMITTABLE_DATA); | 333 sender->last_sent, kPacketSize, HAS_RETRANSMITTABLE_DATA); |
332 // Lose the packet immediately if the buffer is full. | 334 // Lose the packet immediately if the buffer is full. |
333 if (sent_packets_.size() * kPacketSize < buffer_size_) { | 335 if (sent_packets_.size() * kPacketSize < buffer_size_) { |
334 // TODO(ianswett): This buffer simulation is an approximation. | 336 // TODO(ianswett): This buffer simulation is an approximation. |
335 // An ack time of zero means loss. | 337 // An ack time of zero means loss. |
336 bool packet_lost = | 338 bool packet_lost = |
337 forward_loss_rate_ * kuint64max > simple_random_.RandUint64(); | 339 forward_loss_rate_ * kuint64max > simple_random_.RandUint64(); |
338 // Handle correlated loss. | 340 // Handle correlated loss. |
339 if (!sent_packets_.empty() && | 341 if (!sent_packets_.empty() && sent_packets_.back().lost && |
340 !sent_packets_.back().ack_time.IsInitialized() && | |
341 loss_correlation_ * kuint64max > simple_random_.RandUint64()) { | 342 loss_correlation_ * kuint64max > simple_random_.RandUint64()) { |
342 packet_lost = true; | 343 packet_lost = true; |
343 } | 344 } |
344 DVLOG(1) << "losing packet:" << sender->last_sent | 345 DVLOG(1) << "losing packet:" << sender->last_sent |
345 << " due to random loss."; | 346 << " due to random loss."; |
346 | 347 |
347 // If the number of bytes in flight are less than the bdp, there's | 348 // If the number of bytes in flight are less than the bdp, there's |
348 // no buffering delay. Bytes lost from the buffer are not counted. | 349 // no buffering delay. Bytes lost from the buffer are not counted. |
349 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_); | 350 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_); |
350 QuicTime ack_time = clock_->Now().Add(rtt_); | 351 QuicTime ack_time = clock_->Now().Add(rtt_); |
351 if (kPacketSize > bdp) { | 352 if (kPacketSize > bdp) { |
352 ack_time = ack_time.Add(bandwidth_.TransferTime(kPacketSize - bdp)); | 353 ack_time = ack_time.Add(bandwidth_.TransferTime(kPacketSize - bdp)); |
353 } | 354 } |
354 QuicTime queue_ack_time = sent_packets_.empty() ? QuicTime::Zero() : | 355 QuicTime queue_ack_time = sent_packets_.empty() ? QuicTime::Zero() : |
355 sent_packets_.back().ack_time.Add(bandwidth_.TransferTime(kPacketSize)); | 356 sent_packets_.back().ack_time.Add(bandwidth_.TransferTime(kPacketSize)); |
356 ack_time = QuicTime::Max(ack_time, queue_ack_time); | 357 ack_time = QuicTime::Max(ack_time, queue_ack_time); |
357 // If the packet is lost, give it an ack time of Zero. | |
358 sent_packets_.push_back(SentPacket( | 358 sent_packets_.push_back(SentPacket( |
359 sender->last_sent, clock_->Now(), | 359 sender->last_sent, clock_->Now(), ack_time, packet_lost, transfer)); |
360 packet_lost ? QuicTime::Zero() : ack_time, transfer)); | |
361 } else { | 360 } else { |
362 DVLOG(1) << "losing packet:" << sender->last_sent | 361 DVLOG(1) << "losing packet:" << sender->last_sent |
363 << " because the buffer was full."; | 362 << " because the buffer was full."; |
364 } | 363 } |
365 transfer->bytes_in_flight += kPacketSize; | 364 transfer->bytes_in_flight += kPacketSize; |
366 } | 365 } |
367 | 366 |
368 // Advance the time by |delta| without sending anything. | 367 // Advance the time by |delta| without sending anything. |
369 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) { | 368 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) { |
370 clock_->AdvanceTime(delta); | 369 clock_->AdvanceTime(delta); |
371 } | 370 } |
372 | 371 |
373 } // namespace net | 372 } // namespace net |
OLD | NEW |