summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-04 23:23:42 +0000
committerjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-04 23:23:42 +0000
commita8f7d3d010cb872f92132c7c2482c6188829346d (patch)
treefc5d786a39a25d2a7c6df3c03e997ca4dcb51529 /base
parent8f88ceec4a5bfa25cfc08ef4e8b21753eaf85a72 (diff)
downloadchromium_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.cc18
-rw-r--r--base/message_loop.h3
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.