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

Side by Side 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, 2 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 unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/fragmentation_checker_win.h"
6
7 #include <windows.h>
8 #include <winioctl.h>
9
grt (UTC plus 2) 2011/10/01 02:49:46 #include <algorithm> #include <vector>
robertshield 2011/10/01 05:00:41 Done.
10 #include "base/at_exit.h"
11 #include "base/basictypes.h"
12 #include "base/command_line.h"
13 #include "base/file_path.h"
14 #include "base/file_util.h"
15 #include "base/logging.h"
16 #include "base/metrics/histogram.h"
17 #include "base/path_service.h"
18
19 namespace {
20
21 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
22 const uint32 kMaxExtentCount = 10000;
23
24 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.
25 RETRIEVAL_POINTERS_BUFFER buffer;
26 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.
27 (number_of_extents - 1) * sizeof(buffer.Extents);
28 }
29
30 } // namespace
31
32 namespace fragmentation_checker {
33
34 bool CountFileExtents(const FilePath& file_path, uint32* file_extents_count) {
35 DCHECK(file_extents_count);
36
37 bool success = false;
38
39 base::PlatformFileError error_code = base::PLATFORM_FILE_ERROR_FAILED;
40 bool created = false;
41 base::PlatformFile file_handle = CreatePlatformFile(
42 file_path,
43 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
44 &created,
45 &error_code);
46 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.
47 STARTING_VCN_INPUT_BUFFER starting_vcn_input_buffer = {0};
48
49 // 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.
50 // fail when the number of extents exceeds 16, in which case we make
51 // a bigger buffer up to kMaxBufferSize.
52 int extents_guess = 16;
53 size_t output_size = ComputeRetrievalPointersBufferSize(extents_guess);
54 std::vector<uint8> retrieval_pointers_buffer(output_size);
55
56 DWORD bytes_returned = 0;
57
58 bool result = false;
59 do {
60 result = DeviceIoControl(
61 file_handle,
62 FSCTL_GET_RETRIEVAL_POINTERS,
63 reinterpret_cast<void*>(&starting_vcn_input_buffer),
64 sizeof(starting_vcn_input_buffer),
65 reinterpret_cast<void*>(&retrieval_pointers_buffer[0]),
66 retrieval_pointers_buffer.size(),
67 &bytes_returned,
68 NULL) != FALSE;
69
70 if (!result) {
71 if (GetLastError() == ERROR_MORE_DATA) {
72 // Grow the extents we can handle
73 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.
74 output_size = ComputeRetrievalPointersBufferSize(extents_guess);
75 if (output_size > kMaxBufferSize) {
76 LOG(ERROR) << "FSCTL_GET_RETRIEVAL_POINTERS output buffer exceeded "
77 "maximum size.";
78 break;
79 }
80 retrieval_pointers_buffer.assign(output_size, 0);
81 } else {
82 PLOG(ERROR) << "FSCTL_GET_RETRIEVAL_POINTERS failed.";
83 }
84 }
85 } while (!result);
86
87 if (result) {
88 RETRIEVAL_POINTERS_BUFFER* retrieval_pointers =
89 reinterpret_cast<RETRIEVAL_POINTERS_BUFFER*>(
90 &retrieval_pointers_buffer[0]);
91 *file_extents_count = retrieval_pointers->ExtentCount;
92 success = true;
93 } else {
94 LOG(ERROR) << "Failed to retrieve extents.";
95 }
96 } else {
97 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.
98 }
99
100 return success;
101 }
102
103 void RecordFragmentationMetricForCurrentModule() {
104 FilePath module_path;
105 if (PathService::Get(base::FILE_MODULE, &module_path)) {
106 uint32 file_extent_count = 0;
107 if (CountFileExtents(module_path, &file_extent_count)) {
108 int extent_count = static_cast<int>(
109 std::min(file_extent_count, kMaxExtentCount));
110 UMA_HISTOGRAM_COUNTS_10000("Fragmentation.ModuleExtents",
111 extent_count);
112 }
113 } else {
114 NOTREACHED() << "Could not get path to current module.";
115 }
116 }
117
118 } // namespace fragmentation_checker
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698