From 24f4eced42fb95328a05cff0370139efe55b98aa Mon Sep 17 00:00:00 2001 From: Ryan Cumming <ryan@completely.kicks-ass.org> Date: Mon, 25 Nov 2002 01:33:38 +0000 Subject: [PATCH] Partially implement GetThreadTimes. --- include/wine/server_protocol.h | 4 +++- scheduler/thread.c | 28 ++++++++++++++++++++++------ server/protocol.def | 16 +++++++++------- server/thread.c | 16 +++++++++++----- server/thread.h | 2 ++ server/trace.c | 4 +++- 6 files changed, 50 insertions(+), 20 deletions(-) diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 15997ac75de..466c7e543a1 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -394,6 +394,8 @@ struct get_thread_info_reply void* teb; int exit_code; int priority; + time_t creation_time; + time_t exit_time; }; @@ -3460,6 +3462,6 @@ union generic_reply 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 */ diff --git a/scheduler/thread.c b/scheduler/thread.c index d52ced35bbb..86234934812 100644 --- a/scheduler/thread.c +++ b/scheduler/thread.c @@ -677,9 +677,6 @@ DWORD WINAPI QueueUserAPC( PAPCFUNC func, HANDLE hthread, ULONG_PTR data ) /********************************************************************** * GetThreadTimes [KERNEL32.@] Obtains timing information. * - * NOTES - * What are the fields where these values are stored? - * * RETURNS * Success: TRUE * Failure: FALSE @@ -691,9 +688,28 @@ BOOL WINAPI GetThreadTimes( 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; + BOOL ret = TRUE; + + 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 ((ret = !wine_server_call_err( req ))) + { + if (creationtime) + RtlSecondsSince1970ToTime( reply->creation_time, (LARGE_INTEGER*)creationtime ); + if (exittime) + RtlSecondsSince1970ToTime( reply->exit_time, (LARGE_INTEGER*)exittime ); + } + } + SERVER_END_REQ; + } + return ret; } diff --git a/server/protocol.def b/server/protocol.def index bd5177f4195..1b15d85d646 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -336,13 +336,15 @@ typedef struct /* Retrieve information about a thread */ @REQ(get_thread_info) - 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 */ + 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 */ + time_t creation_time; /* thread creation time */ + time_t exit_time; /* thread exit time */ @END diff --git a/server/thread.c b/server/thread.c index c29ba46dcf1..f8396e09436 100644 --- a/server/thread.c +++ b/server/thread.c @@ -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 @@ inline static void init_thread_structure( struct thread *thread ) thread->priority = THREAD_PRIORITY_NORMAL; thread->affinity = 1; thread->suspend = 0; + thread->creation_time = time(NULL); + thread->exit_time = 0; for (i = 0; i < MAX_INFLIGHT_FDS; i++) thread->inflight[i].server = thread->inflight[i].client = -1; @@ -706,6 +708,7 @@ void kill_thread( struct thread *thread, int violent_death ) { if (thread->state == TERMINATED) return; /* already killed */ thread->state = TERMINATED; + thread->exit_time = time(NULL); if (current == thread) current = NULL; if (debug_level) fprintf( stderr,"%08x: *killed* exit_code=%d\n", @@ -878,10 +881,13 @@ DECL_HANDLER(get_thread_info) 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 ); } } diff --git a/server/thread.h b/server/thread.h index 0c029014d85..218a7b3a4b2 100644 --- a/server/thread.h +++ b/server/thread.h @@ -92,6 +92,8 @@ struct thread 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 diff --git a/server/trace.c b/server/trace.c index 49f486b835e..368cca27734 100644 --- a/server/trace.c +++ b/server/trace.c @@ -515,7 +515,9 @@ static void dump_get_thread_info_reply( const struct get_thread_info_reply *req 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 ) -- GitLab