Module: wine Branch: master Commit: 1312c6642851d4a0c5de9a71c824800935f96691 URL: https://source.winehq.org/git/wine.git/?a=commit;h=1312c6642851d4a0c5de9a71c...
Author: Roderick Colenbrander thunderbird2k@gmail.com Date: Wed Jun 20 22:29:44 2018 -0700
ntdll: Report physical cores once with proper thread mask.
Signed-off-by: Roderick Colenbrander thunderbird2k@gmail.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/nt.c | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index e4fec63..82f1b02 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -1333,17 +1333,16 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT if (pdata) { DWORD i;
- if(rel == RelationProcessorPackage){ - for(i=0; i<*len; i++) + for (i=0; i<*len; i++) + { + if (rel == RelationProcessorPackage && (*pdata)[i].Relationship == rel && (*pdata)[i].u.Reserved[1] == id) { - if ((*pdata)[i].Relationship!=rel || (*pdata)[i].u.Reserved[1]!=id) - continue; - (*pdata)[i].ProcessorMask |= mask; return TRUE; } - }else - i = *len; + else if (rel == RelationProcessorCore && (*pdata)[i].Relationship == rel && (*pdata)[i].u.Reserved[1] == id) + return TRUE; + }
while(*len == *pmax_len) { @@ -1369,6 +1368,10 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT dataex->u.Processor.GroupMask[0].Mask |= mask; return TRUE; } + else if (rel == RelationProcessorCore && dataex->Relationship == rel && dataex->u.Processor.Reserved[1] == id) + { + return TRUE; + } ofs += dataex->Size; }
@@ -1554,6 +1557,9 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
for(i=beg; i<=end; i++) { + DWORD phys_core = 0; + ULONG_PTR thread_mask = 0; + if(i > 8*sizeof(ULONG_PTR)) { FIXME("skipping logical processor %d\n", i); @@ -1574,15 +1580,35 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION ** return STATUS_NO_MEMORY; }
- sprintf(name, core_info, i, "core_id"); + /* Sysfs enumerates logical cores (and not physical cores), but Windows enumerates + * by physical core. Upon enumerating a logical core in sysfs, we register a physical + * core and all its logical cores. In order to not report physical cores multiple + * times, we pass a unique physical core ID to logical_proc_info_add_by_id and let + * that call figure out any duplication. + * Obtain a unique physical core ID from the first element of thread_siblings_list. + * This list provides logical cores sharing the same physical core. The IDs are based + * on kernel cpu core numbering as opposed to a hardware core ID like provided through + * 'core_id', so are suitable as a unique ID. + */ + sprintf(name, core_info, i, "thread_siblings_list"); f = fopen(name, "r"); if(f) { - fscanf(f, "%u", &r); + fscanf(f, "%d%c", &phys_core, &op); + fclose(f); + } + else phys_core = i; + + /* Mask of logical threads sharing same physical core in kernel core numbering. */ + sprintf(name, core_info, i, "thread_siblings"); + f = fopen(name, "r"); + if(f) + { + fscanf(f, "%lx", &thread_mask); fclose(f); } - else r = i; - if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, r, (ULONG_PTR)1 << i)) + else thread_mask = 1<<i; + if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, phys_core, thread_mask)) { fclose(fcpu_list); return STATUS_NO_MEMORY;