This one kills an outdated comment and adds a newline to the end of the FIXME message (oops) -Ryan ChangeLog: * Mostly implement GetThreadTimes
Index: include/wine/server_protocol.h =================================================================== RCS file: /home/wine/wine/include/wine/server_protocol.h,v retrieving revision 1.49 diff -u -r1.49 server_protocol.h --- include/wine/server_protocol.h 20 Nov 2002 19:54:32 -0000 1.49 +++ include/wine/server_protocol.h 22 Nov 2002 08:40:19 -0000 @@ -400,6 +400,8 @@ void* teb; int exit_code; int priority; + time_t creation_time; + time_t exit_time; }; @@ -3466,6 +3468,6 @@ struct get_next_hook_reply get_next_hook_reply; }; -#define SERVER_PROTOCOL_VERSION 90 +#define SERVER_PROTOCOL_VERSION 91 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ Index: server/protocol.def =================================================================== RCS file: /home/wine/wine/server/protocol.def,v retrieving revision 1.50 diff -u -r1.50 protocol.def --- server/protocol.def 20 Nov 2002 19:54:32 -0000 1.50 +++ server/protocol.def 22 Nov 2002 08:40:20 -0000 @@ -342,13 +342,15 @@ /* Retrieve information about a thread */ @REQ(get_thread_info) - obj_handle_t handle; /* thread handle */ - thread_id_t tid_in; /* thread id (optional) */ + obj_handle_t handle; /* thread handle */ + thread_id_t tid_in; /* thread id (optional) */ @REPLY - thread_id_t tid; /* server thread id */ - void* teb; /* thread teb pointer */ - int exit_code; /* thread exit code */ - int priority; /* thread priority level */ + thread_id_t tid; /* server thread id */ + void* teb; /* thread teb pointer */ + int exit_code; /* thread exit code */ + int priority; /* thread priority level */ + time_t creation_time; /* thread creation time */ + time_t exit_time; /* thread exit time */ @END Index: server/thread.c =================================================================== RCS file: /home/wine/wine/server/thread.c,v retrieving revision 1.84 diff -u -r1.84 thread.c --- server/thread.c 29 Oct 2002 00:41:42 -0000 1.84 +++ server/thread.c 22 Nov 2002 08:40:20 -0000 @@ -31,7 +31,7 @@ #include <string.h> #include <sys/types.h> #include <unistd.h> -#include <stdarg.h> +#include <time.h> #include "winbase.h" @@ -132,6 +132,8 @@ thread->priority = THREAD_PRIORITY_NORMAL; thread->affinity = 1; thread->suspend = 0; + thread->creation_time = 0; + thread->exit_time = 0; for (i = 0; i < MAX_INFLIGHT_FDS; i++) thread->inflight[i].server = thread->inflight[i].client = -1; @@ -156,6 +158,8 @@ lock_master_socket(1); } + thread->creation_time = time(NULL); + if ((thread->next = first_thread) != NULL) thread->next->prev = thread; first_thread = thread; @@ -844,6 +848,8 @@ if ((thread = get_thread_from_handle( req->handle, THREAD_TERMINATE ))) { thread->exit_code = req->exit_code; + thread->exit_time = time(NULL); + if (thread != current) kill_thread( thread, 1 ); else { @@ -878,10 +884,13 @@ if (thread) { - reply->tid = get_thread_id( thread ); - reply->teb = thread->teb; - reply->exit_code = (thread->state == TERMINATED) ? thread->exit_code : STILL_ACTIVE; - reply->priority = thread->priority; + reply->tid = get_thread_id( thread ); + reply->teb = thread->teb; + reply->exit_code = (thread->state == TERMINATED) ? thread->exit_code : STILL_ACTIVE; + reply->priority = thread->priority; + reply->creation_time = thread->creation_time; + reply->exit_time = thread->exit_time; + release_object( thread ); } } Index: server/thread.h =================================================================== RCS file: /home/wine/wine/server/thread.h,v retrieving revision 1.41 diff -u -r1.41 thread.h --- server/thread.h 29 Oct 2002 00:41:42 -0000 1.41 +++ server/thread.h 22 Nov 2002 08:40:20 -0000 @@ -92,6 +92,8 @@ int priority; /* priority level */ int affinity; /* affinity mask */ int suspend; /* suspend count */ + time_t creation_time; /* Thread creation time */ + time_t exit_time; /* Thread exit time */ }; struct thread_snapshot Index: server/trace.c =================================================================== RCS file: /home/wine/wine/server/trace.c,v retrieving revision 1.145 diff -u -r1.145 trace.c --- server/trace.c 20 Nov 2002 19:54:32 -0000 1.145 +++ server/trace.c 22 Nov 2002 08:40:21 -0000 @@ -515,7 +515,9 @@ fprintf( stderr, " tid=%08x,", req->tid ); fprintf( stderr, " teb=%p,", req->teb ); fprintf( stderr, " exit_code=%d,", req->exit_code ); - fprintf( stderr, " priority=%d", req->priority ); + fprintf( stderr, " priority=%d,", req->priority ); + fprintf( stderr, " creation_time=%ld,", req->creation_time ); + fprintf( stderr, " exit_time=%ld", req->exit_time ); } static void dump_set_thread_info_request( const struct set_thread_info_request *req ) Index: scheduler/thread.c =================================================================== RCS file: /home/wine/wine/scheduler/thread.c,v retrieving revision 1.125 diff -u -r1.125 thread.c --- scheduler/thread.c 21 Nov 2002 03:45:01 -0000 1.125 +++ scheduler/thread.c 22 Nov 2002 08:40:23 -0000 @@ -24,6 +24,7 @@ #include <assert.h> #include <fcntl.h> #include <sys/types.h> +#include <sys/times.h> #ifdef HAVE_SYS_MMAN_H #include <sys/mman.h> #endif @@ -33,6 +34,7 @@ #include "wine/winbase16.h" #include "thread.h" #include "task.h" +#include "file.h" #include "module.h" #include "winerror.h" #include "selectors.h" @@ -677,9 +679,6 @@ /********************************************************************** * GetThreadTimes [KERNEL32.@] Obtains timing information. * - * NOTES - * What are the fields where these values are stored? - * * RETURNS * Success: TRUE * Failure: FALSE @@ -691,9 +690,71 @@ LPFILETIME kerneltime, /* [out] Time thread spent in kernel mode */ LPFILETIME usertime) /* [out] Time thread spent in user mode */ { - FIXME("(0x%p): stub\n",thread); - SetLastError(ERROR_CALL_NOT_IMPLEMENTED); - return FALSE; + if (creationtime || exittime) + { + /* We need to do a server call to get the creation time or exit time */ + /* This works on any thread */ + + SERVER_START_REQ( get_thread_info ) + { + req->handle = thread; + req->tid_in = 0; + if (!wine_server_call_err( req )) + { + if (creationtime) + { + DOSFS_UnixTimeToFileTime(reply->creation_time, creationtime, 0); + } + + if (exittime) + { + DOSFS_UnixTimeToFileTime(reply->exit_time, exittime, 0); + } + } + else + { + return FALSE; + } + + } + SERVER_END_REQ; + } + + if (kerneltime || usertime) + { + /* We call times(2) for kernel time or user time */ + /* We can only (portably) do this for the current thread */ + if (thread == GetCurrentThread()) + { + struct tms time_buf; + long clocks_per_sec; + + times(&time_buf); + clocks_per_sec = sysconf(_SC_CLK_TCK); + + if (kerneltime) + { + DOSFS_UnixTimeToFileTime(time_buf.tms_stime / clocks_per_sec, + kerneltime, + ((time_buf.tms_stime % clocks_per_sec) * 10000000) / clocks_per_sec); + } + + if (usertime) + { + DOSFS_UnixTimeToFileTime(time_buf.tms_utime / clocks_per_sec, + usertime, + ((time_buf.tms_utime % clocks_per_sec) * 10000000) / clocks_per_sec); + } + } + else + { + FIXME("Cannot get kerneltime or usertime of other threads\n"); + + return FALSE; + } + } + + return TRUE; }