From: Paul Gofman pgofman@codeweavers.com
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/ntdll/unix/system.c | 533 ++++++++++++++++++--------------------- 1 file changed, 239 insertions(+), 294 deletions(-)
diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c index 43233faf4a4..4d5fc282e45 100644 --- a/dlls/ntdll/unix/system.c +++ b/dlls/ntdll/unix/system.c @@ -230,6 +230,10 @@ struct smbios_chassis_args #define RSMB 0x52534D42
SYSTEM_CPU_INFORMATION cpu_info = { 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; +static unsigned int logical_proc_info_ex_size, logical_proc_info_ex_alloc_size;
/******************************************************************************* * Architecture specific feature detection for CPUs @@ -536,24 +540,34 @@ static void get_cpuinfo( SYSTEM_CPU_INFORMATION *info )
#endif /* End architecture specific feature detection for CPUs */
-static BOOL grow_logical_proc_buf( SYSTEM_LOGICAL_PROCESSOR_INFORMATION **pdata, DWORD *max_len ) +static BOOL grow_logical_proc_buf(void) { SYSTEM_LOGICAL_PROCESSOR_INFORMATION *new_data; + unsigned int new_len;
- *max_len *= 2; - if (!(new_data = realloc( *pdata, *max_len*sizeof(*new_data) ))) return FALSE; - *pdata = new_data; + if (logical_proc_info_len < logical_proc_info_alloc_len) return TRUE; + + new_len = max( logical_proc_info_alloc_len * 2, logical_proc_info_len + 1 ); + if (!(new_data = realloc( logical_proc_info, new_len * sizeof(*new_data) ))) return FALSE; + memset( new_data + logical_proc_info_alloc_len, 0, + (new_len - logical_proc_info_alloc_len) * sizeof(*new_data) ); + logical_proc_info = new_data; + logical_proc_info_alloc_len = new_len; return TRUE; }
-static BOOL grow_logical_proc_ex_buf( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **pdataex, DWORD *max_len ) +static BOOL grow_logical_proc_ex_buf( unsigned int add_size ) { SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *new_dataex; - DWORD new_len = *max_len * 2; - if (!(new_dataex = realloc( *pdataex, new_len ))) return FALSE; - memset( (char *)new_dataex + *max_len, 0, new_len - *max_len ); - *pdataex = new_dataex; - *max_len = new_len; + DWORD new_len; + + if ( logical_proc_info_ex_size + add_size <= logical_proc_info_ex_alloc_size ) return TRUE; + + new_len = max( logical_proc_info_ex_alloc_size * 2, logical_proc_info_ex_alloc_size + add_size ); + if (!(new_dataex = realloc( logical_proc_info_ex, new_len ))) return FALSE; + memset( (char *)new_dataex + logical_proc_info_ex_alloc_size, 0, new_len - logical_proc_info_ex_alloc_size ); + logical_proc_info_ex = new_dataex; + logical_proc_info_ex_alloc_size = new_len; return TRUE; }
@@ -580,45 +594,37 @@ static DWORD count_bits( ULONG_PTR mask ) * - RelationProcessorPackage: package id ('CPU socket'). * - RelationProcessorCore: physical core number. */ -static BOOL logical_proc_info_add_by_id( SYSTEM_LOGICAL_PROCESSOR_INFORMATION **pdata, - SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **pdataex, DWORD *len, - DWORD *pmax_len, LOGICAL_PROCESSOR_RELATIONSHIP rel, - DWORD id, ULONG_PTR mask ) +static BOOL logical_proc_info_add_by_id( LOGICAL_PROCESSOR_RELATIONSHIP rel, DWORD id, ULONG_PTR mask ) { SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *dataex; unsigned int ofs = 0, i;
- if (pdata) + for (i = 0; i < logical_proc_info_len; i++) { - for (i = 0; i < *len; i++) + if (rel == RelationProcessorPackage && logical_proc_info[i].Relationship == rel + && logical_proc_info[i].u.Reserved[1] == id) { - if (rel == RelationProcessorPackage && (*pdata)[i].Relationship == rel && (*pdata)[i].u.Reserved[1] == id) - { - (*pdata)[i].ProcessorMask |= mask; - return TRUE; - } - else if (rel == RelationProcessorCore && (*pdata)[i].Relationship == rel && (*pdata)[i].u.Reserved[1] == id) - return TRUE; + logical_proc_info[i].ProcessorMask |= mask; + return TRUE; } + else if (rel == RelationProcessorCore && logical_proc_info[i].Relationship == rel + && logical_proc_info[i].u.Reserved[1] == id) + return TRUE; + }
- while (*len == *pmax_len) - { - if (!grow_logical_proc_buf(pdata, pmax_len)) return FALSE; - } + if (!grow_logical_proc_buf()) return FALSE;
- (*pdata)[i].Relationship = rel; - (*pdata)[i].ProcessorMask = mask; - if (rel == RelationProcessorCore) - (*pdata)[i].u.ProcessorCore.Flags = count_bits(mask) > 1 ? LTP_PC_SMT : 0; - (*pdata)[i].u.Reserved[0] = 0; - (*pdata)[i].u.Reserved[1] = id; - *len = i + 1; - return TRUE; - } + logical_proc_info[i].Relationship = rel; + logical_proc_info[i].ProcessorMask = mask; + if (rel == RelationProcessorCore) + logical_proc_info[i].u.ProcessorCore.Flags = count_bits( mask ) > 1 ? LTP_PC_SMT : 0; + logical_proc_info[i].u.Reserved[0] = 0; + logical_proc_info[i].u.Reserved[1] = id; + logical_proc_info_len = i + 1;
- while (ofs < *len) + while (ofs < logical_proc_info_ex_size) { - dataex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)*pdataex) + ofs); + dataex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)logical_proc_info_ex + ofs); if (rel == RelationProcessorPackage && dataex->Relationship == rel && dataex->u.Processor.Reserved[1] == id) { dataex->u.Processor.GroupMask[0].Mask |= mask; @@ -633,13 +639,9 @@ static BOOL logical_proc_info_add_by_id( SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
/* TODO: For now, just one group. If more than 64 processors, then we * need another group. */ + if (!grow_logical_proc_ex_buf( log_proc_ex_size_plus( sizeof(PROCESSOR_RELATIONSHIP) ))) return FALSE;
- while (ofs + log_proc_ex_size_plus( sizeof(PROCESSOR_RELATIONSHIP) ) > *pmax_len) - { - if (!grow_logical_proc_ex_buf(pdataex, pmax_len)) return FALSE; - } - - dataex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)*pdataex) + ofs); + dataex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)logical_proc_info_ex + ofs);
dataex->Relationship = rel; dataex->Size = log_proc_ex_size_plus( sizeof(PROCESSOR_RELATIONSHIP) ); @@ -655,52 +657,42 @@ static BOOL logical_proc_info_add_by_id( SYSTEM_LOGICAL_PROCESSOR_INFORMATION ** dataex->u.Processor.Reserved[0] = 0; dataex->u.Processor.Reserved[1] = id;
- *len += dataex->Size; + logical_proc_info_ex_size += dataex->Size;
return TRUE; }
-static BOOL logical_proc_info_add_cache( SYSTEM_LOGICAL_PROCESSOR_INFORMATION **pdata, - SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **pdataex, DWORD *len, - DWORD *pmax_len, ULONG_PTR mask, CACHE_DESCRIPTOR *cache ) +static BOOL logical_proc_info_add_cache( ULONG_PTR mask, CACHE_DESCRIPTOR *cache ) { SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *dataex; unsigned int ofs = 0, i;
- if (pdata) + for (i = 0; i < logical_proc_info_len; i++) { - for (i = 0; i < *len; i++) - { - if ((*pdata)[i].Relationship==RelationCache && (*pdata)[i].ProcessorMask==mask - && (*pdata)[i].u.Cache.Level==cache->Level && (*pdata)[i].u.Cache.Type==cache->Type) - return TRUE; - } + if (logical_proc_info[i].Relationship==RelationCache && logical_proc_info[i].ProcessorMask==mask + && logical_proc_info[i].u.Cache.Level==cache->Level && logical_proc_info[i].u.Cache.Type==cache->Type) + return TRUE; + }
- while (*len == *pmax_len) - if (!grow_logical_proc_buf(pdata, pmax_len)) return FALSE; + if (!grow_logical_proc_buf()) return FALSE;
- (*pdata)[i].Relationship = RelationCache; - (*pdata)[i].ProcessorMask = mask; - (*pdata)[i].u.Cache = *cache; - *len = i + 1; - return TRUE; - } + logical_proc_info[i].Relationship = RelationCache; + logical_proc_info[i].ProcessorMask = mask; + logical_proc_info[i].u.Cache = *cache; + logical_proc_info_len = i + 1;
- for (ofs = 0; ofs < *len; ) + for (ofs = 0; ofs < logical_proc_info_ex_size; ) { - dataex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)*pdataex) + ofs); - if (dataex->Relationship == RelationCache && dataex->u.Cache.GroupMask.Mask == mask && - dataex->u.Cache.Level == cache->Level && dataex->u.Cache.Type == cache->Type) + dataex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)logical_proc_info_ex + ofs); + if (dataex->Relationship == RelationCache && dataex->u.Cache.GroupMask.Mask == mask + && dataex->u.Cache.Level == cache->Level && dataex->u.Cache.Type == cache->Type) return TRUE; ofs += dataex->Size; }
- while (ofs + log_proc_ex_size_plus( sizeof(CACHE_RELATIONSHIP) ) > *pmax_len) - { - if (!grow_logical_proc_ex_buf(pdataex, pmax_len)) return FALSE; - } + if (!grow_logical_proc_ex_buf( log_proc_ex_size_plus( sizeof(CACHE_RELATIONSHIP) ))) return FALSE;
- dataex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)*pdataex) + ofs); + dataex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)logical_proc_info_ex + ofs);
dataex->Relationship = RelationCache; dataex->Size = log_proc_ex_size_plus( sizeof(CACHE_RELATIONSHIP) ); @@ -712,35 +704,25 @@ static BOOL logical_proc_info_add_cache( SYSTEM_LOGICAL_PROCESSOR_INFORMATION ** dataex->u.Cache.GroupMask.Mask = mask; dataex->u.Cache.GroupMask.Group = 0;
- *len += dataex->Size; + logical_proc_info_ex_size += dataex->Size;
return TRUE; }
-static BOOL logical_proc_info_add_numa_node( SYSTEM_LOGICAL_PROCESSOR_INFORMATION **pdata, - SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **pdataex, DWORD *len, - DWORD *pmax_len, ULONG_PTR mask, DWORD node_id ) +static BOOL logical_proc_info_add_numa_node( ULONG_PTR mask, DWORD node_id ) { SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *dataex;
- if (pdata) - { - while (*len == *pmax_len) - if (!grow_logical_proc_buf(pdata, pmax_len)) return FALSE; + if (!grow_logical_proc_buf()) return FALSE;
- (*pdata)[*len].Relationship = RelationNumaNode; - (*pdata)[*len].ProcessorMask = mask; - (*pdata)[*len].u.NumaNode.NodeNumber = node_id; - (*len)++; - return TRUE; - } + logical_proc_info[logical_proc_info_len].Relationship = RelationNumaNode; + logical_proc_info[logical_proc_info_len].ProcessorMask = mask; + logical_proc_info[logical_proc_info_len].u.NumaNode.NodeNumber = node_id; + ++logical_proc_info_len;
- while (*len + log_proc_ex_size_plus( sizeof(NUMA_NODE_RELATIONSHIP) ) > *pmax_len) - { - if (!grow_logical_proc_ex_buf(pdataex, pmax_len)) return FALSE; - } + if (!grow_logical_proc_ex_buf( log_proc_ex_size_plus( sizeof(NUMA_NODE_RELATIONSHIP) ))) return FALSE;
- dataex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)*pdataex) + *len); + dataex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)logical_proc_info_ex + logical_proc_info_ex_size);
dataex->Relationship = RelationNumaNode; dataex->Size = log_proc_ex_size_plus( sizeof(NUMA_NODE_RELATIONSHIP) ); @@ -748,20 +730,18 @@ static BOOL logical_proc_info_add_numa_node( SYSTEM_LOGICAL_PROCESSOR_INFORMATIO dataex->u.NumaNode.GroupMask.Mask = mask; dataex->u.NumaNode.GroupMask.Group = 0;
- *len += dataex->Size; + logical_proc_info_ex_size += dataex->Size;
return TRUE; }
-static BOOL logical_proc_info_add_group( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **pdataex, - DWORD *len, DWORD *pmax_len, DWORD num_cpus, ULONG_PTR mask ) +static BOOL logical_proc_info_add_group( DWORD num_cpus, ULONG_PTR mask ) { SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *dataex;
- while (*len + log_proc_ex_size_plus( sizeof(GROUP_RELATIONSHIP) ) > *pmax_len) - if (!grow_logical_proc_ex_buf(pdataex, pmax_len)) return FALSE; + if (!grow_logical_proc_ex_buf( log_proc_ex_size_plus( sizeof(GROUP_RELATIONSHIP) ))) return FALSE;
- dataex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)*pdataex) + *len); + dataex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)logical_proc_info_ex) + logical_proc_info_ex_size);
dataex->Relationship = RelationGroup; dataex->Size = log_proc_ex_size_plus( sizeof(GROUP_RELATIONSHIP) ); @@ -771,7 +751,7 @@ static BOOL logical_proc_info_add_group( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX dataex->u.Group.GroupInfo[0].ActiveProcessorCount = num_cpus; dataex->u.Group.GroupInfo[0].ActiveProcessorMask = mask;
- *len += dataex->Size; + logical_proc_info_ex_size += dataex->Size; return TRUE; }
@@ -838,16 +818,14 @@ static BOOL sysfs_count_list_elements(const char *filename, DWORD *result) }
/* for 'data', max_len is the array count. for 'dataex', max_len is in bytes */ -static NTSTATUS create_logical_proc_info( SYSTEM_LOGICAL_PROCESSOR_INFORMATION **data, - SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **dataex, - DWORD *max_len, DWORD relation ) +static NTSTATUS create_logical_proc_info(void) { static const char core_info[] = "/sys/devices/system/cpu/cpu%u/topology/%s"; static const char cache_info[] = "/sys/devices/system/cpu/cpu%u/cache/index%u/%s"; static const char numa_info[] = "/sys/devices/system/node/node%u/cpumap";
FILE *fcpu_list, *fnuma_list, *f; - DWORD len = 0, beg, end, i, j, r, num_cpus = 0, max_cpus = 0; + DWORD beg, end, i, j, r, num_cpus = 0, max_cpus = 0; char op, name[MAX_PATH]; ULONG_PTR all_cpus_mask = 0;
@@ -879,27 +857,24 @@ static NTSTATUS create_logical_proc_info( SYSTEM_LOGICAL_PROCESSOR_INFORMATION * DWORD phys_core = 0; ULONG_PTR thread_mask = 0;
- if (i > 8*sizeof(ULONG_PTR)) + if (i > 8 * sizeof(ULONG_PTR)) { FIXME("skipping logical processor %d\n", i); continue; }
- if (relation == RelationAll || relation == RelationProcessorPackage) + sprintf(name, core_info, i, "physical_package_id"); + f = fopen(name, "r"); + if (f) { - 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; - } + fscanf(f, "%u", &r); + fclose(f); + } + else r = 0; + if (!logical_proc_info_add_by_id( RelationProcessorPackage, r, (ULONG_PTR)1 << i )) + { + fclose(fcpu_list); + return STATUS_NO_MEMORY; }
/* Sysfs enumerates logical cores (and not physical cores), but Windows enumerates @@ -912,92 +887,83 @@ 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. */ - if(relation == RelationAll || relation == RelationProcessorCore || - relation == RelationNumaNode || relation == RelationGroup) - { - /* 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;
- /* Needed later for NumaNode and Group. */ - all_cpus_mask |= thread_mask; + /* 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 (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; + /* Needed later for NumaNode and Group. */ + all_cpus_mask |= thread_mask;
- if (!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, phys_core, thread_mask)) - { - fclose(fcpu_list); - return STATUS_NO_MEMORY; - } - } + 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;
- if (relation == RelationAll || relation == RelationCache) + if (!logical_proc_info_add_by_id( RelationProcessorCore, phys_core, thread_mask )) { - for(j = 0; j < 4; j++) - { - CACHE_DESCRIPTOR cache; - ULONG_PTR mask = 0; + fclose(fcpu_list); + return STATUS_NO_MEMORY; + }
- sprintf(name, cache_info, i, j, "shared_cpu_map"); - if(!sysfs_parse_bitmap(name, &mask)) continue; + for (j = 0; j < 4; j++) + { + CACHE_DESCRIPTOR cache; + ULONG_PTR mask = 0;
- 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, "shared_cpu_map"); + if(!sysfs_parse_bitmap(name, &mask)) continue;
- 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, "level"); + f = fopen(name, "r"); + if(!f) continue; + fscanf(f, "%u", &r); + fclose(f); + cache.Level = 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, "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, "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; + 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 (!logical_proc_info_add_cache(data, dataex, &len, max_len, mask, &cache)) - { - fclose(fcpu_list); - return STATUS_NO_MEMORY; - } + 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( mask, &cache )) + { + fclose(fcpu_list); + return STATUS_NO_MEMORY; } } } @@ -1006,48 +972,39 @@ static NTSTATUS create_logical_proc_info( SYSTEM_LOGICAL_PROCESSOR_INFORMATION *
num_cpus = count_bits(all_cpus_mask);
- if(relation == RelationAll || relation == RelationNumaNode) + fnuma_list = fopen("/sys/devices/system/node/online", "r"); + if (!fnuma_list) { - fnuma_list = fopen("/sys/devices/system/node/online", "r"); - if (!fnuma_list) - { - if (!logical_proc_info_add_numa_node(data, dataex, &len, max_len, all_cpus_mask, 0)) - return STATUS_NO_MEMORY; - } - else + if (!logical_proc_info_add_numa_node( all_cpus_mask, 0 )) + return STATUS_NO_MEMORY; + } + else + { + while (!feof(fnuma_list)) { - while (!feof(fnuma_list)) - { - if (!fscanf(fnuma_list, "%u%c ", &beg, &op)) - break; - if (op == '-') fscanf(fnuma_list, "%u%c ", &end, &op); - else end = beg; + 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++) - { - ULONG_PTR mask = 0; + for (i = beg; i <= end; i++) + { + ULONG_PTR mask = 0;
- sprintf(name, numa_info, i); - if (!sysfs_parse_bitmap( name, &mask )) continue; + sprintf(name, numa_info, i); + if (!sysfs_parse_bitmap( name, &mask )) continue;
- if (!logical_proc_info_add_numa_node(data, dataex, &len, max_len, mask, i)) - { - fclose(fnuma_list); - return STATUS_NO_MEMORY; - } + if (!logical_proc_info_add_numa_node( mask, i )) + { + fclose(fnuma_list); + return STATUS_NO_MEMORY; } } - fclose(fnuma_list); } + fclose(fnuma_list); }
- if(dataex && (relation == RelationAll || relation == RelationGroup)) - logical_proc_info_add_group(dataex, &len, max_len, num_cpus, all_cpus_mask); - - if(data) - *max_len = len * sizeof(**data); - else - *max_len = len; + logical_proc_info_add_group( num_cpus, all_cpus_mask );
return STATUS_SUCCESS; } @@ -1055,11 +1012,9 @@ static NTSTATUS create_logical_proc_info( SYSTEM_LOGICAL_PROCESSOR_INFORMATION * #elif defined(__APPLE__)
/* for 'data', max_len is the array count. for 'dataex', max_len is in bytes */ -static NTSTATUS create_logical_proc_info( SYSTEM_LOGICAL_PROCESSOR_INFORMATION **data, - SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **dataex, - DWORD *max_len, DWORD relation) +static NTSTATUS create_logical_proc_info(void) { - DWORD pkgs_no, cores_no, lcpu_no, lcpu_per_core, cores_per_package, assoc, len = 0; + DWORD pkgs_no, cores_no, lcpu_no, lcpu_per_core, cores_per_package, assoc; DWORD cache_ctrs[10] = {0}; ULONG_PTR all_cpus_mask = 0; CACHE_DESCRIPTOR cache[10]; @@ -1067,9 +1022,6 @@ static NTSTATUS create_logical_proc_info( SYSTEM_LOGICAL_PROCESSOR_INFORMATION * size_t size; DWORD p,i,j,k;
- if (relation != RelationAll) - FIXME("Relationship filtering not implemented: 0x%x\n", relation); - lcpu_no = peb->NumberOfProcessors;
size = sizeof(pkgs_no); @@ -1156,12 +1108,12 @@ static NTSTATUS create_logical_proc_info( SYSTEM_LOGICAL_PROCESSOR_INFORMATION * all_cpus_mask |= mask;
/* add to package */ - if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorPackage, p, mask)) + if(!logical_proc_info_add_by_id( RelationProcessorPackage, p, mask )) return STATUS_NO_MEMORY;
/* add new core */ phys_core = p * cores_per_package + j; - if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, phys_core, mask)) + if(!logical_proc_info_add_by_id( RelationProcessorCore, phys_core, mask )) return STATUS_NO_MEMORY;
for(i = 1; i < 5; ++i) @@ -1172,7 +1124,7 @@ static NTSTATUS create_logical_proc_info( SYSTEM_LOGICAL_PROCESSOR_INFORMATION * for(k = 0; k < cache_sharing[i]; ++k) mask |= (ULONG_PTR)1 << (j * lcpu_per_core + k);
- if(!logical_proc_info_add_cache(data, dataex, &len, max_len, mask, &cache[i])) + if (!logical_proc_info_add_cache( mask, &cache[i] )) return STATUS_NO_MEMORY; }
@@ -1183,24 +1135,17 @@ static NTSTATUS create_logical_proc_info( SYSTEM_LOGICAL_PROCESSOR_INFORMATION * }
/* OSX doesn't support NUMA, so just make one NUMA node for all CPUs */ - if(!logical_proc_info_add_numa_node(data, dataex, &len, max_len, all_cpus_mask, 0)) + if(!logical_proc_info_add_numa_node( all_cpus_mask, 0 )) return STATUS_NO_MEMORY;
- if(dataex) logical_proc_info_add_group(dataex, &len, max_len, lcpu_no, all_cpus_mask); - - if(data) - *max_len = len * sizeof(**data); - else - *max_len = len; + logical_proc_info_add_group( lcpu_no, all_cpus_mask );
return STATUS_SUCCESS; }
#else
-static NTSTATUS create_logical_proc_info( SYSTEM_LOGICAL_PROCESSOR_INFORMATION **data, - SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **dataex, - DWORD *max_len, DWORD relation ) +static NTSTATUS create_logical_proc_info(void) { FIXME("stub\n"); return STATUS_NOT_IMPLEMENTED; @@ -1217,6 +1162,7 @@ static NTSTATUS create_logical_proc_info( SYSTEM_LOGICAL_PROCESSOR_INFORMATION * */ void init_cpu_info(void) { + NTSTATUS status; long num;
#ifdef _SC_NPROCESSORS_ONLN @@ -1245,34 +1191,42 @@ void init_cpu_info(void) TRACE( "<- CPU arch %d, level %d, rev %d, features 0x%x\n", cpu_info.ProcessorArchitecture, cpu_info.ProcessorLevel, cpu_info.ProcessorRevision, cpu_info.ProcessorFeatureBits ); + + if ((status = create_logical_proc_info())) + { + FIXME( "Failed to get logical processor information, status %#x.\n", status ); + free( logical_proc_info ); + logical_proc_info = NULL; + logical_proc_info_len = 0; + + free( logical_proc_info_ex ); + logical_proc_info_ex = NULL; + logical_proc_info_ex_size = 0; + } + else + { + logical_proc_info = realloc( logical_proc_info, logical_proc_info_len * sizeof(*logical_proc_info) ); + logical_proc_info_alloc_len = logical_proc_info_len; + logical_proc_info_ex = realloc( logical_proc_info_ex, logical_proc_info_ex_size ); + logical_proc_info_ex_alloc_size = logical_proc_info_ex_size; + } }
static NTSTATUS create_cpuset_info(SYSTEM_CPU_SET_INFORMATION *info) { - SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *proc_info; + const SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *proc_info; + const DWORD cpu_info_size = logical_proc_info_ex_size; BYTE core_index, cache_index, max_cache_level; unsigned int i, j, count; - BYTE *proc_info_buffer; - DWORD cpu_info_size; ULONG64 cpu_mask; - NTSTATUS status; - - count = peb->NumberOfProcessors;
- cpu_info_size = 3 * sizeof(*proc_info); - if (!(proc_info_buffer = malloc(cpu_info_size))) - return STATUS_NO_MEMORY; + if (!logical_proc_info_ex) return STATUS_NOT_IMPLEMENTED;
- if ((status = create_logical_proc_info(NULL, (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **)&proc_info_buffer, - &cpu_info_size, RelationAll))) - { - free(proc_info_buffer); - return status; - } + count = peb->NumberOfProcessors;
max_cache_level = 0; - proc_info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)proc_info_buffer; - for (i = 0; (BYTE *)proc_info != proc_info_buffer + cpu_info_size; ++i) + proc_info = logical_proc_info_ex; + for (i = 0; (char *)proc_info != (char *)logical_proc_info_ex + cpu_info_size; ++i) { if (proc_info->Relationship == RelationCache) { @@ -1286,7 +1240,7 @@ static NTSTATUS create_cpuset_info(SYSTEM_CPU_SET_INFORMATION *info)
core_index = 0; cache_index = 0; - proc_info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)proc_info_buffer; + proc_info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)logical_proc_info_ex; for (i = 0; i < count; ++i) { info[i].Size = sizeof(*info); @@ -1295,7 +1249,7 @@ static NTSTATUS create_cpuset_info(SYSTEM_CPU_SET_INFORMATION *info) info[i].u.CpuSet.LogicalProcessorIndex = i; }
- for (i = 0; (BYTE *)proc_info != (BYTE *)proc_info_buffer + cpu_info_size; ++i) + for (i = 0; (char *)proc_info != (char *)logical_proc_info_ex + cpu_info_size; ++i) { if (proc_info->Relationship == RelationProcessorCore) { @@ -1331,11 +1285,9 @@ static NTSTATUS create_cpuset_info(SYSTEM_CPU_SET_INFORMATION *info) if (((ULONG64)1 << j) & cpu_mask) info[j].u.CpuSet.NumaNodeIndex = proc_info->u.NumaNode.NodeNumber; } - proc_info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((BYTE *)proc_info + proc_info->Size); + proc_info = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)proc_info + proc_info->Size); }
- free(proc_info_buffer); - return STATUS_SUCCESS; }
@@ -3054,28 +3006,18 @@ NTSTATUS WINAPI NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS class,
case SystemLogicalProcessorInformation: /* 73 */ { - SYSTEM_LOGICAL_PROCESSOR_INFORMATION *buf; - - /* Each logical processor may use up to 7 entries in returned table: - * core, numa node, package, L1i, L1d, L2, L3 */ - len = 7 * peb->NumberOfProcessors; - buf = malloc( len * sizeof(*buf) ); - if (!buf) + if (!logical_proc_info) { - ret = STATUS_NO_MEMORY; + ret = STATUS_NOT_IMPLEMENTED; break; } - ret = create_logical_proc_info(&buf, NULL, &len, RelationAll); - if (!ret) + len = logical_proc_info_len * sizeof(*logical_proc_info); + if (size >= len) { - if (size >= len) - { - if (!info) ret = STATUS_ACCESS_VIOLATION; - else memcpy( info, buf, len); - } - else ret = STATUS_INFO_LENGTH_MISMATCH; + if (!info) ret = STATUS_ACCESS_VIOLATION; + else memcpy( info, logical_proc_info, len); } - free( buf ); + else ret = STATUS_INFO_LENGTH_MISMATCH; break; }
@@ -3233,31 +3175,34 @@ NTSTATUS WINAPI NtQuerySystemInformationEx( SYSTEM_INFORMATION_CLASS class, { case SystemLogicalProcessorInformationEx: { - SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *buf; + SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *p; + DWORD relation;
if (!query || query_len < sizeof(DWORD)) { ret = STATUS_INVALID_PARAMETER; break; } - - len = 3 * sizeof(*buf); - if (!(buf = malloc( len ))) + if (!logical_proc_info_ex) { - ret = STATUS_NO_MEMORY; + ret = STATUS_NOT_IMPLEMENTED; break; } - ret = create_logical_proc_info(NULL, &buf, &len, *(DWORD *)query); - if (!ret) + + relation = *(DWORD *)query; + len = 0; + p = logical_proc_info_ex; + while ((char *)p != (char *)logical_proc_info_ex + logical_proc_info_ex_size) { - if (size >= len) + if (relation == RelationAll || p->Relationship == relation) { - if (!info) ret = STATUS_ACCESS_VIOLATION; - else memcpy(info, buf, len); + if (len + p->Size <= size) + memcpy( (char *)info + len, p, p->Size ); + len += p->Size; } - else ret = STATUS_INFO_LENGTH_MISMATCH; + p = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)((char *)p + p->Size); } - free( buf ); + ret = size >= len ? STATUS_SUCCESS : STATUS_INFO_LENGTH_MISMATCH; break; }