Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(425)

Side by Side Diff: net/quic/core/congestion_control/cubic_bytes.cc

Issue 2550453002: Fixed integer signing bug in cubic bytes/packet implementation (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2015 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/core/congestion_control/cubic_bytes.h" 5 #include "net/quic/core/congestion_control/cubic_bytes.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 25 matching lines...) Expand all
36 // curve. This additional backoff factor is expected to give up bandwidth to 36 // curve. This additional backoff factor is expected to give up bandwidth to
37 // new concurrent flows and speed up convergence. 37 // new concurrent flows and speed up convergence.
38 const float kBetaLastMax = 0.85f; 38 const float kBetaLastMax = 0.85f;
39 39
40 } // namespace 40 } // namespace
41 41
42 CubicBytes::CubicBytes(const QuicClock* clock) 42 CubicBytes::CubicBytes(const QuicClock* clock)
43 : clock_(clock), 43 : clock_(clock),
44 num_connections_(kDefaultNumConnections), 44 num_connections_(kDefaultNumConnections),
45 epoch_(QuicTime::Zero()), 45 epoch_(QuicTime::Zero()),
46 last_update_time_(QuicTime::Zero()) { 46 last_update_time_(QuicTime::Zero()),
47 fix_convex_mode_(false) {
47 Reset(); 48 Reset();
48 } 49 }
49 50
50 void CubicBytes::SetNumConnections(int num_connections) { 51 void CubicBytes::SetNumConnections(int num_connections) {
51 num_connections_ = num_connections; 52 num_connections_ = num_connections;
52 } 53 }
53 54
54 float CubicBytes::Alpha() const { 55 float CubicBytes::Alpha() const {
55 // TCPFriendly alpha is described in Section 3.3 of the CUBIC paper. Note that 56 // TCPFriendly alpha is described in Section 3.3 of the CUBIC paper. Note that
56 // beta here is a cwnd multiplier, and is equal to 1-beta from the paper. 57 // beta here is a cwnd multiplier, and is equal to 1-beta from the paper.
(...skipping 13 matching lines...) Expand all
70 void CubicBytes::Reset() { 71 void CubicBytes::Reset() {
71 epoch_ = QuicTime::Zero(); // Reset time. 72 epoch_ = QuicTime::Zero(); // Reset time.
72 last_update_time_ = QuicTime::Zero(); // Reset time. 73 last_update_time_ = QuicTime::Zero(); // Reset time.
73 last_congestion_window_ = 0; 74 last_congestion_window_ = 0;
74 last_max_congestion_window_ = 0; 75 last_max_congestion_window_ = 0;
75 acked_bytes_count_ = 0; 76 acked_bytes_count_ = 0;
76 estimated_tcp_congestion_window_ = 0; 77 estimated_tcp_congestion_window_ = 0;
77 origin_point_congestion_window_ = 0; 78 origin_point_congestion_window_ = 0;
78 time_to_origin_point_ = 0; 79 time_to_origin_point_ = 0;
79 last_target_congestion_window_ = 0; 80 last_target_congestion_window_ = 0;
81 fix_convex_mode_ = false;
82 }
83
84 void CubicBytes::SetFixConvexMode(bool fix_convex_mode) {
85 fix_convex_mode_ = fix_convex_mode;
80 } 86 }
81 87
82 void CubicBytes::OnApplicationLimited() { 88 void CubicBytes::OnApplicationLimited() {
83 // When sender is not using the available congestion window, the window does 89 // When sender is not using the available congestion window, the window does
84 // not grow. But to be RTT-independent, Cubic assumes that the sender has been 90 // not grow. But to be RTT-independent, Cubic assumes that the sender has been
85 // using the entire window during the time since the beginning of the current 91 // using the entire window during the time since the beginning of the current
86 // "epoch" (the end of the last loss recovery period). Since 92 // "epoch" (the end of the last loss recovery period). Since
87 // application-limited periods break this assumption, we reset the epoch when 93 // application-limited periods break this assumption, we reset the epoch when
88 // in such a period. This reset effectively freezes congestion window growth 94 // in such a period. This reset effectively freezes congestion window growth
89 // through application-limited periods and allows Cubic growth to continue 95 // through application-limited periods and allows Cubic growth to continue
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 } 145 }
140 } 146 }
141 // Change the time unit from microseconds to 2^10 fractions per second. Take 147 // Change the time unit from microseconds to 2^10 fractions per second. Take
142 // the round trip time in account. This is done to allow us to use shift as a 148 // the round trip time in account. This is done to allow us to use shift as a
143 // divide operator. 149 // divide operator.
144 int64_t elapsed_time = 150 int64_t elapsed_time =
145 ((current_time + delay_min - epoch_).ToMicroseconds() << 10) / 151 ((current_time + delay_min - epoch_).ToMicroseconds() << 10) /
146 kNumMicrosPerSecond; 152 kNumMicrosPerSecond;
147 153
148 int64_t offset = time_to_origin_point_ - elapsed_time; 154 int64_t offset = time_to_origin_point_ - elapsed_time;
155 if (fix_convex_mode_) {
156 // Right-shifts of negative, signed numbers have
157 // implementation-dependent behavior. In the fix, force the
158 // offset to be positive, as is done in the kernel.
159 const int64_t positive_offset = labs(time_to_origin_point_ - elapsed_time);
160 offset = positive_offset;
161 }
149 QuicByteCount delta_congestion_window = 162 QuicByteCount delta_congestion_window =
150 ((kCubeCongestionWindowScale * offset * offset * offset) >> kCubeScale) * 163 ((kCubeCongestionWindowScale * offset * offset * offset) >> kCubeScale) *
151 kDefaultTCPMSS; 164 kDefaultTCPMSS;
152 165
166 const bool add_delta = elapsed_time > time_to_origin_point_;
167 DCHECK(add_delta ||
168 (origin_point_congestion_window_ > delta_congestion_window));
153 QuicByteCount target_congestion_window = 169 QuicByteCount target_congestion_window =
154 origin_point_congestion_window_ - delta_congestion_window; 170 (fix_convex_mode_ && add_delta)
171 ? origin_point_congestion_window_ + delta_congestion_window
172 : origin_point_congestion_window_ - delta_congestion_window;
155 // Limit the CWND increase to half the acked bytes. 173 // Limit the CWND increase to half the acked bytes.
156 target_congestion_window = 174 target_congestion_window =
157 min(target_congestion_window, 175 min(target_congestion_window,
158 current_congestion_window + acked_bytes_count_ / 2); 176 current_congestion_window + acked_bytes_count_ / 2);
159 177
160 DCHECK_LT(0u, estimated_tcp_congestion_window_); 178 DCHECK_LT(0u, estimated_tcp_congestion_window_);
161 // Increase the window by Alpha * 1 MSS of bytes every time we ack an 179 // Increase the window by approximately Alpha * 1 MSS of bytes every
162 // estimated tcp window of bytes. 180 // time we ack an estimated tcp window of bytes. For small
181 // congestion windows (less than 25), the formula below will
182 // increase slightly slower than linearly per estimated tcp window
183 // of bytes.
163 estimated_tcp_congestion_window_ += acked_bytes_count_ * 184 estimated_tcp_congestion_window_ += acked_bytes_count_ *
164 (Alpha() * kDefaultTCPMSS) / 185 (Alpha() * kDefaultTCPMSS) /
165 estimated_tcp_congestion_window_; 186 estimated_tcp_congestion_window_;
166 acked_bytes_count_ = 0; 187 acked_bytes_count_ = 0;
167 188
168 // We have a new cubic congestion window. 189 // We have a new cubic congestion window.
169 last_target_congestion_window_ = target_congestion_window; 190 last_target_congestion_window_ = target_congestion_window;
170 191
171 // Compute target congestion_window based on cubic target and estimated TCP 192 // Compute target congestion_window based on cubic target and estimated TCP
172 // congestion_window, use highest (fastest). 193 // congestion_window, use highest (fastest).
173 if (target_congestion_window < estimated_tcp_congestion_window_) { 194 if (target_congestion_window < estimated_tcp_congestion_window_) {
174 target_congestion_window = estimated_tcp_congestion_window_; 195 target_congestion_window = estimated_tcp_congestion_window_;
175 } 196 }
176 197
177 DVLOG(1) << "Final target congestion_window: " << target_congestion_window; 198 DVLOG(1) << "Final target congestion_window: " << target_congestion_window;
178 return target_congestion_window; 199 return target_congestion_window;
179 } 200 }
180 201
181 } // namespace net 202 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698