This source file includes following definitions.
- MainEntryPointTimeInternal
- GetSubsystemStartupTimeHash
- GetSubsystemStartupTimeHashLock
- RecordMainEntryTimeHistogram
- WasNonBrowserUIDisplayed
- SetNonBrowserUIDisplayed
- RecordMainEntryPointTime
- RecordExeMainEntryTime
- RecordSavedMainEntryPointTime
- MainEntryStartTime
- OnBrowserStartupComplete
- OnInitialPageLoadComplete
#include "components/startup_metric_utils/startup_metric_utils.h"
#include "base/containers/hash_tables.h"
#include "base/environment.h"
#include "base/logging.h"
#include "base/metrics/histogram.h"
#include "base/metrics/histogram_base.h"
#include "base/metrics/statistics_recorder.h"
#include "base/process/process_info.h"
#include "base/strings/string_number_conversions.h"
#include "base/synchronization/lock.h"
#include "base/sys_info.h"
#include "base/time/time.h"
namespace {
volatile bool g_non_browser_ui_displayed = false;
base::Time* MainEntryPointTimeInternal() {
static base::Time main_start_time = base::Time::Now();
return &main_start_time;
}
typedef base::hash_map<std::string,base::TimeDelta> SubsystemStartupTimeHash;
SubsystemStartupTimeHash* GetSubsystemStartupTimeHash() {
static SubsystemStartupTimeHash* slow_startup_time_hash =
new SubsystemStartupTimeHash;
return slow_startup_time_hash;
}
base::Lock* GetSubsystemStartupTimeHashLock() {
static base::Lock* slow_startup_time_hash_lock = new base::Lock;
return slow_startup_time_hash_lock;
}
void RecordMainEntryTimeHistogram() {
const int kLowWordMask = 0xFFFFFFFF;
const int kLower31BitsMask = 0x7FFFFFFF;
base::TimeDelta browser_main_entry_time_absolute =
base::TimeDelta::FromMilliseconds(
MainEntryPointTimeInternal()->ToInternalValue() / 1000.0);
uint64 browser_main_entry_time_raw_ms =
browser_main_entry_time_absolute.InMilliseconds();
base::TimeDelta browser_main_entry_time_raw_ms_high_word =
base::TimeDelta::FromMilliseconds(
(browser_main_entry_time_raw_ms >> 32) & kLowWordMask);
base::TimeDelta browser_main_entry_time_raw_ms_low_word =
base::TimeDelta::FromMilliseconds(
(browser_main_entry_time_raw_ms >> 1) & kLower31BitsMask);
HISTOGRAM_TIMES("Startup.BrowserMainEntryTimeAbsoluteHighWord",
browser_main_entry_time_raw_ms_high_word);
HISTOGRAM_TIMES("Startup.BrowserMainEntryTimeAbsoluteLowWord",
browser_main_entry_time_raw_ms_low_word);
}
bool g_main_entry_time_was_recorded = false;
bool g_startup_stats_collection_finished = false;
bool g_was_slow_startup = false;
const char kChromeMainTimeEnvVar[] = "CHROME_MAIN_TIME";
}
namespace startup_metric_utils {
bool WasNonBrowserUIDisplayed() {
return g_non_browser_ui_displayed;
}
void SetNonBrowserUIDisplayed() {
g_non_browser_ui_displayed = true;
}
void RecordMainEntryPointTime() {
DCHECK(!g_main_entry_time_was_recorded);
g_main_entry_time_was_recorded = true;
MainEntryPointTimeInternal();
}
void RecordExeMainEntryTime() {
std::string exe_load_time =
base::Int64ToString(base::Time::Now().ToInternalValue());
scoped_ptr<base::Environment> env(base::Environment::Create());
env->SetVar(kChromeMainTimeEnvVar, exe_load_time);
}
#if defined(OS_ANDROID)
void RecordSavedMainEntryPointTime(const base::Time& entry_point_time) {
DCHECK(!g_main_entry_time_was_recorded);
g_main_entry_time_was_recorded = true;
*MainEntryPointTimeInternal() = entry_point_time;
}
#endif
const base::Time MainEntryStartTime() {
DCHECK(g_main_entry_time_was_recorded);
return *MainEntryPointTimeInternal();
}
void OnBrowserStartupComplete(bool is_first_run) {
RecordMainEntryTimeHistogram();
const int64 kSevenMinutesInMilliseconds =
base::TimeDelta::FromMinutes(7).InMilliseconds();
if (base::SysInfo::Uptime() < kSevenMinutesInMilliseconds) {
g_startup_stats_collection_finished = true;
return;
}
base::TimeDelta startup_time_from_main_entry =
base::Time::Now() - MainEntryStartTime();
if (is_first_run) {
UMA_HISTOGRAM_LONG_TIMES(
"Startup.BrowserMessageLoopStartTimeFromMainEntry.FirstRun",
startup_time_from_main_entry);
} else {
UMA_HISTOGRAM_LONG_TIMES(
"Startup.BrowserMessageLoopStartTimeFromMainEntry",
startup_time_from_main_entry);
}
#if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX)
scoped_ptr<base::Environment> env(base::Environment::Create());
std::string chrome_main_entry_time_string;
if (env->GetVar(kChromeMainTimeEnvVar, &chrome_main_entry_time_string)) {
int64 chrome_main_entry_time_int = 0;
if (base::StringToInt64(chrome_main_entry_time_string,
&chrome_main_entry_time_int)) {
base::Time process_create_time = base::CurrentProcessInfo::CreationTime();
base::Time exe_main_time =
base::Time::FromInternalValue(chrome_main_entry_time_int);
base::Time dll_main_time = MainEntryStartTime();
UMA_HISTOGRAM_LONG_TIMES("Startup.LoadTime.ProcessCreateToExeMain",
exe_main_time - process_create_time);
UMA_HISTOGRAM_LONG_TIMES("Startup.LoadTime.ExeMainToDllMain",
dll_main_time - exe_main_time);
UMA_HISTOGRAM_LONG_TIMES("Startup.LoadTime.ProcessCreateToDllMain",
dll_main_time - process_create_time);
}
}
#endif
const base::TimeDelta kTenSeconds = base::TimeDelta::FromSeconds(10);
if (startup_time_from_main_entry < kTenSeconds) {
g_startup_stats_collection_finished = true;
return;
}
g_was_slow_startup = true;
}
void OnInitialPageLoadComplete() {
if (!g_was_slow_startup)
return;
DCHECK(!g_startup_stats_collection_finished);
const base::TimeDelta kStartupTimeMin(
base::TimeDelta::FromMilliseconds(1));
const base::TimeDelta kStartupTimeMax(base::TimeDelta::FromMinutes(5));
static const size_t kStartupTimeBuckets = 100;
base::HistogramBase* histogram =
base::StatisticsRecorder::FindHistogram("Startup.SlowStartupNSSInit");
if (histogram)
histogram->SetFlags(base::HistogramBase::kUmaTargetedHistogramFlag);
base::AutoLock locker(*GetSubsystemStartupTimeHashLock());
SubsystemStartupTimeHash* time_hash = GetSubsystemStartupTimeHash();
for (SubsystemStartupTimeHash::iterator i = time_hash->begin();
i != time_hash->end();
++i) {
const std::string histogram_name = i->first;
base::HistogramBase* counter = base::Histogram::FactoryTimeGet(
histogram_name,
kStartupTimeMin,
kStartupTimeMax,
kStartupTimeBuckets,
base::Histogram::kUmaTargetedHistogramFlag);
counter->AddTime(i->second);
}
g_startup_stats_collection_finished = true;
}
ScopedSlowStartupUMA::~ScopedSlowStartupUMA() {
if (g_startup_stats_collection_finished)
return;
base::AutoLock locker(*GetSubsystemStartupTimeHashLock());
SubsystemStartupTimeHash* hash = GetSubsystemStartupTimeHash();
if (hash->find(histogram_name_) != hash->end())
return;
(*hash)[histogram_name_] =
base::TimeTicks::Now() - start_time_;
}
}