[PATCH 5/5] wbemprox: Create one processor object per package.

Hans Leidekker hans at codeweavers.com
Fri Jan 25 03:44:14 CST 2019


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/wbemprox/builtin.c     | 61 +++++++++++++++++++----------------
 dlls/wbemprox/tests/query.c | 63 ++++++++++++++++++++++++++++++++-----
 2 files changed, 90 insertions(+), 34 deletions(-)

diff --git a/dlls/wbemprox/builtin.c b/dlls/wbemprox/builtin.c
index 03f6e62562..d2b7dc116f 100644
--- a/dlls/wbemprox/builtin.c
+++ b/dlls/wbemprox/builtin.c
@@ -1365,38 +1365,47 @@ static UINT get_processor_count(void)
     return info.NumberOfProcessors;
 }
 
-static UINT get_logical_processor_count( UINT *num_cores )
+static UINT get_logical_processor_count( UINT *num_physical, UINT *num_packages )
 {
-    SYSTEM_LOGICAL_PROCESSOR_INFORMATION *info;
-    UINT i, j, count = 0;
+    SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *buf, *entry;
+    UINT core_relation_count = 0, package_relation_count = 0;
     NTSTATUS status;
-    ULONG len;
+    ULONG len, offset = 0;
+    BOOL smt_enabled = FALSE;
+    DWORD all;
 
-    if (num_cores) *num_cores = get_processor_count();
-    status = NtQuerySystemInformation( SystemLogicalProcessorInformation, NULL, 0, &len );
+    if (num_packages) *num_packages = 1;
+    status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), NULL, 0, &len );
     if (status != STATUS_INFO_LENGTH_MISMATCH) return get_processor_count();
 
-    if (!(info = heap_alloc( len ))) return get_processor_count();
-    status = NtQuerySystemInformation( SystemLogicalProcessorInformation, info, len, &len );
+    if (!(buf = heap_alloc( len ))) return get_processor_count();
+    status = NtQuerySystemInformationEx( SystemLogicalProcessorInformationEx, &all, sizeof(all), buf, len, NULL );
     if (status != STATUS_SUCCESS)
     {
-        heap_free( info );
+        heap_free( buf );
         return get_processor_count();
     }
-    if (num_cores) *num_cores = 0;
-    for (i = 0; i < len / sizeof(*info); i++)
+
+    while (offset < len)
     {
-        if (info[i].Relationship == RelationProcessorCore)
+        entry = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)buf + offset);
+
+        if (entry->Relationship == RelationProcessorCore)
         {
-            for (j = 0; j < sizeof(ULONG_PTR); j++) if (info[i].ProcessorMask & (1 << j)) count++;
+            core_relation_count++;
+            if (entry->u.Processor.Flags & LTP_PC_SMT) smt_enabled = TRUE;
         }
-        else if (info[i].Relationship == RelationProcessorPackage && num_cores)
+        else if (entry->Relationship == RelationProcessorPackage)
         {
-            for (j = 0; j < sizeof(ULONG_PTR); j++) if (info[i].ProcessorMask & (1 << j)) (*num_cores)++;
+            package_relation_count++;
         }
+        offset += entry->Size;
     }
-    heap_free( info );
-    return count;
+
+    heap_free( buf );
+    if (num_physical) *num_physical = core_relation_count;
+    if (num_packages) *num_packages = package_relation_count;
+    return smt_enabled ? core_relation_count * 2 : core_relation_count;
 }
 
 static UINT64 get_total_physical_memory(void)
