This is jamesr@ code I am landing.

On Windows the message pump code tried to manage the systemwide timer resolution to fire delayed tasks with better than 15ms resolution but it was buggy:

1- A short task that was not followed by any other task will leave the systemwide timer pegged to 1ms

2- After we decided to crank up the timer we would 'lease' the timer for 1 second, for no good reason.

Both issues are detrimental to battery power.

The source of both problems is that we tried to decide with incomplete information. This patch solves that by having 1 bit for each pending task that requires a high resolution timer and a sum of the number of tasks that require high res timers.

BUG=153139
TEST=included here, also see the bug for manual testing.

Review URL: https://codereview.chromium.org/395913006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@284625 0039d316-1c4b-4281-b951-d872f2087c98


CrOS-Libchrome-Original-Commit: f9855fb1637fbca5d0164ae602b98b6fe460e74b
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h
index a281435..d1e5790 100644
--- a/base/message_loop/message_loop.h
+++ b/base/message_loop/message_loop.h
@@ -371,10 +371,6 @@
   void AddTaskObserver(TaskObserver* task_observer);
   void RemoveTaskObserver(TaskObserver* task_observer);
 
-  // When we go into high resolution timer mode, we will stay in hi-res mode
-  // for at least 1s.
-  static const int kHighResolutionTimerModeLeaseTimeMs = 1000;
-
 #if defined(OS_WIN)
   void set_os_modal_loop(bool os_modal_loop) {
     os_modal_loop_ = os_modal_loop;
@@ -390,7 +386,7 @@
 
   // Returns true if the message loop has high resolution timers enabled.
   // Provided for testing.
-  bool IsHighResolutionTimerEnabledForTesting();
+  bool HasHighResolutionTasks();
 
   // Returns true if the message loop is "idle". Provided for testing.
   bool IsIdleForTesting();
@@ -460,6 +456,14 @@
   // this queue is only accessed (push/pop) by our current thread.
   TaskQueue work_queue_;
 
+  // How many high resolution tasks are in the pending task queue. This value
+  // increases by N every time we call ReloadWorkQueue() and decreases by 1
+  // every time we call RunTask() if the task needs a high resolution timer.
+  int pending_high_res_tasks_;
+  // Tracks if we have requested high resolution timers. Its only use is to
+  // turn off the high resolution timer upon loop destruction.
+  bool in_high_res_mode_;
+
   // Contains delayed tasks, sorted by their 'delayed_run_time' property.
   DelayedTaskQueue delayed_work_queue_;