summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2017-01-20 18:28:11 +0100
committerGiampaolo Rodola <g.rodola@gmail.com>2017-01-20 18:28:11 +0100
commit17cbdf8b5e6730373a3b8eb9b0d4a8e477a04fee (patch)
tree34e3c563a72fe72ae26f743681b4d2ec21217b04
parent76690f2a5495b405e5574edc09f6d0d90790a05e (diff)
downloadpsutil-17cbdf8b5e6730373a3b8eb9b0d4a8e477a04fee.tar.gz
#941: cpu frequency - windows implementation
-rw-r--r--psutil/__init__.py4
-rw-r--r--psutil/_psutil_windows.c67
-rw-r--r--psutil/_pswindows.py6
-rwxr-xr-xpsutil/tests/test_memory_leaks.py5
-rwxr-xr-xsetup.py2
5 files changed, 82 insertions, 2 deletions
diff --git a/psutil/__init__.py b/psutil/__init__.py
index 4fed9fea..a8aa84e2 100644
--- a/psutil/__init__.py
+++ b/psutil/__init__.py
@@ -181,7 +181,7 @@ __all__ = [
"pid_exists", "pids", "process_iter", "wait_procs", # proc
"virtual_memory", "swap_memory", # memory
"cpu_times", "cpu_percent", "cpu_times_percent", "cpu_count", # cpu
- "cpu_stats", "cpu_freq",
+ "cpu_stats", # "cpu_freq",
"net_io_counters", "net_connections", "net_if_addrs", # network
"net_if_stats",
"disk_io_counters", "disk_partitions", "disk_usage", # disk
@@ -1869,6 +1869,8 @@ if hasattr(_psplatform, "cpu_freq"):
"""
return _psplatform.cpu_freq()
+ __all__.append("cpu_freq")
+
# =====================================================================
# --- system memory related functions
diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c
index 4d939aff..4caace7d 100644
--- a/psutil/_psutil_windows.c
+++ b/psutil/_psutil_windows.c
@@ -24,6 +24,7 @@
#include <iphlpapi.h>
#include <wtsapi32.h>
#include <Winsvc.h>
+#include <PowrProf.h>
// Link with Iphlpapi.lib
#pragma comment(lib, "IPHLPAPI.lib")
@@ -145,6 +146,16 @@ typedef struct _MIB_UDP6TABLE_OWNER_PID {
} MIB_UDP6TABLE_OWNER_PID, *PMIB_UDP6TABLE_OWNER_PID;
#endif
+typedef struct _PROCESSOR_POWER_INFORMATION {
+ ULONG Number;
+ ULONG MaxMhz;
+ ULONG CurrentMhz;
+ ULONG MhzLimit;
+ ULONG MaxIdleState;
+ ULONG CurrentIdleState;
+} PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION;
+
+
PIP_ADAPTER_ADDRESSES
psutil_get_nic_addresses() {
// allocate a 15 KB buffer to start with
@@ -3391,6 +3402,60 @@ error:
}
+/*
+ * Return CPU frequency.
+ */
+static PyObject *
+psutil_cpu_freq(PyObject *self, PyObject *args) {
+ PROCESSOR_POWER_INFORMATION *ppi;
+ NTSTATUS ret;
+ size_t size;
+ LPBYTE pBuffer = NULL;
+ ULONG current;
+ ULONG max;
+ unsigned int num_cpus;
+ SYSTEM_INFO system_info;
+ system_info.dwNumberOfProcessors = 0;
+
+ // Get the number of CPUs.
+ GetSystemInfo(&system_info);
+ if (system_info.dwNumberOfProcessors == 0)
+ num_cpus = 1;
+ else
+ num_cpus = system_info.dwNumberOfProcessors;
+
+ // Allocate size.
+ size = num_cpus * sizeof(PROCESSOR_POWER_INFORMATION);
+ pBuffer = (BYTE*)LocalAlloc(LPTR, size);
+ if (! pBuffer) {
+ PyErr_SetFromWindowsErr(0);
+ return NULL;
+ }
+
+ // Syscall.
+ ret = CallNtPowerInformation(
+ ProcessorInformation, NULL, 0, pBuffer, size);
+ if (ret != 0) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "CallNtPowerInformation syscall failed");
+ goto error;
+ }
+
+ // Results.
+ ppi = (PROCESSOR_POWER_INFORMATION *)pBuffer;
+ max = ppi->MaxMhz;
+ current = ppi->CurrentMhz;
+ LocalFree(pBuffer);
+
+ return Py_BuildValue("kk", current, max);
+
+error:
+ if (pBuffer != NULL)
+ LocalFree(pBuffer);
+ return NULL;
+}
+
+
// ------------------------ Python init ---------------------------
static PyMethodDef
@@ -3495,6 +3560,8 @@ PsutilMethods[] = {
"Return NICs stats."},
{"cpu_stats", psutil_cpu_stats, METH_VARARGS,
"Return NICs stats."},
+ {"cpu_freq", psutil_cpu_freq, METH_VARARGS,
+ "Return CPU frequency."},
// --- windows services
{"winservice_enumerate", psutil_winservice_enumerate, METH_VARARGS,
diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py
index cb816f73..8c962535 100644
--- a/psutil/_pswindows.py
+++ b/psutil/_pswindows.py
@@ -299,6 +299,12 @@ def cpu_stats():
syscalls)
+def cpu_freq():
+ curr, max_ = cext.cpu_freq()
+ min_ = 0
+ return [_common.scpufreq(curr, min_, max_)]
+
+
# =====================================================================
# --- network
# =====================================================================
diff --git a/psutil/tests/test_memory_leaks.py b/psutil/tests/test_memory_leaks.py
index 46186e41..f1a951f0 100755
--- a/psutil/tests/test_memory_leaks.py
+++ b/psutil/tests/test_memory_leaks.py
@@ -458,6 +458,11 @@ class TestModuleFunctionsLeaks(TestMemLeak):
def test_cpu_stats(self):
self.execute(psutil.cpu_stats)
+ @skip_if_linux()
+ @unittest.skipUnless(hasattr(psutil, "cpu_freq"), "platform not supported")
+ def test_cpu_freq(self):
+ self.execute(psutil.cpu_freq)
+
# --- mem
def test_virtual_memory(self):
diff --git a/setup.py b/setup.py
index 80521a48..01543bee 100755
--- a/setup.py
+++ b/setup.py
@@ -122,7 +122,7 @@ if WINDOWS:
define_macros=macros,
libraries=[
"psapi", "kernel32", "advapi32", "shell32", "netapi32",
- "iphlpapi", "wtsapi32", "ws2_32",
+ "iphlpapi", "wtsapi32", "ws2_32", "PowrProf",
],
# extra_compile_args=["/Z7"],
# extra_link_args=["/DEBUG"]