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

Unified Diff: chrome/browser/fragmentation_checker_win.cc

Issue 8085026: Add a metric to Chrome to measure fragmentation of chrome.dll at startup.BUG=98033TEST=None (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 3 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
Index: chrome/browser/fragmentation_checker_win.cc
===================================================================
--- chrome/browser/fragmentation_checker_win.cc (revision 0)
+++ chrome/browser/fragmentation_checker_win.cc (revision 0)
@@ -0,0 +1,118 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/fragmentation_checker_win.h"
+
+#include <windows.h>
+#include <winioctl.h>
+
grt (UTC plus 2) 2011/10/01 02:49:46 #include <algorithm> #include <vector>
robertshield 2011/10/01 05:00:41 Done.
+#include "base/at_exit.h"
+#include "base/basictypes.h"
+#include "base/command_line.h"
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/metrics/histogram.h"
+#include "base/path_service.h"
+
+namespace {
+
+const size_t kMaxBufferSize = 1 << 20;
grt (UTC plus 2) 2011/10/01 02:49:46 this is waaaaay larger than it needs to be given k
robertshield 2011/10/01 05:00:41 Done, removed the max buffer size, everything is n
+const uint32 kMaxExtentCount = 10000;
+
+size_t ComputeRetrievalPointersBufferSize(int number_of_extents) {
grt (UTC plus 2) 2011/10/01 02:49:46 that an int suffices here for an approximation of
robertshield 2011/10/01 05:00:41 Done.
+ RETRIEVAL_POINTERS_BUFFER buffer;
+ return sizeof(RETRIEVAL_POINTERS_BUFFER) +
grt (UTC plus 2) 2011/10/01 02:49:46 sizeof(buffer) + ...
robertshield 2011/10/01 05:00:41 Done.
+ (number_of_extents - 1) * sizeof(buffer.Extents);
+}
+
+} // namespace
+
+namespace fragmentation_checker {
+
+bool CountFileExtents(const FilePath& file_path, uint32* file_extents_count) {
+ DCHECK(file_extents_count);
+
+ bool success = false;
+
+ base::PlatformFileError error_code = base::PLATFORM_FILE_ERROR_FAILED;
+ bool created = false;
+ base::PlatformFile file_handle = CreatePlatformFile(
+ file_path,
+ base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
+ &created,
+ &error_code);
+ if (error_code == base::PLATFORM_FILE_OK && !created) {
grt (UTC plus 2) 2011/10/01 02:49:46 base::PLATFORM_FILE_OPEN dictates that created wil
robertshield 2011/10/01 05:00:41 Done.
+ STARTING_VCN_INPUT_BUFFER starting_vcn_input_buffer = {0};
+
+ // Compute an output size capable of holding 16 extents at first. This may
grt (UTC plus 2) 2011/10/01 02:49:46 may -> will
robertshield 2011/10/01 05:00:41 Done.
+ // fail when the number of extents exceeds 16, in which case we make
+ // a bigger buffer up to kMaxBufferSize.
+ int extents_guess = 16;
+ size_t output_size = ComputeRetrievalPointersBufferSize(extents_guess);
+ std::vector<uint8> retrieval_pointers_buffer(output_size);
+
+ DWORD bytes_returned = 0;
+
+ bool result = false;
+ do {
+ result = DeviceIoControl(
+ file_handle,
+ FSCTL_GET_RETRIEVAL_POINTERS,
+ reinterpret_cast<void*>(&starting_vcn_input_buffer),
+ sizeof(starting_vcn_input_buffer),
+ reinterpret_cast<void*>(&retrieval_pointers_buffer[0]),
+ retrieval_pointers_buffer.size(),
+ &bytes_returned,
+ NULL) != FALSE;
+
+ if (!result) {
+ if (GetLastError() == ERROR_MORE_DATA) {
+ // Grow the extents we can handle
+ extents_guess *= 2;
grt (UTC plus 2) 2011/10/01 02:49:46 maybe cap this at kMaxExtentCount instead of cappi
robertshield 2011/10/01 05:00:41 Done.
+ output_size = ComputeRetrievalPointersBufferSize(extents_guess);
+ if (output_size > kMaxBufferSize) {
+ LOG(ERROR) << "FSCTL_GET_RETRIEVAL_POINTERS output buffer exceeded "
+ "maximum size.";
+ break;
+ }
+ retrieval_pointers_buffer.assign(output_size, 0);
+ } else {
+ PLOG(ERROR) << "FSCTL_GET_RETRIEVAL_POINTERS failed.";
+ }
+ }
+ } while (!result);
+
+ if (result) {
+ RETRIEVAL_POINTERS_BUFFER* retrieval_pointers =
+ reinterpret_cast<RETRIEVAL_POINTERS_BUFFER*>(
+ &retrieval_pointers_buffer[0]);
+ *file_extents_count = retrieval_pointers->ExtentCount;
+ success = true;
+ } else {
+ LOG(ERROR) << "Failed to retrieve extents.";
+ }
+ } else {
+ LOG(ERROR) << "Failed to open module file to check extents.";
grt (UTC plus 2) 2011/10/01 02:49:46 may as well log error_code
robertshield 2011/10/01 05:00:41 Done.
+ }
+
+ return success;
+}
+
+void RecordFragmentationMetricForCurrentModule() {
+ FilePath module_path;
+ if (PathService::Get(base::FILE_MODULE, &module_path)) {
+ uint32 file_extent_count = 0;
+ if (CountFileExtents(module_path, &file_extent_count)) {
+ int extent_count = static_cast<int>(
+ std::min(file_extent_count, kMaxExtentCount));
+ UMA_HISTOGRAM_COUNTS_10000("Fragmentation.ModuleExtents",
+ extent_count);
+ }
+ } else {
+ NOTREACHED() << "Could not get path to current module.";
+ }
+}
+
+} // namespace fragmentation_checker
Property changes on: chrome\browser\fragmentation_checker_win.cc
___________________________________________________________________
Added: svn:eol-style
+ LF

Powered by Google App Engine
This is Rietveld 408576698