Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
05676e83
Commit
05676e83
authored
May 03, 2022
by
Paul Gofman
Committed by
Alexandre Julliard
May 16, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Collect logical processor info at process start.
Signed-off-by:
Paul Gofman
<
pgofman@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
6aa437de
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
239 additions
and
294 deletions
+239
-294
system.c
dlls/ntdll/unix/system.c
+239
-294
No files found.
dlls/ntdll/unix/system.c
View file @
05676e83
...
...
@@ -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_NO
T_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_NO
T_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
>=
le
n
)
if
(
relation
==
RelationAll
||
p
->
Relationship
==
relatio
n
)
{
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
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment