Signed-off-by: Rémi Bernon rbernon@codeweavers.com ---
This is probably more an RFC but I don't expect it to be merged right away anyway. It fixes the high overhead (Rtl)QueryPerformanceCounter now have with the new syscall frames. There's a few things I'm still not completely confident with:
* The reported Qpc frequency now changes from the default 10MHz. This is also the case on some Windows version (since they introduced QpcBypass but before they introduced the hypervisor page), and applications shouldn't rely on a fixed frequency, but we can expect that some do.
Since the hypervisor page, the reported frequency is 10MHz again, and the divider is stored in the new shared page. We could very well implement the same thing, but it required the new shared memory page to be introduced.
* The rdtsc(p) frequency calibration done when we cannot get the information from cpuid (on AMD and older Intel CPU) is still a little bit imprecise, and I'm not sure how to make it better while keeping the calibration time small. On my computer I can see a ±100KHz error for a nominal 3.6GHz frequency. I believe the Linux kernel also does some estimation there, but it has access to hardware timers that may help to get a better approximation.
programs/wineboot/wineboot.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+)
diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c index 9427448b612..9e36b3c22dd 100644 --- a/programs/wineboot/wineboot.c +++ b/programs/wineboot/wineboot.c @@ -82,6 +82,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(wineboot);
+#define TICKSPERSEC 10000000 + extern BOOL shutdown_close_windows( BOOL force ); extern BOOL shutdown_all_desktops( BOOL force ); extern void kill_processes( BOOL kill_desktop ); @@ -241,12 +243,28 @@ static void initialize_xstate_features(struct _KUSER_SHARED_DATA *data) TRACE("XSAVE feature 2 %#x, %#x, %#x, %#x.\n", regs[0], regs[1], regs[2], regs[3]); }
+static void initialize_qpc_features(struct _KUSER_SHARED_DATA *data) +{ + data->QpcBypassEnabled = 0; + data->QpcFrequency = TICKSPERSEC; + data->QpcShift = 0; + data->QpcBias = 0; +} + #else
static void initialize_xstate_features(struct _KUSER_SHARED_DATA *data) { }
+static void initialize_qpc_features(struct _KUSER_SHARED_DATA *data) +{ + data->QpcBypassEnabled = 0; + data->QpcFrequency = TICKSPERSEC; + data->QpcShift = 0; + data->QpcBias = 0; +} + #endif
static void create_user_shared_data(void) @@ -336,6 +354,7 @@ static void create_user_shared_data(void) data->ActiveGroupCount = 1;
initialize_xstate_features( data ); + initialize_qpc_features( data );
UnmapViewOfFile( data ); }