| 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 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 DVLOG(1) << "Sending, advancing time:" | 99 DVLOG(1) << "Sending, advancing time:" |
| 100 << send_event.time_delta.ToMicroseconds() << "us"; | 100 << send_event.time_delta.ToMicroseconds() << "us"; |
| 101 clock_->AdvanceTime(send_event.time_delta); | 101 clock_->AdvanceTime(send_event.time_delta); |
| 102 SendDataNow(send_event.transfer); | 102 SendDataNow(send_event.transfer); |
| 103 bytes_sent += kPacketSize; | 103 bytes_sent += kPacketSize; |
| 104 } | 104 } |
| 105 } | 105 } |
| 106 } | 106 } |
| 107 | 107 |
| 108 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextSendEvent() { | 108 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextSendEvent() { |
| 109 QuicTime::Delta send_time = QuicTime::Delta::Infinite(); | 109 QuicTime::Delta next_send_time = QuicTime::Delta::Infinite(); |
| 110 Transfer* transfer = NULL; | 110 Transfer* transfer = NULL; |
| 111 for (vector<Transfer>::iterator it = pending_transfers_.begin(); | 111 for (vector<Transfer>::iterator it = pending_transfers_.begin(); |
| 112 it != pending_transfers_.end(); ++it) { | 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. | 113 // 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) { | 114 if (it->bytes_acked + it->bytes_in_flight >= it->num_bytes) { |
| 121 continue; | 115 continue; |
| 122 } | 116 } |
| 123 QuicTime::Delta transfer_send_time = | 117 // If the flow hasn't started, use the start time. |
| 124 it->sender->send_algorithm->TimeUntilSend( | 118 QuicTime::Delta transfer_send_time = it->start_time.Subtract(clock_->Now()); |
| 125 clock_->Now(), it->bytes_in_flight, HAS_RETRANSMITTABLE_DATA); | 119 if (clock_->Now() >= it->start_time) { |
| 126 if (transfer_send_time < send_time) { | 120 transfer_send_time = |
| 127 send_time = transfer_send_time; | 121 it->sender->send_algorithm->TimeUntilSend( |
| 122 clock_->Now(), it->bytes_in_flight, HAS_RETRANSMITTABLE_DATA); |
| 123 } |
| 124 if (transfer_send_time < next_send_time) { |
| 125 next_send_time = transfer_send_time; |
| 128 transfer = &(*it); | 126 transfer = &(*it); |
| 129 } | 127 } |
| 130 } | 128 } |
| 131 DVLOG(1) << "NextSendTime returning delta(ms):" << send_time.ToMilliseconds(); | 129 DVLOG(1) << "NextSendTime returning delta(ms):" |
| 132 return PacketEvent(send_time, transfer); | 130 << next_send_time.ToMilliseconds(); |
| 131 return PacketEvent(next_send_time, transfer); |
| 133 } | 132 } |
| 134 | 133 |
| 135 // NextAck takes into account packet loss in both forward and reverse | 134 // NextAck takes into account packet loss in both forward and reverse |
| 136 // direction, as well as correlated losses. And it assumes the receiver acks | 135 // direction, as well as correlated losses. And it assumes the receiver acks |
| 137 // every other packet when there is no loss. | 136 // every other packet when there is no loss. |
| 138 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextAckEvent() { | 137 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextAckEvent() { |
| 139 if (sent_packets_.empty()) { | 138 if (sent_packets_.empty()) { |
| 140 DVLOG(1) << "No outstanding packets to ack for any transfer."; | 139 DVLOG(1) << "No outstanding packets to ack for any transfer."; |
| 141 return PacketEvent(QuicTime::Delta::Infinite(), NULL); | 140 return PacketEvent(QuicTime::Delta::Infinite(), NULL); |
| 142 } | 141 } |
| 143 | 142 |
| 144 // For each connection, find the next acked packet. | 143 // For each connection, find the next acked packet. |
| 145 QuicTime::Delta ack_time = QuicTime::Delta::Infinite(); | 144 QuicTime::Delta ack_time = QuicTime::Delta::Infinite(); |
| 146 Transfer* transfer = NULL; | 145 Transfer* transfer = NULL; |
| 147 for (vector<Transfer>::iterator it = pending_transfers_.begin(); | 146 for (vector<Transfer>::iterator it = pending_transfers_.begin(); |
| 148 it != pending_transfers_.end(); ++it) { | 147 it != pending_transfers_.end(); ++it) { |
| 149 // If necessary, determine next_acked_. | |
| 150 // This is only done once to ensure multiple calls return the same time. | |
| 151 QuicTime::Delta transfer_ack_time = FindNextAcked(&(*it)); | 148 QuicTime::Delta transfer_ack_time = FindNextAcked(&(*it)); |
| 152 if (transfer_ack_time < ack_time) { | 149 if (transfer_ack_time < ack_time) { |
| 153 ack_time = transfer_ack_time; | 150 ack_time = transfer_ack_time; |
| 154 transfer = &(*it); | 151 transfer = &(*it); |
| 155 } | 152 } |
| 156 } | 153 } |
| 157 | 154 |
| 158 return PacketEvent(ack_time, transfer); | 155 return PacketEvent(ack_time, transfer); |
| 159 } | 156 } |
| 160 | 157 |
| 161 QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) { | 158 QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) { |
| 162 Sender* sender = transfer->sender; | 159 Sender* sender = transfer->sender; |
| 163 if (sender->next_acked == sender->last_acked) { | 160 if (sender->next_acked == sender->last_acked) { |
| 164 // Determine if the next ack is lost only once, to ensure determinism. | 161 // Determine if the next ack is lost only once, to ensure determinism. |
| 165 lose_next_ack_ = | 162 lose_next_ack_ = |
| 166 reverse_loss_rate_ * kuint64max > simple_random_.RandUint64(); | 163 reverse_loss_rate_ * kuint64max > simple_random_.RandUint64(); |
| 167 } | 164 } |
| 168 bool two_acks_remaining = lose_next_ack_; | 165 bool two_acks_remaining = lose_next_ack_; |
| 169 sender->next_acked = sender->last_acked; | 166 sender->next_acked = sender->last_acked; |
| 170 bool packets_lost = false; | 167 bool packets_lost = false; |
| 171 // Remove any packets that are simulated as lost. | 168 // Remove any packets that are simulated as lost. |
| 172 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); | 169 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); |
| 173 it != sent_packets_.end(); ++it) { | 170 it != sent_packets_.end(); ++it) { |
| 174 if (transfer != it->transfer) { | 171 if (transfer != it->transfer) { |
| 175 continue; | 172 continue; |
| 176 } | 173 } |
| 177 | 174 |
| 178 // Lost packets don't trigger an ack. | 175 // Lost packets don't trigger an ack. |
| 179 if (it->ack_time == QuicTime::Zero()) { | 176 if (it->ack_time == QuicTime::Zero()) { |
| 180 packets_lost = true; | 177 packets_lost = true; |
| 181 continue; | 178 continue; |
| 182 } | 179 } |
| 183 // Buffer dropped packets are skipped automatically, but still end up | 180 // Buffer dropped packets are skipped automatically, but still end up |
| 184 // being lost and cause acks to be sent immediately. | 181 // being lost and cause acks to be sent immediately. |
| 185 if (sender->next_acked < it->sequence_number - 1) { | 182 if (sender->next_acked < it->sequence_number - 1) { |
| 186 packets_lost = true; | 183 packets_lost = true; |
| 187 } | 184 } |
| 185 DCHECK_LT(sender->next_acked, it->sequence_number); |
| 188 sender->next_acked = it->sequence_number; | 186 sender->next_acked = it->sequence_number; |
| 189 if (packets_lost || (sender->next_acked - sender->last_acked) % 2 == 0) { | 187 if (packets_lost || (sender->next_acked - sender->last_acked) % 2 == 0) { |
| 190 if (two_acks_remaining) { | 188 if (two_acks_remaining) { |
| 191 two_acks_remaining = false; | 189 two_acks_remaining = false; |
| 192 } else { | 190 } else { |
| 193 break; | 191 break; |
| 194 } | 192 } |
| 195 } | 193 } |
| 196 } | 194 } |
| 195 // If the connection has no packets to be acked, return Infinite. |
| 196 if (sender->next_acked == sender->last_acked) { |
| 197 return QuicTime::Delta::Infinite(); |
| 198 } |
| 197 | 199 |
| 198 QuicTime::Delta ack_time = QuicTime::Delta::Infinite(); | 200 QuicTime::Delta ack_time = QuicTime::Delta::Infinite(); |
| 199 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); | 201 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); |
| 200 it != sent_packets_.end(); ++it) { | 202 it != sent_packets_.end(); ++it) { |
| 201 if (transfer == it->transfer && sender->next_acked == it->sequence_number) { | 203 if (transfer == it->transfer && sender->next_acked == it->sequence_number) { |
| 202 ack_time = it->ack_time.Subtract(clock_->Now()); | 204 ack_time = it->ack_time.Subtract(clock_->Now()); |
| 203 } | 205 } |
| 204 } | 206 } |
| 205 // If only one packet is acked, simulate a delayed ack. | 207 // If only one packet is acked, simulate a delayed ack. |
| 206 if (!ack_time.IsInfinite() && transfer->bytes_in_flight == kPacketSize) { | 208 if (!ack_time.IsInfinite() && transfer->bytes_in_flight == kPacketSize) { |
| 207 ack_time = ack_time.Add(QuicTime::Delta::FromMilliseconds(100)); | 209 ack_time = ack_time.Add(QuicTime::Delta::FromMilliseconds(100)); |
| 208 } | 210 } |
| 209 DVLOG(1) << "FindNextAcked found next_acked_:" | 211 DVLOG(1) << "FindNextAcked found next_acked_:" |
| 210 << transfer->sender->next_acked | 212 << transfer->sender->next_acked |
| 211 << " last_acked:" << transfer->sender->last_acked | 213 << " last_acked:" << transfer->sender->last_acked |
| 212 << " ack_time(ms):" << ack_time.ToMilliseconds(); | 214 << " ack_time(ms):" << ack_time.ToMilliseconds(); |
| 213 return ack_time; | 215 return ack_time; |
| 214 } | 216 } |
| 215 | 217 |
| 216 void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) { | 218 void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) { |
| 217 Sender* sender = transfer->sender; | 219 Sender* sender = transfer->sender; |
| 218 DCHECK_LT(sender->last_acked, sender->next_acked); | 220 DCHECK_LT(sender->last_acked, sender->next_acked); |
| 219 SendAlgorithmInterface::CongestionMap acked_packets; | 221 SendAlgorithmInterface::CongestionMap acked_packets; |
| 220 SendAlgorithmInterface::CongestionMap lost_packets; | 222 SendAlgorithmInterface::CongestionMap lost_packets; |
| 221 // Some entries may be missing from the sent_packets_ array, if they were | 223 // Some entries may be missing from the sent_packets_ array, if they were |
| 222 // dropped due to buffer overruns. | 224 // dropped due to buffer overruns. |
| 223 SentPacket largest_observed = sent_packets_.front(); | 225 SentPacket largest_observed(0, QuicTime::Zero(), QuicTime::Zero(), NULL); |
| 226 list<SentPacket>::iterator it = sent_packets_.begin(); |
| 224 while (sender->last_acked < sender->next_acked) { | 227 while (sender->last_acked < sender->next_acked) { |
| 225 ++sender->last_acked; | 228 ++sender->last_acked; |
| 226 TransmissionInfo info = TransmissionInfo(); | 229 TransmissionInfo info = TransmissionInfo(); |
| 227 info.bytes_sent = kPacketSize; | 230 info.bytes_sent = kPacketSize; |
| 228 info.in_flight = true; | 231 info.in_flight = true; |
| 232 // Find the next SentPacket for this transfer. |
| 233 while (it->transfer != transfer) { |
| 234 DCHECK(it != sent_packets_.end()); |
| 235 ++it; |
| 236 } |
| 229 // If it's missing from the array, it's a loss. | 237 // If it's missing from the array, it's a loss. |
| 230 if (sent_packets_.front().sequence_number > sender->last_acked) { | 238 if (it->sequence_number > sender->last_acked) { |
| 231 DVLOG(1) << "Lost packet:" << sender->last_acked | 239 DVLOG(1) << "Lost packet:" << sender->last_acked |
| 232 << " dropped by buffer overflow."; | 240 << " dropped by buffer overflow."; |
| 233 lost_packets[sender->last_acked] = info; | 241 lost_packets[sender->last_acked] = info; |
| 234 continue; | 242 continue; |
| 235 } | 243 } |
| 236 if (sent_packets_.front().ack_time.IsInitialized()) { | 244 if (it->ack_time.IsInitialized()) { |
| 237 acked_packets[sender->last_acked] = info; | 245 acked_packets[sender->last_acked] = info; |
| 238 } else { | 246 } else { |
| 239 lost_packets[sender->last_acked] = info; | 247 lost_packets[sender->last_acked] = info; |
| 240 } | 248 } |
| 241 // Remove all packets from the front to next_acked_. | 249 // This packet has been acked or lost, remove it from sent_packets_. |
| 242 largest_observed = sent_packets_.front(); | 250 largest_observed = *it; |
| 243 sent_packets_.pop_front(); | 251 sent_packets_.erase(it++); |
| 244 } | 252 } |
| 245 | 253 |
| 246 DCHECK(largest_observed.ack_time.IsInitialized()); | 254 DCHECK(largest_observed.ack_time.IsInitialized()); |
| 255 DVLOG(1) << "Updating RTT from send_time:" |
| 256 << largest_observed.send_time.ToDebuggingValue() << " to ack_time:" |
| 257 << largest_observed.ack_time.ToDebuggingValue(); |
| 247 sender->rtt_stats->UpdateRtt( | 258 sender->rtt_stats->UpdateRtt( |
| 248 largest_observed.ack_time.Subtract(largest_observed.send_time), | 259 largest_observed.ack_time.Subtract(largest_observed.send_time), |
| 249 QuicTime::Delta::Zero(), | 260 QuicTime::Delta::Zero(), |
| 250 clock_->Now()); | 261 clock_->Now()); |
| 251 sender->send_algorithm->OnCongestionEvent( | 262 sender->send_algorithm->OnCongestionEvent( |
| 252 true, transfer->bytes_in_flight, acked_packets, lost_packets); | 263 true, transfer->bytes_in_flight, acked_packets, lost_packets); |
| 253 DCHECK_LE(kPacketSize * (acked_packets.size() + lost_packets.size()), | 264 DCHECK_LE(kPacketSize * (acked_packets.size() + lost_packets.size()), |
| 254 transfer->bytes_in_flight); | 265 transfer->bytes_in_flight); |
| 255 transfer->bytes_in_flight -= | 266 transfer->bytes_in_flight -= |
| 256 kPacketSize * (acked_packets.size() + lost_packets.size()); | 267 kPacketSize * (acked_packets.size() + lost_packets.size()); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 297 DVLOG(1) << "losing packet:" << sender->last_sent | 308 DVLOG(1) << "losing packet:" << sender->last_sent |
| 298 << " due to random loss."; | 309 << " due to random loss."; |
| 299 | 310 |
| 300 QuicTime ack_time = clock_->Now().Add(rtt_); | 311 QuicTime ack_time = clock_->Now().Add(rtt_); |
| 301 // If the number of bytes in flight are less than the bdp, there's | 312 // If the number of bytes in flight are less than the bdp, there's |
| 302 // no buffering delay. Bytes lost from the buffer are not counted. | 313 // no buffering delay. Bytes lost from the buffer are not counted. |
| 303 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_); | 314 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_); |
| 304 if ((sent_packets_.size() + 1) * kPacketSize > bdp) { | 315 if ((sent_packets_.size() + 1) * kPacketSize > bdp) { |
| 305 QuicByteCount qsize = (sent_packets_.size() + 1) * kPacketSize - bdp; | 316 QuicByteCount qsize = (sent_packets_.size() + 1) * kPacketSize - bdp; |
| 306 ack_time = ack_time.Add(bandwidth_.TransferTime(qsize)); | 317 ack_time = ack_time.Add(bandwidth_.TransferTime(qsize)); |
| 318 DVLOG(1) << "Increasing transfer time:" |
| 319 << bandwidth_.TransferTime(qsize).ToMilliseconds() |
| 320 << "ms due to qsize:" << qsize; |
| 307 } | 321 } |
| 308 // If the packet is lost, give it an ack time of Zero. | 322 // If the packet is lost, give it an ack time of Zero. |
| 309 sent_packets_.push_back(SentPacket( | 323 sent_packets_.push_back(SentPacket( |
| 310 sender->last_sent, clock_->Now(), | 324 sender->last_sent, clock_->Now(), |
| 311 packet_lost ? QuicTime::Zero() : ack_time, transfer)); | 325 packet_lost ? QuicTime::Zero() : ack_time, transfer)); |
| 312 } else { | 326 } else { |
| 313 DVLOG(1) << "losing packet:" << sender->last_sent | 327 DVLOG(1) << "losing packet:" << sender->last_sent |
| 314 << " because the buffer was full."; | 328 << " because the buffer was full."; |
| 315 } | 329 } |
| 316 transfer->bytes_in_flight += kPacketSize; | 330 transfer->bytes_in_flight += kPacketSize; |
| 317 } | 331 } |
| 318 | 332 |
| 319 // Advance the time by |delta| without sending anything. | 333 // Advance the time by |delta| without sending anything. |
| 320 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) { | 334 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) { |
| 321 clock_->AdvanceTime(delta); | 335 clock_->AdvanceTime(delta); |
| 322 } | 336 } |
| 323 | 337 |
| 324 } // namespace net | 338 } // namespace net |
| OLD | NEW |