diff options
-rw-r--r-- | psutil/_psutil_common.c | 38 | ||||
-rw-r--r-- | psutil/_psutil_common.h | 2 | ||||
-rw-r--r-- | psutil/_psutil_windows.c | 25 | ||||
-rw-r--r-- | psutil/arch/windows/process_info.c | 11 |
4 files changed, 47 insertions, 29 deletions
diff --git a/psutil/_psutil_common.c b/psutil/_psutil_common.c index 028e48e0..07578eda 100644 --- a/psutil/_psutil_common.c +++ b/psutil/_psutil_common.c @@ -352,6 +352,7 @@ psutil_set_winver() { return 0; } + int psutil_load_globals() { if (psutil_loadlibs() != 0) @@ -362,4 +363,41 @@ psutil_load_globals() { InitializeCriticalSection(&PSUTIL_CRITICAL_SECTION); return 0; } + + +/* + * Convert the hi and lo parts of a FILETIME structure or a LARGE_INTEGER + * to a UNIX time. + * A FILETIME contains a 64-bit value representing the number of + * 100-nanosecond intervals since January 1, 1601 (UTC). + * A UNIX time is the number of seconds that have elapsed since the + * UNIX epoch, that is the time 00:00:00 UTC on 1 January 1970. + */ +static double +_to_unix_time(ULONGLONG hiPart, ULONGLONG loPart) { + ULONGLONG ret; + + // 100 nanosecond intervals since January 1, 1601. + ret = hiPart << 32; + ret += loPart; + // Change starting time to the Epoch (00:00:00 UTC, January 1, 1970). + ret -= 116444736000000000ull; + // Convert nano secs to secs. + return (double) ret / 10000000ull; +} + + +double +psutil_FiletimeToUnixTime(FILETIME ft) { + return _to_unix_time((ULONGLONG)ft.dwHighDateTime, + (ULONGLONG)ft.dwLowDateTime); + +} + + +double +psutil_LargeIntegerToUnixTime(LARGE_INTEGER li) { + return _to_unix_time((ULONGLONG)li.HighPart, + (ULONGLONG)li.LowPart); +} #endif // PSUTIL_WINDOWS diff --git a/psutil/_psutil_common.h b/psutil/_psutil_common.h index 9e1ef887..65defdac 100644 --- a/psutil/_psutil_common.h +++ b/psutil/_psutil_common.h @@ -137,4 +137,6 @@ int psutil_setup(void); PVOID psutil_GetProcAddress(LPCSTR libname, LPCSTR procname); PVOID psutil_GetProcAddressFromLib(LPCSTR libname, LPCSTR procname); PVOID psutil_SetFromNTStatusErr(NTSTATUS Status, const char *syscall); + double psutil_FiletimeToUnixTime(FILETIME ft); + double psutil_LargeIntegerToUnixTime(LARGE_INTEGER li); #endif diff --git a/psutil/_psutil_windows.c b/psutil/_psutil_windows.c index 6b4d2e59..64592103 100644 --- a/psutil/_psutil_windows.c +++ b/psutil/_psutil_windows.c @@ -45,27 +45,6 @@ static PyObject *TimeoutAbandoned; /* - * Convert a FILETIME structure to a UNIX time. - * A FILETIME contains a 64-bit value representing the number of - * 100-nanosecond intervals since January 1, 1601 (UTC). - * A UNIX time is the number of seconds that have elapsed since the - * UNIX epoch, that is the time 00:00:00 UTC on 1 January 1970 - */ -double -psutil_FileTimeToUnixTime(FILETIME ft) { - ULONGLONG ull; - - // 100 nanosecond intervals since January 1, 1601 - ull = (ULONGLONG)ft.dwHighDateTime << 32; - ull += (ULONGLONG)ft.dwLowDateTime; - // change starting time to the Epoch (00:00:00 UTC, January 1, 1970) - ull -= 116444736000000000ull; - // convert nano secs to secs - return (double) ull / 10000000ull; -} - - -/* * Return the number of logical, active CPUs. Return 0 if undetermined. * See discussion at: https://bugs.python.org/issue33166#msg314631 */ @@ -106,7 +85,7 @@ psutil_boot_time(PyObject *self, PyObject *args) { GetSystemTimeAsFileTime(&fileTime); // Number of milliseconds that have elapsed since the system was started. upTime = GetTickCount64() / 1000ull; - return Py_BuildValue("d", psutil_FileTimeToUnixTime(fileTime) - upTime); + return Py_BuildValue("d", psutil_FiletimeToUnixTime(fileTime) - upTime); } @@ -366,7 +345,7 @@ psutil_proc_create_time(PyObject *self, PyObject *args) { } CloseHandle(hProcess); - return Py_BuildValue("d", psutil_FileTimeToUnixTime(ftCreate)); + return Py_BuildValue("d", psutil_FiletimeToUnixTime(ftCreate)); } diff --git a/psutil/arch/windows/process_info.c b/psutil/arch/windows/process_info.c index d8104c81..73a69912 100644 --- a/psutil/arch/windows/process_info.c +++ b/psutil/arch/windows/process_info.c @@ -578,7 +578,8 @@ out: * fills the structure with various process information in one shot * by using NtQuerySystemInformation. * We use this as a fallback when faster functions fail with access - * denied. This is slower because it iterates over all processes. + * denied. This is slower because it iterates over all processes + * but it doesn't require any privilege (also work for PID 0). * On success return 1, else 0 with Python exception already set. */ int @@ -669,7 +670,7 @@ psutil_proc_info(PyObject *self, PyObject *args) { ULONG ctx_switches = 0; double user_time; double kernel_time; - long long create_time; + double create_time; PyObject *py_retlist; if (! PyArg_ParseTuple(args, _Py_PARSE_PID, &pid)) @@ -692,9 +693,7 @@ psutil_proc_info(PyObject *self, PyObject *args) { create_time = 0; } else { - create_time = ((LONGLONG)process->CreateTime.HighPart) << 32; - create_time += process->CreateTime.LowPart - 116444736000000000LL; - create_time /= 10000000; + create_time = psutil_LargeIntegerToUnixTime(process->CreateTime); } py_retlist = Py_BuildValue( @@ -707,7 +706,7 @@ psutil_proc_info(PyObject *self, PyObject *args) { ctx_switches, // num ctx switches user_time, // cpu user time kernel_time, // cpu kernel time - (double)create_time, // create time + create_time, // create time (int)process->NumberOfThreads, // num threads // IO counters process->ReadOperationCount.QuadPart, // io rcount |