| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/containers/hash_tables.h" | 9 #include "base/containers/hash_tables.h" |
| 10 #include "base/environment.h" | 10 #include "base/environment.h" |
| 11 #include "base/lazy_instance.h" | 11 #include "base/lazy_instance.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/metrics/histogram_macros.h" | 13 #include "base/metrics/histogram_macros.h" |
| 14 #include "base/prefs/pref_registry_simple.h" |
| 15 #include "base/prefs/pref_service.h" |
| 16 #include "base/process/process_info.h" |
| 14 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/sys_info.h" | 18 #include "base/sys_info.h" |
| 16 #include "base/threading/platform_thread.h" | 19 #include "base/threading/platform_thread.h" |
| 17 #include "base/trace_event/trace_event.h" | 20 #include "base/trace_event/trace_event.h" |
| 18 #include "build/build_config.h" | 21 #include "build/build_config.h" |
| 19 | 22 |
| 20 #if defined(OS_WIN) | 23 #if defined(OS_WIN) |
| 21 #include <winternl.h> | 24 #include <winternl.h> |
| 22 #include "base/win/win_util.h" | 25 #include "base/win/win_util.h" |
| 23 #include "base/win/windows_version.h" | 26 #include "base/win/windows_version.h" |
| 24 #endif | 27 #endif |
| 25 | 28 |
| 26 namespace startup_metric_utils { | 29 namespace startup_metric_utils { |
| 27 | 30 |
| 28 namespace { | 31 namespace { |
| 29 | 32 |
| 33 const char kLastStartupTimestampPref[] = |
| 34 "startup_metric.last_startup_timestamp"; |
| 35 |
| 30 // Mark as volatile to defensively make sure usage is thread-safe. | 36 // Mark as volatile to defensively make sure usage is thread-safe. |
| 31 // Note that at the time of this writing, access is only on the UI thread. | 37 // Note that at the time of this writing, access is only on the UI thread. |
| 32 volatile bool g_non_browser_ui_displayed = false; | 38 volatile bool g_non_browser_ui_displayed = false; |
| 33 | 39 |
| 34 base::LazyInstance<base::TimeTicks>::Leaky g_process_creation_ticks = | 40 base::LazyInstance<base::TimeTicks>::Leaky g_process_creation_ticks = |
| 35 LAZY_INSTANCE_INITIALIZER; | 41 LAZY_INSTANCE_INITIALIZER; |
| 36 | 42 |
| 37 base::LazyInstance<base::TimeTicks>::Leaky g_browser_main_entry_point_ticks = | 43 base::LazyInstance<base::TimeTicks>::Leaky g_browser_main_entry_point_ticks = |
| 38 LAZY_INSTANCE_INITIALIZER; | 44 LAZY_INSTANCE_INITIALIZER; |
| 39 | 45 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 SIZE_T PrivatePageCount; | 95 SIZE_T PrivatePageCount; |
| 90 LARGE_INTEGER Reserved6[6]; | 96 LARGE_INTEGER Reserved6[6]; |
| 91 // Array of SYSTEM_THREAD_INFORMATION structs follows. | 97 // Array of SYSTEM_THREAD_INFORMATION structs follows. |
| 92 }; | 98 }; |
| 93 | 99 |
| 94 // The signature of the NtQuerySystemInformation function. | 100 // The signature of the NtQuerySystemInformation function. |
| 95 typedef NTSTATUS (WINAPI *NtQuerySystemInformationPtr)( | 101 typedef NTSTATUS (WINAPI *NtQuerySystemInformationPtr)( |
| 96 SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG); | 102 SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG); |
| 97 #endif // defined(OS_WIN) | 103 #endif // defined(OS_WIN) |
| 98 | 104 |
| 105 #define UMA_HISTOGRAM_TIME_IN_MINUTES_MONTH_RANGE(name, sample) \ |
| 106 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample, 1, \ |
| 107 base::TimeDelta::FromDays(30).InMinutes(), 50) |
| 99 | 108 |
| 100 // Helper macro for splitting out an UMA histogram based on cold or warm start. | 109 // Helper macro for splitting out an UMA histogram based on cold or warm start. |
| 101 // |type| is the histogram type, and corresponds to an UMA macro like | 110 // |type| is the histogram type, and corresponds to an UMA macro like |
| 102 // UMA_HISTOGRAM_LONG_TIMES. It must be itself be a macro that only takes two | 111 // UMA_HISTOGRAM_LONG_TIMES. It must be itself be a macro that only takes two |
| 103 // parameters. | 112 // parameters. |
| 104 // |basename| is the basename of the histogram. A histogram of this name will | 113 // |basename| is the basename of the histogram. A histogram of this name will |
| 105 // always be recorded to. If the startup is either cold or warm then a value | 114 // always be recorded to. If the startup is either cold or warm then a value |
| 106 // will also be recorded to the histogram with name |basename| and suffix | 115 // will also be recorded to the histogram with name |basename| and suffix |
| 107 // ".ColdStart" or ".WarmStart", as appropriate. | 116 // ".ColdStart" or ".WarmStart", as appropriate. |
| 108 // |value_expr| is an expression evaluating to the value to be recorded. This | 117 // |value_expr| is an expression evaluating to the value to be recorded. This |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 // looping if the data is in fact invalid. | 384 // looping if the data is in fact invalid. |
| 376 if (proc_info->NextEntryOffset <= 0) | 385 if (proc_info->NextEntryOffset <= 0) |
| 377 return false; | 386 return false; |
| 378 index += proc_info->NextEntryOffset; | 387 index += proc_info->NextEntryOffset; |
| 379 } | 388 } |
| 380 | 389 |
| 381 return false; | 390 return false; |
| 382 } | 391 } |
| 383 #endif // defined(OS_WIN) | 392 #endif // defined(OS_WIN) |
| 384 | 393 |
| 394 void RegisterPrefs(PrefRegistrySimple* registry) { |
| 395 DCHECK(registry); |
| 396 registry->RegisterInt64Pref(kLastStartupTimestampPref, 0); |
| 397 } |
| 398 |
| 385 bool WasNonBrowserUIDisplayed() { | 399 bool WasNonBrowserUIDisplayed() { |
| 386 return g_non_browser_ui_displayed; | 400 return g_non_browser_ui_displayed; |
| 387 } | 401 } |
| 388 | 402 |
| 389 void SetNonBrowserUIDisplayed() { | 403 void SetNonBrowserUIDisplayed() { |
| 390 g_non_browser_ui_displayed = true; | 404 g_non_browser_ui_displayed = true; |
| 391 } | 405 } |
| 392 | 406 |
| 393 void RecordStartupProcessCreationTime(const base::Time& time) { | 407 void RecordStartupProcessCreationTime(const base::Time& time) { |
| 394 DCHECK(g_process_creation_ticks.Get().is_null()); | 408 DCHECK(g_process_creation_ticks.Get().is_null()); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 | 484 |
| 471 // Process create to chrome.dll:main(). Reported as a histogram only as | 485 // Process create to chrome.dll:main(). Reported as a histogram only as |
| 472 // the other two events above are sufficient for tracing purposes. | 486 // the other two events above are sufficient for tracing purposes. |
| 473 UMA_HISTOGRAM_WITH_STARTUP_TEMPERATURE( | 487 UMA_HISTOGRAM_WITH_STARTUP_TEMPERATURE( |
| 474 UMA_HISTOGRAM_LONG_TIMES, "Startup.LoadTime.ProcessCreateToDllMain", | 488 UMA_HISTOGRAM_LONG_TIMES, "Startup.LoadTime.ProcessCreateToDllMain", |
| 475 g_browser_main_entry_point_ticks.Get() - process_creation_ticks); | 489 g_browser_main_entry_point_ticks.Get() - process_creation_ticks); |
| 476 } | 490 } |
| 477 } | 491 } |
| 478 } | 492 } |
| 479 | 493 |
| 494 void RecordTimeSinceLastStartup(PrefService* pref_service) { |
| 495 #if defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX) |
| 496 DCHECK(pref_service); |
| 497 |
| 498 // Get the timestamp of the current startup. |
| 499 const base::Time process_start_time = |
| 500 base::CurrentProcessInfo::CreationTime(); |
| 501 |
| 502 // Get the timestamp of the last startup from |pref_service|. |
| 503 const int64_t last_startup_timestamp_internal = |
| 504 pref_service->GetInt64(kLastStartupTimestampPref); |
| 505 if (last_startup_timestamp_internal != 0) { |
| 506 // Log the Startup.TimeSinceLastStartup histogram. |
| 507 const base::Time last_startup_timestamp = |
| 508 base::Time::FromInternalValue(last_startup_timestamp_internal); |
| 509 const base::TimeDelta time_since_last_startup = |
| 510 process_start_time - last_startup_timestamp; |
| 511 const int minutes_since_last_startup = time_since_last_startup.InMinutes(); |
| 512 |
| 513 // Ignore negative values, which can be caused by system clock changes. |
| 514 if (minutes_since_last_startup >= 0) { |
| 515 UMA_HISTOGRAM_WITH_STARTUP_TEMPERATURE( |
| 516 UMA_HISTOGRAM_TIME_IN_MINUTES_MONTH_RANGE, |
| 517 "Startup.TimeSinceLastStartup", minutes_since_last_startup); |
| 518 } |
| 519 } |
| 520 |
| 521 // Write the timestamp of the current startup in |pref_service|. |
| 522 pref_service->SetInt64(kLastStartupTimestampPref, |
| 523 process_start_time.ToInternalValue()); |
| 524 #endif // defined(OS_MACOSX) || defined(OS_WIN) || defined(OS_LINUX) |
| 525 } |
| 526 |
| 480 void RecordBrowserWindowDisplay(const base::TimeTicks& ticks) { | 527 void RecordBrowserWindowDisplay(const base::TimeTicks& ticks) { |
| 481 static bool is_first_call = true; | 528 static bool is_first_call = true; |
| 482 if (!is_first_call || ticks.is_null()) | 529 if (!is_first_call || ticks.is_null()) |
| 483 return; | 530 return; |
| 484 is_first_call = false; | 531 is_first_call = false; |
| 485 if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null()) | 532 if (WasNonBrowserUIDisplayed() || g_process_creation_ticks.Get().is_null()) |
| 486 return; | 533 return; |
| 487 | 534 |
| 488 UMA_HISTOGRAM_AND_TRACE_WITH_STARTUP_TEMPERATURE( | 535 UMA_HISTOGRAM_AND_TRACE_WITH_STARTUP_TEMPERATURE( |
| 489 UMA_HISTOGRAM_LONG_TIMES, "Startup.BrowserWindowDisplay", | 536 UMA_HISTOGRAM_LONG_TIMES, "Startup.BrowserWindowDisplay", |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 | 616 |
| 570 base::TimeTicks MainEntryPointTicks() { | 617 base::TimeTicks MainEntryPointTicks() { |
| 571 return g_browser_main_entry_point_ticks.Get(); | 618 return g_browser_main_entry_point_ticks.Get(); |
| 572 } | 619 } |
| 573 | 620 |
| 574 StartupTemperature GetStartupTemperature() { | 621 StartupTemperature GetStartupTemperature() { |
| 575 return g_startup_temperature; | 622 return g_startup_temperature; |
| 576 } | 623 } |
| 577 | 624 |
| 578 } // namespace startup_metric_utils | 625 } // namespace startup_metric_utils |
| OLD | NEW |