diff options
author | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-04 23:23:42 +0000 |
---|---|---|
committer | jar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-04 23:23:42 +0000 |
commit | a8f7d3d010cb872f92132c7c2482c6188829346d (patch) | |
tree | fc5d786a39a25d2a7c6df3c03e997ca4dcb51529 /base | |
parent | 8f88ceec4a5bfa25cfc08ef4e8b21753eaf85a72 (diff) | |
download | chromium_src-a8f7d3d010cb872f92132c7c2482c6188829346d.zip chromium_src-a8f7d3d010cb872f92132c7c2482c6188829346d.tar.gz chromium_src-a8f7d3d010cb872f92132c7c2482c6188829346d.tar.bz2 |
Try to improve message_loop efficiency when backlogged
The call to Now() uses a lock to handle roll over events, and that
might make the call more expensive in some scenarios.
Reduce the number of times we need to call Time::Now() when processing
timer events by processing all (fully ripe, and ready to run) events
with only one call to Now(). This should make the queue run faster as
we fall further behind.
I was hoping to see some perf improvement, but I think this will only
have an impact when we are overloaded, which problably doesn't happen
often on the bots. I did some local histogramming, and I do see cases
where we get away with processing several (2-3) events with one call
to Now(), but that is apparently not enough to move the needle on the
perf bots.
r=darin
Review URL: http://codereview.chromium.org/4247003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65131 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/message_loop.cc | 18 | ||||
-rw-r--r-- | base/message_loop.h | 3 |
2 files changed, 17 insertions, 4 deletions
diff --git a/base/message_loop.cc b/base/message_loop.cc index b20e6b6..b860fd8 100644 --- a/base/message_loop.cc +++ b/base/message_loop.cc @@ -542,13 +542,23 @@ bool MessageLoop::DoWork() { bool MessageLoop::DoDelayedWork(base::Time* next_delayed_work_time) { if (!nestable_tasks_allowed_ || delayed_work_queue_.empty()) { - *next_delayed_work_time = base::Time(); + recent_time_ = *next_delayed_work_time = base::Time(); return false; } - if (delayed_work_queue_.top().delayed_run_time > Time::Now()) { - *next_delayed_work_time = delayed_work_queue_.top().delayed_run_time; - return false; + // When we "fall behind," there may be a lot of tasks in the delayed work + // queue that are ready to run. To increase efficiency when we fall behind, + // we will only call Time::Now() intermittently, and then process all tasks + // that are ready to run before calling it again. As a result, the more we + // fall behind (and have a lot of ready-to-run delayed tasks), the more + // efficient we'll be at handling the tasks. + base::Time next_run_time = delayed_work_queue_.top().delayed_run_time; + if (next_run_time > recent_time_) { + recent_time_ = base::Time::Now(); // Get a better view of Now(). + if (next_run_time > recent_time_) { + *next_delayed_work_time = next_run_time; + return false; + } } PendingTask pending_task = delayed_work_queue_.top(); diff --git a/base/message_loop.h b/base/message_loop.h index b182ace..9ac45ab 100644 --- a/base/message_loop.h +++ b/base/message_loop.h @@ -450,6 +450,9 @@ class MessageLoop : public base::MessagePump::Delegate { // Contains delayed tasks, sorted by their 'delayed_run_time' property. DelayedTaskQueue delayed_work_queue_; + // A recent snapshot of Time::Now(), used to check delayed_work_queue_. + base::Time recent_time_; + // A queue of non-nestable tasks that we had to defer because when it came // time to execute them we were in a nested message loop. They will execute // once we're out of nested message loops. |