[PATCH 4/4] ntdll: Collect logical processor info at process start.
Paul Gofman
wine at gitlab.winehq.org
Tue May 3 21:18:02 CDT 2022
From: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Paul Gofman <pgofman at 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;
}
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/32
More information about the wine-devel
mailing list