Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/common/startup_metric_utils.h" | 5 #include "chrome/common/startup_metric_utils.h" |
| 6 | 6 |
| 7 #include "base/hash_tables.h" | |
| 7 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/metrics/histogram.h" | |
| 10 #include "base/synchronization/lock.h" | |
| 11 #include "base/sys_info.h" | |
| 8 #include "base/time.h" | 12 #include "base/time.h" |
| 9 | 13 |
| 10 namespace { | 14 namespace { |
| 11 | 15 |
| 12 // Mark as volatile to defensively make sure usage is thread-safe. | 16 // Mark as volatile to defensively make sure usage is thread-safe. |
| 13 // Note that at the time of this writing, access is only on the UI thread. | 17 // Note that at the time of this writing, access is only on the UI thread. |
| 14 static volatile bool g_non_browser_ui_displayed = false; | 18 volatile bool g_non_browser_ui_displayed = false; |
| 15 | 19 |
| 16 const base::Time* MainEntryPointTimeInternal() { | 20 const base::Time* MainEntryPointTimeInternal() { |
| 17 static base::Time main_start_time = base::Time::Now(); | 21 static base::Time main_start_time = base::Time::Now(); |
| 18 return &main_start_time; | 22 return &main_start_time; |
| 19 } | 23 } |
| 20 | 24 |
| 21 static bool g_main_entry_time_was_recorded = false; | 25 typedef base::hash_map<std::string,base::TimeDelta> SubsystemStartupTimeHash; |
| 26 | |
| 27 SubsystemStartupTimeHash* GetSubsystemStartupTimeHash() { | |
| 28 static SubsystemStartupTimeHash* slow_startup_time_hash = | |
| 29 new SubsystemStartupTimeHash; | |
| 30 return slow_startup_time_hash; | |
| 31 } | |
| 32 | |
| 33 base::Lock* GetSubsystemStartupTimeHashLock() { | |
| 34 static base::Lock* slow_startup_time_hash_lock = new base::Lock; | |
| 35 return slow_startup_time_hash_lock; | |
| 36 } | |
| 37 | |
| 38 bool g_main_entry_time_was_recorded = false; | |
| 22 } // namespace | 39 } // namespace |
| 23 | 40 |
| 24 namespace startup_metric_utils { | 41 namespace startup_metric_utils { |
| 25 | 42 |
| 26 bool WasNonBrowserUIDisplayed() { | 43 bool WasNonBrowserUIDisplayed() { |
| 27 return g_non_browser_ui_displayed; | 44 return g_non_browser_ui_displayed; |
| 28 } | 45 } |
| 29 | 46 |
| 30 void SetNonBrowserUIDisplayed() { | 47 void SetNonBrowserUIDisplayed() { |
| 31 g_non_browser_ui_displayed = true; | 48 g_non_browser_ui_displayed = true; |
| 32 } | 49 } |
| 33 | 50 |
| 34 void RecordMainEntryPointTime() { | 51 void RecordMainEntryPointTime() { |
| 35 DCHECK(!g_main_entry_time_was_recorded); | 52 DCHECK(!g_main_entry_time_was_recorded); |
| 36 g_main_entry_time_was_recorded = true; | 53 g_main_entry_time_was_recorded = true; |
| 37 MainEntryPointTimeInternal(); | 54 MainEntryPointTimeInternal(); |
| 38 } | 55 } |
| 39 | 56 |
| 57 // Return the time recorded by RecordMainEntryPointTime(). | |
| 40 const base::Time MainEntryStartTime() { | 58 const base::Time MainEntryStartTime() { |
| 41 DCHECK(g_main_entry_time_was_recorded); | 59 DCHECK(g_main_entry_time_was_recorded); |
| 42 return *MainEntryPointTimeInternal(); | 60 return *MainEntryPointTimeInternal(); |
| 43 } | 61 } |
| 44 | 62 |
| 63 void OnBrowserStartupComplete() { | |
| 64 // Bail if uptime < 7 minutes, to filter out cases where Chrome may have been | |
|
sky
2013/01/14 21:54:11
This case seems pretty common to me, eg reboot and
| |
| 65 // autostarted and the machine is under io pressure. | |
| 66 const int64 kSevenMinutesInMilliseconds = | |
| 67 base::TimeDelta::FromMinutes(7).InMilliseconds(); | |
| 68 if (base::SysInfo::Uptime() < kSevenMinutesInMilliseconds) | |
| 69 return; | |
| 70 | |
| 71 const base::TimeDelta kStartupTimeMin(base::TimeDelta::FromMilliseconds(1)); | |
| 72 const base::TimeDelta kStartupTimeMax(base::TimeDelta::FromMinutes(5)); | |
| 73 static const size_t kStartupTimeBuckets(100); | |
| 74 | |
| 75 // The Startup.BrowserMessageLoopStartTime histogram recorded in | |
| 76 // chrome_browser_main.cc exhibits instability in the field which limits its | |
| 77 // usefulness in all scenarios except when we have a very large sample size. | |
| 78 // Attempt to mitigate this with a new metric: | |
| 79 // * Measure time from main entry rather than the OS' notion of process start | |
| 80 // time. | |
| 81 // * Only measure launches that occur 7 minutes after boot to try to avoid | |
| 82 // cases where Chrome is auto-started and IO is heavily loaded. | |
| 83 base::TimeDelta startup_time_from_main_entry = | |
| 84 base::Time::Now() - MainEntryStartTime(); | |
| 85 UMA_HISTOGRAM_LONG_TIMES( | |
| 86 "Startup.BrowserMessageLoopStartTimeFromMainEntry", | |
| 87 startup_time_from_main_entry); | |
| 88 | |
| 89 // Record histograms for the subsystem times for startups > 10 seconds. | |
| 90 const base::TimeDelta kTenSeconds = base::TimeDelta::FromSeconds(10); | |
| 91 if (startup_time_from_main_entry < kTenSeconds) | |
| 92 return; | |
| 93 { | |
| 94 base::AutoLock locker(*GetSubsystemStartupTimeHashLock()); | |
| 95 SubsystemStartupTimeHash* time_hash = GetSubsystemStartupTimeHash(); | |
| 96 for (auto i = time_hash->begin(); i != time_hash->end(); ++i) { | |
| 97 const std::string histogram_name = i->first; | |
| 98 base::Histogram* counter = base::Histogram::FactoryTimeGet( | |
| 99 histogram_name, | |
| 100 kStartupTimeMin, | |
| 101 kStartupTimeMax, | |
| 102 kStartupTimeBuckets, | |
| 103 base::Histogram::kUmaTargetedHistogramFlag); | |
| 104 counter->AddTime(i->second); | |
| 105 } | |
| 106 } | |
| 107 } | |
| 108 | |
| 109 ScopedSlowStartupUMA::~ScopedSlowStartupUMA() { | |
| 110 base::AutoLock locker(*GetSubsystemStartupTimeHashLock()); | |
| 111 (*GetSubsystemStartupTimeHash())[histogram_name_] = | |
| 112 base::TimeTicks::Now() - start_time_; | |
| 113 } | |
| 114 | |
| 45 } // namespace startup_metric_utils | 115 } // namespace startup_metric_utils |
| OLD | NEW |