| 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 36aa32163d9356d54225c27607cd641e3d1103ba..7af949ad2eb3040a7d22d6126ae56b2d8bceb19f 100644
|
| --- a/net/quic/congestion_control/send_algorithm_simulator.cc
|
| +++ b/net/quic/congestion_control/send_algorithm_simulator.cc
|
| @@ -48,7 +48,8 @@ SendAlgorithmSimulator::SendAlgorithmSimulator(
|
| loss_correlation_(0),
|
| bandwidth_(bandwidth),
|
| rtt_(rtt),
|
| - buffer_size_(1000000) {
|
| + buffer_size_(1000000),
|
| + delayed_ack_timer_(QuicTime::Delta::FromMilliseconds(100)) {
|
| uint32 seed = base::RandInt(0, std::numeric_limits<int32>::max());
|
| DVLOG(1) << "Seeding SendAlgorithmSimulator with " << seed;
|
| simple_random_.set_seed(seed);
|
| @@ -92,7 +93,8 @@ void SendAlgorithmSimulator::TransferBytes(QuicByteCount max_bytes,
|
| clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
|
| SendDataNow(&pending_transfers_.front());
|
| } else if (ack_event.time_delta < send_event.time_delta) {
|
| - DVLOG(1) << "Handling ack, advancing time:"
|
| + DVLOG(1) << "Handling ack of largest observed:"
|
| + << ack_event.transfer->sender->next_acked << ", advancing time:"
|
| << ack_event.time_delta.ToMicroseconds() << "us";
|
| // Ack data all the data up to ack time and lose any missing sequence
|
| // numbers.
|
| @@ -165,57 +167,78 @@ QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) {
|
| lose_next_ack_ =
|
| reverse_loss_rate_ * kuint64max > simple_random_.RandUint64();
|
| }
|
| - bool two_acks_remaining = lose_next_ack_;
|
| - sender->next_acked = sender->last_acked;
|
| - bool packets_lost = false;
|
| +
|
| + QuicPacketSequenceNumber next_acked = sender->last_acked;
|
| + QuicTime::Delta next_ack_delay =
|
| + FindNextAck(transfer, sender->last_acked, &next_acked);
|
| + if (lose_next_ack_) {
|
| + next_ack_delay = FindNextAck(transfer, next_acked, &next_acked);
|
| + }
|
| + sender->next_acked = next_acked;
|
| + return next_ack_delay;
|
| +}
|
| +
|
| +QuicTime::Delta SendAlgorithmSimulator::FindNextAck(
|
| + const Transfer* transfer,
|
| + QuicPacketSequenceNumber last_acked,
|
| + QuicPacketSequenceNumber* next_acked) const {
|
| + *next_acked = last_acked;
|
| + QuicTime::Delta ack_delay = QuicTime::Delta::Infinite();
|
| // Remove any packets that are simulated as lost.
|
| for (list<SentPacket>::const_iterator it = sent_packets_.begin();
|
| it != sent_packets_.end(); ++it) {
|
| if (transfer != it->transfer) {
|
| continue;
|
| }
|
| -
|
| + // Skip over any packets less than or equal to last_acked.
|
| + if (it->sequence_number <= last_acked) {
|
| + continue;
|
| + }
|
| // Lost packets don't trigger an ack.
|
| if (it->ack_time == QuicTime::Zero()) {
|
| - packets_lost = true;
|
| continue;
|
| }
|
| - // Buffer dropped packets are skipped automatically, but still end up
|
| - // being lost and cause acks to be sent immediately.
|
| - if (sender->next_acked < it->sequence_number - 1) {
|
| - packets_lost = true;
|
| + DCHECK_LT(*next_acked, it->sequence_number);
|
| + // Consider a delayed ack for the current next_acked.
|
| + if (ack_delay < it->ack_time.Subtract(clock_->Now())) {
|
| + break;
|
| }
|
| - 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) {
|
| - two_acks_remaining = false;
|
| - } else {
|
| - break;
|
| - }
|
| + *next_acked = it->sequence_number;
|
| + ack_delay = it->ack_time.Subtract(clock_->Now());
|
| + if (HasRecentLostPackets(transfer, *next_acked) ||
|
| + (*next_acked - last_acked) >= 2) {
|
| + break;
|
| }
|
| - }
|
| - // If the connection has no packets to be acked, return Infinite.
|
| - if (sender->next_acked == sender->last_acked) {
|
| - return QuicTime::Delta::Infinite();
|
| + ack_delay = ack_delay.Add(delayed_ack_timer_);
|
| }
|
|
|
| - QuicTime::Delta ack_time = QuicTime::Delta::Infinite();
|
| - for (list<SentPacket>::const_iterator it = sent_packets_.begin();
|
| - it != sent_packets_.end(); ++it) {
|
| - if (transfer == it->transfer && sender->next_acked == it->sequence_number) {
|
| - ack_time = it->ack_time.Subtract(clock_->Now());
|
| - }
|
| - }
|
| - // If only one packet is acked, simulate a delayed ack.
|
| - if (!ack_time.IsInfinite() && transfer->bytes_in_flight == kPacketSize) {
|
| - ack_time = ack_time.Add(QuicTime::Delta::FromMilliseconds(100));
|
| - }
|
| DVLOG(1) << "FindNextAcked found next_acked_:"
|
| << transfer->sender->next_acked
|
| << " last_acked:" << transfer->sender->last_acked
|
| - << " ack_time(ms):" << ack_time.ToMilliseconds();
|
| - return ack_time;
|
| + << " ack_delay(ms):" << ack_delay.ToMilliseconds();
|
| + return ack_delay;
|
| +}
|
| +
|
| +bool SendAlgorithmSimulator::HasRecentLostPackets(
|
| + const Transfer* transfer, QuicPacketSequenceNumber next_acked) const {
|
| + QuicPacketSequenceNumber last_packet = transfer->sender->last_acked;
|
| + for (list<SentPacket>::const_iterator it = sent_packets_.begin();
|
| + it != sent_packets_.end() && it->sequence_number < next_acked; ++it) {
|
| + if (transfer != it->transfer) {
|
| + continue;
|
| + }
|
| + // Lost packets don't trigger an ack.
|
| + if (it->ack_time == QuicTime::Zero()) {
|
| + return true;
|
| + }
|
| + // Buffer dropped packets are skipped automatically, but still end up
|
| + // being lost and cause acks to be sent immediately.
|
| + if (it->sequence_number > last_packet + 1) {
|
| + return true;
|
| + }
|
| + last_packet = it->sequence_number;
|
| + }
|
| + return false;
|
| }
|
|
|
| void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) {
|
| @@ -223,6 +246,10 @@ void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) {
|
| DCHECK_LT(sender->last_acked, sender->next_acked);
|
| SendAlgorithmInterface::CongestionMap acked_packets;
|
| SendAlgorithmInterface::CongestionMap lost_packets;
|
| + DVLOG(1) << "Acking packets from:" << sender->last_acked
|
| + << " to " << sender->next_acked
|
| + << " bytes_in_flight:" << transfer->bytes_in_flight
|
| + << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms";
|
| // Some entries may be missing from the sent_packets_ array, if they were
|
| // dropped due to buffer overruns.
|
| SentPacket largest_observed(0, QuicTime::Zero(), QuicTime::Zero(), NULL);
|
| @@ -258,10 +285,12 @@ void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) {
|
| 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(),
|
| - clock_->Now());
|
| + QuicTime::Delta measured_rtt =
|
| + largest_observed.ack_time.Subtract(largest_observed.send_time);
|
| + DCHECK_GE(measured_rtt.ToMicroseconds(), rtt_.ToMicroseconds());
|
| + sender->rtt_stats->UpdateRtt(measured_rtt,
|
| + QuicTime::Delta::Zero(),
|
| + clock_->Now());
|
| sender->send_algorithm->OnCongestionEvent(
|
| true, transfer->bytes_in_flight, acked_packets, lost_packets);
|
| DCHECK_LE(kPacketSize * (acked_packets.size() + lost_packets.size()),
|
| @@ -295,7 +324,8 @@ void SendAlgorithmSimulator::SendDataNow(Transfer* transfer) {
|
| Sender* sender = transfer->sender;
|
| ++sender->last_sent;
|
| DVLOG(1) << "Sending packet:" << sender->last_sent
|
| - << " bytes_in_flight:" << transfer->bytes_in_flight;
|
| + << " bytes_in_flight:" << transfer->bytes_in_flight
|
| + << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms";
|
| sender->send_algorithm->OnPacketSent(
|
| clock_->Now(), transfer->bytes_in_flight,
|
| sender->last_sent, kPacketSize, HAS_RETRANSMITTABLE_DATA);
|
| @@ -314,17 +344,16 @@ void SendAlgorithmSimulator::SendDataNow(Transfer* transfer) {
|
| DVLOG(1) << "losing packet:" << sender->last_sent
|
| << " due to random loss.";
|
|
|
| - QuicTime ack_time = clock_->Now().Add(rtt_);
|
| // If the number of bytes in flight are less than the bdp, there's
|
| // no buffering delay. Bytes lost from the buffer are not counted.
|
| QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_);
|
| - 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;
|
| + QuicTime ack_time = clock_->Now().Add(rtt_);
|
| + if (kPacketSize > bdp) {
|
| + ack_time = ack_time.Add(bandwidth_.TransferTime(kPacketSize - bdp));
|
| }
|
| + QuicTime queue_ack_time = sent_packets_.empty() ? QuicTime::Zero() :
|
| + sent_packets_.back().ack_time.Add(bandwidth_.TransferTime(kPacketSize));
|
| + ack_time = QuicTime::Max(ack_time, queue_ack_time);
|
| // If the packet is lost, give it an ack time of Zero.
|
| sent_packets_.push_back(SentPacket(
|
| sender->last_sent, clock_->Now(),
|
|
|