From: Mohamad Al-Jaf mohamadaljaf@gmail.com
--- include/Makefile.in | 1 + include/realtimeapiset.h | 42 ++++++++++++++++++++++++++++++++++++++++ include/winbase.h | 2 +- 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 include/realtimeapiset.h
diff --git a/include/Makefile.in b/include/Makefile.in index 54cbf4d955c..7c7f4dafa87 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -628,6 +628,7 @@ SOURCES = \ ras.h \ rasdlg.h \ raserror.h \ + realtimeapiset.h \ reason.h \ regstr.h \ relogger.idl \ diff --git a/include/realtimeapiset.h b/include/realtimeapiset.h new file mode 100644 index 00000000000..124a7987c8c --- /dev/null +++ b/include/realtimeapiset.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2023 Mohamad Al-Jaf + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _REALTIMEAPISET_H_ +#define _REALTIMEAPISET_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +WINBASEAPI HRESULT WINAPI ConvertAuxiliaryCounterToPerformanceCounter(ULONGLONG,ULONGLONG*,ULONGLONG*); +WINBASEAPI HRESULT WINAPI ConvertPerformanceCounterToAuxiliaryCounter(ULONGLONG,ULONGLONG*,ULONGLONG*); +WINBASEAPI HRESULT WINAPI QueryAuxiliaryCounterFrequency(ULONGLONG*); +WINBASEAPI BOOL WINAPI QueryIdleProcessorCycleTime(ULONG*,PULONG64*); +WINBASEAPI BOOL WINAPI QueryIdleProcessorCycleTimeEx(USHORT,ULONG*,ULONG64*); +WINBASEAPI VOID WINAPI QueryInterruptTime(ULONGLONG*); +WINBASEAPI VOID WINAPI QueryInterruptTimePrecise(ULONGLONG*); +WINBASEAPI BOOL WINAPI QueryProcessCycleTime(HANDLE,ULONG64*); +WINBASEAPI BOOL WINAPI QueryThreadCycleTime(HANDLE,ULONG64*); +WINBASEAPI BOOL WINAPI QueryUnbiasedInterruptTime(ULONGLONG*); +WINBASEAPI VOID WINAPI QueryUnbiasedInterruptTimePrecise(ULONGLONG*); + +#ifdef __cplusplus +} +#endif + +#endif /* _REALTIMEAPISET_H_ */ diff --git a/include/winbase.h b/include/winbase.h index 45492782cd5..6b3048f795e 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -46,6 +46,7 @@ extern "C" { #include <synchapi.h> #include <threadpoolapiset.h> #include <memoryapi.h> +#include <realtimeapiset.h>
/* Windows Exit Procedure flag values */ #define WEP_FREE_DLL 0 @@ -2605,7 +2606,6 @@ WINBASEAPI BOOL WINAPI QueryInformationJobObject(HANDLE,JOBOBJECTINFOCLAS WINBASEAPI BOOL WINAPI QueryMemoryResourceNotification(HANDLE,PBOOL); WINBASEAPI BOOL WINAPI QueryPerformanceCounter(LARGE_INTEGER*); WINBASEAPI BOOL WINAPI QueryPerformanceFrequency(LARGE_INTEGER*); -WINBASEAPI BOOL WINAPI QueryThreadCycleTime(HANDLE,PULONG64); WINBASEAPI BOOL WINAPI QueryUmsThreadInformation(PUMS_CONTEXT,UMS_THREAD_INFO_CLASS,PVOID,ULONG,PULONG); WINBASEAPI DWORD WINAPI QueueUserAPC(PAPCFUNC,HANDLE,ULONG_PTR); WINBASEAPI BOOL WINAPI QueueUserWorkItem(LPTHREAD_START_ROUTINE,PVOID,ULONG);
From: Mohamad Al-Jaf mohamadaljaf@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54338 --- dlls/kernelbase/kernelbase.spec | 2 +- dlls/kernelbase/main.c | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 95d4b64d76e..8596868df61 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -1250,7 +1250,7 @@ @ stdcall QueryThreadCycleTime(long ptr) @ stdcall QueryThreadpoolStackInformation(ptr ptr) @ stdcall QueryUnbiasedInterruptTime(ptr) ntdll.RtlQueryUnbiasedInterruptTime -# @ stub QueryUnbiasedInterruptTimePrecise +@ stdcall QueryUnbiasedInterruptTimePrecise(ptr) @ stdcall QueryVirtualMemoryInformation(long ptr long ptr long ptr) @ stdcall QueryWorkingSet(long ptr long) @ stdcall QueryWorkingSetEx(long ptr long) diff --git a/dlls/kernelbase/main.c b/dlls/kernelbase/main.c index 0309ec91589..27cd3d38fb2 100644 --- a/dlls/kernelbase/main.c +++ b/dlls/kernelbase/main.c @@ -405,6 +405,15 @@ ULONG WINAPI PerfStopProvider(HANDLE handle) return STATUS_SUCCESS; }
+/*********************************************************************** + * QueryUnbiasedInterruptTimePrecise (KERNELBASE.@) + */ +void WINAPI QueryUnbiasedInterruptTimePrecise(ULONGLONG *time) +{ + FIXME("(%p): semi-stub.\n", time); + RtlQueryUnbiasedInterruptTime(time); +} + /*********************************************************************** * QuirkIsEnabled (KERNELBASE.@) */
This should probably use RtlGetInterruptTimePrecise(), but I haven't checked actual output values.
On Wed Jan 25 19:42:17 2023 +0000, Nikolay Sivov wrote:
This should probably use RtlGetInterruptTimePrecise(), but I haven't checked actual output values.
RtlGetInterruptTimePrecise is undocumented, but I was able to find a header that has a prototype. I also ran some tests and the function itself returns a value in addition to the pointer passed in the parameters.
The value of the parameter appears to always be greater than the return value of the function. I'm not sure how to implement that without knowing more about the function.
On Wed Jan 25 19:42:17 2023 +0000, Mohamad Al-Jaf wrote:
RtlGetInterruptTimePrecise is undocumented, but I was able to find a header that has a prototype. I also ran some tests and the function itself returns a value in addition to the pointer passed in the parameters. The value of the parameter appears to always be greater than the return value of the function. I'm not sure how to implement that without knowing more about the function.
I've confirmed that the parameter is just a performance counter and is exactly the same as QueryPerformanceCounter(), depending on the timing, sometimes +/- 1. So the function itself is what returns the interrupt time.
However, QueryUnbiasedInterruptTime is still needed in the kernelbase function to subtract the unbiased time after getting the interrupt time from RtlGetInterruptTimePrecise. I have a partial implementation of RtlGetInterruptTimePrecise, but I don't know how to make it read the timer hardware directly, so it's not precise. Though it's very close to what Windows reports.
Based on the differences between Wine and Windows, I don't think it matters in this case if the function returns an approximate value.
Should I submit my current revision for review or is there a way to get precise time feasibly?
This merge request was closed by Mohamad Al-Jaf.