From 3868624c41bc318ee89c5c5183d3ca9ef483f6ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Thu, 9 Mar 2017 16:27:23 +0100 Subject: ntdll: Fill process kernel and user time. --- dlls/ntdll/nt.c | 6 +++- dlls/ntdll/ntdll_misc.h | 3 ++ dlls/ntdll/thread.c | 84 ++++++++++++++++++++++++++++--------------------- 3 files changed, 56 insertions(+), 37 deletions(-) diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index fbd0fdf51a9..cac95325541 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -1927,6 +1927,7 @@ NTSTATUS WINAPI NtQuerySystemInformation( { SYSTEM_PROCESS_INFORMATION* spi = SystemInformation; SYSTEM_PROCESS_INFORMATION* last = NULL; + unsigned long clk_tck = sysconf(_SC_CLK_TCK); HANDLE hSnap = 0; WCHAR procname[1024]; WCHAR* exename; @@ -1964,7 +1965,7 @@ NTSTATUS WINAPI NtQuerySystemInformation( if (Length >= len + procstructlen) { - /* ftCreationTime, ftUserTime, ftKernelTime; + /* ftCreationTime; * vmCounters, ioCounters */ @@ -1982,6 +1983,9 @@ NTSTATUS WINAPI NtQuerySystemInformation( /* spi->ti will be set later on */ + if (reply->unix_pid != -1) + read_process_time(reply->unix_pid, -1, clk_tck, + &spi->KernelTime, &spi->UserTime); } len += procstructlen; } diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h index c97b1e1f73f..260e7030dae 100644 --- a/dlls/ntdll/ntdll_misc.h +++ b/dlls/ntdll/ntdll_misc.h @@ -245,4 +245,7 @@ extern HANDLE keyed_event DECLSPEC_HIDDEN; NTSTATUS WINAPI RtlHashUnicodeString(PCUNICODE_STRING,BOOLEAN,ULONG,ULONG*); +/* process / thread time */ +extern BOOL read_process_time(int unix_pid, int unix_tid, unsigned long clk_tck, + LARGE_INTEGER *kernel, LARGE_INTEGER *user) DECLSPEC_HIDDEN; #endif diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index 00d03f103ce..1c6cab3aa28 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -80,6 +80,53 @@ static RTL_CRITICAL_SECTION_DEBUG critsect_debug = }; static RTL_CRITICAL_SECTION peb_lock = { &critsect_debug, -1, 0, 0, 0, 0 }; + +BOOL read_process_time(int unix_pid, int unix_tid, unsigned long clk_tck, + LARGE_INTEGER *kernel, LARGE_INTEGER *user) +{ +#ifdef __linux__ + unsigned long usr, sys; + char buf[512], *pos; + FILE *fp; + int i; + + /* based on https://github.com/torvalds/linux/blob/master/fs/proc/array.c */ + if (unix_tid != -1) + sprintf( buf, "/proc/%u/task/%u/stat", unix_pid, unix_tid ); + else + sprintf( buf, "/proc/%u/stat", unix_pid ); + if ((fp = fopen( buf, "r" ))) + { + pos = fgets( buf, sizeof(buf), fp ); + fclose( fp ); + + /* format of first chunk is "%d (%s) %c" - we have to skip to the last ')' + * to avoid misinterpreting the string. */ + if (pos) pos = strrchr( pos, ')' ); + if (pos) pos = strchr( pos + 1, ' ' ); + if (pos) pos++; + + /* skip over the following fields: state, ppid, pgid, sid, tty_nr, tty_pgrp, + * task->flags, min_flt, cmin_flt, maj_flt, cmaj_flt */ + for (i = 0; (i < 11) && pos; i++) + { + pos = strchr( pos + 1, ' ' ); + if (pos) pos++; + } + + /* the next two values are user and system time */ + if (pos && (sscanf( pos, "%lu %lu", &usr, &sys ) == 2)) + { + kernel->QuadPart = (ULONGLONG)sys * 10000000 / clk_tck; + user->QuadPart = (ULONGLONG)usr * 10000000 / clk_tck; + return TRUE; + } + } +#endif + return FALSE; +} + + /*********************************************************************** * get_unicode_string * @@ -989,42 +1036,7 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class, #ifdef __linux__ /* only /proc provides exact values for a specific thread */ if (unix_pid != -1 && unix_tid != -1) - { - unsigned long usr, sys; - char buf[512], *pos; - FILE *fp; - int i; - - /* based on https://github.com/torvalds/linux/blob/master/fs/proc/array.c */ - sprintf( buf, "/proc/%u/task/%u/stat", unix_pid, unix_tid ); - if ((fp = fopen( buf, "r" ))) - { - pos = fgets( buf, sizeof(buf), fp ); - fclose( fp ); - - /* format of first chunk is "%d (%s) %c" - we have to skip to the last ')' - * to avoid misinterpreting the string. */ - if (pos) pos = strrchr( pos, ')' ); - if (pos) pos = strchr( pos + 1, ' ' ); - if (pos) pos++; - - /* skip over the following fields: state, ppid, pgid, sid, tty_nr, tty_pgrp, - * task->flags, min_flt, cmin_flt, maj_flt, cmaj_flt */ - for (i = 0; (i < 11) && pos; i++) - { - pos = strchr( pos + 1, ' ' ); - if (pos) pos++; - } - - /* the next two values are user and system time */ - if (pos && (sscanf( pos, "%lu %lu", &usr, &sys ) == 2)) - { - kusrt.KernelTime.QuadPart = (ULONGLONG)sys * 10000000 / clk_tck; - kusrt.UserTime.QuadPart = (ULONGLONG)usr * 10000000 / clk_tck; - filled_times = TRUE; - } - } - } + filled_times = read_process_time(unix_pid, unix_tid, clk_tck, &kusrt.KernelTime, &kusrt.UserTime); #endif /* get values for current process instead */ -- 2.14.1