OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/api/system_cpu/cpu_info_provider.h" | 5 #include "chrome/browser/extensions/api/system_cpu/cpu_info_provider.h" |
6 | 6 |
7 #include <cstdio> | 7 #include <cstdio> |
8 #include <sstream> | 8 #include <sstream> |
9 | 9 |
10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
11 #include "base/format_macros.h" | 11 #include "base/format_macros.h" |
12 | 12 |
13 namespace extensions { | 13 namespace extensions { |
14 | 14 |
15 namespace { | 15 namespace { |
16 | 16 |
17 const char kProcStat[] = "/proc/stat"; | 17 const char kProcStat[] = "/proc/stat"; |
18 | 18 |
19 } // namespace | 19 } // namespace |
20 | 20 |
21 bool CpuInfoProvider::QueryCpuTimePerProcessor( | 21 bool CpuInfoProvider::QueryCpuTimePerProcessor( |
22 std::vector<linked_ptr<api::system_cpu::ProcessorInfo> >* infos) { | 22 std::vector<linked_ptr<api::system_cpu::ProcessorInfo> >* infos) { |
23 DCHECK(infos); | 23 DCHECK(infos); |
24 | 24 |
| 25 // WARNING: this method may return incomplete data because some processors may |
| 26 // be brought offline at runtime. /proc/stat does not report statistics of |
| 27 // offline processors. CPU usages of offline processors will be filled with |
| 28 // zeros. |
| 29 // |
| 30 // An example of output of /proc/stat when processor 0 and 3 are online, but |
| 31 // processor 1 and 2 are offline: |
| 32 // |
| 33 // cpu 145292 20018 83444 1485410 995 44 3578 0 0 0 |
| 34 // cpu0 138060 19947 78350 1479514 570 44 3576 0 0 0 |
| 35 // cpu3 2033 32 1075 1400 52 0 1 0 0 0 |
25 std::string contents; | 36 std::string contents; |
26 if (!base::ReadFileToString(base::FilePath(kProcStat), &contents)) | 37 if (!base::ReadFileToString(base::FilePath(kProcStat), &contents)) |
27 return false; | 38 return false; |
28 | 39 |
29 std::istringstream iss(contents); | 40 std::istringstream iss(contents); |
30 std::string line; | 41 std::string line; |
31 | 42 |
32 // Skip the first line because it is just an aggregated number of | 43 // Skip the first line because it is just an aggregated number of |
33 // all cpuN lines. | 44 // all cpuN lines. |
34 std::getline(iss, line); | 45 std::getline(iss, line); |
35 size_t i = 0; | |
36 while (std::getline(iss, line)) { | 46 while (std::getline(iss, line)) { |
37 if (line.compare(0, 3, "cpu") != 0) | 47 if (line.compare(0, 3, "cpu") != 0) |
38 continue; | 48 continue; |
39 | 49 |
40 // The number of entries in /proc/stat may mismatch the size of infos | 50 uint64 user = 0, nice = 0, sys = 0, idle = 0; |
41 // because the number of online processors may change after the value has | 51 uint32 pindex = 0; |
42 // been decided in CpuInfoProvider::QueryInfo(). | 52 int vals = sscanf(line.c_str(), |
43 // | 53 "cpu%" PRIu32 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, |
44 // TODO(jchuang): fix the fail case by using the number of configured | 54 &pindex, &user, &nice, &sys, &idle); |
45 // processors instead of online processors. | 55 if (vals != 5 || pindex >= infos->size()) { |
46 if (i == infos->size()) { | 56 NOTREACHED(); |
47 LOG(ERROR) << "Got more entries in /proc/stat than online CPUs"; | |
48 return false; | 57 return false; |
49 } | 58 } |
50 | 59 |
51 uint64 user = 0, nice = 0, sys = 0, idle = 0; | 60 infos->at(pindex)->usage.kernel = static_cast<double>(sys); |
52 int vals = sscanf(line.c_str(), | 61 infos->at(pindex)->usage.user = static_cast<double>(user + nice); |
53 "%*s %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, | 62 infos->at(pindex)->usage.idle = static_cast<double>(idle); |
54 &user, &nice, &sys, &idle); | 63 infos->at(pindex)->usage.total = static_cast<double>(sys + user + |
55 DCHECK_EQ(4, vals); | 64 nice + idle); |
56 | |
57 infos->at(i)->usage.kernel = static_cast<double>(sys); | |
58 infos->at(i)->usage.user = static_cast<double>(user + nice); | |
59 infos->at(i)->usage.idle = static_cast<double>(idle); | |
60 infos->at(i)->usage.total = static_cast<double>(sys + user + nice + idle); | |
61 ++i; | |
62 } | |
63 if (i < infos->size()) { | |
64 LOG(ERROR) << "Got fewer entries in /proc/stat than online CPUs"; | |
65 return false; | |
66 } | 65 } |
67 | 66 |
68 return true; | 67 return true; |
69 } | 68 } |
70 | 69 |
71 } // namespace extensions | 70 } // namespace extensions |
OLD | NEW |