OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/startup_metric_utils/browser/startup_metric_utils.h" | 5 #include "components/startup_metric_utils/browser/startup_metric_utils.h" |
6 | 6 |
7 #include "base/containers/hash_tables.h" | 7 #include "base/containers/hash_tables.h" |
8 #include "base/environment.h" | 8 #include "base/environment.h" |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/metrics/histogram_macros.h" | 11 #include "base/metrics/histogram_macros.h" |
| 12 #include "base/prefs/pref_registry_simple.h" |
| 13 #include "base/prefs/pref_service.h" |
| 14 #include "base/process/process_info.h" |
12 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
13 #include "base/sys_info.h" | 16 #include "base/sys_info.h" |
14 #include "base/threading/platform_thread.h" | 17 #include "base/threading/platform_thread.h" |
15 #include "base/trace_event/trace_event.h" | 18 #include "base/trace_event/trace_event.h" |
16 | 19 |
17 #if defined(OS_WIN) | 20 #if defined(OS_WIN) |
18 #include <winternl.h> | 21 #include <winternl.h> |
19 #include "base/win/windows_version.h" | 22 #include "base/win/windows_version.h" |
20 #endif | 23 #endif |
21 | 24 |
22 namespace startup_metric_utils { | 25 namespace startup_metric_utils { |
23 | 26 |
24 namespace { | 27 namespace { |
25 | 28 |
| 29 const char kLastStartupTimestampPref[] = |
| 30 "startup_metric.last_startup_timestamp"; |
| 31 |
26 // Mark as volatile to defensively make sure usage is thread-safe. | 32 // Mark as volatile to defensively make sure usage is thread-safe. |
27 // Note that at the time of this writing, access is only on the UI thread. | 33 // Note that at the time of this writing, access is only on the UI thread. |
28 volatile bool g_non_browser_ui_displayed = false; | 34 volatile bool g_non_browser_ui_displayed = false; |
29 | 35 |
30 base::LazyInstance<base::TimeTicks>::Leaky g_process_creation_ticks = | 36 base::LazyInstance<base::TimeTicks>::Leaky g_process_creation_ticks = |
31 LAZY_INSTANCE_INITIALIZER; | 37 LAZY_INSTANCE_INITIALIZER; |
32 | 38 |
33 base::LazyInstance<base::TimeTicks>::Leaky g_main_entry_point_ticks = | 39 base::LazyInstance<base::TimeTicks>::Leaky g_main_entry_point_ticks = |
34 LAZY_INSTANCE_INITIALIZER; | 40 LAZY_INSTANCE_INITIALIZER; |
35 | 41 |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 if (proc_info->NextEntryOffset <= 0) | 158 if (proc_info->NextEntryOffset <= 0) |
153 return false; | 159 return false; |
154 index += proc_info->NextEntryOffset; | 160 index += proc_info->NextEntryOffset; |
155 } | 161 } |
156 | 162 |
157 return false; | 163 return false; |
158 } | 164 } |
159 | 165 |
160 #endif // defined(OS_WIN) | 166 #endif // defined(OS_WIN) |
161 | 167 |
| 168 #define UMA_HISTOGRAM_TIME_IN_MINUTES_MONTH_RANGE(name, sample) \ |
| 169 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, \ |
| 170 base::TimeDelta::FromDays(30).InMinutes(), 50) |
162 | 171 |
163 // Helper macro for splitting out an UMA histogram based on cold or warm start. | 172 // Helper macro for splitting out an UMA histogram based on cold or warm start. |
164 // |type| is the histogram type, and corresponds to an UMA macro like | 173 // |type| is the histogram type, and corresponds to an UMA macro like |
165 // UMA_HISTOGRAM_LONG_TIMES. It must itself be a macro that only takes two | 174 // UMA_HISTOGRAM_LONG_TIMES. It must itself be a macro that only takes two |
166 // parameters. | 175 // parameters. |
167 // |basename| is the basename of the histogram. A histogram of this name will | 176 // |basename| is the basename of the histogram. A histogram of this name will |
168 // always be recorded to. If the startup is either cold or warm then a value | 177 // always be recorded to. If the startup is either cold or warm then a value |
169 // will also be recorded to the histogram with name |basename| and suffix | 178 // will also be recorded to the histogram with name |basename| and suffix |
170 // ".ColdStart" or ".WarmStart", as appropriate. | 179 // ".ColdStart" or ".WarmStart", as appropriate. |
171 // |value_expr| is an expression evaluating to the value to be recorded. This | 180 // |value_expr| is an expression evaluating to the value to be recorded. This |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
371 int64 time_int = 0; | 380 int64 time_int = 0; |
372 if (env->GetVar(kChromeMainTicksEnvVar, &ticks_string) && | 381 if (env->GetVar(kChromeMainTicksEnvVar, &ticks_string) && |
373 base::StringToInt64(ticks_string, &time_int)) { | 382 base::StringToInt64(ticks_string, &time_int)) { |
374 return base::TimeTicks::FromInternalValue(time_int); | 383 return base::TimeTicks::FromInternalValue(time_int); |
375 } | 384 } |
376 return base::TimeTicks(); | 385 return base::TimeTicks(); |
377 } | 386 } |
378 | 387 |
379 } // namespace | 388 } // namespace |
380 | 389 |
| 390 void RegisterPrefs(PrefRegistrySimple* registry) { |
| 391 DCHECK(registry); |
| 392 registry->RegisterInt64Pref(kLastStartupTimestampPref, 0); |
| 393 } |
| 394 |
381 bool WasNonBrowserUIDisplayed() { | 395 bool WasNonBrowserUIDisplayed() { |
382 return g_non_browser_ui_displayed; | 396 return g_non_browser_ui_displayed; |
383 } | 397 } |
384 | 398 |
385 void SetNonBrowserUIDisplayed() { | 399 void SetNonBrowserUIDisplayed() { |
386 g_non_browser_ui_displayed = true; | 400 g_non_browser_ui_displayed = true; |
387 } | 401 } |
388 | 402 |
389 void RecordStartupProcessCreationTime(const base::Time& time) { | 403 void RecordStartupProcessCreationTime(const base::Time& time) { |
390 DCHECK(g_process_creation_ticks.Get().is_null()); | 404 DCHECK(g_process_creation_ticks.Get().is_null()); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 | 479 |
466 // Process create to chrome.dll:main(). Reported as a histogram only as | 480 // Process create to chrome.dll:main(). Reported as a histogram only as |
467 // the other two events above are sufficient for tracing purposes. | 481 // the other two events above are sufficient for tracing purposes. |
468 UMA_HISTOGRAM_WITH_STARTUP_TEMPERATURE( | 482 UMA_HISTOGRAM_WITH_STARTUP_TEMPERATURE( |
469 UMA_HISTOGRAM_LONG_TIMES, "Startup.LoadTime.ProcessCreateToDllMain", | 483 UMA_HISTOGRAM_LONG_TIMES, "Startup.LoadTime.ProcessCreateToDllMain", |
470 g_main_entry_point_ticks.Get() - process_creation_ticks); | 484 g_main_entry_point_ticks.Get() - process_creation_ticks); |
471 } | 485 } |
472 } | 486 } |
473 } | 487 } |
474 | 488 |
| 489 void RecordTimeSinceLastStartup(PrefService* pref_service) { |
| 490 #if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX) |
| 491 DCHECK(pref_service); |
| 492 |
| 493 // Get the timestamp of the current startup. |
| 494 const base::Time process_start_time = |
| 495 base::CurrentProcessInfo::CreationTime(); |
| 496 |
| 497 // Get the timestamp of the last startup from |pref_service|. |
| 498 const int64_t last_startup_timestamp_internal = |
| 499 pref_service->GetInt64(kLastStartupTimestampPref); |
| 500 if (last_startup_timestamp_internal != 0) { |
| 501 // Log the Startup.TimeSinceLastStartup histogram. |
| 502 const base::Time last_startup_timestamp = |
| 503 base::Time::FromInternalValue(last_startup_timestamp_internal); |
| 504 const base::TimeDelta time_since_last_startup = |
| 505 process_start_time - last_startup_timestamp; |
| 506 const int minutes_since_last_startup = time_since_last_startup.InMinutes(); |
| 507 |
| 508 // Ignore negative values, which can be caused by system clock changes. |
| 509 if (minutes_since_last_startup >= 0) { |
| 510 UMA_HISTOGRAM_WITH_STARTUP_TEMPERATURE( |
| 511 UMA_HISTOGRAM_TIME_IN_MINUTES_MONTH_RANGE, |
| 512 "Startup.TimeSinceLastStartup", minutes_since_last_startup); |
| 513 } |
| 514 } |
| 515 |
| 516 // Write the timestamp of the current startup in |pref_service|. |
| 517 pref_service->SetInt64(kLastStartupTimestampPref, |
| 518 process_start_time.ToInternalValue()); |
| 519 #endif // defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX) |
| 520 } |
| 521 |
475 void RecordBrowserWindowDisplay(const base::TimeTicks& ticks) { | 522 void RecordBrowserWindowDisplay(const base::TimeTicks& ticks) { |
476 static bool is_first_call = true; | 523 static bool is_first_call = true; |
477 if (!is_first_call || ticks.is_null()) | 524 if (!is_first_call || ticks.is_null()) |
478 return; | 525 return; |
479 is_first_call = false; | 526 is_first_call = false; |
480 if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null()) | 527 if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null()) |
481 return; | 528 return; |
482 | 529 |
483 UMA_HISTOGRAM_AND_TRACE_WITH_STARTUP_TEMPERATURE( | 530 UMA_HISTOGRAM_AND_TRACE_WITH_STARTUP_TEMPERATURE( |
484 UMA_HISTOGRAM_LONG_TIMES, "Startup.BrowserWindowDisplay", | 531 UMA_HISTOGRAM_LONG_TIMES, "Startup.BrowserWindowDisplay", |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 | 627 |
581 base::TimeTicks MainEntryPointTicks() { | 628 base::TimeTicks MainEntryPointTicks() { |
582 return g_main_entry_point_ticks.Get(); | 629 return g_main_entry_point_ticks.Get(); |
583 } | 630 } |
584 | 631 |
585 StartupTemperature GetStartupTemperature() { | 632 StartupTemperature GetStartupTemperature() { |
586 return g_startup_temperature; | 633 return g_startup_temperature; |
587 } | 634 } |
588 | 635 |
589 } // namespace startup_metric_utils | 636 } // namespace startup_metric_utils |
OLD | NEW |