diff options
-rw-r--r-- | chrome/renderer/render_view.cc | 10 | ||||
-rw-r--r-- | net/socket/tcp_client_socket_win.cc | 43 |
2 files changed, 52 insertions, 1 deletions
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 7d2d9f7..442b929 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -3246,6 +3246,16 @@ void RenderView::DumpLoadHistograms() const { finish - start, kBeginToFinishMin, kBeginToFinishMax, kBeginToFinishBucketCount); + static bool use_async_tcp(FieldTrialList::Find("AsyncSlowStart") && + !FieldTrialList::Find("AsyncSlowStart")->group_name().empty()); + if (use_async_tcp) { + UMA_HISTOGRAM_CUSTOM_TIMES( + FieldTrial::MakeName("Renderer4.StartToFinish", + "AsyncSlowStart").data(), + finish - start, kBeginToFinishMin, + kBeginToFinishMax, kBeginToFinishBucketCount); + } + UMA_HISTOGRAM_MEDIUM_TIMES("Renderer4.CommitToFinish", finish - commit); if (!first_paint.is_null()) { diff --git a/net/socket/tcp_client_socket_win.cc b/net/socket/tcp_client_socket_win.cc index de3cac6..eeefb70 100644 --- a/net/socket/tcp_client_socket_win.cc +++ b/net/socket/tcp_client_socket_win.cc @@ -6,6 +6,7 @@ #include "base/basictypes.h" #include "base/compiler_specific.h" +#include "base/field_trial.h" // for SlowStart trial #include "base/memory_debug.h" #include "base/string_util.h" #include "base/sys_info.h" @@ -118,6 +119,19 @@ class TCPClientSocketWin::Core : public base::RefCounted<Core> { scoped_refptr<IOBuffer> read_iobuffer_; scoped_refptr<IOBuffer> write_iobuffer_; + // Throttle the read size based on our current slow start state. + // Returns the throttled read size. + int ThrottleReadSize(int size) { + if (!use_slow_start_throttle_) + return size; + + if (slow_start_throttle_ < kMaxSlowStartThrottle) { + size = std::min(size, slow_start_throttle_); + slow_start_throttle_ *= 2; + } + return size; + } + private: class ReadDelegate : public base::ObjectWatcher::Delegate { public: @@ -156,16 +170,41 @@ class TCPClientSocketWin::Core : public base::RefCounted<Core> { // |write_watcher_| watches for events from Write(); base::ObjectWatcher write_watcher_; + // When doing reads from the socket, we try to mirror TCP's slow start. + // We do this because otherwise the async IO subsystem artifically delays + // returning data to the application. + static const int kInitialSlowStartThrottle = 1 * 1024; + static const int kMaxSlowStartThrottle = 32 * kInitialSlowStartThrottle; + int slow_start_throttle_; + + static bool use_slow_start_throttle_; + static bool trial_initialized_; + DISALLOW_COPY_AND_ASSIGN(Core); }; +bool TCPClientSocketWin::Core::use_slow_start_throttle_ = true; +bool TCPClientSocketWin::Core::trial_initialized_ = false; + TCPClientSocketWin::Core::Core( TCPClientSocketWin* socket) : socket_(socket), ALLOW_THIS_IN_INITIALIZER_LIST(reader_(this)), - ALLOW_THIS_IN_INITIALIZER_LIST(writer_(this)) { + ALLOW_THIS_IN_INITIALIZER_LIST(writer_(this)), + slow_start_throttle_(kInitialSlowStartThrottle) { memset(&read_overlapped_, 0, sizeof(read_overlapped_)); memset(&write_overlapped_, 0, sizeof(write_overlapped_)); + + // Initialize the AsyncSlowStart FieldTrial. + if (!trial_initialized_) { + trial_initialized_ = true; + scoped_refptr<FieldTrial> trial = new FieldTrial("AsyncSlowStart", 100); + int my_group = trial->AppendGroup("_AsyncSlowStart", 50); + trial->AppendGroup("_AsyncSlowStart_off", 50); + + // Only use the throttling if the FieldTrial is enabled. + use_slow_start_throttle_ = trial->group() == my_group; + } } TCPClientSocketWin::Core::~Core() { @@ -366,6 +405,8 @@ int TCPClientSocketWin::Read(IOBuffer* buf, DCHECK(!read_callback_); DCHECK(!core_->read_iobuffer_); + buf_len = core_->ThrottleReadSize(buf_len); + core_->read_buffer_.len = buf_len; core_->read_buffer_.buf = buf->data(); |