diff options
author | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-28 07:46:56 +0000 |
---|---|---|
committer | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-28 07:46:56 +0000 |
commit | 7024e3fc02ae1b26d47c2235b1b34bdf1f084894 (patch) | |
tree | 258928b48c24643b66955552b61b2a9ce9822f1a /chrome/browser/metrics/thread_watcher.cc | |
parent | 32e56e56e65ebe54ab437c008f0722c2fb0fd875 (diff) | |
download | chromium_src-7024e3fc02ae1b26d47c2235b1b34bdf1f084894.zip chromium_src-7024e3fc02ae1b26d47c2235b1b34bdf1f084894.tar.gz chromium_src-7024e3fc02ae1b26d47c2235b1b34bdf1f084894.tar.bz2 |
Trying changes to see the perfomance impact on Mac.
This change list is same as CL 6588039.
Will back out immediately.
BUG=73915
Review URL: http://codereview.chromium.org/6602004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76199 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/metrics/thread_watcher.cc')
-rw-r--r-- | chrome/browser/metrics/thread_watcher.cc | 176 |
1 files changed, 113 insertions, 63 deletions
diff --git a/chrome/browser/metrics/thread_watcher.cc b/chrome/browser/metrics/thread_watcher.cc index ececcac..54f8bf9 100644 --- a/chrome/browser/metrics/thread_watcher.cc +++ b/chrome/browser/metrics/thread_watcher.cc @@ -2,14 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#if 0 - #include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "chrome/browser/metrics/metrics_service.h" #include "chrome/browser/metrics/thread_watcher.h" #include "chrome/common/notification_service.h" +#if defined(OS_WIN) +#include <Objbase.h> +#endif + // static const int ThreadWatcher::kPingCount = 3; @@ -42,19 +44,20 @@ void ThreadWatcher::StartWatching(const BrowserThread::ID thread_id, DCHECK_GE(sleep_time.InMilliseconds(), 0); DCHECK_GE(unresponsive_time.InMilliseconds(), sleep_time.InMilliseconds()); - // If we are not on WATCHDOG thread, then post a task to call StartWatching on - // WATCHDOG thread. - if (!BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)) { - BrowserThread::PostTask( - BrowserThread::WATCHDOG, - FROM_HERE, - NewRunnableFunction( - &ThreadWatcher::StartWatching, - thread_id, thread_name, sleep_time, unresponsive_time)); + // If we are not on WatchDogThread, then post a task to call StartWatching on + // WatchDogThread. + if (!WatchDogThread::CurrentlyOnWatchDogThread()) { + MessageLoop* message_loop = WatchDogThread::CurrentMessageLoop(); + if (message_loop) + message_loop->PostTask( + FROM_HERE, + NewRunnableFunction( + &ThreadWatcher::StartWatching, + thread_id, thread_name, sleep_time, unresponsive_time)); return; } - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); + DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); // Create a new thread watcher object for the given thread and activate it. ThreadWatcher* watcher = @@ -64,7 +67,7 @@ void ThreadWatcher::StartWatching(const BrowserThread::ID thread_id, } void ThreadWatcher::ActivateThreadWatching() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); + DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); if (active_) return; active_ = true; ping_count_ = kPingCount; @@ -74,14 +77,14 @@ void ThreadWatcher::ActivateThreadWatching() { } void ThreadWatcher::DeActivateThreadWatching() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); + DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); active_ = false; ping_count_ = 0; method_factory_.RevokeAll(); } void ThreadWatcher::WakeUp() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); + DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); // There is some user activity, PostPingMessage task of thread watcher if // needed. if (!active_) return; @@ -95,7 +98,7 @@ void ThreadWatcher::WakeUp() { } void ThreadWatcher::PostPingMessage() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); + DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); // If we have stopped watching or if the user is idle, then stop sending // ping messages. if (!active_ || ping_count_ <= 0) @@ -126,7 +129,7 @@ void ThreadWatcher::PostPingMessage() { } void ThreadWatcher::OnPongMessage(uint64 ping_sequence_number) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); + DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); // Record watched thread's response time. base::TimeDelta response_time = base::TimeTicks::Now() - ping_time_; histogram_->AddTime(response_time); @@ -152,7 +155,7 @@ void ThreadWatcher::OnPongMessage(uint64 ping_sequence_number) { } bool ThreadWatcher::OnCheckResponsiveness(uint64 ping_sequence_number) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); + DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); // If we have stopped watching then consider thread as responding. if (!active_) return true; @@ -178,7 +181,11 @@ void ThreadWatcher::OnPingMessage(const BrowserThread::ID thread_id, Task* callback_task) { // This method is called on watched thread. DCHECK(BrowserThread::CurrentlyOn(thread_id)); - BrowserThread::PostTask(BrowserThread::WATCHDOG, FROM_HERE, callback_task); + MessageLoop* message_loop = WatchDogThread::CurrentMessageLoop(); + if (message_loop) + message_loop->PostTask(FROM_HERE, callback_task); + else + delete callback_task; } //------------------------------------------------------------------------------ @@ -191,22 +198,15 @@ ThreadWatcherList::ThreadWatcherList() : last_wakeup_time_(base::TimeTicks::Now()) { // Assert we are not running on WATCHDOG thread. Would be ideal to assert we // are on UI thread, but Unit tests are not running on UI thread. - DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); - DCHECK(!global_); + DCHECK(!WatchDogThread::CurrentlyOnWatchDogThread()); + CHECK(!global_); global_ = this; // Register Notifications observer. -#if defined(OS_WIN) MetricsService::SetupNotifications(®istrar_, this); -#endif } ThreadWatcherList::~ThreadWatcherList() { base::AutoLock auto_lock(lock_); - while (!registered_.empty()) { - RegistrationList::iterator it = registered_.begin(); - delete it->second; - registered_.erase(it->first); - } DCHECK(this == global_); global_ = NULL; } @@ -224,15 +224,16 @@ void ThreadWatcherList::StopWatchingAll() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); if (!global_) return; - base::AutoLock auto_lock(global_->lock_); - for (RegistrationList::iterator it = global_->registered_.begin(); - global_->registered_.end() != it; - ++it) - BrowserThread::PostTask( - BrowserThread::WATCHDOG, + + // Remove all notifications for all watched threads. + RemoveNotifications(); + + // Delete all thread watcher objects on WatchDogThread. + MessageLoop* message_loop = WatchDogThread::CurrentMessageLoop(); + if (message_loop) + message_loop->PostTask( FROM_HERE, - NewRunnableMethod( - it->second, &ThreadWatcher::DeActivateThreadWatching)); + NewRunnableMethod(global_, &ThreadWatcherList::DeleteAll)); } // static @@ -240,10 +241,18 @@ void ThreadWatcherList::RemoveNotifications() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); if (!global_) return; -#if defined(OS_WIN) base::AutoLock auto_lock(global_->lock_); global_->registrar_.RemoveAll(); -#endif +} + +void ThreadWatcherList::DeleteAll() { + DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); + base::AutoLock auto_lock(lock_); + while (!registered_.empty()) { + RegistrationList::iterator it = registered_.begin(); + delete it->second; + registered_.erase(it->first); + } } void ThreadWatcherList::Observe(NotificationType type, @@ -260,15 +269,17 @@ void ThreadWatcherList::Observe(NotificationType type, last_wakeup_time_ = now; } } - if (need_to_awaken) - BrowserThread::PostTask( - BrowserThread::WATCHDOG, - FROM_HERE, - NewRunnableMethod(this, &ThreadWatcherList::WakeUpAll)); + if (need_to_awaken) { + MessageLoop* message_loop = WatchDogThread::CurrentMessageLoop(); + if (message_loop) + message_loop->PostTask( + FROM_HERE, + NewRunnableMethod(this, &ThreadWatcherList::WakeUpAll)); + } } void ThreadWatcherList::WakeUpAll() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)); + DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); base::AutoLock auto_lock(lock_); for (RegistrationList::iterator it = global_->registered_.begin(); global_->registered_.end() != it; @@ -294,42 +305,81 @@ ThreadWatcher* ThreadWatcherList::PreLockedFind( //------------------------------------------------------------------------------ // WatchDogThread methods and members. +// static +base::Lock WatchDogThread::lock_; +// static +WatchDogThread* WatchDogThread::watchdog_thread_ = NULL; + // The WatchDogThread object must outlive any tasks posted to the IO thread // before the Quit task. DISABLE_RUNNABLE_METHOD_REFCOUNT(WatchDogThread); -WatchDogThread::WatchDogThread() - : BrowserProcessSubThread(BrowserThread::WATCHDOG) { +WatchDogThread::WatchDogThread() : Thread("WATCHDOG") { } WatchDogThread::~WatchDogThread() { - // Remove all notifications for all watched threads. - ThreadWatcherList::RemoveNotifications(); // We cannot rely on our base class to stop the thread since we want our // CleanUp function to run. Stop(); } +void WatchDogThread::StartWatchingAll() { + const base::TimeDelta kSleepTime = base::TimeDelta::FromSeconds(5); + const base::TimeDelta kUnresponsiveTime = base::TimeDelta::FromSeconds(10); + if (BrowserThread::IsMessageLoopValid(BrowserThread::UI)) + ThreadWatcher::StartWatching(BrowserThread::UI, "UI", kSleepTime, + kUnresponsiveTime); + if (BrowserThread::IsMessageLoopValid(BrowserThread::IO)) + ThreadWatcher::StartWatching(BrowserThread::IO, "IO", kSleepTime, + kUnresponsiveTime); + if (BrowserThread::IsMessageLoopValid(BrowserThread::DB)) + ThreadWatcher::StartWatching(BrowserThread::DB, "DB", kSleepTime, + kUnresponsiveTime); + if (BrowserThread::IsMessageLoopValid(BrowserThread::FILE)) + ThreadWatcher::StartWatching(BrowserThread::FILE, "FILE", kSleepTime, + kUnresponsiveTime); + if (BrowserThread::IsMessageLoopValid(BrowserThread::CACHE)) + ThreadWatcher::StartWatching(BrowserThread::CACHE, "CACHE", kSleepTime, + kUnresponsiveTime); +} + +// static +MessageLoop* WatchDogThread::CurrentMessageLoop() { + base::AutoLock lock(lock_); + MessageLoop* message_loop = watchdog_thread_ ? + watchdog_thread_->message_loop() : NULL; + return message_loop; +} + +// static +bool WatchDogThread::CurrentlyOnWatchDogThread() { + base::AutoLock lock(lock_); + return watchdog_thread_ && + watchdog_thread_->message_loop() == MessageLoop::current(); +} + void WatchDogThread::Init() { // This thread shouldn't be allowed to perform any blocking disk I/O. base::ThreadRestrictions::SetIOAllowed(false); - BrowserProcessSubThread::Init(); - #if defined(OS_WIN) - const base::TimeDelta kSleepTime = base::TimeDelta::FromSeconds(5); - const base::TimeDelta kUnresponsiveTime = base::TimeDelta::FromSeconds(10); - ThreadWatcher::StartWatching(BrowserThread::UI, "UI", kSleepTime, - kUnresponsiveTime); - ThreadWatcher::StartWatching(BrowserThread::IO, "IO", kSleepTime, - kUnresponsiveTime); - ThreadWatcher::StartWatching(BrowserThread::DB, "DB", kSleepTime, - kUnresponsiveTime); - ThreadWatcher::StartWatching(BrowserThread::FILE, "FILE", kSleepTime, - kUnresponsiveTime); - ThreadWatcher::StartWatching(BrowserThread::CACHE, "CACHE", kSleepTime, - kUnresponsiveTime); + // Initializes the COM library on the current thread. + CoInitialize(NULL); #endif + + base::AutoLock lock(lock_); + watchdog_thread_ = this; +} + +void WatchDogThread::CleanUp() { + base::AutoLock lock(lock_); + watchdog_thread_ = NULL; } -#endif // 0 +void WatchDogThread::CleanUpAfterMessageLoopDestruction() { +#if defined(OS_WIN) + // Closes the COM library on the current thread. CoInitialize must + // be balanced by a corresponding call to CoUninitialize. + CoUninitialize(); +#endif +} |