summaryrefslogtreecommitdiffstats
path: root/base/message_loop.cc
diff options
context:
space:
mode:
authorjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-21 06:11:11 +0000
committerjar@chromium.org <jar@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-21 06:11:11 +0000
commit0bb07852c6769a990a585a740613014520503dfe (patch)
treee9d580bd4286e428f66aba5c64e83fab475e4f5a /base/message_loop.cc
parentf6f7e9f58f9d8c6b676ae26f462a4bb9f079bdcd (diff)
downloadchromium_src-0bb07852c6769a990a585a740613014520503dfe.zip
chromium_src-0bb07852c6769a990a585a740613014520503dfe.tar.gz
chromium_src-0bb07852c6769a990a585a740613014520503dfe.tar.bz2
Test of performance value of reducing calls to Now().
I'll revert asap, once the perf bots have kicked off. TBR=mbelshe Review URL: http://codereview.chromium.org/3936003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@63332 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/message_loop.cc')
-rw-r--r--base/message_loop.cc47
1 files changed, 39 insertions, 8 deletions
diff --git a/base/message_loop.cc b/base/message_loop.cc
index 8f6c997b..50bd44c 100644
--- a/base/message_loop.cc
+++ b/base/message_loop.cc
@@ -494,6 +494,11 @@ bool MessageLoop::DeletePendingTasks() {
delete task;
}
did_work |= !delayed_work_queue_.empty();
+ while (!ripe_work_queue_.empty()) {
+ Task* task = ripe_work_queue_.front().task;
+ delayed_work_queue_.pop();
+ delete task;
+ }
while (!delayed_work_queue_.empty()) {
Task* task = delayed_work_queue_.top().task;
delayed_work_queue_.pop();
@@ -520,7 +525,8 @@ bool MessageLoop::DoWork() {
if (!pending_task.delayed_run_time.is_null()) {
AddToDelayedWorkQueue(pending_task);
// If we changed the topmost task, then it is time to re-schedule.
- if (delayed_work_queue_.top().task == pending_task.task)
+ if (ripe_work_queue_.empty() &&
+ delayed_work_queue_.top().task == pending_task.task)
pump_->ScheduleDelayedWork(pending_task.delayed_run_time);
} else {
if (DeferOrRunPendingTask(pending_task))
@@ -534,21 +540,46 @@ bool MessageLoop::DoWork() {
}
bool MessageLoop::DoDelayedWork(Time* next_delayed_work_time) {
- if (!nestable_tasks_allowed_ || delayed_work_queue_.empty()) {
+ if (!nestable_tasks_allowed_ ||
+ (delayed_work_queue_.empty() && ripe_work_queue_.empty())) {
*next_delayed_work_time = 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 will 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() once, and then move all ready-to-run tasks
+ // (i.e., tasks that are "ripe") into ripe_work_queue_. 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.
+
+ if (ripe_work_queue_.empty()) {
+ base::Time now(Time::Now());
+
+ if (delayed_work_queue_.top().delayed_run_time > now) {
+ *next_delayed_work_time = delayed_work_queue_.top().delayed_run_time;
+ return false;
+ }
+
+ do {
+ ripe_work_queue_.push(delayed_work_queue_.top());
+ delayed_work_queue_.pop();
+ } while (!delayed_work_queue_.empty() &&
+ (delayed_work_queue_.top().delayed_run_time <= now));
+ /* DHISTOGRAM_COUNTS("Chrome.RipeSize",
+ static_cast<int>(ripe_work_queue_.size()));
+ */
}
- PendingTask pending_task = delayed_work_queue_.top();
- delayed_work_queue_.pop();
+ PendingTask pending_task = ripe_work_queue_.front();
+ ripe_work_queue_.pop();
- if (!delayed_work_queue_.empty())
+ if (!ripe_work_queue_.empty())
+ *next_delayed_work_time = ripe_work_queue_.front().delayed_run_time;
+ else if (!delayed_work_queue_.empty())
*next_delayed_work_time = delayed_work_queue_.top().delayed_run_time;
+ else
+ *next_delayed_work_time = Time();
return DeferOrRunPendingTask(pending_task);
}