diff options
author | jchuang@chromium.org <jchuang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-18 04:52:48 +0000 |
---|---|---|
committer | jchuang@chromium.org <jchuang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-08-18 04:54:16 +0000 |
commit | d617e8bed8c797344feb4511e15aa30fdd922693 (patch) | |
tree | aec67f86e6da0601a0f957d08f9e94482b3c0fa3 | |
parent | 6624676b3e8cd6084bc9309c2e22813ab5fd180b (diff) | |
download | chromium_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.cc | 17 | ||||
-rw-r--r-- | chrome/browser/extensions/api/system_cpu/cpu_info_provider_linux.cc | 47 |
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; |