Also calculate all_cpus_mask on first pass.
Signed-off-by: Anastasios Simeonidis symeonidis@csd.auth.gr --- dlls/ntdll/nt.c | 254 ++++++++++++++++++++++++------------------------ 1 file changed, 128 insertions(+), 126 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index 8c652a0615..52616b37be 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -1686,9 +1686,6 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION ** char op, name[MAX_PATH]; ULONG_PTR all_cpus_mask = 0;
- if (relation != RelationAll) - FIXME("Relationship filtering not implemented: 0x%x\n", relation); - /* On systems with a large number of CPU cores (32 or 64 depending on 32-bit or 64-bit), * we have issues parsing processor information: * - ULONG_PTR masks as used in data structures can't hold all cores. Requires splitting @@ -1725,18 +1722,21 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION ** continue; }
- sprintf(name, core_info, i, "physical_package_id"); - f = fopen(name, "r"); - if(f) - { - fscanf(f, "%u", &r); - fclose(f); - } - else r = 0; - if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorPackage, r, (ULONG_PTR)1 << i)) + if(relation == RelationAll || relation == RelationProcessorPackage) { - fclose(fcpu_list); - return STATUS_NO_MEMORY; + sprintf(name, core_info, i, "physical_package_id"); + f = fopen(name, "r"); + if(f) + { + fscanf(f, "%u", &r); + fclose(f); + } + else r = 0; + if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorPackage, r, (ULONG_PTR)1 << i)) + { + fclose(fcpu_list); + return STATUS_NO_MEMORY; + } }
/* Sysfs enumerates logical cores (and not physical cores), but Windows enumerates @@ -1749,143 +1749,145 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION ** * 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) + if(relation == RelationAll || relation == RelationProcessorCore || + relation == RelationNumaNode || relation == RelationGroup) { - 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"); + if(!sysfs_parse_bitmap(name, &thread_mask)) + thread_mask = 1<<i;
- /* Mask of logical threads sharing same physical core in kernel core numbering. */ - sprintf(name, core_info, i, "thread_siblings"); - if(!sysfs_parse_bitmap(name, &thread_mask)) - 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; - } + /* Needed later for NumaNode and Group. */ + all_cpus_mask |= thread_mask;
- for(j=0; j<4; j++) - { - CACHE_DESCRIPTOR cache; - ULONG_PTR mask = 0; - - sprintf(name, cache_info, i, j, "shared_cpu_map"); - if(!sysfs_parse_bitmap(name, &mask)) continue; - - sprintf(name, cache_info, i, j, "level"); - f = fopen(name, "r"); - if(!f) continue; - fscanf(f, "%u", &r); - fclose(f); - cache.Level = r; - - sprintf(name, cache_info, i, j, "ways_of_associativity"); - f = fopen(name, "r"); - if(!f) continue; - fscanf(f, "%u", &r); - fclose(f); - cache.Associativity = r; - - sprintf(name, cache_info, i, j, "coherency_line_size"); - f = fopen(name, "r"); - if(!f) continue; - fscanf(f, "%u", &r); - fclose(f); - cache.LineSize = r; + if(relation == RelationAll || relation == RelationProcessorCore) + { + sprintf(name, core_info, i, "thread_siblings_list"); + f = fopen(name, "r"); + if(f) + { + fscanf(f, "%d%c", &phys_core, &op); + fclose(f); + } + else phys_core = i;
- sprintf(name, cache_info, i, j, "size"); - f = fopen(name, "r"); - if(!f) continue; - fscanf(f, "%u%c", &r, &op); - fclose(f); - if(op != 'K') - WARN("unknown cache size %u%c\n", r, op); - cache.Size = (op=='K' ? r*1024 : r); - - sprintf(name, cache_info, i, j, "type"); - f = fopen(name, "r"); - if(!f) continue; - fscanf(f, "%s", name); - fclose(f); - if(!memcmp(name, "Data", 5)) - cache.Type = CacheData; - else if(!memcmp(name, "Instruction", 11)) - cache.Type = CacheInstruction; - else - cache.Type = CacheUnified; + if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, phys_core, thread_mask)) + { + fclose(fcpu_list); + return STATUS_NO_MEMORY; + } + } + }
- if(!logical_proc_info_add_cache(data, dataex, &len, max_len, mask, &cache)) + if (relation == RelationAll || relation == RelationCache) + { + for(j=0; j<4; j++) { - fclose(fcpu_list); - return STATUS_NO_MEMORY; + CACHE_DESCRIPTOR cache; + ULONG_PTR mask = 0; + + sprintf(name, cache_info, i, j, "shared_cpu_map"); + if(!sysfs_parse_bitmap(name, &mask)) continue; + + sprintf(name, cache_info, i, j, "level"); + f = fopen(name, "r"); + if(!f) continue; + fscanf(f, "%u", &r); + fclose(f); + cache.Level = r; + + sprintf(name, cache_info, i, j, "ways_of_associativity"); + f = fopen(name, "r"); + if(!f) continue; + fscanf(f, "%u", &r); + fclose(f); + cache.Associativity = r; + + sprintf(name, cache_info, i, j, "coherency_line_size"); + f = fopen(name, "r"); + if(!f) continue; + fscanf(f, "%u", &r); + fclose(f); + cache.LineSize = r; + + sprintf(name, cache_info, i, j, "size"); + f = fopen(name, "r"); + if(!f) continue; + fscanf(f, "%u%c", &r, &op); + fclose(f); + if(op != 'K') + WARN("unknown cache size %u%c\n", r, op); + cache.Size = (op=='K' ? r*1024 : r); + + sprintf(name, cache_info, i, j, "type"); + f = fopen(name, "r"); + if(!f) continue; + fscanf(f, "%s", name); + fclose(f); + if(!memcmp(name, "Data", 5)) + cache.Type = CacheData; + else if(!memcmp(name, "Instruction", 11)) + cache.Type = CacheInstruction; + else + cache.Type = CacheUnified; + + if(!logical_proc_info_add_cache(data, dataex, &len, max_len, mask, &cache)) + { + fclose(fcpu_list); + return STATUS_NO_MEMORY; + } } } } } fclose(fcpu_list);
- if(data){ - for(i=0; i<len; i++){ - if((*data)[i].Relationship == RelationProcessorCore){ - all_cpus_mask |= (*data)[i].ProcessorMask; - } - } - }else{ - for(i = 0; i < len; ){ - SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *infoex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)*dataex) + i); - if(infoex->Relationship == RelationProcessorCore){ - all_cpus_mask |= infoex->u.Processor.GroupMask[0].Mask; - } - i += infoex->Size; - } - } num_cpus = count_bits(all_cpus_mask);
- fnuma_list = fopen("/sys/devices/system/node/online", "r"); - if(!fnuma_list) + if(relation == RelationAll || relation == RelationNumaNode) { - if(!logical_proc_info_add_numa_node(data, dataex, &len, max_len, all_cpus_mask, 0)) - return STATUS_NO_MEMORY; - } - else - { - while(!feof(fnuma_list)) + fnuma_list = fopen("/sys/devices/system/node/online", "r"); + if(!fnuma_list) { - if(!fscanf(fnuma_list, "%u%c ", &beg, &op)) - break; - if(op == '-') fscanf(fnuma_list, "%u%c ", &end, &op); - else end = beg; - - for(i=beg; i<=end; i++) + if(!logical_proc_info_add_numa_node(data, dataex, &len, max_len, all_cpus_mask, 0)) + return STATUS_NO_MEMORY; + } + else + { + while(!feof(fnuma_list)) { - ULONG_PTR mask = 0; + if(!fscanf(fnuma_list, "%u%c ", &beg, &op)) + break; + if(op == '-') fscanf(fnuma_list, "%u%c ", &end, &op); + else end = beg;
- sprintf(name, numa_info, i); - f = fopen(name, "r"); - if(!f) continue; - while(!feof(f)) + for(i=beg; i<=end; i++) { - if(!fscanf(f, "%x%c ", &r, &op)) - break; - mask = (sizeof(ULONG_PTR)>sizeof(int) ? mask<<(8*sizeof(DWORD)) : 0) + r; - } - fclose(f); + ULONG_PTR mask = 0;
- if(!logical_proc_info_add_numa_node(data, dataex, &len, max_len, mask, i)) - { - fclose(fnuma_list); - return STATUS_NO_MEMORY; + sprintf(name, numa_info, i); + f = fopen(name, "r"); + if(!f) continue; + while(!feof(f)) + { + if(!fscanf(f, "%x%c ", &r, &op)) + break; + mask = (sizeof(ULONG_PTR)>sizeof(int) ? mask<<(8*sizeof(DWORD)) : 0) + r; + } + fclose(f); + + if(!logical_proc_info_add_numa_node(data, dataex, &len, max_len, mask, i)) + { + fclose(fnuma_list); + return STATUS_NO_MEMORY; + } } } + fclose(fnuma_list); } - fclose(fnuma_list); }
- if(dataex) + if(dataex && (relation == RelationAll || relation == RelationGroup)) logical_proc_info_add_group(dataex, &len, max_len, num_cpus, all_cpus_mask);
if(data)