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