summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2016-03-05 11:00:44 -0800
committerGiampaolo Rodola <g.rodola@gmail.com>2016-03-05 11:00:44 -0800
commit2255b1285ed9577f79f0b83a1e9b5fb6400f9464 (patch)
treee45e5ec96507752d7dc143717ff07e5c7f48fa0f
parent77386f15f2c83895c6ba97e10fc35ffe92a02f56 (diff)
downloadpsutil-2255b1285ed9577f79f0b83a1e9b5fb6400f9464.tar.gz
#792 / cpu_stats: win impl
-rw-r--r--docs/index.rst24
-rw-r--r--psutil/_psutil_windows.c125
-rw-r--r--psutil/_pswindows.py9
-rw-r--r--psutil/arch/windows/ntextapi.h89
4 files changed, 241 insertions, 6 deletions
diff --git a/docs/index.rst b/docs/index.rst
index 6fd3dfa5..b8ff418e 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -155,18 +155,16 @@ CPU
Return various CPU statistics as a namedtuple whose fields change depending
on the platform.
- ctx_switches, interrupts, soft_interrupts, syscalls, traps
-
+-----------------+-----------------+--------------+-----------------+-----------------+-----------------+--------------+
| Linux | OSX | Windows | FreeBSD | OpenBSD | NetBSD | SunOS |
+=================+=================+==============+=================+=================+=================+==============+
- | ctx_switches | ctx_switches | | ctx_switches | ctx_switches | ctx_switches | ctx_switches |
+ | ctx_switches | ctx_switches | ctx_switches | ctx_switches | ctx_switches | ctx_switches | ctx_switches |
+-----------------+-----------------+--------------+-----------------+-----------------+-----------------+--------------+
- | interrupts | interrupts | | interrupts | interrupts | interrupts | interrupts |
+ | interrupts | interrupts | interrupts | interrupts | interrupts | interrupts | interrupts |
+-----------------+-----------------+--------------+-----------------+-----------------+-----------------+--------------+
- | soft_interrupts | soft_interrupts | | soft_interrupts | soft_interrupts | soft_interrupts | syscalls |
+ | soft_interrupts | soft_interrupts | dpcs | soft_interrupts | soft_interrupts | soft_interrupts | syscalls |
+-----------------+-----------------+--------------+-----------------+-----------------+-----------------+--------------+
- | procs_running | syscalls | | syscalls | syscalls | syscalls | traps |
+ | procs_running | syscalls | syscalls | syscalls | syscalls | syscalls | traps |
+-----------------+-----------------+--------------+-----------------+-----------------+-----------------+--------------+
| procs_blocked | traps | | traps | traps | traps | |
+-----------------+-----------------+--------------+-----------------+-----------------+-----------------+--------------+
@@ -177,6 +175,20 @@ CPU
| | | | | | | |
+-----------------+-----------------+--------------+-----------------+-----------------+-----------------+--------------+
+ - **ctx_switches**:
+ number of context switches (voluntary + involuntary) since boot.
+ - **interrupts**:
+ number of interrupts since boot.
+ - **interrupts**:
+ number of software interrupts since boot.
+ - **syscalls**: number of system calls since boot.
+ - **traps**: number of kernel traps since boot.
+ - **dpcs** *(Windows)*: number of
+ `delayed procedure calls <https://technet.microsoft.com/en-us/library/cc938646.aspx>`__
+ since boot.
+ - **procs_running** *(Linux)*: current number of actively running processes.
+ - **procs_blocked** *(Linux)*: current number of processes waiting for I/O.
+
Example (Linux):
.. code-block:: python
diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c
index 05ad39d5..54a3a5d3 100644
--- a/psutil/_psutil_windows.c
+++ b/psutil/_psutil_windows.c
@@ -3119,6 +3119,129 @@ error:
}
+/*
+ * Return CPU statistics.
+ */
+static PyObject *
+psutil_cpu_stats(PyObject *self, PyObject *args) {
+ // NtQuerySystemInformation stuff
+ typedef DWORD (_stdcall * NTQSI_PROC) (int, PVOID, ULONG, PULONG);
+ NTQSI_PROC NtQuerySystemInformation;
+ HINSTANCE hNtDll;
+
+ NTSTATUS status;
+ _SYSTEM_PERFORMANCE_INFORMATION *spi = NULL;
+ _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppi = NULL;
+ _SYSTEM_INTERRUPT_INFORMATION *InterruptInformation = NULL;
+ SYSTEM_INFO si;
+ UINT i;
+ ULONG64 dpcs = 0;
+ ULONG interrupts = 0;
+
+ // obtain NtQuerySystemInformation
+ hNtDll = LoadLibrary(TEXT("ntdll.dll"));
+ if (hNtDll == NULL) {
+ PyErr_SetFromWindowsErr(0);
+ goto error;
+ }
+ NtQuerySystemInformation = (NTQSI_PROC)GetProcAddress(
+ hNtDll, "NtQuerySystemInformation");
+ if (NtQuerySystemInformation == NULL) {
+ PyErr_SetFromWindowsErr(0);
+ goto error;
+ }
+
+ // retrives number of processors
+ GetSystemInfo(&si);
+
+ // get syscalls / ctx switches
+ spi = (_SYSTEM_PERFORMANCE_INFORMATION *) \
+ malloc(si.dwNumberOfProcessors * \
+ sizeof(_SYSTEM_PERFORMANCE_INFORMATION));
+ if (spi == NULL) {
+ PyErr_NoMemory();
+ goto error;
+ }
+ status = NtQuerySystemInformation(
+ SystemPerformanceInformation,
+ spi,
+ si.dwNumberOfProcessors * sizeof(_SYSTEM_PERFORMANCE_INFORMATION),
+ NULL);
+ if (status != 0) {
+ PyErr_SetFromWindowsErr(0);
+ goto error;
+ }
+
+ // get DPCs
+ InterruptInformation = \
+ malloc(sizeof(_SYSTEM_INTERRUPT_INFORMATION) *
+ si.dwNumberOfProcessors);
+ if (InterruptInformation == NULL) {
+ PyErr_NoMemory();
+ goto error;
+ }
+ status = NtQuerySystemInformation(
+ SystemInterruptInformation,
+ InterruptInformation,
+ si.dwNumberOfProcessors * sizeof(SYSTEM_INTERRUPT_INFORMATION),
+ NULL);
+ if (status != 0) {
+ PyErr_SetFromWindowsErr(0);
+ goto error;
+ }
+ for (i = 0; i < si.dwNumberOfProcessors; i++) {
+ dpcs += InterruptInformation[i].DpcCount;
+ }
+
+ // get interrupts
+ sppi = (_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *) \
+ malloc(si.dwNumberOfProcessors * \
+ sizeof(_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION));
+ if (sppi == NULL) {
+ PyErr_NoMemory();
+ goto error;
+ }
+
+ status = NtQuerySystemInformation(
+ SystemProcessorPerformanceInformation,
+ sppi,
+ si.dwNumberOfProcessors * sizeof
+ (_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION),
+ NULL);
+ if (status != 0) {
+ PyErr_SetFromWindowsErr(0);
+ goto error;
+ }
+
+ for (i = 0; i < si.dwNumberOfProcessors; i++) {
+ interrupts += sppi[i].InterruptCount;
+ }
+
+
+ // done
+ free(spi);
+ free(InterruptInformation);
+ FreeLibrary(hNtDll);
+ return Py_BuildValue(
+ "kkkk",
+ spi->ContextSwitches,
+ interrupts,
+ (unsigned long)dpcs,
+ spi->SystemCalls
+ );
+
+error:
+ if (spi)
+ free(spi);
+ if (InterruptInformation)
+ free(InterruptInformation);
+ if (hNtDll)
+ FreeLibrary(hNtDll);
+ return NULL;
+}
+
+
+
// ------------------------ Python init ---------------------------
static PyMethodDef
@@ -3223,6 +3346,8 @@ PsutilMethods[] = {
"Return NICs addresses."},
{"net_if_stats", psutil_net_if_stats, METH_VARARGS,
"Return NICs stats."},
+ {"cpu_stats", psutil_cpu_stats, METH_VARARGS,
+ "Return NICs stats."},
// --- windows API bindings
{"win32_QueryDosDevice", psutil_win32_QueryDosDevice, METH_VARARGS,
diff --git a/psutil/_pswindows.py b/psutil/_pswindows.py
index 4143afd7..731c2051 100644
--- a/psutil/_pswindows.py
+++ b/psutil/_pswindows.py
@@ -98,6 +98,9 @@ ntpinfo = namedtuple(
'ntpinfo', ['num_handles', 'ctx_switches', 'user_time', 'kernel_time',
'create_time', 'num_threads', 'io_rcount', 'io_wcount',
'io_rbytes', 'io_wbytes'])
+ssysinfo = namedtuple(
+ 'ssysinfo', ['ctx_switches', 'interrupts', 'dpcs', 'syscalls'])
+
# set later from __init__.py
NoSuchProcess = None
@@ -209,6 +212,12 @@ def cpu_count_physical():
return cext.cpu_count_phys()
+def cpu_stats():
+ """Return CPU statistics."""
+ ctx_switches, interrupts, dpcs, syscalls = cext.cpu_stats()
+ return ssysinfo(ctx_switches, interrupts, dpcs, syscalls)
+
+
def boot_time():
"""The system boot time expressed in seconds since the epoch."""
return cext.boot_time()
diff --git a/psutil/arch/windows/ntextapi.h b/psutil/arch/windows/ntextapi.h
index 7cfa6fa5..74adce22 100644
--- a/psutil/arch/windows/ntextapi.h
+++ b/psutil/arch/windows/ntextapi.h
@@ -18,6 +18,95 @@ typedef struct {
} _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
+typedef struct {
+ LARGE_INTEGER IdleProcessTime;
+ LARGE_INTEGER IoReadTransferCount;
+ LARGE_INTEGER IoWriteTransferCount;
+ LARGE_INTEGER IoOtherTransferCount;
+ ULONG IoReadOperationCount;
+ ULONG IoWriteOperationCount;
+ ULONG IoOtherOperationCount;
+ ULONG AvailablePages;
+ ULONG CommittedPages;
+ ULONG CommitLimit;
+ ULONG PeakCommitment;
+ ULONG PageFaultCount;
+ ULONG CopyOnWriteCount;
+ ULONG TransitionCount;
+ ULONG CacheTransitionCount;
+ ULONG DemandZeroCount;
+ ULONG PageReadCount;
+ ULONG PageReadIoCount;
+ ULONG CacheReadCount;
+ ULONG CacheIoCount;
+ ULONG DirtyPagesWriteCount;
+ ULONG DirtyWriteIoCount;
+ ULONG MappedPagesWriteCount;
+ ULONG MappedWriteIoCount;
+ ULONG PagedPoolPages;
+ ULONG NonPagedPoolPages;
+ ULONG PagedPoolAllocs;
+ ULONG PagedPoolFrees;
+ ULONG NonPagedPoolAllocs;
+ ULONG NonPagedPoolFrees;
+ ULONG FreeSystemPtes;
+ ULONG ResidentSystemCodePage;
+ ULONG TotalSystemDriverPages;
+ ULONG TotalSystemCodePages;
+ ULONG NonPagedPoolLookasideHits;
+ ULONG PagedPoolLookasideHits;
+ ULONG AvailablePagedPoolPages;
+ ULONG ResidentSystemCachePage;
+ ULONG ResidentPagedPoolPage;
+ ULONG ResidentSystemDriverPage;
+ ULONG CcFastReadNoWait;
+ ULONG CcFastReadWait;
+ ULONG CcFastReadResourceMiss;
+ ULONG CcFastReadNotPossible;
+ ULONG CcFastMdlReadNoWait;
+ ULONG CcFastMdlReadWait;
+ ULONG CcFastMdlReadResourceMiss;
+ ULONG CcFastMdlReadNotPossible;
+ ULONG CcMapDataNoWait;
+ ULONG CcMapDataWait;
+ ULONG CcMapDataNoWaitMiss;
+ ULONG CcMapDataWaitMiss;
+ ULONG CcPinMappedDataCount;
+ ULONG CcPinReadNoWait;
+ ULONG CcPinReadWait;
+ ULONG CcPinReadNoWaitMiss;
+ ULONG CcPinReadWaitMiss;
+ ULONG CcCopyReadNoWait;
+ ULONG CcCopyReadWait;
+ ULONG CcCopyReadNoWaitMiss;
+ ULONG CcCopyReadWaitMiss;
+ ULONG CcMdlReadNoWait;
+ ULONG CcMdlReadWait;
+ ULONG CcMdlReadNoWaitMiss;
+ ULONG CcMdlReadWaitMiss;
+ ULONG CcReadAheadIos;
+ ULONG CcLazyWriteIos;
+ ULONG CcLazyWritePages;
+ ULONG CcDataFlushes;
+ ULONG CcDataPages;
+ ULONG ContextSwitches;
+ ULONG FirstLevelTbFills;
+ ULONG SecondLevelTbFills;
+ ULONG SystemCalls;
+
+} _SYSTEM_PERFORMANCE_INFORMATION;
+
+
+typedef struct {
+ ULONG ContextSwitches;
+ ULONG DpcCount;
+ ULONG DpcRate;
+ ULONG TimeIncrement;
+ ULONG DpcBypassCount;
+ ULONG ApcBypassCount;
+} _SYSTEM_INTERRUPT_INFORMATION;
+
+
typedef enum _KTHREAD_STATE {
Initialized,
Ready,