summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2021-01-15 19:07:38 +0100
committerGiampaolo Rodola <g.rodola@gmail.com>2021-01-15 19:07:38 +0100
commit4ad3380bb312b6ea06717e3adc1f60ac8daf4a05 (patch)
tree923f2b548ada7533fb6e794b8253941ec225b6f6
parent3223228b0558e42508cf9f8cce84d89c79b5c52b (diff)
parente80cabe5206fd7ef14fd6a47e2571f660f95babf (diff)
downloadpsutil-new-cpu-count.tar.gz
Merge branch 'master' into new-cpu-countnew-cpu-count
-rw-r--r--.github/workflows/issues.py17
-rw-r--r--CREDITS9
-rw-r--r--HISTORY.rst10
-rw-r--r--README.rst9
-rw-r--r--docs/DEVNOTES6
-rw-r--r--docs/index.rst23
-rw-r--r--psutil/_pslinux.py52
-rw-r--r--psutil/_psutil_common.c3
-rw-r--r--psutil/_psutil_osx.c16
-rw-r--r--psutil/_psutil_windows.c29
-rw-r--r--psutil/arch/osx/process_info.c13
-rw-r--r--psutil/arch/windows/wmi.c26
-rwxr-xr-xpsutil/tests/test_linux.py4
13 files changed, 93 insertions, 124 deletions
diff --git a/.github/workflows/issues.py b/.github/workflows/issues.py
index 91e12202..964e5192 100644
--- a/.github/workflows/issues.py
+++ b/.github/workflows/issues.py
@@ -180,14 +180,6 @@ def is_event_new_pr():
return False
-def is_event_new_comment():
- data = _get_event_data()
- try:
- return data['action'] == 'created' and 'comment' in data
- except KeyError:
- return False
-
-
def get_issue():
data = _get_event_data()
try:
@@ -317,10 +309,6 @@ def on_new_pr(issue):
# issue.create_comment(REPLY_UPDATE_CHANGELOG)
-def on_new_comment(issue):
- pass
-
-
def main():
issue = get_issue()
stype = "PR" if is_pr(issue) else "issue"
@@ -336,11 +324,8 @@ def main():
add_labels_from_text(issue, issue.title)
add_labels_from_new_body(issue, issue.body)
on_new_pr(issue)
- elif is_event_new_comment():
- log("created new comment for %s" % issue)
- on_new_comment(issue)
else:
- raise ValueError("unhandled event")
+ log("unhandled event")
if __name__ == '__main__':
diff --git a/CREDITS b/CREDITS
index 7e7ce954..fa8cbf1c 100644
--- a/CREDITS
+++ b/CREDITS
@@ -95,6 +95,9 @@ I: 557
Donations
-------------------------------------------------------------------------------
+N: aristocratos
+W: https://github.com/aristocratos
+
N: Daniel Widdis
C: Washington, USA
W: https://github.com/dbwiddis
@@ -542,7 +545,7 @@ I: 1042, 1079, 1070
N: Oleksii Shevchuk
W: https://github.com/alxchk
-I: 1077, 1093, 1091, 1220, 1346
+I: 1077, 1093, 1091, 1220, 1346, 1904
N: Prodesire
W: https://github.com/Prodesire
@@ -729,3 +732,7 @@ I: 1620, 1727
N: Tim Schlueter
W: https://github.com/modelrockettier
I: 1822
+
+N: marxin
+W: https://github.com/marxin
+I: 1851
diff --git a/HISTORY.rst b/HISTORY.rst
index 9f5281f9..dc4afbff 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -5,11 +5,21 @@
XXXX-XX-XX
+**Enhancements**
+
+- 1851_: [Linux] cpu_freq() is slow on systems with many CPUs. Read current
+ frequency values for all CPUs from /proc/cpuinfo instead of opening many
+ files in /sys fs. (patch by marxin)
+
**Bug fixes**
- 1456_: [macOS] psutil.cpu_freq()'s min and max are set to 0 if can't be
determined (instead of crashing).
+- 1512_: [macOS] sometimes Process.connections() will crash with EOPNOTSUPP
+ for one connection; this is now ignored.
- 1892_: [macOS] psutil.cpu_freq() broken on Apple M1.
+- 1904_: [Windows] OpenProcess fails with ERROR_SUCCESS due to GetLastError()
+ called after sprintf(). (patch by alxchk)
5.8.0
=====
diff --git a/README.rst b/README.rst
index 83e79aab..2631e059 100644
--- a/README.rst
+++ b/README.rst
@@ -23,7 +23,7 @@
:alt: Code quality
.. |github-actions| image:: https://img.shields.io/github/workflow/status/giampaolo/psutil/CI?label=Linux%2C%20macOS%2C%20FreeBSD
- :target: https://github.com/giampaolo/psutil/actions?query=workflow%3ACI
+ :target: https://github.com/giampaolo/psutil/actions?query=workflow%3Abuild
:alt: Linux, macOS, Windows tests
.. |appveyor| image:: https://img.shields.io/appveyor/ci/giampaolo/psutil/master.svg?maxAge=3600&label=Windows
@@ -35,7 +35,7 @@
:alt: Test coverage (coverall.io)
.. |doc| image:: https://readthedocs.org/projects/psutil/badge/?version=latest
- :target: http://psutil.readthedocs.io/en/latest/?badge=latest
+ :target: https://psutil.readthedocs.io/en/latest/
:alt: Documentation Status
.. |version| image:: https://img.shields.io/pypi/v/psutil.svg?label=pypi
@@ -43,7 +43,6 @@
:alt: Latest version
.. |py-versions| image:: https://img.shields.io/pypi/pyversions/psutil.svg
- :target: https://pypi.org/project/psutil
:alt: Supported Python versions
.. |packages| image:: https://repology.org/badge/tiny-repos/python:psutil.svg
@@ -133,10 +132,12 @@ Supporters
.. raw:: html
<div>
- <a href="https://github.com/dbwiddis"><img height="40" width="40" src="https://avatars1.githubusercontent.com/u/9291703?s=88&amp;u=3a4cbf1ea36068a36392856adb2fb02f623a3235&amp;v=4" /></a>
+ <a href="https://github.com/dbwiddis"><img height="40" width="40" title="Daniel Widdis" src="https://avatars1.githubusercontent.com/u/9291703?s=88&amp;v=4" /></a>
+ <a href="https://github.com/aristocratos"><img height="40" width="40" title="aristocratos" src="https://avatars3.githubusercontent.com/u/59659483?s=96&amp;v=4" /></a>
</div>
<sup><a href="https://github.com/sponsors/giampaolo">add your avatar</a></sup>
+
Contributing
============
diff --git a/docs/DEVNOTES b/docs/DEVNOTES
index 7fe14f7d..915754d6 100644
--- a/docs/DEVNOTES
+++ b/docs/DEVNOTES
@@ -34,18 +34,12 @@ FEATURES
- #772: extended net_io_counters() metrics.
-- #900: wheels for macOS and Linux.
-
- #922: extended net_io_stats() info.
- #914: extended platform specific process info.
- #898: wifi stats
-- #893: (BSD) process environ
-
-- #809: (BSD) per-process resource limits (rlimit()).
-
- (UNIX) process root (different from cwd)
- #782: (UNIX) process num of signals received.
diff --git a/docs/index.rst b/docs/index.rst
index 612cafb8..595130cd 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -73,28 +73,21 @@ Sponsors
Supporters
----------
-None yet.
-
.. raw:: html
+ <div>
+ <a href="https://github.com/dbwiddis"><img height="40" width="40" title="Daniel Widdis" src="https://avatars1.githubusercontent.com/u/9291703?s=88&amp;v=4" /></a>
+ <a href="https://github.com/aristocratos"><img height="40" width="40" title="aristocratos" src="https://avatars3.githubusercontent.com/u/59659483?s=96&amp;v=4" /></a>
+ </div>
+ <br />
<sup><a href="https://github.com/sponsors/giampaolo">add your avatar</a></sup>
Install
=======
-Linux Ubuntu / Debian::
-
- sudo apt-get install gcc python3-dev
- sudo pip3 install psutil
-
-Linux Redhat::
-
- sudo yum install gcc python3-devel
- sudo pip3 install psutil
-
-Windows::
+On Linux, Windows, macOS::
- pip3 install psutil
+ pip install psutil
For other platforms see more detailed
`install <https://github.com/giampaolo/psutil/blob/master/INSTALL.rst>`_
@@ -2438,7 +2431,7 @@ Kill process tree
timeout=None, on_terminate=None):
"""Kill a process tree (including grandchildren) with signal
"sig" and return a (gone, still_alive) tuple.
- "on_terminate", if specified, is a callabck function which is
+ "on_terminate", if specified, is a callback function which is
called as soon as a child terminates.
"""
assert pid != os.getpid(), "won't kill myself"
diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py
index 0cb8eaf3..69b175c5 100644
--- a/psutil/_pslinux.py
+++ b/psutil/_pslinux.py
@@ -736,6 +736,17 @@ def cpu_stats():
ctx_switches, interrupts, soft_interrupts, syscalls)
+def _cpu_get_cpuinfo_freq():
+ """Return current CPU frequency from cpuinfo if available.
+ """
+ ret = []
+ with open_binary('%s/cpuinfo' % get_procfs_path()) as f:
+ for line in f:
+ if line.lower().startswith(b'cpu mhz'):
+ ret.append(float(line.split(b':', 1)[1]))
+ return ret
+
+
if os.path.exists("/sys/devices/system/cpu/cpufreq/policy0") or \
os.path.exists("/sys/devices/system/cpu/cpu0/cpufreq"):
def cpu_freq():
@@ -743,20 +754,19 @@ if os.path.exists("/sys/devices/system/cpu/cpufreq/policy0") or \
Contrarily to other OSes, Linux updates these values in
real-time.
"""
- def get_path(num):
- for p in ("/sys/devices/system/cpu/cpufreq/policy%s" % num,
- "/sys/devices/system/cpu/cpu%s/cpufreq" % num):
- if os.path.exists(p):
- return p
-
+ cpuinfo_freqs = _cpu_get_cpuinfo_freq()
+ paths = sorted(
+ glob.glob("/sys/devices/system/cpu/cpufreq/policy[0-9]*") or
+ glob.glob("/sys/devices/system/cpu/cpu[0-9]*/cpufreq"))
ret = []
- for n in range(cpu_count_logical()):
- path = get_path(n)
- if not path:
- continue
-
- pjoin = os.path.join
- curr = cat(pjoin(path, "scaling_cur_freq"), fallback=None)
+ pjoin = os.path.join
+ for i, path in enumerate(paths):
+ if len(paths) == len(cpuinfo_freqs):
+ # take cached value from cpuinfo if available, see:
+ # https://github.com/giampaolo/psutil/issues/1851
+ curr = cpuinfo_freqs[i]
+ else:
+ curr = cat(pjoin(path, "scaling_cur_freq"), fallback=None)
if curr is None:
# Likely an old RedHat, see:
# https://github.com/giampaolo/psutil/issues/1071
@@ -770,24 +780,12 @@ if os.path.exists("/sys/devices/system/cpu/cpufreq/policy0") or \
ret.append(_common.scpufreq(curr, min_, max_))
return ret
-elif os.path.exists("/proc/cpuinfo"):
+else:
def cpu_freq():
"""Alternate implementation using /proc/cpuinfo.
min and max frequencies are not available and are set to None.
"""
- ret = []
- with open_binary('%s/cpuinfo' % get_procfs_path()) as f:
- for line in f:
- if line.lower().startswith(b'cpu mhz'):
- key, value = line.split(b':', 1)
- ret.append(_common.scpufreq(float(value), 0., 0.))
- return ret
-
-else:
- def cpu_freq():
- """Dummy implementation when none of the above files are present.
- """
- return []
+ return [_common.scpufreq(x, 0., 0.) for x in _cpu_get_cpuinfo_freq()]
# =====================================================================
diff --git a/psutil/_psutil_common.c b/psutil/_psutil_common.c
index e9f86179..b82d5e89 100644
--- a/psutil/_psutil_common.c
+++ b/psutil/_psutil_common.c
@@ -83,8 +83,9 @@ PyErr_SetFromOSErrnoWithSyscall(const char *syscall) {
char fullmsg[1024];
#ifdef PSUTIL_WINDOWS
+ DWORD dwLastError = GetLastError();
sprintf(fullmsg, "(originated from %s)", syscall);
- PyErr_SetFromWindowsErrWithFilename(GetLastError(), fullmsg);
+ PyErr_SetFromWindowsErrWithFilename(dwLastError, fullmsg);
#else
PyObject *exc;
sprintf(fullmsg, "%s (originated from %s)", strerror(errno), syscall);
diff --git a/psutil/_psutil_osx.c b/psutil/_psutil_osx.c
index 47b5393f..a12679ec 100644
--- a/psutil/_psutil_osx.c
+++ b/psutil/_psutil_osx.c
@@ -1027,9 +1027,18 @@ psutil_proc_connections(PyObject *self, PyObject *args) {
PROC_PIDFDSOCKETINFO, &si, sizeof(si));
// --- errors checking
- if ((nb <= 0) || (nb < sizeof(si))) {
+ if ((nb <= 0) || (nb < sizeof(si)) || (errno != 0)) {
if (errno == EBADF) {
// let's assume socket has been closed
+ psutil_debug("proc_pidfdinfo(PROC_PIDFDSOCKETINFO) -> "
+ "EBADF (ignored)");
+ continue;
+ }
+ else if (errno == EOPNOTSUPP) {
+ // may happen sometimes, see:
+ // https://github.com/giampaolo/psutil/issues/1512
+ psutil_debug("proc_pidfdinfo(PROC_PIDFDSOCKETINFO) -> "
+ "EOPNOTSUPP (ignored)");
continue;
}
else {
@@ -1063,11 +1072,6 @@ psutil_proc_connections(PyObject *self, PyObject *args) {
if (inseq == 0)
continue;
- if (errno != 0) {
- PyErr_SetFromErrno(PyExc_OSError);
- goto error;
- }
-
if ((family == AF_INET) || (family == AF_INET6)) {
if (family == AF_INET) {
inet_ntop(AF_INET,
diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c
index 1ac98a07..1b813f99 100644
--- a/psutil/_psutil_windows.c
+++ b/psutil/_psutil_windows.c
@@ -44,35 +44,6 @@ static PyObject *TimeoutAbandoned;
/*
- * Return the number of logical, active CPUs. Return 0 if undetermined.
- * See discussion at: https://bugs.python.org/issue33166#msg314631
- */
-unsigned int
-psutil_get_num_cpus(int fail_on_err) {
- unsigned int ncpus = 0;
-
- // Minimum requirement: Windows 7
- if (GetActiveProcessorCount != NULL) {
- ncpus = GetActiveProcessorCount(ALL_PROCESSOR_GROUPS);
- if ((ncpus == 0) && (fail_on_err == 1)) {
- PyErr_SetFromWindowsErr(0);
- }
- }
- else {
- psutil_debug("GetActiveProcessorCount() not available; "
- "using GetSystemInfo()");
- ncpus = (unsigned int)PSUTIL_SYSTEM_INFO.dwNumberOfProcessors;
- if ((ncpus <= 0) && (fail_on_err == 1)) {
- PyErr_SetString(
- PyExc_RuntimeError,
- "GetSystemInfo() failed to retrieve CPU count");
- }
- }
- return ncpus;
-}
-
-
-/*
* Return a Python float representing the system uptime expressed in seconds
* since the epoch.
*/
diff --git a/psutil/arch/osx/process_info.c b/psutil/arch/osx/process_info.c
index fb9f24ff..15ad3b89 100644
--- a/psutil/arch/osx/process_info.c
+++ b/psutil/arch/osx/process_info.c
@@ -370,14 +370,21 @@ psutil_get_kinfo_proc(pid_t pid, struct kinfo_proc *kp) {
/*
* A wrapper around proc_pidinfo().
+ * https://opensource.apple.com/source/xnu/xnu-2050.7.9/bsd/kern/proc_info.c.
* Returns 0 on failure (and Python exception gets already set).
*/
int
psutil_proc_pidinfo(pid_t pid, int flavor, uint64_t arg, void *pti, int size) {
errno = 0;
- int ret = proc_pidinfo(pid, flavor, arg, pti, size);
- if ((ret <= 0) || ((unsigned long)ret < sizeof(pti))) {
- psutil_raise_for_pid(pid, "proc_pidinfo()");
+ int ret;
+
+ ret = proc_pidinfo(pid, flavor, arg, pti, size);
+ if (ret <= 0) {
+ psutil_raise_for_pid(pid, "proc_pidinfo() failed");
+ return 0;
+ }
+ else if ((unsigned long )ret < sizeof(pti)) {
+ psutil_raise_for_pid(pid, "proc_pidinfo() len mismatch");
return 0;
}
return ret;
diff --git a/psutil/arch/windows/wmi.c b/psutil/arch/windows/wmi.c
index f9a847d3..5fad4053 100644
--- a/psutil/arch/windows/wmi.c
+++ b/psutil/arch/windows/wmi.c
@@ -64,22 +64,28 @@ psutil_init_loadavg_counter(PyObject *self, PyObject *args) {
HANDLE event;
HANDLE waitHandle;
- if ((PdhOpenQueryW(NULL, 0, &hQuery)) != ERROR_SUCCESS)
- goto error;
+ if ((PdhOpenQueryW(NULL, 0, &hQuery)) != ERROR_SUCCESS) {
+ PyErr_Format(PyExc_RuntimeError, "PdhOpenQueryW failed");
+ return NULL;
+ }
s = PdhAddEnglishCounterW(hQuery, szCounterPath, 0, &hCounter);
- if (s != ERROR_SUCCESS)
- goto error;
+ if (s != ERROR_SUCCESS) {
+ PyErr_Format(PyExc_RuntimeError, "PdhAddEnglishCounterW failed");
+ return NULL;
+ }
event = CreateEventW(NULL, FALSE, FALSE, L"LoadUpdateEvent");
if (event == NULL) {
- PyErr_SetFromWindowsErr(0);
+ PyErr_SetFromOSErrnoWithSyscall("CreateEventW");
return NULL;
}
s = PdhCollectQueryDataEx(hQuery, SAMPLING_INTERVAL, event);
- if (s != ERROR_SUCCESS)
- goto error;
+ if (s != ERROR_SUCCESS) {
+ PyErr_Format(PyExc_RuntimeError, "PdhCollectQueryDataEx failed");
+ return NULL;
+ }
ret = RegisterWaitForSingleObject(
&waitHandle,
@@ -91,15 +97,11 @@ psutil_init_loadavg_counter(PyObject *self, PyObject *args) {
WT_EXECUTEDEFAULT);
if (ret == 0) {
- PyErr_SetFromWindowsErr(0);
+ PyErr_SetFromOSErrnoWithSyscall("RegisterWaitForSingleObject");
return NULL;
}
Py_RETURN_NONE;
-
-error:
- PyErr_SetFromWindowsErr(0);
- return NULL;
}
diff --git a/psutil/tests/test_linux.py b/psutil/tests/test_linux.py
index c6759ba0..e03490b3 100755
--- a/psutil/tests/test_linux.py
+++ b/psutil/tests/test_linux.py
@@ -794,18 +794,14 @@ class TestSystemCPUFrequency(PsutilTestCase):
if path.startswith('/sys/devices/system/cpu/'):
return False
else:
- if path == "/proc/cpuinfo":
- flags.append(None)
return os_path_exists(path)
- flags = []
os_path_exists = os.path.exists
try:
with mock.patch("os.path.exists", side_effect=path_exists_mock):
reload_module(psutil._pslinux)
ret = psutil.cpu_freq()
assert ret
- assert flags
self.assertEqual(ret.max, 0.0)
self.assertEqual(ret.min, 0.0)
for freq in psutil.cpu_freq(percpu=True):