Index: net/quic/congestion_control/send_algorithm_simulator.cc |
diff --git a/net/quic/congestion_control/send_algorithm_simulator.cc b/net/quic/congestion_control/send_algorithm_simulator.cc |
index 0798d5774ca7ed0ff32c2e0201dbdfb333c85d14..5c55f5b5d69d225486d7daefe22ba0592924bc76 100644 |
--- a/net/quic/congestion_control/send_algorithm_simulator.cc |
+++ b/net/quic/congestion_control/send_algorithm_simulator.cc |
@@ -34,7 +34,8 @@ SendAlgorithmSimulator::Sender::Sender(SendAlgorithmInterface* send_algorithm, |
min_cwnd(100000), |
max_cwnd_drop(0), |
last_cwnd(0), |
- last_transfer_bandwidth(QuicBandwidth::Zero()) {} |
+ last_transfer_bandwidth(QuicBandwidth::Zero()), |
+ last_transfer_loss_rate(0) {} |
SendAlgorithmSimulator::SendAlgorithmSimulator( |
MockClock* clock, |
@@ -106,30 +107,29 @@ void SendAlgorithmSimulator::TransferBytes(QuicByteCount max_bytes, |
} |
SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextSendEvent() { |
- QuicTime::Delta send_time = QuicTime::Delta::Infinite(); |
+ QuicTime::Delta next_send_time = QuicTime::Delta::Infinite(); |
Transfer* transfer = NULL; |
for (vector<Transfer>::iterator it = pending_transfers_.begin(); |
it != pending_transfers_.end(); ++it) { |
- // If the flow hasn't started, return the start time. |
- if (clock_->Now() < it->start_time) { |
- send_time = it->start_time.Subtract(clock_->Now()); |
- transfer = &(*it); |
- continue; |
- } |
// If we've already sent enough bytes, wait for them to be acked. |
if (it->bytes_acked + it->bytes_in_flight >= it->num_bytes) { |
continue; |
} |
- QuicTime::Delta transfer_send_time = |
- it->sender->send_algorithm->TimeUntilSend( |
- clock_->Now(), it->bytes_in_flight, HAS_RETRANSMITTABLE_DATA); |
- if (transfer_send_time < send_time) { |
- send_time = transfer_send_time; |
+ // If the flow hasn't started, use the start time. |
+ QuicTime::Delta transfer_send_time = it->start_time.Subtract(clock_->Now()); |
+ if (clock_->Now() >= it->start_time) { |
+ transfer_send_time = |
+ it->sender->send_algorithm->TimeUntilSend( |
+ clock_->Now(), it->bytes_in_flight, HAS_RETRANSMITTABLE_DATA); |
+ } |
+ if (transfer_send_time < next_send_time) { |
+ next_send_time = transfer_send_time; |
transfer = &(*it); |
} |
} |
- DVLOG(1) << "NextSendTime returning delta(ms):" << send_time.ToMilliseconds(); |
- return PacketEvent(send_time, transfer); |
+ DVLOG(1) << "NextSendTime returning delta(ms):" |
+ << next_send_time.ToMilliseconds(); |
+ return PacketEvent(next_send_time, transfer); |
} |
// NextAck takes into account packet loss in both forward and reverse |
@@ -146,8 +146,6 @@ SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextAckEvent() { |
Transfer* transfer = NULL; |
for (vector<Transfer>::iterator it = pending_transfers_.begin(); |
it != pending_transfers_.end(); ++it) { |
- // If necessary, determine next_acked_. |
- // This is only done once to ensure multiple calls return the same time. |
QuicTime::Delta transfer_ack_time = FindNextAcked(&(*it)); |
if (transfer_ack_time < ack_time) { |
ack_time = transfer_ack_time; |
@@ -159,7 +157,7 @@ SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextAckEvent() { |
} |
QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) { |
- Sender* sender = transfer->sender; |
+ Sender* sender = transfer->sender; |
if (sender->next_acked == sender->last_acked) { |
// Determine if the next ack is lost only once, to ensure determinism. |
lose_next_ack_ = |
@@ -176,7 +174,7 @@ QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) { |
} |
// Lost packets don't trigger an ack. |
- if (it->ack_time == QuicTime::Zero()) { |
+ if (it->ack_time == QuicTime::Zero()) { |
packets_lost = true; |
continue; |
} |
@@ -185,6 +183,7 @@ QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) { |
if (sender->next_acked < it->sequence_number - 1) { |
packets_lost = true; |
} |
+ DCHECK_LT(sender->next_acked, it->sequence_number); |
sender->next_acked = it->sequence_number; |
if (packets_lost || (sender->next_acked - sender->last_acked) % 2 == 0) { |
if (two_acks_remaining) { |
@@ -194,6 +193,10 @@ QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) { |
} |
} |
} |
+ // If the connection has no packets to be acked, return Infinite. |
+ if (sender->next_acked == sender->last_acked) { |
+ return QuicTime::Delta::Infinite(); |
+ } |
QuicTime::Delta ack_time = QuicTime::Delta::Infinite(); |
for (list<SentPacket>::const_iterator it = sent_packets_.begin(); |
@@ -220,30 +223,39 @@ void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) { |
SendAlgorithmInterface::CongestionMap lost_packets; |
// Some entries may be missing from the sent_packets_ array, if they were |
// dropped due to buffer overruns. |
- SentPacket largest_observed = sent_packets_.front(); |
+ SentPacket largest_observed(0, QuicTime::Zero(), QuicTime::Zero(), NULL); |
+ list<SentPacket>::iterator it = sent_packets_.begin(); |
while (sender->last_acked < sender->next_acked) { |
++sender->last_acked; |
TransmissionInfo info = TransmissionInfo(); |
info.bytes_sent = kPacketSize; |
info.in_flight = true; |
+ // Find the next SentPacket for this transfer. |
+ while (it->transfer != transfer) { |
+ DCHECK(it != sent_packets_.end()); |
+ ++it; |
+ } |
// If it's missing from the array, it's a loss. |
- if (sent_packets_.front().sequence_number > sender->last_acked) { |
+ if (it->sequence_number > sender->last_acked) { |
DVLOG(1) << "Lost packet:" << sender->last_acked |
<< " dropped by buffer overflow."; |
lost_packets[sender->last_acked] = info; |
continue; |
} |
- if (sent_packets_.front().ack_time.IsInitialized()) { |
+ if (it->ack_time.IsInitialized()) { |
acked_packets[sender->last_acked] = info; |
} else { |
lost_packets[sender->last_acked] = info; |
} |
- // Remove all packets from the front to next_acked_. |
- largest_observed = sent_packets_.front(); |
- sent_packets_.pop_front(); |
+ // This packet has been acked or lost, remove it from sent_packets_. |
+ largest_observed = *it; |
+ sent_packets_.erase(it++); |
} |
DCHECK(largest_observed.ack_time.IsInitialized()); |
+ DVLOG(1) << "Updating RTT from send_time:" |
+ << largest_observed.send_time.ToDebuggingValue() << " to ack_time:" |
+ << largest_observed.ack_time.ToDebuggingValue(); |
sender->rtt_stats->UpdateRtt( |
largest_observed.ack_time.Subtract(largest_observed.send_time), |
QuicTime::Delta::Zero(), |
@@ -257,10 +269,13 @@ void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) { |
sender->RecordStats(); |
transfer->bytes_acked += acked_packets.size() * kPacketSize; |
+ transfer->bytes_lost += lost_packets.size() * kPacketSize; |
if (transfer->bytes_acked >= transfer->num_bytes) { |
// Remove completed transfers and record transfer bandwidth. |
QuicTime::Delta transfer_time = |
clock_->Now().Subtract(transfer->start_time); |
+ sender->last_transfer_loss_rate = static_cast<float>(transfer->bytes_lost) / |
+ (transfer->bytes_lost + transfer->bytes_acked); |
sender->last_transfer_bandwidth = |
QuicBandwidth::FromBytesAndTimeDelta(transfer->num_bytes, |
transfer_time); |
@@ -304,6 +319,9 @@ void SendAlgorithmSimulator::SendDataNow(Transfer* transfer) { |
if ((sent_packets_.size() + 1) * kPacketSize > bdp) { |
QuicByteCount qsize = (sent_packets_.size() + 1) * kPacketSize - bdp; |
ack_time = ack_time.Add(bandwidth_.TransferTime(qsize)); |
+ DVLOG(1) << "Increasing transfer time:" |
+ << bandwidth_.TransferTime(qsize).ToMilliseconds() |
+ << "ms due to qsize:" << qsize; |
} |
// If the packet is lost, give it an ack time of Zero. |
sent_packets_.push_back(SentPacket( |