[PATCH 1/5] ntdll: Don't read current CPU frequency on Linux.

Matteo Bruni mbruni at codeweavers.com
Fri Jul 24 04:14:05 CDT 2020


On the Linux boxes I tested, reading scaling_cur_freq usually takes
about 12 ms per core.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47128
Signed-off-by: Matteo Bruni <mbruni at codeweavers.com>
---
FWIW it looks like the kernel does some kind of optimization and
returns "immediately" if the file is accessed often enough (possibly
faster than once per second?)

Heroes of the Storm calls NtPowerInformation() on the main rendering
thread about once per second and, with enough cores, it means stalling
the whole game for pretty sizeable amounts of time.

 dlls/ntdll/unix/system.c | 17 ++++-------------
 1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c
index 681d56a869f4..3756bd7cee03 100644
--- a/dlls/ntdll/unix/system.c
+++ b/dlls/ntdll/unix/system.c
@@ -2907,11 +2907,12 @@ NTSTATUS WINAPI NtPowerInformation( POWER_INFORMATION_LEVEL level, void *input,
             FILE* f;
 
             for(i = 0; i < out_cpus; i++) {
-                sprintf(filename, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", i);
+                sprintf(filename, "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", i);
                 f = fopen(filename, "r");
-                if (f && (fscanf(f, "%d", &cpu_power[i].CurrentMhz) == 1)) {
-                    cpu_power[i].CurrentMhz /= 1000;
+                if (f && (fscanf(f, "%d", &cpu_power[i].MaxMhz) == 1)) {
+                    cpu_power[i].MaxMhz /= 1000;
                     fclose(f);
+                    cpu_power[i].CurrentMhz = cpu_power[i].MaxMhz;
                 }
                 else {
                     if(i == 0) {
@@ -2921,16 +2922,6 @@ NTSTATUS WINAPI NtPowerInformation( POWER_INFORMATION_LEVEL level, void *input,
                     }
                     else
                         cpu_power[i].CurrentMhz = cpu_power[0].CurrentMhz;
-                    if(f) fclose(f);
-                }
-
-                sprintf(filename, "/sys/devices/system/cpu/cpu%d/cpufreq/cpuinfo_max_freq", i);
-                f = fopen(filename, "r");
-                if (f && (fscanf(f, "%d", &cpu_power[i].MaxMhz) == 1)) {
-                    cpu_power[i].MaxMhz /= 1000;
-                    fclose(f);
-                }
-                else {
                     cpu_power[i].MaxMhz = cpu_power[i].CurrentMhz;
                     if(f) fclose(f);
                 }
-- 
2.26.2




More information about the wine-devel mailing list