[PATCH] Fix GetThreadTimes() for all threads=0A=
Ray Hinchliffe
ray at pobox.co.uk
Tue Apr 19 08:30:09 CDT 2011
=0A=
---=0A=
dlls/ntdll/thread.c | 89 =
++++++++++++++++++++++++++++++++--------=0A=
include/wine/server_protocol.h | 21 +++++++++-=0A=
server/protocol.def | 11 +++++=0A=
server/request.h | 9 ++++=0A=
server/thread.c | 18 ++++++++=0A=
server/trace.c | 16 +++++++=0A=
6 files changed, 145 insertions(+), 19 deletions(-)=0A=
mode change 100644 =3D> 100755 dlls/ntdll/thread.c=0A=
mode change 100644 =3D> 100755 server/protocol.def=0A=
mode change 100644 =3D> 100755 server/thread.c=0A=
=0A=
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c=0A=
old mode 100644=0A=
new mode 100755=0A=
index 56eca23..aa33db0=0A=
--- a/dlls/ntdll/thread.c=0A=
+++ b/dlls/ntdll/thread.c=0A=
@@ -23,6 +23,8 @@=0A=
=0A=
#include <assert.h>=0A=
#include <stdarg.h>=0A=
+#include <string.h>=0A=
+#include <stdio.h>=0A=
#include <sys/types.h>=0A=
#ifdef HAVE_SYS_MMAN_H=0A=
#include <sys/mman.h>=0A=
@@ -916,45 +918,96 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE =
handle, THREADINFOCLASS class,=0A=
case ThreadTimes:=0A=
{=0A=
KERNEL_USER_TIMES kusrt;=0A=
- /* We need to do a server call to get the creation time or =
exit time */=0A=
+ int unix_pid, unix_tid;=0A=
+=0A=
+ /* We need to do a server call to get the creation time, =
exit time, PID and TID */=0A=
/* This works on any thread */=0A=
- SERVER_START_REQ( get_thread_info )=0A=
+ SERVER_START_REQ( get_thread_times )=0A=
{=0A=
req->handle =3D wine_server_obj_handle( handle );=0A=
- req->tid_in =3D 0;=0A=
status =3D wine_server_call( req );=0A=
if (status =3D=3D STATUS_SUCCESS)=0A=
{=0A=
kusrt.CreateTime.QuadPart =3D reply->creation_time;=0A=
kusrt.ExitTime.QuadPart =3D reply->exit_time;=0A=
+ unix_pid =3D reply->unix_pid;=0A=
+ unix_tid =3D reply->unix_tid;=0A=
}=0A=
}=0A=
SERVER_END_REQ;=0A=
if (status =3D=3D STATUS_SUCCESS)=0A=
{=0A=
- /* We call times(2) for kernel time or user time */=0A=
- /* We can only (portably) do this for the current =
thread */=0A=
+ /* do this portably for the current thread */=0A=
if (handle =3D=3D GetCurrentThread())=0A=
{=0A=
- struct tms time_buf;=0A=
- long clocks_per_sec =3D sysconf(_SC_CLK_TCK);=0A=
+#ifdef HAVE_CLOCK_GETTIME=0A=
+ struct timespec spec_buf;=0A=
+=0A=
+ /* are thread times available ? */=0A=
+=0A=
+ if (( sysconf(_POSIX_THREAD_CPUTIME)) &&=0A=
+ ( !clock_gettime(CLOCK_THREAD_CPUTIME_ID, =
&spec_buf)))=0A=
+ {=0A=
+ /* yes, but no kernel time, so just return user =
time */=0A=
+=0A=
+ kusrt.KernelTime.QuadPart =3D 0;=0A=
+ kusrt.UserTime.QuadPart =3D =
(ULONGLONG)spec_buf.tv_sec * 10000000 +=0A=
+ =
spec_buf.tv_nsec / 100;=0A=
+ }=0A=
+ else=0A=
+#endif=0A=
+ {=0A=
+ struct tms time_buf;=0A=
+ long tick_time =3D 10000000 / =
sysconf(_SC_CLK_TCK);=0A=
=0A=
- times(&time_buf);=0A=
- kusrt.KernelTime.QuadPart =3D =
(ULONGLONG)time_buf.tms_stime * 10000000 / clocks_per_sec;=0A=
- kusrt.UserTime.QuadPart =3D =
(ULONGLONG)time_buf.tms_utime * 10000000 / clocks_per_sec;=0A=
+ /* call times(2) for kernel time or user time */=0A=
+=0A=
+ times(&time_buf);=0A=
+=0A=
+ kusrt.KernelTime.QuadPart =3D =
(ULONGLONG)time_buf.tms_stime * tick_time;=0A=
+ kusrt.UserTime.QuadPart =3D =
(ULONGLONG)time_buf.tms_utime * tick_time;=0A=
+ }=0A=
}=0A=
else=0A=
{=0A=
- static BOOL reported =3D FALSE;=0A=
+ ULONG usr;=0A=
+ ULONG sys;=0A=
+ ULONG ctt;=0A=
+ ULONG got;=0A=
+ const char *pos;=0A=
+ FILE *fid;=0A=
+ char buf[256];=0A=
=0A=
- kusrt.KernelTime.QuadPart =3D 0;=0A=
- kusrt.UserTime.QuadPart =3D 0;=0A=
- if (reported)=0A=
- TRACE("Cannot get kerneltime or usertime of =
other threads\n");=0A=
- else=0A=
+ sprintf( buf, "/proc/%d/task/%d/stat", unix_pid, =
unix_tid );=0A=
+=0A=
+ if (got =3D ((fid =3D fopen( buf, "r" )) !=3D NULL))=0A=
{=0A=
- FIXME("Cannot get kerneltime or usertime of =
other threads\n");=0A=
- reported =3D TRUE;=0A=
+ fgets(buf, sizeof(buf) - 1, fid);=0A=
+ fclose(fid);=0A=
+=0A=
+ for( got =3D 0, pos =3D buf; (got < 13) && pos; =
got++, pos =3D strchr(pos + 1, ' ')) {}=0A=
+=0A=
+ if( got =3D pos && (sscanf(pos, " %u %u", &usr, =
&sys) =3D=3D 2))=0A=
+ {=0A=
+ ctt =3D 10000000 / sysconf(_SC_CLK_TCK);=0A=
+ kusrt.KernelTime.QuadPart =3D =
(ULONGLONG)sys * ctt;=0A=
+ kusrt.UserTime.QuadPart =3D =
(ULONGLONG)usr * ctt;=0A=
+ }=0A=
+ }=0A=
+=0A=
+ if( !got ) /* failed to read and decode =
/proc ? */=0A=
+ {=0A=
+ static BOOL reported =3D FALSE;=0A=
+=0A=
+ kusrt.KernelTime.QuadPart =3D 0;=0A=
+ kusrt.UserTime.QuadPart =3D 0;=0A=
+ if (reported)=0A=
+ TRACE("Cannot get kerneltime or usertime of =
other threads\n");=0A=
+ else=0A=
+ {=0A=
+ FIXME("Cannot get kerneltime or usertime of =
other threads\n");=0A=
+ reported =3D TRUE;=0A=
+ }=0A=
}=0A=
}=0A=
if (data) memcpy( data, &kusrt, min( length, =
sizeof(kusrt) ));=0A=
diff --git a/server/protocol.def b/server/protocol.def=0A=
old mode 100644=0A=
new mode 100755=0A=
index 8e50ed9..6a40853=0A=
--- a/server/protocol.def=0A=
+++ b/server/protocol.def=0A=
@@ -747,6 +747,17 @@ typedef union=0A=
#define SET_PROCESS_INFO_AFFINITY 0x02=0A=
=0A=
=0A=
+/* Retrieve information about thread times */=0A=
+ at REQ(get_thread_times)=0A=
+ obj_handle_t handle; /* thread handle */=0A=
+ at REPLY=0A=
+ timeout_t creation_time; /* thread creation time */=0A=
+ timeout_t exit_time; /* thread exit time */=0A=
+ int unix_pid; /* thread native pid */=0A=
+ int unix_tid; /* thread native pid */=0A=
+ at END=0A=
+=0A=
+=0A=
/* Retrieve information about a thread */=0A=
@REQ(get_thread_info)=0A=
obj_handle_t handle; /* thread handle */=0A=
diff --git a/server/thread.c b/server/thread.c=0A=
old mode 100644=0A=
new mode 100755=0A=
index 983ba2d..0cf694c=0A=
--- a/server/thread.c=0A=
+++ b/server/thread.c=0A=
@@ -1239,6 +1239,24 @@ DECL_HANDLER(open_thread)=0A=
}=0A=
}=0A=
=0A=
+/* fetch information about thread times */=0A=
+DECL_HANDLER(get_thread_times)=0A=
+{=0A=
+ struct thread *thread;=0A=
+=0A=
+ thread =3D get_thread_from_handle( req->handle, =
THREAD_QUERY_INFORMATION );=0A=
+=0A=
+ if (thread)=0A=
+ {=0A=
+ reply->creation_time =3D thread->creation_time;=0A=
+ reply->exit_time =3D thread->exit_time;=0A=
+ reply->unix_pid =3D thread->unix_pid;=0A=
+ reply->unix_tid =3D thread->unix_tid;;=0A=
+=0A=
+ release_object( thread );=0A=
+ }=0A=
+}=0A=
+=0A=
/* fetch information about a thread */=0A=
DECL_HANDLER(get_thread_info)=0A=
{=0A=
-- =0A=
1.7.0.4=0A=
=0A=
------=_NextPart_000_004A_01CBFE6D.F8B67AB0--
More information about the wine-patches
mailing list