diff options
author | evan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-08 03:58:29 +0000 |
---|---|---|
committer | evan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-07-08 03:58:29 +0000 |
commit | 16e0efd89b890932ff32fb612228b48dea4371fa (patch) | |
tree | e8de88cf77fbc568fae0d377392ded1df0cb33f7 /chrome | |
parent | 8351861274bcfad6e2c3580f7256d8d863ac4f17 (diff) | |
download | chromium_src-16e0efd89b890932ff32fb612228b48dea4371fa.zip chromium_src-16e0efd89b890932ff32fb612228b48dea4371fa.tar.gz chromium_src-16e0efd89b890932ff32fb612228b48dea4371fa.tar.bz2 |
linux: port Jankometer
Originally I had split it into multiple files, but I think it's
cleaner to just use one.
(I want to use this for measuring plugin jank.)
BUG=8077
Review URL: http://codereview.chromium.org/155194
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@20130 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/jankometer.cc | 81 | ||||
-rw-r--r-- | chrome/browser/jankometer.h | 10 | ||||
-rw-r--r-- | chrome/chrome.gyp | 2 | ||||
-rw-r--r-- | chrome/common/gtk_util.cc | 73 | ||||
-rw-r--r-- | chrome/common/gtk_util.h | 5 | ||||
-rw-r--r-- | chrome/common/temp_scaffolding_stubs.cc | 2 |
6 files changed, 148 insertions, 25 deletions
diff --git a/chrome/browser/jankometer.cc b/chrome/browser/jankometer.cc index c7bb0a5..1c73d72 100644 --- a/chrome/browser/jankometer.cc +++ b/chrome/browser/jankometer.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -16,9 +16,14 @@ #include "base/thread.h" #include "base/time.h" #include "base/watchdog.h" +#include "build/build_config.h" #include "chrome/browser/browser_process.h" #include "chrome/common/chrome_switches.h" +#if defined(OS_LINUX) +#include "chrome/common/gtk_util.h" +#endif + using base::TimeDelta; using base::TimeTicks; @@ -109,33 +114,24 @@ class JankObserver : public base::RefCountedThreadSafe<JankObserver>, MessageLoopForUI::current()->RemoveObserver(this); } - void WillProcessMessage(const MSG& msg) { - begin_process_message_ = TimeTicks::Now(); - - // GetMessageTime returns a LONG (signed 32-bit) and GetTickCount returns - // a DWORD (unsigned 32-bit). They both wrap around when the time is longer - // than they can hold. I'm not sure if GetMessageTime wraps around to 0, - // or if the original time comes from GetTickCount, it might wrap around - // to -1. - // - // Therefore, I cast to DWORD so if it wraps to -1 we will correct it. If - // it doesn't, then our time delta will be negative if a message happens - // to straddle the wraparound point, it will still be OK. - DWORD cur_message_issue_time = static_cast<DWORD>(msg.time); - DWORD cur_time = GetTickCount(); - queueing_time_ = TimeDelta::FromMilliseconds(cur_time - - cur_message_issue_time); + // Called when a message has just begun processing, initializes + // per-message variables and timers. + void StartProcessingTimers() { // Simulate arming when the message entered the queue. total_time_watchdog_.ArmSomeTimeDeltaAgo(queueing_time_); if (queueing_time_ > MaxMessageDelay_) { // Message is too delayed. queueing_delay_counter_.Increment(); +#if defined(OS_WIN) if (kPlaySounds) MessageBeep(MB_ICONASTERISK); +#endif } } - void DidProcessMessage(const MSG& msg) { + // Called when a message has just finished processing, finalizes + // per-message variables and timers. + void EndProcessingTimers() { total_time_watchdog_.Disarm(); TimeTicks now = TimeTicks::Now(); if (begin_process_message_ != TimeTicks()) { @@ -147,14 +143,61 @@ class JankObserver : public base::RefCountedThreadSafe<JankObserver>, TimeDelta::FromMilliseconds(kMaxMessageProcessingMs)) { // Message took too long to process. slow_processing_counter_.Increment(); +#if defined(OS_WIN) if (kPlaySounds) MessageBeep(MB_ICONHAND); +#endif } } +#if defined(OS_WIN) + virtual void WillProcessMessage(const MSG& msg) { + begin_process_message_ = TimeTicks::Now(); + + // GetMessageTime returns a LONG (signed 32-bit) and GetTickCount returns + // a DWORD (unsigned 32-bit). They both wrap around when the time is longer + // than they can hold. I'm not sure if GetMessageTime wraps around to 0, + // or if the original time comes from GetTickCount, it might wrap around + // to -1. + // + // Therefore, I cast to DWORD so if it wraps to -1 we will correct it. If + // it doesn't, then our time delta will be negative if a message happens + // to straddle the wraparound point, it will still be OK. + DWORD cur_message_issue_time = static_cast<DWORD>(msg.time); + DWORD cur_time = GetTickCount(); + queueing_time_ = + base::TimeDelta::FromMilliseconds(cur_time - cur_message_issue_time); + + StartProcessingTimers(); + } + + virtual void DidProcessMessage(const MSG& msg) { + EndProcessingTimers(); + } +#elif defined(OS_LINUX) + virtual void WillProcessEvent(GdkEvent* event) { + begin_process_message_ = TimeTicks::Now(); + // TODO(evanm): we want to set queueing_time_ using + // event_utils::GetGdkEventTime, but how do you convert that info + // into a delta? + // guint event_time = event_utils::GetGdkEventTime(event); + queueing_time_ = base::TimeDelta::FromMilliseconds(0); + StartProcessingTimers(); + } + + virtual void DidProcessEvent(GdkEvent* event) { + EndProcessingTimers(); + } +#endif + private: const TimeDelta MaxMessageDelay_; + + // Time at which the current message processing began. TimeTicks begin_process_message_; + + // Time the current message spent in the queue -- delta between message + // construction time and message processing time. TimeDelta queueing_time_; // Counters for the two types of jank we measure. @@ -173,7 +216,7 @@ JankObserver* io_observer = NULL; } // namespace -void InstallJankometer(const CommandLine &parsed_command_line) { +void InstallJankometer(const CommandLine& parsed_command_line) { if (ui_observer || io_observer) { NOTREACHED() << "Initializing jank-o-meter twice"; return; diff --git a/chrome/browser/jankometer.h b/chrome/browser/jankometer.h index bd2f5d5..fe5d4f6 100644 --- a/chrome/browser/jankometer.h +++ b/chrome/browser/jankometer.h @@ -1,9 +1,9 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2009 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_JANKOMETER_H__ -#define CHROME_BROWSER_JANKOMETER_H__ +#ifndef CHROME_BROWSER_JANKOMETER_H_ +#define CHROME_BROWSER_JANKOMETER_H_ class CommandLine; @@ -14,9 +14,9 @@ class CommandLine; // // This function will initialize the service, which will install itself in // critical threads. It should be called on the UI thread. -void InstallJankometer(const CommandLine &parsed_command_line); +void InstallJankometer(const CommandLine& parsed_command_line); // Clean up Jank-O-Meter junk void UninstallJankometer(); -#endif // CHROME_BROWSER_JANKOMETER_H__ +#endif // CHROME_BROWSER_JANKOMETER_H_ diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 67b113b9..86359ee 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -1822,6 +1822,7 @@ 'browser/dock_info.cc', 'browser/download/download_exe.cc', 'browser/download/download_request_dialog_delegate_win.cc', + 'browser/jankometer.cc', 'browser/login_prompt.cc', 'browser/password_manager/password_store_gnome.h', 'browser/password_manager/password_store_gnome.cc', @@ -2106,7 +2107,6 @@ 'browser/history_view.cc', 'browser/ime_input.cc', 'browser/importer/ie_importer.cc', - 'browser/jankometer.cc', 'browser/memory_details.cc', 'browser/modal_html_dialog_delegate.cc', 'browser/sandbox_policy.cc', diff --git a/chrome/common/gtk_util.cc b/chrome/common/gtk_util.cc index c126cac..e985bf6 100644 --- a/chrome/common/gtk_util.cc +++ b/chrome/common/gtk_util.cc @@ -61,6 +61,79 @@ WindowOpenDisposition DispositionFromEventFlags(guint event_flags) { return false /*event.IsAltDown()*/ ? SAVE_TO_DISK : CURRENT_TAB; } +guint32 GetGdkEventTime(GdkEvent* event) { + // The order of these entries in the switch statement match the GDK enum. + switch (event->type) { + case GDK_NOTHING: + case GDK_DELETE: + case GDK_DESTROY: + case GDK_EXPOSE: + return 0; + + case GDK_MOTION_NOTIFY: + return reinterpret_cast<GdkEventMotion*>(event)->time; + + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + return reinterpret_cast<GdkEventButton*>(event)->time; + + case GDK_KEY_PRESS: + case GDK_KEY_RELEASE: + return reinterpret_cast<GdkEventKey*>(event)->time; + + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: + return reinterpret_cast<GdkEventCrossing*>(event)->time; + + case GDK_FOCUS_CHANGE: + case GDK_CONFIGURE: + case GDK_MAP: + case GDK_UNMAP: + return 0; + + case GDK_PROPERTY_NOTIFY: + return reinterpret_cast<GdkEventProperty*>(event)->time; + + case GDK_SELECTION_CLEAR: + case GDK_SELECTION_REQUEST: + case GDK_SELECTION_NOTIFY: + return reinterpret_cast<GdkEventSelection*>(event)->time; + + case GDK_PROXIMITY_IN: + case GDK_PROXIMITY_OUT: + return reinterpret_cast<GdkEventProximity*>(event)->time; + + case GDK_DRAG_ENTER: + case GDK_DRAG_LEAVE: + case GDK_DRAG_MOTION: + case GDK_DRAG_STATUS: + case GDK_DROP_START: + case GDK_DROP_FINISHED: + return reinterpret_cast<GdkEventDND*>(event)->time; + + case GDK_CLIENT_EVENT: + case GDK_VISIBILITY_NOTIFY: + case GDK_NO_EXPOSE: + return 0; + + case GDK_SCROLL: + return reinterpret_cast<GdkEventScroll*>(event)->time; + + case GDK_WINDOW_STATE: + case GDK_SETTING: + return 0; + + case GDK_OWNER_CHANGE: + return reinterpret_cast<GdkEventOwnerChange*>(event)->time; + + case GDK_GRAB_BROKEN: + default: + return 0; + } +} + } // namespace event_utils namespace gtk_util { diff --git a/chrome/common/gtk_util.h b/chrome/common/gtk_util.h index e4e7da3..58339d4 100644 --- a/chrome/common/gtk_util.h +++ b/chrome/common/gtk_util.h @@ -22,6 +22,11 @@ namespace event_utils { // event_flags are the state in the GdkEvent structure. WindowOpenDisposition DispositionFromEventFlags(guint state); +// Get the timestamp (milliseconds) out of a GdkEvent. +// Returns 0 if the event has no timestamp. +// TODO(evanm): see comments in jankometer.cc about using this. +guint32 GetGdkEventTime(GdkEvent* event); + } // namespace event_utils namespace gtk_util { diff --git a/chrome/common/temp_scaffolding_stubs.cc b/chrome/common/temp_scaffolding_stubs.cc index 3ba508d..bd2797f 100644 --- a/chrome/common/temp_scaffolding_stubs.cc +++ b/chrome/common/temp_scaffolding_stubs.cc @@ -204,6 +204,7 @@ Upgrade::TryResult ShowTryChromeDialog() { //-------------------------------------------------------------------------- +#if defined(OS_MACOSX) void InstallJankometer(const CommandLine&) { // http://code.google.com/p/chromium/issues/detail?id=8077 } @@ -211,6 +212,7 @@ void InstallJankometer(const CommandLine&) { void UninstallJankometer() { // http://code.google.com/p/chromium/issues/detail?id=8077 } +#endif //-------------------------------------------------------------------------- |