[PATCH v2 3/5] ntdll: Report physical cores once with proper thread mask.

Roderick Colenbrander thunderbird2k at gmail.com
Thu Jun 21 00:29:44 CDT 2018


Signed-off-by: Roderick Colenbrander <thunderbird2k at gmail.com>
---
 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 14e18dc6af..b16f320957 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1322,17 +1322,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)
         {
@@ -1358,6 +1357,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;
-- 
2.14.4




More information about the wine-devel mailing list