wine-staging/patches/ntdll-ThreadTime/0003-ntdll-Fill-process-kernel-and-user-time.patch

160 lines
6.2 KiB
Diff
Raw Normal View History

From 2578dfb02f0a8781970f5c7d967b1d07ae433e2f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
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 fc8e3b1eb4..6b67397471 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1922,6 +1922,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;
@@ -1959,7 +1960,7 @@ NTSTATUS WINAPI NtQuerySystemInformation(
if (Length >= len + procstructlen)
{
- /* ftCreationTime, ftUserTime, ftKernelTime;
+ /* ftCreationTime;
* vmCounters, ioCounters
*/
@@ -1977,6 +1978,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 5e4c39e8bd..443c86000d 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -266,4 +266,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 91a59517b3..29b6513f38 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -71,6 +71,53 @@ static RTL_BITMAP tls_expansion_bitmap;
static RTL_BITMAP fls_bitmap;
static int nb_threads = 1;
+
+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
*
@@ -1009,42 +1056,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.11.0