| 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 <stdint.h> | 7 #include <stdint.h> |
| 8 #include <algorithm> | 8 #include <algorithm> |
| 9 #include <cmath> | 9 #include <cmath> |
| 10 | 10 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 } | 110 } |
| 111 | 111 |
| 112 QuicPacketCount Cubic::CongestionWindowAfterAck( | 112 QuicPacketCount Cubic::CongestionWindowAfterAck( |
| 113 QuicPacketCount current_congestion_window, | 113 QuicPacketCount current_congestion_window, |
| 114 QuicTime::Delta delay_min) { | 114 QuicTime::Delta delay_min) { |
| 115 acked_packets_count_ += 1; // Packets acked. | 115 acked_packets_count_ += 1; // Packets acked. |
| 116 QuicTime current_time = clock_->ApproximateNow(); | 116 QuicTime current_time = clock_->ApproximateNow(); |
| 117 | 117 |
| 118 // 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. |
| 119 if (last_congestion_window_ == current_congestion_window && | 119 if (last_congestion_window_ == current_congestion_window && |
| 120 (current_time.Subtract(last_update_time_) <= MaxCubicTimeInterval())) { | 120 (current_time - last_update_time_ <= MaxCubicTimeInterval())) { |
| 121 return max(last_target_congestion_window_, | 121 return max(last_target_congestion_window_, |
| 122 estimated_tcp_congestion_window_); | 122 estimated_tcp_congestion_window_); |
| 123 } | 123 } |
| 124 last_congestion_window_ = current_congestion_window; | 124 last_congestion_window_ = current_congestion_window; |
| 125 last_update_time_ = current_time; | 125 last_update_time_ = current_time; |
| 126 | 126 |
| 127 if (!epoch_.IsInitialized()) { | 127 if (!epoch_.IsInitialized()) { |
| 128 // First ACK after a loss event. | 128 // First ACK after a loss event. |
| 129 epoch_ = current_time; // Start of epoch. | 129 epoch_ = current_time; // Start of epoch. |
| 130 acked_packets_count_ = 1; // Reset count. | 130 acked_packets_count_ = 1; // Reset count. |
| 131 // Reset estimated_tcp_congestion_window_ to be in sync with cubic. | 131 // Reset estimated_tcp_congestion_window_ to be in sync with cubic. |
| 132 estimated_tcp_congestion_window_ = current_congestion_window; | 132 estimated_tcp_congestion_window_ = current_congestion_window; |
| 133 if (last_max_congestion_window_ <= current_congestion_window) { | 133 if (last_max_congestion_window_ <= current_congestion_window) { |
| 134 time_to_origin_point_ = 0; | 134 time_to_origin_point_ = 0; |
| 135 origin_point_congestion_window_ = current_congestion_window; | 135 origin_point_congestion_window_ = current_congestion_window; |
| 136 } else { | 136 } else { |
| 137 time_to_origin_point_ = static_cast<uint32_t>( | 137 time_to_origin_point_ = static_cast<uint32_t>( |
| 138 cbrt(kCubeFactor * | 138 cbrt(kCubeFactor * |
| 139 (last_max_congestion_window_ - current_congestion_window))); | 139 (last_max_congestion_window_ - current_congestion_window))); |
| 140 origin_point_congestion_window_ = last_max_congestion_window_; | 140 origin_point_congestion_window_ = last_max_congestion_window_; |
| 141 } | 141 } |
| 142 } else { | 142 } else { |
| 143 // If sender was app-limited, then freeze congestion window growth during | 143 // If sender was app-limited, then freeze congestion window growth during |
| 144 // app-limited period. Continue growth now by shifting the epoch-start | 144 // app-limited period. Continue growth now by shifting the epoch-start |
| 145 // through the app-limited period. | 145 // through the app-limited period. |
| 146 if (FLAGS_shift_quic_cubic_epoch_when_app_limited && | 146 if (FLAGS_shift_quic_cubic_epoch_when_app_limited && |
| 147 app_limited_start_time_ != QuicTime::Zero()) { | 147 app_limited_start_time_ != QuicTime::Zero()) { |
| 148 QuicTime::Delta shift = current_time.Subtract(app_limited_start_time_); | 148 QuicTime::Delta shift = current_time - app_limited_start_time_; |
| 149 DVLOG(1) << "Shifting epoch for quiescence by " << shift.ToMicroseconds(); | 149 DVLOG(1) << "Shifting epoch for quiescence by " << shift.ToMicroseconds(); |
| 150 epoch_ = epoch_.Add(shift); | 150 epoch_ = epoch_ + shift; |
| 151 app_limited_start_time_ = QuicTime::Zero(); | 151 app_limited_start_time_ = QuicTime::Zero(); |
| 152 } | 152 } |
| 153 } | 153 } |
| 154 | 154 |
| 155 // Change the time unit from microseconds to 2^10 fractions per second. Take | 155 // Change the time unit from microseconds to 2^10 fractions per second. Take |
| 156 // the round trip time in account. This is done to allow us to use shift as a | 156 // the round trip time in account. This is done to allow us to use shift as a |
| 157 // divide operator. | 157 // divide operator. |
| 158 int64_t elapsed_time = | 158 int64_t elapsed_time = |
| 159 (current_time.Add(delay_min).Subtract(epoch_).ToMicroseconds() << 10) / | 159 ((current_time + delay_min - epoch_).ToMicroseconds() << 10) / |
| 160 kNumMicrosPerSecond; | 160 kNumMicrosPerSecond; |
| 161 | 161 |
| 162 int64_t offset = time_to_origin_point_ - elapsed_time; | 162 int64_t offset = time_to_origin_point_ - elapsed_time; |
| 163 QuicPacketCount delta_congestion_window = | 163 QuicPacketCount delta_congestion_window = |
| 164 (kCubeCongestionWindowScale * offset * offset * offset) >> kCubeScale; | 164 (kCubeCongestionWindowScale * offset * offset * offset) >> kCubeScale; |
| 165 | 165 |
| 166 QuicPacketCount target_congestion_window = | 166 QuicPacketCount target_congestion_window = |
| 167 origin_point_congestion_window_ - delta_congestion_window; | 167 origin_point_congestion_window_ - delta_congestion_window; |
| 168 | 168 |
| 169 DCHECK_LT(0u, estimated_tcp_congestion_window_); | 169 DCHECK_LT(0u, estimated_tcp_congestion_window_); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 188 // congestion_window, use highest (fastest). | 188 // congestion_window, use highest (fastest). |
| 189 if (target_congestion_window < estimated_tcp_congestion_window_) { | 189 if (target_congestion_window < estimated_tcp_congestion_window_) { |
| 190 target_congestion_window = estimated_tcp_congestion_window_; | 190 target_congestion_window = estimated_tcp_congestion_window_; |
| 191 } | 191 } |
| 192 | 192 |
| 193 DVLOG(1) << "Final target congestion_window: " << target_congestion_window; | 193 DVLOG(1) << "Final target congestion_window: " << target_congestion_window; |
| 194 return target_congestion_window; | 194 return target_congestion_window; |
| 195 } | 195 } |
| 196 | 196 |
| 197 } // namespace net | 197 } // namespace net |
| OLD | NEW |