From 323451a8e94be9e20453d66b85585fcb456f4405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= Date: Thu, 8 Dec 2022 12:10:53 +0100 Subject: [PATCH] Improve the CPU core count detection See https://github.com/theofidry/cpu-core-counter/issues/11 for the motivations. The code should be sensibly the same, the notable differences are: - fixed the deprecated usage of `hw.ncpu` - /proc/cpuinfo is check _last_ - nproc is checked first (before was not checked at all, it's considered to be more accurate and less convoluted than cpuinfo though) - not sure about the `return 2`, but this was not too clear [here](https://github.com/phpstan/phpstan-src/pull/514#pullrequestreview-660926363) neither. I could otherwise change the fallback value to return `1` if `proc_open` doesn't exist and 2 otherwise - add more ways to find the CPU cores count --- composer.json | 1 + composer.lock | 63 +++++++++++++++++++++++++++++++++- src/Process/CpuCoreCounter.php | 51 ++++----------------------- 3 files changed, 70 insertions(+), 45 deletions(-) diff --git a/composer.json b/composer.json index df2c60498c..5ddd0691ca 100644 --- a/composer.json +++ b/composer.json @@ -10,6 +10,7 @@ "clue/ndjson-react": "^1.0", "composer/ca-bundle": "^1.2", "composer/xdebug-handler": "^3.0.3", + "fidry/cpu-core-counter": "^0.4.0", "hoa/compiler": "3.17.08.08", "hoa/exception": "^1.0", "hoa/regex": "1.17.01.13", diff --git a/composer.lock b/composer.lock index 4d01d2e09c..e6708f7ab5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b8442972e5e817244cd2e9ae1bf28a37", + "content-hash": "527711a596fb0d4639393d90d1efd0eb", "packages": [ { "name": "clue/ndjson-react", @@ -330,6 +330,67 @@ }, "time": "2017-07-23T21:35:13+00:00" }, + { + "name": "fidry/cpu-core-counter", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "666cb04a02f2801f3b19955fc23c824f9018bf64" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/666cb04a02f2801f3b19955fc23c824f9018bf64", + "reference": "666cb04a02f2801f3b19955fc23c824f9018bf64", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^1.9.2", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.2.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^9.5.26 || ^8.5.31", + "theofidry/php-cs-fixer-config": "^1.0", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/0.4.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2022-12-10T21:26:31+00:00" + }, { "name": "fig/http-message-util", "version": "1.1.5", diff --git a/src/Process/CpuCoreCounter.php b/src/Process/CpuCoreCounter.php index 609baad081..cff6084b87 100644 --- a/src/Process/CpuCoreCounter.php +++ b/src/Process/CpuCoreCounter.php @@ -2,16 +2,8 @@ namespace PHPStan\Process; -use function count; -use function fgets; -use function file_get_contents; -use function function_exists; -use function is_file; -use function is_resource; -use function pclose; -use function popen; -use function preg_match_all; -use const DIRECTORY_SEPARATOR; +use Fidry\CpuCoreCounter\CpuCoreCounter as FidryCpuCoreCounter; +use Fidry\CpuCoreCounter\NumberOfCpuCoreNotFound; class CpuCoreCounter { @@ -24,42 +16,13 @@ public function getNumberOfCpuCores(): int return $this->count; } - if (!function_exists('proc_open')) { - return $this->count = 1; + try { + $this->count = (new FidryCpuCoreCounter())->getCount(); + } catch (NumberOfCpuCoreNotFound) { + $this->count = 1; } - // from brianium/paratest - if (@is_file('/proc/cpuinfo')) { - // Linux (and potentially Windows with linux sub systems) - $cpuinfo = @file_get_contents('/proc/cpuinfo'); - if ($cpuinfo !== false) { - preg_match_all('/^processor/m', $cpuinfo, $matches); - return $this->count = count($matches[0]); - } - } - - if (DIRECTORY_SEPARATOR === '\\') { - // Windows - $process = @popen('wmic cpu get NumberOfLogicalProcessors', 'rb'); - if (is_resource($process)) { - fgets($process); - $cores = (int) fgets($process); - pclose($process); - - return $this->count = $cores; - } - } - - $process = @popen('sysctl -n hw.ncpu', 'rb'); - if (is_resource($process)) { - // *nix (Linux, BSD and Mac) - $cores = (int) fgets($process); - pclose($process); - - return $this->count = $cores; - } - - return $this->count = 2; + return $this->count; } }