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; } - - while (*len == *pmax_len) - { - if (!grow_logical_proc_buf(pdata, pmax_len)) 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; + else if (rel == RelationProcessorCore && logical_proc_info[i].Relationship == rel + && logical_proc_info[i].u.Reserved[1] == id) + return TRUE; } - while (ofs < *len) + if (!grow_logical_proc_buf()) return FALSE; + + 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 < 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; - } - - while (*len == *pmax_len) - if (!grow_logical_proc_buf(pdata, pmax_len)) return FALSE; - - (*pdata)[i].Relationship = RelationCache; - (*pdata)[i].ProcessorMask = mask; - (*pdata)[i].u.Cache = *cache; - *len = i + 1; - 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; } - for (ofs = 0; ofs < *len; ) + if (!grow_logical_proc_buf()) return FALSE; + + 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 < 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<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; + + if (!logical_proc_info_ex) return STATUS_NOT_IMPLEMENTED; count = peb->NumberOfProcessors; - cpu_info_size = 3 * sizeof(*proc_info); - if (!(proc_info_buffer = malloc(cpu_info_size))) - return STATUS_NO_MEMORY; - - 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; - } - 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; }