| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/hybrid_slow_start.h" | 5 #include "net/quic/congestion_control/hybrid_slow_start.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 using std::max; | 9 using std::max; |
| 10 using std::min; | 10 using std::min; |
| 11 | 11 |
| 12 namespace net { | 12 namespace net { |
| 13 | 13 |
| 14 // Note(pwestin): the magic clamping numbers come from the original code in | 14 // Note(pwestin): the magic clamping numbers come from the original code in |
| 15 // tcp_cubic.c. | 15 // tcp_cubic.c. |
| 16 const int64 kHybridStartLowWindow = 16; | 16 const int64 kHybridStartLowWindow = 16; |
| 17 // Number of delay samples for detecting the increase of delay. | 17 // Number of delay samples for detecting the increase of delay. |
| 18 const uint32 kHybridStartMinSamples = 8; | 18 const uint32 kHybridStartMinSamples = 8; |
| 19 const int kHybridStartDelayFactorExp = 4; // 2^4 = 16 | 19 const int kHybridStartDelayFactorExp = 4; // 2^4 = 16 |
| 20 // The original paper specifies 2 and 8ms, but those have changed over time. | 20 // The original paper specifies 2 and 8ms, but those have changed over time. |
| 21 const int64 kHybridStartDelayMinThresholdUs = 4000; | 21 const int64 kHybridStartDelayMinThresholdUs = 4000; |
| 22 const int64 kHybridStartDelayMaxThresholdUs = 16000; | 22 const int64 kHybridStartDelayMaxThresholdUs = 16000; |
| 23 | 23 |
| 24 HybridSlowStart::HybridSlowStart(const QuicClock* clock) | 24 HybridSlowStart::HybridSlowStart(const QuicClock* clock) |
| 25 : clock_(clock), | 25 : clock_(clock), |
| 26 ack_train_detection_(true), |
| 26 started_(false), | 27 started_(false), |
| 27 hystart_found_(NOT_FOUND), | 28 hystart_found_(NOT_FOUND), |
| 28 last_sent_sequence_number_(0), | 29 last_sent_sequence_number_(0), |
| 29 round_start_(QuicTime::Zero()), | 30 round_start_(QuicTime::Zero()), |
| 30 end_sequence_number_(0), | 31 end_sequence_number_(0), |
| 31 last_close_ack_pair_time_(QuicTime::Zero()), | 32 last_close_ack_pair_time_(QuicTime::Zero()), |
| 32 rtt_sample_count_(0), | 33 rtt_sample_count_(0), |
| 33 current_min_rtt_(QuicTime::Delta::Zero()) { | 34 current_min_rtt_(QuicTime::Delta::Zero()) { |
| 34 } | 35 } |
| 35 | 36 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 } | 78 } |
| 78 QuicTime current_time = clock_->ApproximateNow(); | 79 QuicTime current_time = clock_->ApproximateNow(); |
| 79 | 80 |
| 80 // First detection parameter - ack-train detection. | 81 // First detection parameter - ack-train detection. |
| 81 // Since slow start burst out packets we can indirectly estimate the inter- | 82 // Since slow start burst out packets we can indirectly estimate the inter- |
| 82 // arrival time by looking at the arrival time of the ACKs if the ACKs are | 83 // arrival time by looking at the arrival time of the ACKs if the ACKs are |
| 83 // spread out more then half the minimum RTT packets are being spread out | 84 // spread out more then half the minimum RTT packets are being spread out |
| 84 // more than the capacity. | 85 // more than the capacity. |
| 85 // This first trigger will not come into play until we hit roughly 9.6 Mbps | 86 // This first trigger will not come into play until we hit roughly 9.6 Mbps |
| 86 // with delayed acks (or 4.8Mbps without delayed acks) | 87 // with delayed acks (or 4.8Mbps without delayed acks) |
| 87 // TODO(ianswett): QUIC always uses delayed acks, even at the beginning, so | 88 if (ack_train_detection_ && |
| 88 // this should likely be at least 4ms. | 89 current_time.Subtract(last_close_ack_pair_time_).ToMicroseconds() <= |
| 89 // TODO(pwestin): we need to make sure our pacing don't trigger this detector. | |
| 90 // TODO(ianswett): Pacing or other cases could be handled by checking the send | |
| 91 // time of the first acked packet in a receive round. | |
| 92 if (current_time.Subtract(last_close_ack_pair_time_).ToMicroseconds() <= | |
| 93 kHybridStartDelayMinThresholdUs) { | 90 kHybridStartDelayMinThresholdUs) { |
| 94 last_close_ack_pair_time_ = current_time; | 91 last_close_ack_pair_time_ = current_time; |
| 95 if (current_time.Subtract(round_start_).ToMicroseconds() >= | 92 if (current_time.Subtract(round_start_).ToMicroseconds() >= |
| 96 min_rtt.ToMicroseconds() >> 1) { | 93 min_rtt.ToMicroseconds() >> 1) { |
| 97 hystart_found_ = ACK_TRAIN; | 94 hystart_found_ = ACK_TRAIN; |
| 98 } | 95 } |
| 99 } else if (last_close_ack_pair_time_ == round_start_) { | 96 } else if (last_close_ack_pair_time_ == round_start_) { |
| 100 // If the previous ack wasn't close, then move forward the round start time | 97 // If the previous ack wasn't close, then move forward the round start time |
| 101 // to the incoming ack. | 98 // to the incoming ack. |
| 102 last_close_ack_pair_time_ = round_start_ = current_time; | 99 last_close_ack_pair_time_ = round_start_ = current_time; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 129 hystart_found_= DELAY; | 126 hystart_found_= DELAY; |
| 130 } | 127 } |
| 131 } | 128 } |
| 132 // Exit from slow start if the cwnd is greater than 16 and an ack train or | 129 // Exit from slow start if the cwnd is greater than 16 and an ack train or |
| 133 // increasing delay are found. | 130 // increasing delay are found. |
| 134 return congestion_window >= kHybridStartLowWindow && | 131 return congestion_window >= kHybridStartLowWindow && |
| 135 hystart_found_ != NOT_FOUND; | 132 hystart_found_ != NOT_FOUND; |
| 136 } | 133 } |
| 137 | 134 |
| 138 } // namespace net | 135 } // namespace net |
| OLD | NEW |