Add instrumentation to the MessagePumpMac family of classes.
This adds UMA-uploaded histograms of sampling intervals for key points of data:
* Total time spent in a CFRunLoop
* Total time waiting in CFRunLoop
* Total time servicing MessagePump::Delegate (the MessageLoop)
* The MessageLoop queue size and queueing delay before servicing
It adds 1 second sampling for 15 seconds at startup, only for the main thread
(NSApplication-based) run loops.
The data will be used to determine if adding scheduling-like behavior to the
MessagePump will result in more efficient processing of the MessageLoop work.
An unforunate side effect of this change is exposing another method on the
MessagePump::Delegate interface, but there does not appear to be a better way
to do this.
BUG=264886
R=jar@chromium.org, mark@chromium.org
Review URL: https://codereview.chromium.org/22911026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@221427 0039d316-1c4b-4281-b951-d872f2087c98
CrOS-Libchrome-Original-Commit: 370d7cb8ebcaaac4cf1f9075981b41de92348bc7
diff --git a/base/message_loop/message_loop.cc b/base/message_loop/message_loop.cc
index 701594a..cf0b31c 100644
--- a/base/message_loop/message_loop.cc
+++ b/base/message_loop/message_loop.cc
@@ -660,6 +660,20 @@
return false;
}
+void MessageLoop::GetQueueingInformation(size_t* queue_size,
+ TimeDelta* queueing_delay) {
+ *queue_size = work_queue_.size();
+ if (*queue_size == 0) {
+ *queueing_delay = TimeDelta();
+ return;
+ }
+
+ const PendingTask& next_to_run = work_queue_.front();
+ tracked_objects::Duration duration =
+ tracked_objects::TrackedTime::Now() - next_to_run.EffectiveTimePosted();
+ *queueing_delay = TimeDelta::FromMilliseconds(duration.InMilliseconds());
+}
+
void MessageLoop::DeleteSoonInternal(const tracked_objects::Location& from_here,
void(*deleter)(const void*),
const void* object) {
diff --git a/base/message_loop/message_loop.h b/base/message_loop/message_loop.h
index f22c904..db6aa9b 100644
--- a/base/message_loop/message_loop.h
+++ b/base/message_loop/message_loop.h
@@ -478,6 +478,8 @@
virtual bool DoWork() OVERRIDE;
virtual bool DoDelayedWork(TimeTicks* next_delayed_work_time) OVERRIDE;
virtual bool DoIdleWork() OVERRIDE;
+ virtual void GetQueueingInformation(size_t* queue_size,
+ TimeDelta* queueing_delay) OVERRIDE;
Type type_;
diff --git a/base/message_loop/message_pump.h b/base/message_loop/message_pump.h
index 0ebba3a..816bb3c 100644
--- a/base/message_loop/message_pump.h
+++ b/base/message_loop/message_pump.h
@@ -6,10 +6,12 @@
#define BASE_MESSAGE_LOOP_MESSAGE_PUMP_H_
#include "base/base_export.h"
+#include "base/basictypes.h"
#include "base/threading/non_thread_safe.h"
namespace base {
+class TimeDelta;
class TimeTicks;
class BASE_EXPORT MessagePump : public NonThreadSafe {
@@ -39,6 +41,19 @@
// Called from within Run just before the message pump goes to sleep.
// Returns true to indicate that idle work was done.
virtual bool DoIdleWork() = 0;
+
+ // Via the two required out pointers, returns the length of the Delegate's
+ // work queue and the length of time that the first item in the queue has
+ // been waiting to run. If the work queue is empty, the count and delay
+ // will both be zero.
+ // Note that this only counts the tasks in the ready-to-run queue and not
+ // the incoming queue that is used by other threads to post tasks. The
+ // latter queue requires holding a lock, which is deemed too expensive for
+ // instrumentation code. Under normal conditions, the incoming queue should
+ // be small or zero, but under heavy loads it may be much larger and
+ // |queue_count| may be up to 1/4 the size of the incoming queue.
+ virtual void GetQueueingInformation(size_t* queue_count,
+ TimeDelta* queueing_delay) {}
};
MessagePump();