Commit d617e8be authored by jchuang@chromium.org's avatar jchuang@chromium.org

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
parent 6624676b
...@@ -30,9 +30,20 @@ namespace { ...@@ -30,9 +30,20 @@ namespace {
#if !defined(OS_OPENBSD) #if !defined(OS_OPENBSD)
int NumberOfProcessors() { int NumberOfProcessors() {
// It seems that sysconf returns the number of "logical" processors on both // sysconf returns the number of "logical" (not "physical") processors on both
// Mac and Linux. So we get the number of "online logical" processors. // Mac and Linux. So we get the number of max available "logical" processors.
long res = sysconf(_SC_NPROCESSORS_ONLN); //
// 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) { if (res == -1) {
NOTREACHED(); NOTREACHED();
return 1; return 1;
......
...@@ -22,6 +22,17 @@ bool CpuInfoProvider::QueryCpuTimePerProcessor( ...@@ -22,6 +22,17 @@ bool CpuInfoProvider::QueryCpuTimePerProcessor(
std::vector<linked_ptr<api::system_cpu::ProcessorInfo> >* infos) { std::vector<linked_ptr<api::system_cpu::ProcessorInfo> >* infos) {
DCHECK(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; std::string contents;
if (!base::ReadFileToString(base::FilePath(kProcStat), &contents)) if (!base::ReadFileToString(base::FilePath(kProcStat), &contents))
return false; return false;
...@@ -32,37 +43,25 @@ bool CpuInfoProvider::QueryCpuTimePerProcessor( ...@@ -32,37 +43,25 @@ bool CpuInfoProvider::QueryCpuTimePerProcessor(
// Skip the first line because it is just an aggregated number of // Skip the first line because it is just an aggregated number of
// all cpuN lines. // all cpuN lines.
std::getline(iss, line); std::getline(iss, line);
size_t i = 0;
while (std::getline(iss, line)) { while (std::getline(iss, line)) {
if (line.compare(0, 3, "cpu") != 0) if (line.compare(0, 3, "cpu") != 0)
continue; 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; uint64 user = 0, nice = 0, sys = 0, idle = 0;
uint32 pindex = 0;
int vals = sscanf(line.c_str(), int vals = sscanf(line.c_str(),
"%*s %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, "cpu%" PRIu32 " %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64,
&user, &nice, &sys, &idle); &pindex, &user, &nice, &sys, &idle);
DCHECK_EQ(4, vals); if (vals != 5 || pindex >= infos->size()) {
NOTREACHED();
return false;
}
infos->at(i)->usage.kernel = static_cast<double>(sys); infos->at(pindex)->usage.kernel = static_cast<double>(sys);
infos->at(i)->usage.user = static_cast<double>(user + nice); infos->at(pindex)->usage.user = static_cast<double>(user + nice);
infos->at(i)->usage.idle = static_cast<double>(idle); infos->at(pindex)->usage.idle = static_cast<double>(idle);
infos->at(i)->usage.total = static_cast<double>(sys + user + nice + idle); infos->at(pindex)->usage.total = static_cast<double>(sys + user +
++i; nice + idle);
}
if (i < infos->size()) {
LOG(ERROR) << "Got fewer entries in /proc/stat than online CPUs";
return false;
} }
return true; return true;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment