diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index 3c9ff28110..41c14b2e86 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -672,41 +672,43 @@ def cpu_stats(): ctx_switches, interrupts, soft_interrupts, syscalls) -if os.path.exists("/sys/devices/system/cpu/cpufreq/policy0") or \ - os.path.exists("/sys/devices/system/cpu/cpu0/cpufreq"): - def cpu_freq(): - """Return frequency metrics for all CPUs. - 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 +HAS_CPUFREQ = (os.path.exists("/sys/devices/system/cpu/cpufreq/policy0") or + os.path.exists("/sys/devices/system/cpu/cpu0/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) - if curr is None: - # Likely an old RedHat, see: - # https://github.com/giampaolo/psutil/issues/1071 - curr = cat(pjoin(path, "cpuinfo_cur_freq"), fallback=None) - if curr is None: - raise NotImplementedError( - "can't find current frequency file") - curr = int(curr) / 1000 - max_ = int(cat(pjoin(path, "scaling_max_freq"))) / 1000 - min_ = int(cat(pjoin(path, "scaling_min_freq"))) / 1000 - ret.append(_common.scpufreq(curr, min_, max_)) - return ret +def _get_path(num): + """Return frequency metrics for all CPUs. + Contrarily to other OSes, Linux updates these values in + real-time. + """ + 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 + + +def _get_cpu_scaling_value(num, key): + """Return frequncy value based on key for a NUMth CPU. """ + if not HAS_CPUFREQ: + return 0. + + path = _get_path(num) + if not path: + return 0. + + pjoin = os.path.join + value = cat(pjoin(path, key), fallback=None) + if value is None and key == "scaling_cur_freq": + # Likely an old RedHat, see: + # https://github.com/giampaolo/psutil/issues/1071 + value = cat(pjoin(path, key), fallback=None) + if value is None: + raise NotImplementedError( + "can't find current frequency file") + return int(value) / 1000 + -elif os.path.exists("/proc/cpuinfo"): +if os.path.exists("/proc/cpuinfo"): def cpu_freq(): """Alternate implementation using /proc/cpuinfo. min and max frequencies are not available and are set to None. @@ -716,7 +718,20 @@ def cpu_freq(): 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.)) + n = len(ret) + max_ = _get_cpu_scaling_value(n, "scaling_max_freq") + min_ = _get_cpu_scaling_value(n, "scaling_min_freq") + ret.append(_common.scpufreq(float(value), min_, max_)) + return ret + +elif HAS_CPUFREQ: + def cpu_freq(): + ret = [] + for n in range(cpu_count_logical()): + curr = _get_cpu_scaling_value(n, "scaling_cur_freq") + max_ = _get_cpu_scaling_value(n, "scaling_max_freq") + min_ = _get_cpu_scaling_value(n, "scaling_min_freq") + ret.append(_common.scpufreq(curr, min_, max_)) return ret else: