summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjchuang@chromium.org <jchuang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-18 04:52:48 +0000
committerjchuang@chromium.org <jchuang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-08-18 04:54:16 +0000
commitd617e8bed8c797344feb4511e15aa30fdd922693 (patch)
treeaec67f86e6da0601a0f957d08f9e94482b3c0fa3
parent6624676b3e8cd6084bc9309c2e22813ab5fd180b (diff)
downloadchromium_src-d617e8bed8c797344feb4511e15aa30fdd922693.zip
chromium_src-d617e8bed8c797344feb4511e15aa30fdd922693.tar.gz
chromium_src-d617e8bed8c797344feb4511e15aa30fdd922693.tar.bz2
Return configured processors in NumberOfProcessors() on posix platforms
On Linux/Mac/FreeBSD platform, NumberOfProcessors() was returning the number of online processors. Change it to return the number of configured processors (incl. offline processors). 1. Most callers of this API expect it to return totally available cpu cores, mainly for threading optimization. 2. The number of online processors is changed within seconds on some embedded platforms. It is wrong to pass the cached value of the number of currently online processors to Blink sandbox. BUG=404364 TEST=Tested on nyan (it may have 1~4 cpu cores online) Review URL: https://codereview.chromium.org/454053002 Cr-Commit-Position: refs/heads/master@{#290209} git-svn-id: svn://svn.chromium.org/chrome/trunk/src@290209 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/sys_info_posix.cc17
-rw-r--r--chrome/browser/extensions/api/system_cpu/cpu_info_provider_linux.cc47
2 files changed, 37 insertions, 27 deletions
diff --git a/base/sys_info_posix.cc b/base/sys_info_posix.cc
index c201ae1..3d49bf9 100644
--- a/base/sys_info_posix.cc
+++ b/base/sys_info_posix.cc
@@ -30,9 +30,20 @@ namespace {
#if !defined(OS_OPENBSD)
int NumberOfProcessors() {
- // It seems that sysconf returns the number of "logical" processors on both
- // Mac and Linux. So we get the number of "online logical" processors.
- long res = sysconf(_SC_NPROCESSORS_ONLN);
+ // sysconf returns the number of "logical" (not "physical") processors on both
+ // Mac and Linux. So we get the number of max available "logical" processors.
+ //
+ // Note that the number of "currently online" processors may be fewer than the
+ // returned value of NumberOfProcessors(). On some platforms, the kernel may
+ // make some processors offline intermittently, to save power when system
+ // loading is low.
+ //
+ // One common use case that needs to know the processor count is to create
+ // optimal number of threads for optimization. It should make plan according
+ // to the number of "max available" processors instead of "currently online"
+ // ones. The kernel should be smart enough to make all processors online when
+ // it has sufficient number of threads waiting to run.
+ long res = sysconf(_SC_NPROCESSORS_CONF);
if (res == -1) {
NOTREACHED();
return 1;
diff --git a/chrome/browser/extensions/api/system_cpu/cpu_info_provider_linux.cc b/chrome/browser/extensions/api/system_cpu/cpu_info_provider_linux.cc
index 7885414..927f581 100644
--- a/chrome/browser/extensions/api/system_cpu/cpu_info_provider_linux.cc
+++ b/chrome/browser/extensions/api/system_cpu/cpu_info_provider_linux.cc
@@ -22,6 +22,17 @@ bool CpuInfoProvider::QueryCpuTimePerProcessor(
std::vector<linked_ptr<api::system_cpu::ProcessorInfo> >* infos) {
DCHECK(infos);
+ // WARNING: this method may return incomplete data because some processors may
+ // be brought offline at runtime. /proc/stat does not report statistics of
+ // offline processors. CPU usages of offline processors will be filled with
+ // zeros.
+ //
+ // An example of output of /proc/stat when processor 0 and 3 are online, but
+ // processor 1 and 2 are offline:
+ //
+ // cpu 145292 20018 83444 1485410 995 44 3578 0 0 0
+ // cpu0 138060 19947 78350 1479514 570 44 3576 0 0 0
+ // cpu3 2033 32 1075 1400 52 0 1 0 0 0
std::string contents;
if (!base::ReadFileToString(base::FilePath(kProcStat), &contents))
return false;
@@ -32,37 +43,25 @@ bool CpuInfoProvider::QueryCpuTimePerProcessor(
// Skip the first line because it is just an aggregated number of
// all cpuN lines.
std::getline(iss, line);
- size_t i = 0;
while (std::getline(iss, line)) {
if (line.compare(0, 3, "cpu") != 0)
continue;
- // The number of entries in /proc/stat may mismatch the size of infos
- // because the number of online processors may change after the value has
- // been decided in CpuInfoProvider::QueryInfo().
- //
- // TODO(jchuang): fix the fail case by using the number of configured
- // processors instead of online processors.
- if (i == infos->size()) {
- LOG(ERROR) << "Got more entries in /proc/stat than online CPUs";
- return false;
- }
-
uint64 user = 0, nice = 0, sys = 0, idle = 0;
+ uint32 pindex = 0;
int vals = sscanf(line.c_str(),
- "%*s %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64,
- &user, &nice, &sys, &idle);
- DCHECK_EQ(4, vals);
+ "cpu%" PRIu32 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64,
+ &pindex, &user, &nice, &sys, &idle);
+ if (vals != 5 || pindex >= infos->size()) {
+ NOTREACHED();
+ return false;
+ }
- infos->at(i)->usage.kernel = static_cast<double>(sys);
- infos->at(i)->usage.user = static_cast<double>(user + nice);
- infos->at(i)->usage.idle = static_cast<double>(idle);
- infos->at(i)->usage.total = static_cast<double>(sys + user + nice + idle);
- ++i;
- }
- if (i < infos->size()) {
- LOG(ERROR) << "Got fewer entries in /proc/stat than online CPUs";
- return false;
+ infos->at(pindex)->usage.kernel = static_cast<double>(sys);
+ infos->at(pindex)->usage.user = static_cast<double>(user + nice);
+ infos->at(pindex)->usage.idle = static_cast<double>(idle);
+ infos->at(pindex)->usage.total = static_cast<double>(sys + user +
+ nice + idle);
}
return true;