Avoid scheduling a message loop that we know is not sleeping

When tasks are posted to a message loop, we may need to schedule the
message loop to wake up if it was sleeping so it processes the message.
The incoming task queue checks whether the incoming queue was already
empty as a way to avoid scheduling unnecessarily, but we can be more
precise. Once a message loop is scheduled, we know that it will sooner
or later wake up and enter its run loop. In its run loop it will
repeatedly drain the work queue and attempt to reload from the incoming
queue until there is no work immediately available to do. This means that
before waiting for more work the loop will always reload from an empty
incoming queue. Thus, once we schedule a loop we do not need to schedule
the same loop again until after an empty reload occurs.

This adds a bool to IncomingTaskQueue protected by the incoming task
queue lock that keeps track of if the loop has been scheduled since the
last empty reload.

Local testing on Linux desktop and a ChromeShell Android build shows
that this avoids roughly 40% of the ScheduleWork calls when browsing
around to random websites.

This also has the very nice consequence that when running a task and
posting another task to the same thread we *never* need to invoke
ScheduleWork which avoids the cost of the ScheduleWork call and avoids
a spurious wakeup when going to sleep.

BUG=412137

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

Cr-Commit-Position: refs/heads/master@{#308221}


CrOS-Libchrome-Original-Commit: 23a5e54a3ae47b3f5dfb9ca62e19f10db02d1b42
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc
index 2f4a03c..8180733 100644
--- a/base/message_loop/message_loop.cc
+++ b/base/message_loop/message_loop.cc
@@ -86,18 +86,6 @@
 
 MessageLoop::MessagePumpFactory* message_pump_for_ui_factory_ = NULL;
 
-// Returns true if MessagePump::ScheduleWork() must be called one
-// time for every task that is added to the MessageLoop incoming queue.
-bool AlwaysNotifyPump(MessageLoop::Type type) {
-#if defined(OS_ANDROID)
-  // The Android UI message loop needs to get notified each time a task is added
-  // to the incoming queue.
-  return type == MessageLoop::TYPE_UI || type == MessageLoop::TYPE_JAVA;
-#else
-  return false;
-#endif
-}
-
 #if defined(OS_IOS)
 typedef MessagePumpIOSForIO MessagePumpForIO;
 #elif defined(OS_NACL_SFI)
@@ -512,9 +500,8 @@
   }
 }
 
-void MessageLoop::ScheduleWork(bool was_empty) {
-  if (was_empty || AlwaysNotifyPump(type_))
-    pump_->ScheduleWork();
+void MessageLoop::ScheduleWork() {
+  pump_->ScheduleWork();
 }
 
 //------------------------------------------------------------------------------