diff --git a/dlls/kernel/thread.c b/dlls/kernel/thread.c index fb0ae75119c..17bdd597cb5 100644 --- a/dlls/kernel/thread.c +++ b/dlls/kernel/thread.c @@ -25,9 +25,6 @@ #include #include #include -#ifdef HAVE_SYS_TIMES_H -#include -#endif #ifdef HAVE_UNISTD_H # include #endif @@ -545,59 +542,38 @@ BOOL WINAPI GetThreadTimes( LPFILETIME kerneltime, /* [out] Time thread spent in kernel mode */ LPFILETIME usertime) /* [out] Time thread spent in user mode */ { - BOOL ret = TRUE; + KERNEL_USER_TIMES kusrt; + NTSTATUS status; - if (creationtime || exittime) + status = NtQueryInformationThread(thread, ThreadTimes, &kusrt, + sizeof(kusrt), NULL); + if (status) { - /* 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; + SetLastError( RtlNtStatusToDosError(status) ); + return FALSE; } - if (ret && (kerneltime || usertime)) + if (creationtime) { - /* We call times(2) for kernel time or user time */ - /* We can only (portably) do this for the current thread */ - if (thread == GetCurrentThread()) - { - ULONGLONG time; - struct tms time_buf; - long clocks_per_sec = sysconf(_SC_CLK_TCK); - - times(&time_buf); - if (kerneltime) - { - time = (ULONGLONG)time_buf.tms_stime * 10000000 / clocks_per_sec; - kerneltime->dwHighDateTime = time >> 32; - kerneltime->dwLowDateTime = (DWORD)time; - } - if (usertime) - { - time = (ULONGLONG)time_buf.tms_utime * 10000000 / clocks_per_sec; - usertime->dwHighDateTime = time >> 32; - usertime->dwLowDateTime = (DWORD)time; - } - } - else - { - if (kerneltime) kerneltime->dwHighDateTime = kerneltime->dwLowDateTime = 0; - if (usertime) usertime->dwHighDateTime = usertime->dwLowDateTime = 0; - FIXME("Cannot get kerneltime or usertime of other threads\n"); - } + creationtime->dwLowDateTime = kusrt.CreateTime.u.LowPart; + creationtime->dwHighDateTime = kusrt.CreateTime.u.HighPart; } - return ret; + if (exittime) + { + exittime->dwLowDateTime = kusrt.ExitTime.u.LowPart; + exittime->dwHighDateTime = kusrt.ExitTime.u.HighPart; + } + if (kerneltime) + { + kerneltime->dwLowDateTime = kusrt.KernelTime.u.LowPart; + kerneltime->dwHighDateTime = kusrt.KernelTime.u.HighPart; + } + if (usertime) + { + usertime->dwLowDateTime = kusrt.UserTime.u.LowPart; + usertime->dwHighDateTime = kusrt.UserTime.u.HighPart; + } + + return TRUE; } diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c index f7dca185562..e245609bf51 100644 --- a/dlls/ntdll/thread.c +++ b/dlls/ntdll/thread.c @@ -25,6 +25,9 @@ #ifdef HAVE_SYS_MMAN_H #include #endif +#ifdef HAVE_SYS_TIMES_H +#include +#endif #include "ntstatus.h" #include "thread.h" @@ -553,6 +556,46 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class, } return status; case ThreadTimes: + { + KERNEL_USER_TIMES kusrt; + /* 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 = handle; + req->tid_in = 0; + status = wine_server_call( req ); + if (status == STATUS_SUCCESS) + { + RtlSecondsSince1970ToTime( reply->creation_time, &kusrt.CreateTime ); + RtlSecondsSince1970ToTime( reply->exit_time, &kusrt.ExitTime ); + } + } + SERVER_END_REQ; + if (status == STATUS_SUCCESS) + { + /* We call times(2) for kernel time or user time */ + /* We can only (portably) do this for the current thread */ + if (handle == GetCurrentThread()) + { + struct tms time_buf; + long clocks_per_sec = sysconf(_SC_CLK_TCK); + + times(&time_buf); + kusrt.KernelTime.QuadPart = (ULONGLONG)time_buf.tms_stime * 10000000 / clocks_per_sec; + kusrt.UserTime.QuadPart = (ULONGLONG)time_buf.tms_utime * 10000000 / clocks_per_sec; + } + else + { + kusrt.KernelTime.QuadPart = 0; + kusrt.UserTime.QuadPart = 0; + FIXME("Cannot get kerneltime or usertime of other threads\n"); + } + if (data) memcpy( data, &kusrt, min( length, sizeof(kusrt) )); + if (ret_len) *ret_len = min( length, sizeof(kusrt) ); + } + } + return status; case ThreadPriority: case ThreadBasePriority: case ThreadAffinityMask: