| 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/cubic.h" | 5 #include "net/quic/congestion_control/cubic.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 last_update_time_ = QuicTime::Zero(); // Reset time. | 71 last_update_time_ = QuicTime::Zero(); // Reset time. |
| 72 last_congestion_window_ = 0; | 72 last_congestion_window_ = 0; |
| 73 last_max_congestion_window_ = 0; | 73 last_max_congestion_window_ = 0; |
| 74 acked_packets_count_ = 0; | 74 acked_packets_count_ = 0; |
| 75 estimated_tcp_congestion_window_ = 0; | 75 estimated_tcp_congestion_window_ = 0; |
| 76 origin_point_congestion_window_ = 0; | 76 origin_point_congestion_window_ = 0; |
| 77 time_to_origin_point_ = 0; | 77 time_to_origin_point_ = 0; |
| 78 last_target_congestion_window_ = 0; | 78 last_target_congestion_window_ = 0; |
| 79 } | 79 } |
| 80 | 80 |
| 81 void Cubic::UpdateCongestionControlStats( | 81 void Cubic::UpdateCongestionControlStats(QuicPacketCount new_cubic_mode_cwnd, |
| 82 QuicTcpCongestionWindow new_cubic_mode_cwnd, | 82 QuicPacketCount new_reno_mode_cwnd) { |
| 83 QuicTcpCongestionWindow new_reno_mode_cwnd) { | |
| 84 | 83 |
| 85 QuicTcpCongestionWindow highest_new_cwnd = max(new_cubic_mode_cwnd, | 84 QuicPacketCount highest_new_cwnd = max(new_cubic_mode_cwnd, |
| 86 new_reno_mode_cwnd); | 85 new_reno_mode_cwnd); |
| 87 if (last_congestion_window_ < highest_new_cwnd) { | 86 if (last_congestion_window_ < highest_new_cwnd) { |
| 88 // cwnd will increase to highest_new_cwnd. | 87 // cwnd will increase to highest_new_cwnd. |
| 89 stats_->cwnd_increase_congestion_avoidance += | 88 stats_->cwnd_increase_congestion_avoidance += |
| 90 highest_new_cwnd - last_congestion_window_; | 89 highest_new_cwnd - last_congestion_window_; |
| 91 if (new_cubic_mode_cwnd > new_reno_mode_cwnd) { | 90 if (new_cubic_mode_cwnd > new_reno_mode_cwnd) { |
| 92 // This cwnd increase is due to cubic mode. | 91 // This cwnd increase is due to cubic mode. |
| 93 stats_->cwnd_increase_cubic_mode += | 92 stats_->cwnd_increase_cubic_mode += |
| 94 new_cubic_mode_cwnd - last_congestion_window_; | 93 new_cubic_mode_cwnd - last_congestion_window_; |
| 95 } | 94 } |
| 96 } | 95 } |
| 97 } | 96 } |
| 98 | 97 |
| 99 QuicTcpCongestionWindow Cubic::CongestionWindowAfterPacketLoss( | 98 QuicPacketCount Cubic::CongestionWindowAfterPacketLoss( |
| 100 QuicTcpCongestionWindow current_congestion_window) { | 99 QuicPacketCount current_congestion_window) { |
| 101 if (current_congestion_window < last_max_congestion_window_) { | 100 if (current_congestion_window < last_max_congestion_window_) { |
| 102 // We never reached the old max, so assume we are competing with another | 101 // We never reached the old max, so assume we are competing with another |
| 103 // flow. Use our extra back off factor to allow the other flow to go up. | 102 // flow. Use our extra back off factor to allow the other flow to go up. |
| 104 last_max_congestion_window_ = | 103 last_max_congestion_window_ = |
| 105 static_cast<int>(kBetaLastMax * current_congestion_window); | 104 static_cast<int>(kBetaLastMax * current_congestion_window); |
| 106 } else { | 105 } else { |
| 107 last_max_congestion_window_ = current_congestion_window; | 106 last_max_congestion_window_ = current_congestion_window; |
| 108 } | 107 } |
| 109 epoch_ = QuicTime::Zero(); // Reset time. | 108 epoch_ = QuicTime::Zero(); // Reset time. |
| 110 return static_cast<int>(current_congestion_window * Beta()); | 109 return static_cast<int>(current_congestion_window * Beta()); |
| 111 } | 110 } |
| 112 | 111 |
| 113 QuicTcpCongestionWindow Cubic::CongestionWindowAfterAck( | 112 QuicPacketCount Cubic::CongestionWindowAfterAck( |
| 114 QuicTcpCongestionWindow current_congestion_window, | 113 QuicPacketCount current_congestion_window, |
| 115 QuicTime::Delta delay_min) { | 114 QuicTime::Delta delay_min) { |
| 116 acked_packets_count_ += 1; // Packets acked. | 115 acked_packets_count_ += 1; // Packets acked. |
| 117 QuicTime current_time = clock_->ApproximateNow(); | 116 QuicTime current_time = clock_->ApproximateNow(); |
| 118 | 117 |
| 119 // Cubic is "independent" of RTT, the update is limited by the time elapsed. | 118 // Cubic is "independent" of RTT, the update is limited by the time elapsed. |
| 120 if (last_congestion_window_ == current_congestion_window && | 119 if (last_congestion_window_ == current_congestion_window && |
| 121 (current_time.Subtract(last_update_time_) <= MaxCubicTimeInterval())) { | 120 (current_time.Subtract(last_update_time_) <= MaxCubicTimeInterval())) { |
| 122 return max(last_target_congestion_window_, | 121 return max(last_target_congestion_window_, |
| 123 estimated_tcp_congestion_window_); | 122 estimated_tcp_congestion_window_); |
| 124 } | 123 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 143 } | 142 } |
| 144 } | 143 } |
| 145 // Change the time unit from microseconds to 2^10 fractions per second. Take | 144 // Change the time unit from microseconds to 2^10 fractions per second. Take |
| 146 // the round trip time in account. This is done to allow us to use shift as a | 145 // the round trip time in account. This is done to allow us to use shift as a |
| 147 // divide operator. | 146 // divide operator. |
| 148 int64 elapsed_time = | 147 int64 elapsed_time = |
| 149 (current_time.Add(delay_min).Subtract(epoch_).ToMicroseconds() << 10) / | 148 (current_time.Add(delay_min).Subtract(epoch_).ToMicroseconds() << 10) / |
| 150 base::Time::kMicrosecondsPerSecond; | 149 base::Time::kMicrosecondsPerSecond; |
| 151 | 150 |
| 152 int64 offset = time_to_origin_point_ - elapsed_time; | 151 int64 offset = time_to_origin_point_ - elapsed_time; |
| 153 QuicTcpCongestionWindow delta_congestion_window = (kCubeCongestionWindowScale | 152 QuicPacketCount delta_congestion_window = (kCubeCongestionWindowScale |
| 154 * offset * offset * offset) >> kCubeScale; | 153 * offset * offset * offset) >> kCubeScale; |
| 155 | 154 |
| 156 QuicTcpCongestionWindow target_congestion_window = | 155 QuicPacketCount target_congestion_window = |
| 157 origin_point_congestion_window_ - delta_congestion_window; | 156 origin_point_congestion_window_ - delta_congestion_window; |
| 158 | 157 |
| 159 DCHECK_LT(0u, estimated_tcp_congestion_window_); | 158 DCHECK_LT(0u, estimated_tcp_congestion_window_); |
| 160 // With dynamic beta/alpha based on number of active streams, it is possible | 159 // With dynamic beta/alpha based on number of active streams, it is possible |
| 161 // for the required_ack_count to become much lower than acked_packets_count_ | 160 // for the required_ack_count to become much lower than acked_packets_count_ |
| 162 // suddenly, leading to more than one iteration through the following loop. | 161 // suddenly, leading to more than one iteration through the following loop. |
| 163 while (true) { | 162 while (true) { |
| 164 // Update estimated TCP congestion_window. | 163 // Update estimated TCP congestion_window. |
| 165 uint32 required_ack_count = | 164 uint32 required_ack_count = |
| 166 estimated_tcp_congestion_window_ / Alpha(); | 165 estimated_tcp_congestion_window_ / Alpha(); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 182 // congestion_window, use highest (fastest). | 181 // congestion_window, use highest (fastest). |
| 183 if (target_congestion_window < estimated_tcp_congestion_window_) { | 182 if (target_congestion_window < estimated_tcp_congestion_window_) { |
| 184 target_congestion_window = estimated_tcp_congestion_window_; | 183 target_congestion_window = estimated_tcp_congestion_window_; |
| 185 } | 184 } |
| 186 | 185 |
| 187 DVLOG(1) << "Target congestion_window: " << target_congestion_window; | 186 DVLOG(1) << "Target congestion_window: " << target_congestion_window; |
| 188 return target_congestion_window; | 187 return target_congestion_window; |
| 189 } | 188 } |
| 190 | 189 |
| 191 } // namespace net | 190 } // namespace net |
| OLD | NEW |