• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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/test/perf/perf_test.h"
6 
7 #include <stdio.h>
8 
9 #include "base/logging.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "base/strings/stringprintf.h"
12 #include "chrome/test/base/chrome_process_util.h"
13 #include "testing/perf/perf_test.h"
14 
15 namespace perf_test {
16 
PrintIOPerfInfo(const std::string & test_name,const ChromeProcessList & chrome_processes,base::ProcessId browser_pid)17 void PrintIOPerfInfo(const std::string& test_name,
18                      const ChromeProcessList& chrome_processes,
19                      base::ProcessId browser_pid) {
20   PrintIOPerfInfo(stdout, test_name, chrome_processes, browser_pid);
21 }
22 
PrintIOPerfInfo(FILE * target,const std::string & test_name,const ChromeProcessList & chrome_processes,base::ProcessId browser_pid)23 void PrintIOPerfInfo(FILE* target,
24                      const std::string& test_name,
25                      const ChromeProcessList& chrome_processes,
26                      base::ProcessId browser_pid) {
27   fprintf(target, "%s", IOPerfInfoToString(test_name, chrome_processes,
28                                            browser_pid).c_str());
29 }
30 
IOPerfInfoToString(const std::string & test_name,const ChromeProcessList & chrome_processes,base::ProcessId browser_pid)31 std::string IOPerfInfoToString(const std::string& test_name,
32                                const ChromeProcessList& chrome_processes,
33                                base::ProcessId browser_pid) {
34   size_t read_op_b = 0;
35   size_t read_op_r = 0;
36   size_t write_op_b = 0;
37   size_t write_op_r = 0;
38   size_t other_op_b = 0;
39   size_t other_op_r = 0;
40   size_t total_op_b = 0;
41   size_t total_op_r = 0;
42 
43   size_t read_byte_b = 0;
44   size_t read_byte_r = 0;
45   size_t write_byte_b = 0;
46   size_t write_byte_r = 0;
47   size_t other_byte_b = 0;
48   size_t other_byte_r = 0;
49   size_t total_byte_b = 0;
50   size_t total_byte_r = 0;
51 
52   std::string output;
53   ChromeProcessList::const_iterator it;
54   for (it = chrome_processes.begin(); it != chrome_processes.end(); ++it) {
55     base::ProcessHandle process_handle;
56     if (!base::OpenProcessHandle(*it, &process_handle)) {
57       NOTREACHED();
58       return output;
59     }
60 
61     // TODO(sgk):  if/when base::ProcessMetrics returns real stats on mac:
62     // scoped_ptr<base::ProcessMetrics> process_metrics(
63     //     base::ProcessMetrics::CreateProcessMetrics(process_handle));
64     scoped_ptr<ChromeTestProcessMetrics> process_metrics(
65         ChromeTestProcessMetrics::CreateProcessMetrics(process_handle));
66     base::IoCounters io_counters;
67     memset(&io_counters, 0, sizeof(io_counters));
68 
69     if (process_metrics.get()->GetIOCounters(&io_counters)) {
70       // Print out IO performance.  We assume that the values can be
71       // converted to size_t (they're reported as ULONGLONG, 64-bit numbers).
72       std::string chrome_name = (*it == browser_pid) ? "_b" : "_r";
73 
74       size_t read_op = static_cast<size_t>(io_counters.ReadOperationCount);
75       size_t write_op = static_cast<size_t>(io_counters.WriteOperationCount);
76       size_t other_op = static_cast<size_t>(io_counters.OtherOperationCount);
77       size_t total_op = static_cast<size_t>(io_counters.ReadOperationCount +
78                                             io_counters.WriteOperationCount +
79                                             io_counters.OtherOperationCount);
80 
81       size_t read_byte = static_cast<size_t>(io_counters.ReadTransferCount
82                                              / 1024);
83       size_t write_byte = static_cast<size_t>(io_counters.WriteTransferCount
84                                               / 1024);
85       size_t other_byte = static_cast<size_t>(io_counters.OtherTransferCount
86                                               / 1024);
87       size_t total_byte = static_cast<size_t>((io_counters.ReadTransferCount +
88                                                io_counters.WriteTransferCount +
89                                                io_counters.OtherTransferCount)
90                                               / 1024);
91 
92       if (*it == browser_pid) {
93         read_op_b = read_op;
94         write_op_b = write_op;
95         other_op_b = other_op;
96         total_op_b = total_op;
97         read_byte_b = read_byte;
98         write_byte_b = write_byte;
99         other_byte_b = other_byte;
100         total_byte_b = total_byte;
101       } else {
102         read_op_r += read_op;
103         write_op_r += write_op;
104         other_op_r += other_op;
105         total_op_r += total_op;
106         read_byte_r += read_byte;
107         write_byte_r += write_byte;
108         other_byte_r += other_byte;
109         total_byte_r += total_byte;
110       }
111     }
112 
113     base::CloseProcessHandle(process_handle);
114   }
115 
116   std::string t_name(test_name);
117   AppendResult(output,
118                "read_op_b",
119                std::string(),
120                "r_op_b" + t_name,
121                read_op_b,
122                "ops",
123                false);
124   AppendResult(output,
125                "write_op_b",
126                std::string(),
127                "w_op_b" + t_name,
128                write_op_b,
129                "ops",
130                false);
131   AppendResult(output,
132                "other_op_b",
133                std::string(),
134                "o_op_b" + t_name,
135                other_op_b,
136                "ops",
137                false);
138   AppendResult(output,
139                "total_op_b",
140                std::string(),
141                "IO_op_b" + t_name,
142                total_op_b,
143                "ops",
144                false);
145 
146   AppendResult(output,
147                "read_byte_b",
148                std::string(),
149                "r_b" + t_name,
150                read_byte_b,
151                "kb",
152                false);
153   AppendResult(output,
154                "write_byte_b",
155                std::string(),
156                "w_b" + t_name,
157                write_byte_b,
158                "kb",
159                false);
160   AppendResult(output,
161                "other_byte_b",
162                std::string(),
163                "o_b" + t_name,
164                other_byte_b,
165                "kb",
166                false);
167   AppendResult(output,
168                "total_byte_b",
169                std::string(),
170                "IO_b" + t_name,
171                total_byte_b,
172                "kb",
173                false);
174 
175   AppendResult(output,
176                "read_op_r",
177                std::string(),
178                "r_op_r" + t_name,
179                read_op_r,
180                "ops",
181                false);
182   AppendResult(output,
183                "write_op_r",
184                std::string(),
185                "w_op_r" + t_name,
186                write_op_r,
187                "ops",
188                false);
189   AppendResult(output,
190                "other_op_r",
191                std::string(),
192                "o_op_r" + t_name,
193                other_op_r,
194                "ops",
195                false);
196   AppendResult(output,
197                "total_op_r",
198                std::string(),
199                "IO_op_r" + t_name,
200                total_op_r,
201                "ops",
202                false);
203 
204   AppendResult(output,
205                "read_byte_r",
206                std::string(),
207                "r_r" + t_name,
208                read_byte_r,
209                "kb",
210                false);
211   AppendResult(output,
212                "write_byte_r",
213                std::string(),
214                "w_r" + t_name,
215                write_byte_r,
216                "kb",
217                false);
218   AppendResult(output,
219                "other_byte_r",
220                std::string(),
221                "o_r" + t_name,
222                other_byte_r,
223                "kb",
224                false);
225   AppendResult(output,
226                "total_byte_r",
227                std::string(),
228                "IO_r" + t_name,
229                total_byte_r,
230                "kb",
231                false);
232 
233   return output;
234 }
235 
PrintMemoryUsageInfo(const std::string & test_name,const ChromeProcessList & chrome_processes,base::ProcessId browser_pid)236 void PrintMemoryUsageInfo(const std::string& test_name,
237                           const ChromeProcessList& chrome_processes,
238                           base::ProcessId browser_pid) {
239   PrintMemoryUsageInfo(stdout, test_name, chrome_processes, browser_pid);
240 }
241 
PrintMemoryUsageInfo(FILE * target,const std::string & test_name,const ChromeProcessList & chrome_processes,base::ProcessId browser_pid)242 void PrintMemoryUsageInfo(FILE* target,
243                           const std::string& test_name,
244                           const ChromeProcessList& chrome_processes,
245                           base::ProcessId browser_pid) {
246   fprintf(target, "%s", MemoryUsageInfoToString(test_name, chrome_processes,
247                                                 browser_pid).c_str());
248 }
249 
MemoryUsageInfoToString(const std::string & test_name,const ChromeProcessList & chrome_processes,base::ProcessId browser_pid)250 std::string MemoryUsageInfoToString(const std::string& test_name,
251                                     const ChromeProcessList& chrome_processes,
252                                     base::ProcessId browser_pid) {
253   size_t browser_virtual_size = 0;
254   size_t browser_working_set_size = 0;
255   size_t renderer_virtual_size = 0;
256   size_t renderer_working_set_size = 0;
257   size_t total_virtual_size = 0;
258   size_t total_working_set_size = 0;
259 #if defined(OS_WIN)
260   size_t browser_peak_virtual_size = 0;
261   size_t browser_peak_working_set_size = 0;
262   size_t renderer_total_peak_virtual_size = 0;
263   size_t renderer_total_peak_working_set_size = 0;
264   size_t renderer_single_peak_virtual_size = 0;
265   size_t renderer_single_peak_working_set_size = 0;
266 #endif
267 
268   std::string output;
269   ChromeProcessList::const_iterator it;
270   for (it = chrome_processes.begin(); it != chrome_processes.end(); ++it) {
271     base::ProcessHandle process_handle;
272     if (!base::OpenProcessHandle(*it, &process_handle)) {
273       NOTREACHED();
274       return output;
275     }
276 
277     // TODO(sgk):  if/when base::ProcessMetrics returns real stats on mac:
278     // scoped_ptr<base::ProcessMetrics> process_metrics(
279     //     base::ProcessMetrics::CreateProcessMetrics(process_handle));
280     scoped_ptr<ChromeTestProcessMetrics> process_metrics(
281         ChromeTestProcessMetrics::CreateProcessMetrics(process_handle));
282 
283     size_t current_virtual_size = process_metrics->GetPagefileUsage();
284     size_t current_working_set_size = process_metrics->GetWorkingSetSize();
285 
286     if (*it == browser_pid) {
287       browser_virtual_size = current_virtual_size;
288       browser_working_set_size = current_working_set_size;
289     } else {
290       renderer_virtual_size += current_virtual_size;
291       renderer_working_set_size += current_working_set_size;
292     }
293     total_virtual_size += current_virtual_size;
294     total_working_set_size += current_working_set_size;
295 
296 #if defined(OS_WIN)
297     size_t peak_virtual_size = process_metrics->GetPeakPagefileUsage();
298     size_t peak_working_set_size = process_metrics->GetPeakWorkingSetSize();
299     if (*it == browser_pid) {
300       browser_peak_virtual_size = peak_virtual_size;
301       browser_peak_working_set_size = peak_working_set_size;
302     } else {
303       if (peak_virtual_size > renderer_single_peak_virtual_size) {
304         renderer_single_peak_virtual_size = peak_virtual_size;
305       }
306       if (peak_working_set_size > renderer_single_peak_working_set_size) {
307         renderer_single_peak_working_set_size = peak_working_set_size;
308       }
309       renderer_total_peak_virtual_size += peak_virtual_size;
310       renderer_total_peak_working_set_size += peak_working_set_size;
311     }
312 #endif
313 
314     base::CloseProcessHandle(process_handle);
315   }
316 
317   std::string trace_name(test_name);
318 #if defined(OS_WIN)
319   AppendResult(output, "vm_peak_b", "", "vm_pk_b" + trace_name,
320                browser_peak_virtual_size, "bytes",
321                false /* not important */);
322   AppendResult(output, "ws_peak_b", "", "ws_pk_b" + trace_name,
323                browser_peak_working_set_size, "bytes",
324                false /* not important */);
325   AppendResult(output, "vm_peak_r", "", "vm_pk_r" + trace_name,
326                renderer_total_peak_virtual_size, "bytes",
327                false /* not important */);
328   AppendResult(output, "ws_peak_r", "", "ws_pk_r" + trace_name,
329                renderer_total_peak_working_set_size, "bytes",
330                false /* not important */);
331   AppendResult(output, "vm_single_peak_r", "", "vm_spk_r" + trace_name,
332                renderer_single_peak_virtual_size, "bytes",
333                false /* not important */);
334   AppendResult(output, "ws_single_peak_r", "", "ws_spk_r" + trace_name,
335                renderer_single_peak_working_set_size, "bytes",
336                false /* important */);
337   AppendResult(output, "vm_final_b", "", "vm_f_b" + trace_name,
338                browser_virtual_size, "bytes",
339                false /* not important */);
340   AppendResult(output, "ws_final_b", "", "ws_f_b" + trace_name,
341                browser_working_set_size, "bytes",
342                false /* not important */);
343   AppendResult(output, "vm_final_r", "", "vm_f_r" + trace_name,
344                renderer_virtual_size, "bytes",
345                false /* not important */);
346   AppendResult(output, "ws_final_r", "", "ws_f_r" + trace_name,
347                renderer_working_set_size, "bytes",
348                false /* not important */);
349   AppendResult(output, "vm_final_t", "", "vm_f_t" + trace_name,
350                total_virtual_size, "bytes",
351                false /* not important */);
352   AppendResult(output, "ws_final_t", "", "ws_f_t" + trace_name,
353                total_working_set_size, "bytes",
354                false /* not important */);
355 #elif defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_ANDROID)
356   AppendResult(output,
357                "vm_size_final_b",
358                std::string(),
359                "vm_size_f_b" + trace_name,
360                browser_virtual_size,
361                "bytes",
362                false /* not important */);
363   AppendResult(output,
364                "vm_rss_final_b",
365                std::string(),
366                "vm_rss_f_b" + trace_name,
367                browser_working_set_size,
368                "bytes",
369                false /* not important */);
370   AppendResult(output,
371                "vm_size_final_r",
372                std::string(),
373                "vm_size_f_r" + trace_name,
374                renderer_virtual_size,
375                "bytes",
376                false /* not important */);
377   AppendResult(output,
378                "vm_rss_final_r",
379                std::string(),
380                "vm_rss_f_r" + trace_name,
381                renderer_working_set_size,
382                "bytes",
383                false /* not important */);
384   AppendResult(output,
385                "vm_size_final_t",
386                std::string(),
387                "vm_size_f_t" + trace_name,
388                total_virtual_size,
389                "bytes",
390                false /* not important */);
391   AppendResult(output,
392                "vm_rss_final_t",
393                std::string(),
394                "vm_rss_f_t" + trace_name,
395                total_working_set_size,
396                "bytes",
397                false /* not important */);
398 #else
399   NOTIMPLEMENTED();
400 #endif
401   AppendResult(output,
402                "processes",
403                std::string(),
404                "proc_" + trace_name,
405                chrome_processes.size(),
406                "count",
407                false /* not important */);
408 
409   return output;
410 }
411 
412 }  // namespace perf_test
413