[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