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

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
10 #include <algorithm>
11 #include <vector>
12
13 #include "base/at_exit.h"
14 #include "base/basictypes.h"
15 #include "base/command_line.h"
16 #include "base/file_path.h"
17 #include "base/file_util.h"
18 #include "base/logging.h"
19 #include "base/metrics/histogram.h"
20 #include "base/path_service.h"
21
22 namespace {
23
24 const int kMaxExtentCount = 1 << 16;
25
26 size_t ComputeRetrievalPointersBufferSize(int number_of_extents) {
27 RETRIEVAL_POINTERS_BUFFER buffer;
28 return sizeof(buffer) + (number_of_extents - 1) * sizeof(buffer.Extents);
29 }
30
31 } // namespace
32
33 namespace fragmentation_checker {
34
35 bool CountFileExtents(const FilePath& file_path, int* file_extents_count) {
36 DCHECK(file_extents_count);
37
38 bool success = false;
39
40 base::PlatformFileError error_code = base::PLATFORM_FILE_ERROR_FAILED;
41 base::PlatformFile file_handle = CreatePlatformFile(
42 file_path,
43 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ,
44 NULL,
45 &error_code);
46 if (error_code == base::PLATFORM_FILE_OK) {
47 STARTING_VCN_INPUT_BUFFER starting_vcn_input_buffer = {0};
48
49 // Compute an output size capable of holding 16 extents at first. This will
50 // fail when the number of extents exceeds 16, in which case we make
51 // a bigger buffer capable of holding up to kMaxExtentCounts.
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;
74 if (extents_guess > kMaxExtentCount) {
grt (UTC plus 2) 2011/10/01 10:59:38 ? *file_extents_count = kMaxExtentCount; return tr
robertshield 2011/10/03 01:46:36 Done.
75 LOG(ERROR) << "FSCTL_GET_RETRIEVAL_POINTERS output buffer exceeded "
76 "maximum size.";
77 break;
78 }
79 output_size = ComputeRetrievalPointersBufferSize(extents_guess);
80 retrieval_pointers_buffer.assign(output_size, 0);
81 } else {
82 PLOG(ERROR) << "FSCTL_GET_RETRIEVAL_POINTERS failed.";
83 break;
84 }
85 }
86 } while (!result);
87
88 if (result) {
89 RETRIEVAL_POINTERS_BUFFER* retrieval_pointers =
90 reinterpret_cast<RETRIEVAL_POINTERS_BUFFER*>(
91 &retrieval_pointers_buffer[0]);
92 *file_extents_count = static_cast<int>(retrieval_pointers->ExtentCount);
93 success = true;
94 } else {
95 LOG(ERROR) << "Failed to retrieve extents.";
96 }
97 } else {
98 LOG(ERROR) << "Failed to open module file to check extents. Error code = "
99 << error_code;
100 }
101
102 return success;
103 }
104
105 void RecordFragmentationMetricForCurrentModule() {
106 FilePath module_path;
107 if (PathService::Get(base::FILE_MODULE, &module_path)) {
108 int file_extent_count = 0;
109 if (CountFileExtents(module_path, &file_extent_count)) {
110 UMA_HISTOGRAM_CUSTOM_COUNTS("Fragmentation.ModuleExtents",
111 file_extent_count,
112 1,
grt (UTC plus 2) 2011/10/01 11:04:09 wdyt about sending up 0 as the count when the coun
grt (UTC plus 2) 2011/10/01 22:34:53 reached -> read (i.e., CountFileExtents returns fa
robertshield 2011/10/03 01:46:36 Done.
robertshield 2011/10/03 01:46:36 Sounds reasonable. I modified the CountFileExtents
113 kMaxExtentCount,
114 50);
115 }
116 } else {
117 NOTREACHED() << "Could not get path to current module.";
118 }
119 }
120
121 } // namespace fragmentation_checker
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698