Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Unified Diff: components/startup_metric_utils/browser/startup_metric_utils.cc

Issue 2283073002: Cleanup startup_metric_utils.h/.cc. (Closed)
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/startup_metric_utils/browser/startup_metric_utils.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/startup_metric_utils/browser/startup_metric_utils.cc
diff --git a/components/startup_metric_utils/browser/startup_metric_utils.cc b/components/startup_metric_utils/browser/startup_metric_utils.cc
index 3949e6f3aaf53e5f0cedbc8cac070470285fe899..64e934f7674bf8ee5d9248f7710c4a21d1c16290 100644
--- a/components/startup_metric_utils/browser/startup_metric_utils.cc
+++ b/components/startup_metric_utils/browser/startup_metric_utils.cc
@@ -5,8 +5,10 @@
#include "components/startup_metric_utils/browser/startup_metric_utils.h"
#include <stddef.h>
+#include <stdint.h>
#include <memory>
+#include <string>
#include "base/containers/hash_tables.h"
#include "base/environment.h"
@@ -28,7 +30,6 @@
#if defined(OS_WIN)
#include <winternl.h>
#include "base/win/win_util.h"
-#include "base/win/windows_version.h"
#endif
namespace startup_metric_utils {
@@ -54,6 +55,25 @@ base::LazyInstance<base::TimeTicks>::Leaky g_renderer_main_entry_point_ticks =
base::LazyInstance<base::Time>::Leaky g_browser_main_entry_point_time =
LAZY_INSTANCE_INITIALIZER;
+// An enumeration of startup temperatures. This must be kept in sync with the
+// UMA StartupType enumeration defined in histograms.xml.
+enum StartupTemperature {
+ // The startup was a cold start: nearly all of the binaries and resources were
+ // brought into memory using hard faults.
+ COLD_STARTUP_TEMPERATURE = 0,
+ // The startup was a warm start: the binaries and resources were mostly
+ // already resident in memory and effectively no hard faults were observed.
+ WARM_STARTUP_TEMPERATURE = 1,
+ // The startup type couldn't quite be classified as warm or cold, but rather
+ // was somewhere in between.
+ LUKEWARM_STARTUP_TEMPERATURE = 2,
+ // This must be after all meaningful values. All new values should be added
+ // above this one.
+ STARTUP_TEMPERATURE_COUNT,
+ // Startup temperature wasn't yet determined.
+ UNDETERMINED_STARTUP_TEMPERATURE
+};
+
StartupTemperature g_startup_temperature = UNDETERMINED_STARTUP_TEMPERATURE;
constexpr int kUndeterminedStartupsWithCurrentVersion = 0;
@@ -70,11 +90,11 @@ int g_startups_with_current_version = kUndeterminedStartupsWithCurrentVersion;
// Maximum number of hard faults tolerated for a startup to be classified as a
// warm start. Set at roughly the 40th percentile of the HardFaultCount
// histogram.
-const uint32_t WARM_START_HARD_FAULT_COUNT_THRESHOLD = 5;
+constexpr uint32_t kWarmStartHardFaultCountThreshold = 5;
// Minimum number of hard faults expected for a startup to be classified as a
// cold start. Set at roughly the 60th percentile of the HardFaultCount
// histogram.
-const uint32_t COLD_START_HARD_FAULT_COUNT_THRESHOLD = 1200;
+constexpr uint32_t kColdStartHardFaultCountThreshold = 1200;
// The struct used to return system process information via the NT internal
// QuerySystemInformation call. This is partially documented at
@@ -105,6 +125,61 @@ struct SYSTEM_PROCESS_INFORMATION_EX {
// The signature of the NtQuerySystemInformation function.
typedef NTSTATUS (WINAPI *NtQuerySystemInformationPtr)(
SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG);
+
+// Gets the hard fault count of the current process through |hard_fault_count|.
+// Returns true on success.
+bool GetHardFaultCountForCurrentProcess(uint32_t* hard_fault_count) {
gab 2016/08/31 16:30:45 Assuming cut&paste as-is, not reviewing each line.
fdoray 2016/08/31 19:08:09 cut&paste + removed "if (base::win::GetVersion() <
+ DCHECK(hard_fault_count);
+
+ // Get the function pointer.
+ static const NtQuerySystemInformationPtr query_sys_info =
+ reinterpret_cast<NtQuerySystemInformationPtr>(::GetProcAddress(
+ GetModuleHandle(L"ntdll.dll"), "NtQuerySystemInformation"));
+ if (query_sys_info == nullptr)
+ return false;
+
+ // The output of this system call depends on the number of threads and
+ // processes on the entire system, and this can change between calls. Retry
+ // a small handful of times growing the buffer along the way.
+ // NOTE: The actual required size depends entirely on the number of processes
+ // and threads running on the system. The initial guess suffices for
+ // ~100s of processes and ~1000s of threads.
+ std::vector<uint8_t> buffer(32 * 1024);
+ for (size_t tries = 0; tries < 3; ++tries) {
+ ULONG return_length = 0;
+ const NTSTATUS status =
+ query_sys_info(SystemProcessInformation, buffer.data(),
+ static_cast<ULONG>(buffer.size()), &return_length);
+ // Insufficient space in the buffer.
+ if (return_length > buffer.size()) {
+ buffer.resize(return_length);
+ continue;
+ }
+ if (NT_SUCCESS(status) && return_length <= buffer.size())
+ break;
+ return false;
+ }
+
+ // Look for the struct housing information for the current process.
+ const DWORD proc_id = ::GetCurrentProcessId();
+ size_t index = 0;
+ while (index < buffer.size()) {
+ DCHECK_LE(index + sizeof(SYSTEM_PROCESS_INFORMATION_EX), buffer.size());
+ SYSTEM_PROCESS_INFORMATION_EX* proc_info =
+ reinterpret_cast<SYSTEM_PROCESS_INFORMATION_EX*>(buffer.data() + index);
+ if (base::win::HandleToUint32(proc_info->UniqueProcessId) == proc_id) {
+ *hard_fault_count = proc_info->HardFaultCount;
+ return true;
+ }
+ // The list ends when NextEntryOffset is zero. This also prevents busy
+ // looping if the data is in fact invalid.
+ if (proc_info->NextEntryOffset <= 0)
+ return false;
+ index += proc_info->NextEntryOffset;
+ }
+
+ return false;
+}
#endif // defined(OS_WIN)
#define UMA_HISTOGRAM_TIME_IN_MINUTES_MONTH_RANGE(name, sample) \
@@ -279,9 +354,9 @@ void RecordHardFaultHistogram() {
// Determine the startup type based on the number of observed hard faults.
DCHECK_EQ(UNDETERMINED_STARTUP_TEMPERATURE, g_startup_temperature);
- if (hard_fault_count < WARM_START_HARD_FAULT_COUNT_THRESHOLD) {
+ if (hard_fault_count < kWarmStartHardFaultCountThreshold) {
g_startup_temperature = WARM_STARTUP_TEMPERATURE;
- } else if (hard_fault_count >= COLD_START_HARD_FAULT_COUNT_THRESHOLD) {
+ } else if (hard_fault_count >= kColdStartHardFaultCountThreshold) {
g_startup_temperature = COLD_STARTUP_TEMPERATURE;
} else {
g_startup_temperature = LUKEWARM_STARTUP_TEMPERATURE;
@@ -488,64 +563,6 @@ void RecordSameVersionStartupCount(PrefService* pref_service) {
} // namespace
-#if defined(OS_WIN)
-bool GetHardFaultCountForCurrentProcess(uint32_t* hard_fault_count) {
- DCHECK(hard_fault_count);
-
- if (base::win::GetVersion() < base::win::VERSION_WIN7)
- return false;
-
- // Get the function pointer.
- static const NtQuerySystemInformationPtr query_sys_info =
- reinterpret_cast<NtQuerySystemInformationPtr>(::GetProcAddress(
- GetModuleHandle(L"ntdll.dll"), "NtQuerySystemInformation"));
- if (query_sys_info == nullptr)
- return false;
-
- // The output of this system call depends on the number of threads and
- // processes on the entire system, and this can change between calls. Retry
- // a small handful of times growing the buffer along the way.
- // NOTE: The actual required size depends entirely on the number of processes
- // and threads running on the system. The initial guess suffices for
- // ~100s of processes and ~1000s of threads.
- std::vector<uint8_t> buffer(32 * 1024);
- for (size_t tries = 0; tries < 3; ++tries) {
- ULONG return_length = 0;
- NTSTATUS status =
- query_sys_info(SystemProcessInformation, buffer.data(),
- static_cast<ULONG>(buffer.size()), &return_length);
- // Insufficient space in the buffer.
- if (return_length > buffer.size()) {
- buffer.resize(return_length);
- continue;
- }
- if (NT_SUCCESS(status) && return_length <= buffer.size())
- break;
- return false;
- }
-
- // Look for the struct housing information for the current process.
- DWORD proc_id = ::GetCurrentProcessId();
- size_t index = 0;
- while (index < buffer.size()) {
- DCHECK_LE(index + sizeof(SYSTEM_PROCESS_INFORMATION_EX), buffer.size());
- SYSTEM_PROCESS_INFORMATION_EX* proc_info =
- reinterpret_cast<SYSTEM_PROCESS_INFORMATION_EX*>(buffer.data() + index);
- if (base::win::HandleToUint32(proc_info->UniqueProcessId) == proc_id) {
- *hard_fault_count = proc_info->HardFaultCount;
- return true;
- }
- // The list ends when NextEntryOffset is zero. This also prevents busy
- // looping if the data is in fact invalid.
- if (proc_info->NextEntryOffset <= 0)
- return false;
- index += proc_info->NextEntryOffset;
- }
-
- return false;
-}
-#endif // defined(OS_WIN)
-
void RegisterPrefs(PrefRegistrySimple* registry) {
DCHECK(registry);
registry->RegisterInt64Pref(prefs::kLastStartupTimestamp, 0);
@@ -771,8 +788,4 @@ base::TimeTicks MainEntryPointTicks() {
return g_browser_main_entry_point_ticks.Get();
}
-StartupTemperature GetStartupTemperature() {
- return g_startup_temperature;
-}
-
} // namespace startup_metric_utils
« no previous file with comments | « components/startup_metric_utils/browser/startup_metric_utils.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698