@@ -1460,8 +1469,7 @@ static enum fill_status fill_compsys( struct table *table, const struct expr *co
     rec->manufacturer           = compsys_manufacturerW;
     rec->model                  = compsys_modelW;
     rec->name                   = get_computername();
-    rec->num_logical_processors = get_logical_processor_count( NULL );
-    rec->num_processors         = get_processor_count();
+    rec->num_logical_processors = get_logical_processor_count( NULL, &rec->num_processors );
     rec->total_physical_memory  = get_total_physical_memory();
     rec->username               = get_username();
     if (!match_row( table, row, cond, &status )) free_row_values( table, row );
@@ -2981,10 +2989,12 @@ static enum fill_status fill_processor( struct table *table, const struct expr *
     static const WCHAR fmtW[] = {'C','P','U','%','u',0};
     WCHAR caption[100], device_id[14], processor_id[17], manufacturer[13], name[49] = {0}, version[50];
     struct record_processor *rec;
-    UINT i, offset = 0, num_rows = 0, num_cores, num_logical_processors, count = get_processor_count();
+    UINT i, offset = 0, num_rows = 0, num_logical, num_physical, num_packages;
     enum fill_status status = FILL_STATUS_UNFILTERED;
 
-    if (!resize_table( table, count, sizeof(*rec) )) return FILL_STATUS_FAILED;
+    num_logical = get_logical_processor_count( &num_physical, &num_packages );
+
+    if (!resize_table( table, num_packages, sizeof(*rec) )) return FILL_STATUS_FAILED;
 
     get_processor_caption( caption );
     get_processor_id( processor_id );
@@ -2992,10 +3002,7 @@ static enum fill_status fill_processor( struct table *table, const struct expr *
     get_processor_name( name );
     get_processor_version( version );
 
-    num_logical_processors = get_logical_processor_count( &num_cores ) / count;
-    num_cores /= count;
-
-    for (i = 0; i < count; i++)
+    for (i = 0; i < num_packages; i++)
     {
         rec = (struct record_processor *)(table->data + offset);
         rec->addresswidth           = get_osarchitecture() == os_32bitW ? 32 : 64;
@@ -3012,8 +3019,8 @@ static enum fill_status fill_processor( struct table *table, const struct expr *
         rec->manufacturer           = heap_strdupW( manufacturer );
         rec->maxclockspeed          = get_processor_maxclockspeed( i );
         rec->name                   = heap_strdupW( name );
-        rec->num_cores              = num_cores;
-        rec->num_logical_processors = num_logical_processors;
+        rec->num_cores              = num_physical / num_packages;
+        rec->num_logical_processors = num_logical / num_packages;
         rec->processor_id           = heap_strdupW( processor_id );
         rec->processortype          = 3; /* central processor */
         rec->revision               = get_processor_revision();
diff --git a/dlls/wbemprox/tests/query.c b/dlls/wbemprox/tests/query.c
index 82195ebedd..ae0106a341 100644
--- a/dlls/wbemprox/tests/query.c
+++ b/dlls/wbemprox/tests/query.c
@@ -529,12 +529,16 @@ static void test_Win32_ComputerSystem( IWbemServices *services )
     static const WCHAR modelW[] = {'M','o','d','e','l',0};
     static const WCHAR nameW[] = {'N','a','m','e',0};
     static const WCHAR usernameW[] = {'U','s','e','r','N','a','m','e',0};
+    static const WCHAR numprocessorsW[] =
+        {'N','u','m','b','e','r','O','f','P','r','o','c','e','s','s','o','r','s',0};
+    static const WCHAR numlogicalprocessorsW[] =
+        {'N','u','m','b','e','r','O','f','L','o','g','i','c','a','l','P','r','o','c','e','s','s','o','r','s',0};
     static const WCHAR queryW[] =
         {'S','E','L','E','C','T',' ','*',' ','F','R','O','M',' ','W','i','n','3','2','_',
          'C','o','m','p','u','t','e','r','S','y','s','t','e','m',0};
     BSTR wql = SysAllocString( wqlW ), query = SysAllocString( queryW );
     IEnumWbemClassObject *result;
-    IWbemClassObject *service;
+    IWbemClassObject *obj;
     VARIANT value;
     CIMTYPE type;
     HRESULT hr;
@@ -565,17 +569,17 @@ static void test_Win32_ComputerSystem( IWbemServices *services )
         goto out;
     }
 
-    hr = IEnumWbemClassObject_Next( result, 10000, 1, &service, &count );
+    hr = IEnumWbemClassObject_Next( result, 10000, 1, &obj, &count );
     ok( hr == S_OK, "got %08x\n", hr );
 
     type = 0xdeadbeef;
     VariantInit( &value );
-    hr = IWbemClassObject_Get( service, memorytypeW, 0, &value, &type, NULL );
+    hr = IWbemClassObject_Get( obj, memorytypeW, 0, &value, &type, NULL );
     ok( hr == WBEM_E_NOT_FOUND, "got %08x\n", hr );
 
     type = 0xdeadbeef;
     VariantInit( &value );
-    hr = IWbemClassObject_Get( service, modelW, 0, &value, &type, NULL );
+    hr = IWbemClassObject_Get( obj, modelW, 0, &value, &type, NULL );
     ok( hr == S_OK, "failed to get model %08x\n", hr );
     ok( V_VT( &value ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &value ) );
     ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
@@ -584,7 +588,7 @@ static void test_Win32_ComputerSystem( IWbemServices *services )
 
     type = 0xdeadbeef;
     VariantInit( &value );
-    hr = IWbemClassObject_Get( service, nameW, 0, &value, &type, NULL );
+    hr = IWbemClassObject_Get( obj, nameW, 0, &value, &type, NULL );
     ok( hr == S_OK, "failed to get computer name %08x\n", hr );
     ok( V_VT( &value ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &value ) );
     ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
@@ -593,14 +597,33 @@ static void test_Win32_ComputerSystem( IWbemServices *services )
 
     type = 0xdeadbeef;
     VariantInit( &value );
-    hr = IWbemClassObject_Get( service, usernameW, 0, &value, &type, NULL );
+    hr = IWbemClassObject_Get( obj, numlogicalprocessorsW, 0, &value, &type, NULL );
+    ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND) /* win2k3 */, "got %08x\n", hr );
+    if (hr == S_OK)
+    {
+        ok( V_VT( &value ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &value ) );
+        ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
+        trace( "numlogicalprocessors %u\n", V_I4( &value ) );
+    }
+
+    type = 0xdeadbeef;
+    VariantInit( &value );
+    hr = IWbemClassObject_Get( obj, numprocessorsW, 0, &value, &type, NULL );
+    ok( hr == S_OK, "got %08x\n", hr );
+    ok( V_VT( &value ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &value ) );
+    ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
+    trace( "numprocessors %u\n", V_I4( &value ) );
+
+    type = 0xdeadbeef;
+    VariantInit( &value );
+    hr = IWbemClassObject_Get( obj, usernameW, 0, &value, &type, NULL );
     ok( hr == S_OK, "failed to get computer name %08x\n", hr );
     ok( V_VT( &value ) == VT_BSTR, "unexpected variant type 0x%x\n", V_VT( &value ) );
     ok( type == CIM_STRING, "unexpected type 0x%x\n", type );
     ok( !lstrcmpiW( V_BSTR( &value ), username ), "got %s, expected %s\n", wine_dbgstr_w(V_BSTR(&value)), wine_dbgstr_w(username) );
     VariantClear( &value );
 
-    IWbemClassObject_Release( service );
+    IWbemClassObject_Release( obj );
     IEnumWbemClassObject_Release( result );
 out:
     SysFreeString( query );
@@ -1563,6 +1586,10 @@ static void test_Win32_Processor( IWbemServices *services )
         {'M','a','n','u','f','a','c','t','u','r','e','r',0};
     static const WCHAR nameW[] =
         {'N','a','m','e',0};
+    static const WCHAR numcoresW[] =
+        {'N','u','m','b','e','r','O','f','C','o','r','e','s',0};
+    static const WCHAR numlogicalprocessorsW[] =
+        {'N','u','m','b','e','r','O','f','L','o','g','i','c','a','l','P','r','o','c','e','s','s','o','r','s',0};
     static const WCHAR processoridW[] =
         {'P','r','o','c','e','s','s','o','r','I','d',0};
     static const WCHAR revisionW[] =
@@ -1665,6 +1692,28 @@ static void test_Win32_Processor( IWbemServices *services )
         trace( "version %s\n", wine_dbgstr_w(V_BSTR( &val )) );
         VariantClear( &val );
 
+        type = 0xdeadbeef;
+        VariantInit( &val );
+        hr = IWbemClassObject_Get( obj, numlogicalprocessorsW, 0, &val, &type, NULL );
+        ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND) /* win2k3 */, "got %08x\n", hr );
+        if (hr == S_OK)
+        {
+            ok( V_VT( &val ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &val ) );
+            ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
+            trace( "numlogicalprocessors %u\n", V_I4( &val ) );
+        }
+
+        type = 0xdeadbeef;
+        VariantInit( &val );
+        hr = IWbemClassObject_Get( obj, numcoresW, 0, &val, &type, NULL );
+        ok( hr == S_OK || broken(hr == WBEM_E_NOT_FOUND) /* win2k3 */, "got %08x\n", hr );
+        if (hr == S_OK)
+        {
+            ok( V_VT( &val ) == VT_I4, "unexpected variant type 0x%x\n", V_VT( &val ) );
+            ok( type == CIM_UINT32, "unexpected type 0x%x\n", type );
+            trace( "numcores %u\n", V_I4( &val ) );
+        }
+
         IWbemClassObject_Release( obj );
     }
 
-- 
2.20.1




More information about the wine-devel mailing list