Signed-off-by: Torge Matthies tmatthies@codeweavers.com
-- v4: ntdll: Implement efficiency class reporting for intel hybrid CPUs.
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/ntdll/unix/system.c | 50 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c index 04755fac5ea..91e31520821 100644 --- a/dlls/ntdll/unix/system.c +++ b/dlls/ntdll/unix/system.c @@ -231,6 +231,8 @@ struct smbios_chassis_args SYSTEM_CPU_INFORMATION cpu_info = { 0 }; static SYSTEM_PROCESSOR_FEATURES_INFORMATION cpu_features; static char cpu_name[49]; +static ULONG *performance_cores; +static unsigned int performance_cores_capacity = 0; static SYSTEM_LOGICAL_PROCESSOR_INFORMATION *logical_proc_info; static unsigned int logical_proc_info_len, logical_proc_info_alloc_len; static SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *logical_proc_info_ex; @@ -643,7 +645,10 @@ static BOOL logical_proc_info_ex_add_by_id( LOGICAL_PROCESSOR_RELATIONSHIP rel, dataex->u.Processor.Flags = count_bits( mask ) > 1 ? LTP_PC_SMT : 0; else dataex->u.Processor.Flags = 0; - dataex->u.Processor.EfficiencyClass = 0; + if (rel == RelationProcessorCore && id / 32 < performance_cores_capacity) + dataex->u.Processor.EfficiencyClass = (performance_cores[id / 32] >> (id % 32)) & 1; + else + dataex->u.Processor.EfficiencyClass = 0; dataex->u.Processor.GroupCount = 1; dataex->u.Processor.GroupMask[0].Mask = mask; dataex->u.Processor.GroupMask[0].Group = 0; @@ -846,6 +851,43 @@ static BOOL sysfs_count_list_elements(const char *filename, unsigned int *result return TRUE; }
+static void fill_performance_core_info(void) +{ + FILE *fpcore_list; + unsigned int beg, end, i; + char op = ','; + ULONG *p; + + fpcore_list = fopen("/sys/devices/cpu_core/cpus", "r"); + if (!fpcore_list) return; + + performance_cores = calloc(16, sizeof(ULONG)); + if (!performance_cores) goto done; + performance_cores_capacity = 16; + + while (!feof(fpcore_list) && op == ',') + { + if (!fscanf(fpcore_list, "%u %c ", &beg, &op)) break; + if (op == '-') fscanf(fpcore_list, "%u %c ", &end, &op); + else end = beg; + + for(i = beg; i <= end; i++) + { + if (i / 32 > performance_cores_capacity) + { + p = realloc(performance_cores, performance_cores_capacity * 2 * sizeof(ULONG)); + if (!p) break; + memset(p + performance_cores_capacity, 0, performance_cores_capacity * sizeof(ULONG)); + performance_cores = p; + performance_cores_capacity *= 2; + } + performance_cores[i / 32] |= 1 << (i % 32); + } + } +done: + fclose(fpcore_list); +} + /* for 'data', max_len is the array count. for 'dataex', max_len is in bytes */ static NTSTATUS create_logical_proc_info(void) { @@ -872,6 +914,8 @@ static NTSTATUS create_logical_proc_info(void) max_cpus, MAXIMUM_PROCESSORS); }
+ fill_performance_core_info(); + fcpu_list = fopen("/sys/devices/system/cpu/online", "r"); if (!fcpu_list) return STATUS_NOT_IMPLEMENTED;
@@ -1035,6 +1079,10 @@ static NTSTATUS create_logical_proc_info(void)
logical_proc_info_add_group( num_cpus, all_cpus_mask );
+ performance_cores_capacity = 0; + free(performance_cores); + performance_cores = NULL; + return STATUS_SUCCESS; }
On Thu Apr 27 18:01:52 2023 +0000, Torge Matthies wrote:
changed this line in [version 4 of the diff](/wine/wine/-/merge_requests/2710/diffs?diff_id=44385&start_sha=62931b1a131edf1f1b0bc326c3cddf62e06accc1#d5bcbaed4ae76fff7d2641017921e07798a7da0e_859_859)
I removed the access check
On Thu Apr 27 18:01:54 2023 +0000, Torge Matthies wrote:
changed this line in [version 4 of the diff](/wine/wine/-/merge_requests/2710/diffs?diff_id=44385&start_sha=62931b1a131edf1f1b0bc326c3cddf62e06accc1#d5bcbaed4ae76fff7d2641017921e07798a7da0e_234_234)
Latest version allocates the memory dynamically, with initial size 16 * sizeof(ULONG) and doubling with each realloc