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
a124064c
Commit
a124064c
authored
Jan 25, 2016
by
Andrew Eikum
Committed by
Alexandre Julliard
Jan 29, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ntdll: Implement SystemLogicalProcessorInformationEx.
Signed-off-by:
Andrew Eikum
<
aeikum@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
3cffe923
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
474 additions
and
205 deletions
+474
-205
process.c
dlls/kernel32/process.c
+5
-0
process.c
dlls/kernel32/tests/process.c
+1
-6
nt.c
dlls/ntdll/nt.c
+412
-194
info.c
dlls/ntdll/tests/info.c
+56
-5
No files found.
dlls/kernel32/process.c
View file @
a124064c
...
...
@@ -3850,6 +3850,11 @@ BOOL WINAPI GetLogicalProcessorInformationEx(LOGICAL_PROCESSOR_RELATIONSHIP rela
status
=
NtQuerySystemInformationEx
(
SystemLogicalProcessorInformationEx
,
&
relationship
,
sizeof
(
relationship
),
buffer
,
*
len
,
len
);
if
(
status
==
STATUS_INFO_LENGTH_MISMATCH
)
{
SetLastError
(
ERROR_INSUFFICIENT_BUFFER
);
return
FALSE
;
}
if
(
status
!=
STATUS_SUCCESS
)
{
SetLastError
(
RtlNtStatusToDosError
(
status
)
);
...
...
dlls/kernel32/tests/process.c
View file @
a124064c
...
...
@@ -3125,25 +3125,20 @@ static void test_GetLogicalProcessorInformationEx(void)
len
=
0
;
ret
=
pGetLogicalProcessorInformationEx
(
RelationProcessorCore
,
NULL
,
&
len
);
todo_wine
{
ok
(
!
ret
&&
GetLastError
()
==
ERROR_INSUFFICIENT_BUFFER
,
"got %d, error %d
\n
"
,
ret
,
GetLastError
());
ok
(
len
>
0
,
"got %u
\n
"
,
len
);
}
len
=
0
;
ret
=
pGetLogicalProcessorInformationEx
(
RelationAll
,
NULL
,
&
len
);
todo_wine
{
ok
(
!
ret
&&
GetLastError
()
==
ERROR_INSUFFICIENT_BUFFER
,
"got %d, error %d
\n
"
,
ret
,
GetLastError
());
ok
(
len
>
0
,
"got %u
\n
"
,
len
);
}
if
(
len
)
{
info
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
len
);
ret
=
pGetLogicalProcessorInformationEx
(
RelationAll
,
info
,
&
len
);
ok
(
ret
,
"got %d, error %d
\n
"
,
ret
,
GetLastError
());
ok
(
info
->
Size
>
0
,
"got %u
\n
"
,
info
->
Size
);
HeapFree
(
GetProcessHeap
(),
0
,
info
);
}
}
START_TEST
(
process
)
{
...
...
dlls/ntdll/nt.c
View file @
a124064c
...
...
@@ -1243,77 +1243,255 @@ void fill_cpu_info(void)
cached_sci
.
Architecture
,
cached_sci
.
Level
,
cached_sci
.
Revision
,
cached_sci
.
FeatureSet
);
}
#ifdef linux
static
inline
BOOL
logical_proc_info_add_by_id
(
SYSTEM_LOGICAL_PROCESSOR_INFORMATION
*
data
,
DWORD
*
len
,
DWORD
max_len
,
LOGICAL_PROCESSOR_RELATIONSHIP
rel
,
DWORD
id
,
DWORD
proc
)
static
BOOL
grow_logical_proc_buf
(
SYSTEM_LOGICAL_PROCESSOR_INFORMATION
**
pdata
,
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
**
pdataex
,
DWORD
*
max_len
)
{
DWORD
i
;
if
(
pdata
)
{
SYSTEM_LOGICAL_PROCESSOR_INFORMATION
*
new_data
;
for
(
i
=
0
;
i
<*
len
;
i
++
)
*
max_len
*=
2
;
new_data
=
RtlReAllocateHeap
(
GetProcessHeap
(),
0
,
*
pdata
,
*
max_len
*
sizeof
(
*
new_data
));
if
(
!
new_data
)
return
FALSE
;
*
pdata
=
new_data
;
}
else
{
if
(
data
[
i
].
Relationship
!=
rel
||
data
[
i
].
u
.
Reserved
[
1
]
!=
id
)
continue
;
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*
new_dataex
;
data
[
i
].
ProcessorMask
|=
(
ULONG_PTR
)
1
<<
proc
;
return
TRUE
;
*
max_len
*=
2
;
new_dataex
=
RtlReAllocateHeap
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
*
pdataex
,
*
max_len
*
sizeof
(
*
new_dataex
));
if
(
!
new_dataex
)
return
FALSE
;
*
pdataex
=
new_dataex
;
}
if
(
*
len
==
max_len
)
return
FALSE
;
return
TRUE
;
}
static
DWORD
log_proc_ex_size_plus
(
DWORD
size
)
{
/* add SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX.Relationship and .Size */
return
sizeof
(
LOGICAL_PROCESSOR_RELATIONSHIP
)
+
sizeof
(
DWORD
)
+
size
;
}
static
inline
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
)
{
if
(
pdata
)
{
DWORD
i
;
if
(
rel
==
RelationProcessorPackage
){
for
(
i
=
0
;
i
<*
len
;
i
++
)
{
if
((
*
pdata
)[
i
].
Relationship
!=
rel
||
(
*
pdata
)[
i
].
u
.
Reserved
[
1
]
!=
id
)
continue
;
(
*
pdata
)[
i
].
ProcessorMask
|=
mask
;
return
TRUE
;
}
}
else
i
=
*
len
;
while
(
*
len
==
*
pmax_len
)
{
if
(
!
grow_logical_proc_buf
(
pdata
,
NULL
,
pmax_len
))
return
FALSE
;
}
(
*
pdata
)[
i
].
Relationship
=
rel
;
(
*
pdata
)[
i
].
ProcessorMask
=
mask
;
/* TODO: set processor core flags */
(
*
pdata
)[
i
].
u
.
Reserved
[
0
]
=
0
;
(
*
pdata
)[
i
].
u
.
Reserved
[
1
]
=
id
;
*
len
=
i
+
1
;
}
else
{
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*
dataex
=
*
pdataex
;
DWORD
ofs
=
0
;
while
(
ofs
<
*
len
)
{
dataex
=
(
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*
)(((
char
*
)
*
pdataex
)
+
ofs
);
if
(
rel
==
RelationProcessorPackage
&&
dataex
->
Relationship
==
rel
&&
dataex
->
u
.
Processor
.
Reserved
[
1
]
==
id
)
{
dataex
->
u
.
Processor
.
GroupMask
[
0
].
Mask
|=
mask
;
return
TRUE
;
}
ofs
+=
dataex
->
Size
;
}
/* TODO: For now, just one group. If more than 64 processors, then we
* need another group. */
while
(
ofs
+
log_proc_ex_size_plus
(
sizeof
(
PROCESSOR_RELATIONSHIP
))
>
*
pmax_len
)
{
if
(
!
grow_logical_proc_buf
(
NULL
,
pdataex
,
pmax_len
))
return
FALSE
;
}
dataex
=
(
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*
)(((
char
*
)
*
pdataex
)
+
ofs
);
dataex
->
Relationship
=
rel
;
dataex
->
Size
=
log_proc_ex_size_plus
(
sizeof
(
PROCESSOR_RELATIONSHIP
));
dataex
->
u
.
Processor
.
Flags
=
0
;
/* TODO */
dataex
->
u
.
Processor
.
EfficiencyClass
=
0
;
dataex
->
u
.
Processor
.
GroupCount
=
1
;
dataex
->
u
.
Processor
.
GroupMask
[
0
].
Mask
=
mask
;
dataex
->
u
.
Processor
.
GroupMask
[
0
].
Group
=
0
;
/* mark for future lookup */
dataex
->
u
.
Processor
.
Reserved
[
0
]
=
0
;
dataex
->
u
.
Processor
.
Reserved
[
1
]
=
id
;
*
len
+=
dataex
->
Size
;
}
data
[
i
].
Relationship
=
rel
;
data
[
i
].
ProcessorMask
=
(
ULONG_PTR
)
1
<<
proc
;
/* TODO: set processor core flags */
data
[
i
].
u
.
Reserved
[
0
]
=
0
;
data
[
i
].
u
.
Reserved
[
1
]
=
id
;
*
len
=
i
+
1
;
return
TRUE
;
}
static
inline
BOOL
logical_proc_info_add_cache
(
SYSTEM_LOGICAL_PROCESSOR_INFORMATION
*
data
,
DWORD
*
len
,
DWORD
max_len
,
ULONG_PTR
mask
,
CACHE_DESCRIPTOR
*
cache
)
static
inline
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
)
{
DWORD
i
;
if
(
pdata
)
{
DWORD
i
;
for
(
i
=
0
;
i
<*
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
,
NULL
,
pmax_len
))
return
FALSE
;
(
*
pdata
)[
i
].
Relationship
=
RelationCache
;
(
*
pdata
)[
i
].
ProcessorMask
=
mask
;
(
*
pdata
)[
i
].
u
.
Cache
=
*
cache
;
*
len
=
i
+
1
;
}
else
{
if
(
data
[
i
].
Relationship
==
RelationCache
&&
data
[
i
].
ProcessorMask
==
mask
&&
data
[
i
].
u
.
Cache
.
Level
==
cache
->
Level
&&
data
[
i
].
u
.
Cache
.
Type
==
cache
->
Type
)
return
TRUE
;
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*
dataex
=
*
pdataex
;
DWORD
ofs
;
for
(
ofs
=
0
;
ofs
<
*
len
;
)
{
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
)
return
TRUE
;
ofs
+=
dataex
->
Size
;
}
while
(
ofs
+
log_proc_ex_size_plus
(
sizeof
(
CACHE_RELATIONSHIP
))
>
*
pmax_len
)
{
if
(
!
grow_logical_proc_buf
(
NULL
,
pdataex
,
pmax_len
))
return
FALSE
;
}
dataex
=
(
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*
)(((
char
*
)
*
pdataex
)
+
ofs
);
dataex
->
Relationship
=
RelationCache
;
dataex
->
Size
=
log_proc_ex_size_plus
(
sizeof
(
CACHE_RELATIONSHIP
));
dataex
->
u
.
Cache
.
Level
=
cache
->
Level
;
dataex
->
u
.
Cache
.
Associativity
=
cache
->
Associativity
;
dataex
->
u
.
Cache
.
LineSize
=
cache
->
LineSize
;
dataex
->
u
.
Cache
.
CacheSize
=
cache
->
Size
;
dataex
->
u
.
Cache
.
Type
=
cache
->
Type
;
dataex
->
u
.
Cache
.
GroupMask
.
Mask
=
mask
;
dataex
->
u
.
Cache
.
GroupMask
.
Group
=
0
;
*
len
+=
dataex
->
Size
;
}
if
(
*
len
==
max_len
)
return
FALSE
;
return
TRUE
;
}
static
inline
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
)
{
if
(
pdata
)
{
while
(
*
len
==
*
pmax_len
)
if
(
!
grow_logical_proc_buf
(
pdata
,
NULL
,
pmax_len
))
return
FALSE
;
(
*
pdata
)[
*
len
].
Relationship
=
RelationNumaNode
;
(
*
pdata
)[
*
len
].
ProcessorMask
=
mask
;
(
*
pdata
)[
*
len
].
u
.
NumaNode
.
NodeNumber
=
node_id
;
(
*
len
)
++
;
}
else
{
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*
dataex
;
while
(
*
len
+
log_proc_ex_size_plus
(
sizeof
(
NUMA_NODE_RELATIONSHIP
))
>
*
pmax_len
)
{
if
(
!
grow_logical_proc_buf
(
NULL
,
pdataex
,
pmax_len
))
return
FALSE
;
}
dataex
=
(
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*
)(((
char
*
)
*
pdataex
)
+
*
len
);
dataex
->
Relationship
=
RelationNumaNode
;
dataex
->
Size
=
log_proc_ex_size_plus
(
sizeof
(
NUMA_NODE_RELATIONSHIP
));
dataex
->
u
.
NumaNode
.
NodeNumber
=
node_id
;
dataex
->
u
.
NumaNode
.
GroupMask
.
Mask
=
mask
;
dataex
->
u
.
NumaNode
.
GroupMask
.
Group
=
0
;
*
len
+=
dataex
->
Size
;
}
data
[
i
].
Relationship
=
RelationCache
;
data
[
i
].
ProcessorMask
=
mask
;
data
[
i
].
u
.
Cache
=
*
cache
;
*
len
=
i
+
1
;
return
TRUE
;
}
static
inline
BOOL
logical_proc_info_add_
numa_node
(
SYSTEM_LOGICAL_PROCESSOR_INFORMATION
*
data
,
DWORD
*
len
,
DWORD
max_len
,
ULONG_PTR
mask
,
DWORD
node_id
)
static
inline
BOOL
logical_proc_info_add_
group
(
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
**
pdataex
,
DWORD
*
len
,
DWORD
*
pmax_len
,
DWORD
num_cpus
,
ULONG_PTR
mask
)
{
if
(
*
len
==
max_len
)
return
FALSE
;
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*
dataex
;
while
(
*
len
+
log_proc_ex_size_plus
(
sizeof
(
GROUP_RELATIONSHIP
))
>
*
pmax_len
)
{
if
(
!
grow_logical_proc_buf
(
NULL
,
pdataex
,
pmax_len
))
return
FALSE
;
}
dataex
=
(
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*
)(((
char
*
)
*
pdataex
)
+
*
len
);
dataex
->
Relationship
=
RelationGroup
;
dataex
->
Size
=
log_proc_ex_size_plus
(
sizeof
(
GROUP_RELATIONSHIP
));
dataex
->
u
.
Group
.
MaximumGroupCount
=
1
;
dataex
->
u
.
Group
.
ActiveGroupCount
=
1
;
dataex
->
u
.
Group
.
GroupInfo
[
0
].
MaximumProcessorCount
=
num_cpus
;
dataex
->
u
.
Group
.
GroupInfo
[
0
].
ActiveProcessorCount
=
num_cpus
;
dataex
->
u
.
Group
.
GroupInfo
[
0
].
ActiveProcessorMask
=
mask
;
*
len
+=
dataex
->
Size
;
data
[
*
len
].
Relationship
=
RelationNumaNode
;
data
[
*
len
].
ProcessorMask
=
mask
;
data
[
*
len
].
u
.
NumaNode
.
NodeNumber
=
node_id
;
(
*
len
)
++
;
return
TRUE
;
}
static
NTSTATUS
create_logical_proc_info
(
SYSTEM_LOGICAL_PROCESSOR_INFORMATION
**
data
,
DWORD
*
max_len
)
#ifdef linux
/* 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
)
{
static
const
char
core_info
[]
=
"/sys/devices/system/cpu/cpu%u/%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
;
DWORD
len
=
0
,
beg
,
end
,
i
,
j
,
r
,
num_cpus
=
0
;
char
op
,
name
[
MAX_PATH
];
ULONG_PTR
all_cpus_mask
=
0
;
fcpu_list
=
fopen
(
"/sys/devices/system/cpu/online"
,
"r"
);
if
(
!
fcpu_list
)
...
...
@@ -1334,52 +1512,32 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
continue
;
}
sprintf
(
name
,
core_info
,
i
,
"
cor
e_id"
);
sprintf
(
name
,
core_info
,
i
,
"
physical_packag
e_id"
);
f
=
fopen
(
name
,
"r"
);
if
(
f
)
{
fscanf
(
f
,
"%u"
,
&
r
);
fclose
(
f
);
}
else
r
=
i
;
if
(
!
logical_proc_info_add_by_id
(
*
data
,
&
len
,
*
max_len
,
RelationProcessorCore
,
r
,
i
))
else
r
=
0
;
if
(
!
logical_proc_info_add_by_id
(
data
,
dataex
,
&
len
,
max_len
,
RelationProcessorPackage
,
r
,
1
<<
i
))
{
SYSTEM_LOGICAL_PROCESSOR_INFORMATION
*
new_data
;
*
max_len
*=
2
;
new_data
=
RtlReAllocateHeap
(
GetProcessHeap
(),
0
,
*
data
,
*
max_len
*
sizeof
(
*
new_data
));
if
(
!
new_data
)
{
fclose
(
fcpu_list
);
return
STATUS_NO_MEMORY
;
}
*
data
=
new_data
;
logical_proc_info_add_by_id
(
*
data
,
&
len
,
*
max_len
,
RelationProcessorCore
,
r
,
i
);
fclose
(
fcpu_list
);
return
STATUS_NO_MEMORY
;
}
sprintf
(
name
,
core_info
,
i
,
"
physical_packag
e_id"
);
sprintf
(
name
,
core_info
,
i
,
"
cor
e_id"
);
f
=
fopen
(
name
,
"r"
);
if
(
f
)
{
fscanf
(
f
,
"%u"
,
&
r
);
fclose
(
f
);
}
else
r
=
0
;
if
(
!
logical_proc_info_add_by_id
(
*
data
,
&
len
,
*
max_len
,
RelationProcessorPackage
,
r
,
i
))
else
r
=
i
;
if
(
!
logical_proc_info_add_by_id
(
data
,
dataex
,
&
len
,
max_len
,
RelationProcessorCore
,
r
,
1
<<
i
))
{
SYSTEM_LOGICAL_PROCESSOR_INFORMATION
*
new_data
;
*
max_len
*=
2
;
new_data
=
RtlReAllocateHeap
(
GetProcessHeap
(),
0
,
*
data
,
*
max_len
*
sizeof
(
*
new_data
));
if
(
!
new_data
)
{
fclose
(
fcpu_list
);
return
STATUS_NO_MEMORY
;
}
*
data
=
new_data
;
logical_proc_info_add_by_id
(
*
data
,
&
len
,
*
max_len
,
RelationProcessorPackage
,
r
,
i
);
fclose
(
fcpu_list
);
return
STATUS_NO_MEMORY
;
}
for
(
j
=
0
;
j
<
4
;
j
++
)
...
...
@@ -1440,47 +1598,39 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
else
cache
.
Type
=
CacheUnified
;
if
(
!
logical_proc_info_add_cache
(
*
data
,
&
len
,
*
max_len
,
mask
,
&
cache
))
if
(
!
logical_proc_info_add_cache
(
data
,
dataex
,
&
len
,
max_len
,
mask
,
&
cache
))
{
SYSTEM_LOGICAL_PROCESSOR_INFORMATION
*
new_data
;
*
max_len
*=
2
;
new_data
=
RtlReAllocateHeap
(
GetProcessHeap
(),
0
,
*
data
,
*
max_len
*
sizeof
(
*
new_data
));
if
(
!
new_data
)
{
fclose
(
fcpu_list
);
return
STATUS_NO_MEMORY
;
}
*
data
=
new_data
;
logical_proc_info_add_cache
(
*
data
,
&
len
,
*
max_len
,
mask
,
&
cache
);
fclose
(
fcpu_list
);
return
STATUS_NO_MEMORY
;
}
}
}
}
fclose
(
fcpu_list
);
if
(
data
){
for
(
i
=
0
;
i
<
len
;
i
++
){
if
((
*
data
)[
i
].
Relationship
==
RelationProcessorCore
){
all_cpus_mask
|=
(
*
data
)[
i
].
ProcessorMask
;
++
num_cpus
;
}
}
}
else
{
for
(
i
=
0
;
i
<
len
;
){
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*
infoex
=
(
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*
)(((
char
*
)
*
dataex
)
+
i
);
if
(
infoex
->
Relationship
==
RelationProcessorCore
){
all_cpus_mask
|=
infoex
->
u
.
Processor
.
GroupMask
[
0
].
Mask
;
++
num_cpus
;
}
i
+=
infoex
->
Size
;
}
}
fnuma_list
=
fopen
(
"/sys/devices/system/node/online"
,
"r"
);
if
(
!
fnuma_list
)
{
ULONG_PTR
mask
=
0
;
for
(
i
=
0
;
i
<
len
;
i
++
)
if
((
*
data
)[
i
].
Relationship
==
RelationProcessorCore
)
mask
|=
(
*
data
)[
i
].
ProcessorMask
;
if
(
len
==
*
max_len
)
{
SYSTEM_LOGICAL_PROCESSOR_INFORMATION
*
new_data
;
*
max_len
*=
2
;
new_data
=
RtlReAllocateHeap
(
GetProcessHeap
(),
0
,
*
data
,
*
max_len
*
sizeof
(
*
new_data
));
if
(
!
new_data
)
return
STATUS_NO_MEMORY
;
*
data
=
new_data
;
}
logical_proc_info_add_numa_node
(
*
data
,
&
len
,
*
max_len
,
mask
,
0
);
if
(
!
logical_proc_info_add_numa_node
(
data
,
dataex
,
&
len
,
max_len
,
all_cpus_mask
,
0
))
return
STATUS_NO_MEMORY
;
}
else
{
...
...
@@ -1506,151 +1656,163 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
}
fclose
(
f
);
if
(
len
==
*
max_len
)
if
(
!
logical_proc_info_add_numa_node
(
data
,
dataex
,
&
len
,
max_len
,
mask
,
i
)
)
{
SYSTEM_LOGICAL_PROCESSOR_INFORMATION
*
new_data
;
*
max_len
*=
2
;
new_data
=
RtlReAllocateHeap
(
GetProcessHeap
(),
0
,
*
data
,
*
max_len
*
sizeof
(
*
new_data
));
if
(
!
new_data
)
{
fclose
(
fnuma_list
);
return
STATUS_NO_MEMORY
;
}
*
data
=
new_data
;
fclose
(
fnuma_list
);
return
STATUS_NO_MEMORY
;
}
logical_proc_info_add_numa_node
(
*
data
,
&
len
,
*
max_len
,
mask
,
i
);
}
}
fclose
(
fnuma_list
);
}
*
max_len
=
len
*
sizeof
(
**
data
);
if
(
dataex
)
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
;
return
STATUS_SUCCESS
;
}
#elif defined(__APPLE__)
static
NTSTATUS
create_logical_proc_info
(
SYSTEM_LOGICAL_PROCESSOR_INFORMATION
**
data
,
DWORD
*
max_len
)
/* 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
len
=
0
,
i
,
j
,
k
;
DWORD
c
ores_no
,
lcpu_no
,
lcpu_per_core
,
cores_per_package
,
assoc
;
size_t
size
;
ULONG_PTR
mask
;
DWORD
pkgs_no
,
cores_no
,
lcpu_no
,
lcpu_per_core
,
cores_per_package
,
assoc
,
len
=
0
;
DWORD
c
ache_ctrs
[
10
]
=
{
0
}
;
ULONG_PTR
all_cpus_mask
=
0
;
CACHE_DESCRIPTOR
cache
[
10
]
;
LONGLONG
cache_size
,
cache_line_size
,
cache_sharing
[
10
];
CACHE_DESCRIPTOR
cache
[
4
];
size_t
size
;
DWORD
p
,
i
,
j
,
k
;
lcpu_no
=
NtCurrentTeb
()
->
Peb
->
NumberOfProcessors
;
size
=
sizeof
(
pkgs_no
);
if
(
sysctlbyname
(
"hw.packages"
,
&
pkgs_no
,
&
size
,
NULL
,
0
))
pkgs_no
=
1
;
size
=
sizeof
(
cores_no
);
if
(
sysctlbyname
(
"
machdep.cpu.core_count
"
,
&
cores_no
,
&
size
,
NULL
,
0
))
if
(
sysctlbyname
(
"
hw.physicalcpu
"
,
&
cores_no
,
&
size
,
NULL
,
0
))
cores_no
=
lcpu_no
;
lcpu_per_core
=
lcpu_no
/
cores_no
;
for
(
i
=
0
;
i
<
cores_no
;
i
++
)
{
mask
=
0
;
for
(
j
=
lcpu_per_core
*
i
;
j
<
lcpu_per_core
*
(
i
+
1
);
j
++
)
mask
|=
(
ULONG_PTR
)
1
<<
j
;
(
*
data
)[
len
].
Relationship
=
RelationProcessorCore
;
(
*
data
)[
len
].
ProcessorMask
=
mask
;
(
*
data
)[
len
].
u
.
ProcessorCore
.
Flags
=
0
;
/* TODO */
len
++
;
}
size
=
sizeof
(
cores_per_package
);
if
(
sysctlbyname
(
"machdep.cpu.cores_per_package"
,
&
cores_per_package
,
&
size
,
NULL
,
0
))
cores_per_package
=
lcpu_no
;
for
(
i
=
0
;
i
<
(
lcpu_no
+
cores_per_package
-
1
)
/
cores_per_package
;
i
++
)
{
mask
=
0
;
for
(
j
=
cores_per_package
*
i
;
j
<
cores_per_package
*
(
i
+
1
)
&&
j
<
lcpu_no
;
j
++
)
mask
|=
(
ULONG_PTR
)
1
<<
j
;
TRACE
(
"%u logical CPUs from %u physical cores across %u packages
\n
"
,
lcpu_no
,
cores_no
,
pkgs_no
);
(
*
data
)[
len
].
Relationship
=
RelationProcessorPackage
;
(
*
data
)[
len
].
ProcessorMask
=
mask
;
len
++
;
}
lcpu_per_core
=
lcpu_no
/
cores_no
;
cores_per_package
=
cores_no
/
pkgs_no
;
memset
(
cache
,
0
,
sizeof
(
cache
));
cache
[
0
].
Level
=
1
;
cache
[
0
].
Type
=
CacheInstruction
;
cache
[
1
].
Level
=
1
;
cache
[
1
].
Type
=
CacheData
;
cache
[
2
].
Level
=
2
;
cache
[
2
].
Type
=
CacheUnified
;
cache
[
3
].
Level
=
3
;
cache
[
1
].
Type
=
CacheInstruction
;
cache
[
1
].
Associativity
=
8
;
/* reasonable default */
cache
[
1
].
LineSize
=
0x40
;
/* reasonable default */
cache
[
2
].
Level
=
1
;
cache
[
2
].
Type
=
CacheData
;
cache
[
2
].
Associativity
=
8
;
cache
[
2
].
LineSize
=
0x40
;
cache
[
3
].
Level
=
2
;
cache
[
3
].
Type
=
CacheUnified
;
cache
[
3
].
Associativity
=
8
;
cache
[
3
].
LineSize
=
0x40
;
cache
[
4
].
Level
=
3
;
cache
[
4
].
Type
=
CacheUnified
;
cache
[
4
].
Associativity
=
12
;
cache
[
4
].
LineSize
=
0x40
;
size
=
sizeof
(
cache_line_size
);
if
(
!
sysctlbyname
(
"hw.cachelinesize"
,
&
cache_line_size
,
&
size
,
NULL
,
0
))
{
for
(
i
=
0
;
i
<
4
;
i
++
)
for
(
i
=
1
;
i
<
5
;
i
++
)
cache
[
i
].
LineSize
=
cache_line_size
;
}
/* TODO: set associativity for all caches */
/* TODO: set a
ctual a
ssociativity for all caches */
size
=
sizeof
(
assoc
);
if
(
!
sysctlbyname
(
"machdep.cpu.cache.L2_associativity"
,
&
assoc
,
&
size
,
NULL
,
0
))
cache
[
2
].
Associativity
=
assoc
;
cache
[
3
].
Associativity
=
assoc
;
size
=
sizeof
(
cache_size
);
if
(
!
sysctlbyname
(
"hw.l1icachesize"
,
&
cache_size
,
&
size
,
NULL
,
0
))
cache
[
0
].
Size
=
cache_size
;
cache
[
1
].
Size
=
cache_size
;
size
=
sizeof
(
cache_size
);
if
(
!
sysctlbyname
(
"hw.l1dcachesize"
,
&
cache_size
,
&
size
,
NULL
,
0
))
cache
[
1
].
Size
=
cache_size
;
cache
[
2
].
Size
=
cache_size
;
size
=
sizeof
(
cache_size
);
if
(
!
sysctlbyname
(
"hw.l2cachesize"
,
&
cache_size
,
&
size
,
NULL
,
0
))
cache
[
2
].
Size
=
cache_size
;
cache
[
3
].
Size
=
cache_size
;
size
=
sizeof
(
cache_size
);
if
(
!
sysctlbyname
(
"hw.l3cachesize"
,
&
cache_size
,
&
size
,
NULL
,
0
))
cache
[
3
].
Size
=
cache_size
;
cache
[
4
].
Size
=
cache_size
;
size
=
sizeof
(
cache_sharing
);
if
(
!
sysctlbyname
(
"hw.cacheconfig"
,
cache_sharing
,
&
size
,
NULL
,
0
))
{
for
(
i
=
1
;
i
<
4
&&
i
<
size
/
sizeof
(
*
cache_sharing
);
i
++
)
{
if
(
!
cache_sharing
[
i
]
||
!
cache
[
i
].
Size
)
continue
;
if
(
sysctlbyname
(
"hw.cacheconfig"
,
cache_sharing
,
&
size
,
NULL
,
0
)
<
0
){
cache_sharing
[
1
]
=
lcpu_per_core
;
cache_sharing
[
2
]
=
lcpu_per_core
;
cache_sharing
[
3
]
=
lcpu_per_core
;
cache_sharing
[
4
]
=
lcpu_no
;
}
else
{
/* in cache[], indexes 1 and 2 are l1 caches */
cache_sharing
[
4
]
=
cache_sharing
[
3
];
cache_sharing
[
3
]
=
cache_sharing
[
2
];
cache_sharing
[
2
]
=
cache_sharing
[
1
];
}
for
(
j
=
0
;
j
<
lcpu_no
/
cache_sharing
[
i
];
j
++
)
{
mask
=
0
;
for
(
k
=
j
*
cache_sharing
[
i
];
k
<
lcpu_no
&&
k
<
(
j
+
1
)
*
cache_sharing
[
i
];
k
++
)
mask
|=
(
ULONG_PTR
)
1
<<
k
;
for
(
p
=
0
;
p
<
pkgs_no
;
++
p
){
for
(
j
=
0
;
j
<
cores_per_package
&&
p
*
cores_per_package
+
j
<
cores_no
;
++
j
){
ULONG_PTR
mask
=
0
;
if
(
i
==
1
&&
cache
[
0
].
Size
)
{
(
*
data
)[
len
].
Relationship
=
RelationCache
;
(
*
data
)[
len
].
ProcessorMask
=
mask
;
(
*
data
)[
len
].
u
.
Cache
=
cache
[
0
];
len
++
;
for
(
k
=
0
;
k
<
lcpu_per_core
;
++
k
)
mask
|=
(
ULONG_PTR
)
1
<<
(
j
*
lcpu_per_core
+
k
);
all_cpus_mask
|=
mask
;
/* add to package */
if
(
!
logical_proc_info_add_by_id
(
data
,
dataex
,
&
len
,
max_len
,
RelationProcessorPackage
,
p
,
mask
))
return
STATUS_NO_MEMORY
;
/* add new core */
if
(
!
logical_proc_info_add_by_id
(
data
,
dataex
,
&
len
,
max_len
,
RelationProcessorCore
,
p
,
mask
))
return
STATUS_NO_MEMORY
;
for
(
i
=
1
;
i
<
5
;
++
i
){
if
(
cache_ctrs
[
i
]
==
0
&&
cache
[
i
].
Size
>
0
){
mask
=
0
;
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
]))
return
STATUS_NO_MEMORY
;
}
(
*
data
)[
len
].
Relationship
=
RelationCach
e
;
(
*
data
)[
len
].
ProcessorMask
=
mask
;
(
*
data
)[
len
].
u
.
Cache
=
cache
[
i
];
len
++
;
cache_ctrs
[
i
]
+=
lcpu_per_cor
e
;
if
(
cache_ctrs
[
i
]
==
cache_sharing
[
i
])
cache_ctrs
[
i
]
=
0
;
}
}
}
mask
=
0
;
for
(
i
=
0
;
i
<
lcpu_no
;
i
++
)
mask
|=
(
ULONG_PTR
)
1
<<
i
;
(
*
data
)[
len
].
Relationship
=
RelationNumaNode
;
(
*
data
)[
len
].
ProcessorMask
=
mask
;
(
*
data
)[
len
].
u
.
NumaNode
.
NodeNumber
=
0
;
len
++
;
/* 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
))
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
;
*
max_len
=
len
*
sizeof
(
**
data
);
return
STATUS_SUCCESS
;
}
#else
static
NTSTATUS
create_logical_proc_info
(
SYSTEM_LOGICAL_PROCESSOR_INFORMATION
**
data
,
DWORD
*
max_len
)
static
NTSTATUS
create_logical_proc_info
(
SYSTEM_LOGICAL_PROCESSOR_INFORMATION
**
data
,
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
**
dataex
,
DWORD
*
max_len
)
{
FIXME
(
"stub
\n
"
);
return
STATUS_NOT_IMPLEMENTED
;
...
...
@@ -2139,7 +2301,7 @@ NTSTATUS WINAPI NtQuerySystemInformation(
break
;
}
ret
=
create_logical_proc_info
(
&
buf
,
&
len
);
ret
=
create_logical_proc_info
(
&
buf
,
NULL
,
&
len
);
if
(
ret
!=
STATUS_SUCCESS
)
{
RtlFreeHeap
(
GetProcessHeap
(),
0
,
buf
);
...
...
@@ -2178,9 +2340,65 @@ NTSTATUS WINAPI NtQuerySystemInformation(
NTSTATUS
WINAPI
NtQuerySystemInformationEx
(
SYSTEM_INFORMATION_CLASS
SystemInformationClass
,
void
*
Query
,
ULONG
QueryLength
,
void
*
SystemInformation
,
ULONG
Length
,
ULONG
*
ResultLength
)
{
FIXME
(
"(0x%08x,%p,%u,%p,%u,%p) stub
\n
"
,
SystemInformationClass
,
Query
,
QueryLength
,
SystemInformation
,
ULONG
len
;
NTSTATUS
ret
=
STATUS_NOT_IMPLEMENTED
;
TRACE
(
"(0x%08x,%p,%u,%p,%u,%p) stub
\n
"
,
SystemInformationClass
,
Query
,
QueryLength
,
SystemInformation
,
Length
,
ResultLength
);
return
STATUS_NOT_IMPLEMENTED
;
switch
(
SystemInformationClass
)
{
case
SystemLogicalProcessorInformationEx
:
{
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*
buf
;
if
(
!
Query
||
QueryLength
<
sizeof
(
DWORD
))
{
ret
=
STATUS_INVALID_PARAMETER
;
break
;
}
if
(
*
(
DWORD
*
)
Query
!=
RelationAll
)
FIXME
(
"Relationship filtering not implemented: 0x%x
\n
"
,
*
(
DWORD
*
)
Query
);
len
=
3
*
sizeof
(
*
buf
);
buf
=
RtlAllocateHeap
(
GetProcessHeap
(),
0
,
len
);
if
(
!
buf
)
{
ret
=
STATUS_NO_MEMORY
;
break
;
}
ret
=
create_logical_proc_info
(
NULL
,
&
buf
,
&
len
);
if
(
ret
!=
STATUS_SUCCESS
)
{
RtlFreeHeap
(
GetProcessHeap
(),
0
,
buf
);
break
;
}
if
(
Length
>=
len
)
{
if
(
!
SystemInformation
)
ret
=
STATUS_ACCESS_VIOLATION
;
else
memcpy
(
SystemInformation
,
buf
,
len
);
}
else
ret
=
STATUS_INFO_LENGTH_MISMATCH
;
RtlFreeHeap
(
GetProcessHeap
(),
0
,
buf
);
break
;
}
default:
FIXME
(
"(0x%08x,%p,%u,%p,%u,%p) stub
\n
"
,
SystemInformationClass
,
Query
,
QueryLength
,
SystemInformation
,
Length
,
ResultLength
);
break
;
}
if
(
ResultLength
)
*
ResultLength
=
len
;
return
ret
;
}
/******************************************************************************
...
...
dlls/ntdll/tests/info.c
View file @
a124064c
...
...
@@ -721,24 +721,23 @@ static void test_query_logicalprocex(void)
len
=
0
;
relationship
=
RelationProcessorCore
;
status
=
pNtQuerySystemInformationEx
(
SystemLogicalProcessorInformationEx
,
&
relationship
,
sizeof
(
relationship
),
NULL
,
0
,
&
len
);
todo_wine
{
ok
(
status
==
STATUS_INFO_LENGTH_MISMATCH
,
"got 0x%08x
\n
"
,
status
);
ok
(
len
>
0
,
"got %u
\n
"
,
len
);
}
len
=
0
;
relationship
=
RelationAll
;
status
=
pNtQuerySystemInformationEx
(
SystemLogicalProcessorInformationEx
,
&
relationship
,
sizeof
(
relationship
),
NULL
,
0
,
&
len
);
todo_wine
{
ok
(
status
==
STATUS_INFO_LENGTH_MISMATCH
,
"got 0x%08x
\n
"
,
status
);
ok
(
len
>
0
,
"got %u
\n
"
,
len
);
}
len2
=
0
;
ret
=
pGetLogicalProcessorInformationEx
(
RelationAll
,
NULL
,
&
len2
);
todo_wine
ok
(
!
ret
&&
GetLastError
()
==
ERROR_INSUFFICIENT_BUFFER
,
"got %d, error %d
\n
"
,
ret
,
GetLastError
());
ok
(
len
==
len2
,
"got %u, expected %u
\n
"
,
len2
,
len
);
if
(
len
&&
len
==
len2
)
{
int
j
,
i
;
infoex
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
len
);
infoex2
=
HeapAlloc
(
GetProcessHeap
(),
HEAP_ZERO_MEMORY
,
len
);
...
...
@@ -750,6 +749,58 @@ todo_wine
ok
(
ret
,
"got %d, error %d
\n
"
,
ret
,
GetLastError
());
ok
(
!
memcmp
(
infoex
,
infoex2
,
len
),
"returned info data mismatch
\n
"
);
for
(
i
=
0
;
i
<
len
;
){
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
*
ex
=
(
void
*
)(((
char
*
)
infoex
)
+
i
);
ok
(
ex
->
Relationship
>=
RelationProcessorCore
&&
ex
->
Relationship
<=
RelationGroup
,
"Got invalid relationship value: 0x%x
\n
"
,
ex
->
Relationship
);
trace
(
"infoex[%u].Size: %u
\n
"
,
i
,
ex
->
Size
);
switch
(
ex
->
Relationship
){
case
RelationProcessorCore
:
case
RelationProcessorPackage
:
trace
(
"infoex[%u].Relationship: 0x%x (Core == 0x0 or Package == 0x3)
\n
"
,
i
,
ex
->
Relationship
);
trace
(
"infoex[%u].Processor.Flags: 0x%x
\n
"
,
i
,
ex
->
Processor
.
Flags
);
trace
(
"infoex[%u].Processor.EfficiencyClass: 0x%x
\n
"
,
i
,
ex
->
Processor
.
EfficiencyClass
);
trace
(
"infoex[%u].Processor.GroupCount: 0x%x
\n
"
,
i
,
ex
->
Processor
.
GroupCount
);
for
(
j
=
0
;
j
<
ex
->
Processor
.
GroupCount
;
++
j
){
trace
(
"infoex[%u].Processor.GroupMask[%u].Mask: 0x%lx
\n
"
,
i
,
j
,
ex
->
Processor
.
GroupMask
[
j
].
Mask
);
trace
(
"infoex[%u].Processor.GroupMask[%u].Group: 0x%x
\n
"
,
i
,
j
,
ex
->
Processor
.
GroupMask
[
j
].
Group
);
}
break
;
case
RelationNumaNode
:
trace
(
"infoex[%u].Relationship: 0x%x (NumaNode)
\n
"
,
i
,
ex
->
Relationship
);
trace
(
"infoex[%u].NumaNode.NodeNumber: 0x%x
\n
"
,
i
,
ex
->
NumaNode
.
NodeNumber
);
trace
(
"infoex[%u].NumaNode.GroupMask.Mask: 0x%lx
\n
"
,
i
,
ex
->
NumaNode
.
GroupMask
.
Mask
);
trace
(
"infoex[%u].NumaNode.GroupMask.Group: 0x%x
\n
"
,
i
,
ex
->
NumaNode
.
GroupMask
.
Group
);
break
;
case
RelationCache
:
trace
(
"infoex[%u].Relationship: 0x%x (Cache)
\n
"
,
i
,
ex
->
Relationship
);
trace
(
"infoex[%u].Cache.Level: 0x%x
\n
"
,
i
,
ex
->
Cache
.
Level
);
trace
(
"infoex[%u].Cache.Associativity: 0x%x
\n
"
,
i
,
ex
->
Cache
.
Associativity
);
trace
(
"infoex[%u].Cache.LineSize: 0x%x
\n
"
,
i
,
ex
->
Cache
.
LineSize
);
trace
(
"infoex[%u].Cache.CacheSize: 0x%x
\n
"
,
i
,
ex
->
Cache
.
CacheSize
);
trace
(
"infoex[%u].Cache.Type: 0x%x
\n
"
,
i
,
ex
->
Cache
.
Type
);
trace
(
"infoex[%u].Cache.GroupMask.Mask: 0x%lx
\n
"
,
i
,
ex
->
Cache
.
GroupMask
.
Mask
);
trace
(
"infoex[%u].Cache.GroupMask.Group: 0x%x
\n
"
,
i
,
ex
->
Cache
.
GroupMask
.
Group
);
break
;
case
RelationGroup
:
trace
(
"infoex[%u].Relationship: 0x%x (Group)
\n
"
,
i
,
ex
->
Relationship
);
trace
(
"infoex[%u].Group.MaximumGroupCount: 0x%x
\n
"
,
i
,
ex
->
Group
.
MaximumGroupCount
);
trace
(
"infoex[%u].Group.ActiveGroupCount: 0x%x
\n
"
,
i
,
ex
->
Group
.
ActiveGroupCount
);
for
(
j
=
0
;
j
<
ex
->
Group
.
ActiveGroupCount
;
++
j
){
trace
(
"infoex[%u].Group.GroupInfo[%u].MaximumProcessorCount: 0x%x
\n
"
,
i
,
j
,
ex
->
Group
.
GroupInfo
[
j
].
MaximumProcessorCount
);
trace
(
"infoex[%u].Group.GroupInfo[%u].ActiveProcessorCount: 0x%x
\n
"
,
i
,
j
,
ex
->
Group
.
GroupInfo
[
j
].
ActiveProcessorCount
);
trace
(
"infoex[%u].Group.GroupInfo[%u].ActiveProcessorMask: 0x%lx
\n
"
,
i
,
j
,
ex
->
Group
.
GroupInfo
[
j
].
ActiveProcessorMask
);
}
break
;
default:
break
;
}
i
+=
ex
->
Size
;
}
HeapFree
(
GetProcessHeap
(),
0
,
infoex
);
HeapFree
(
GetProcessHeap
(),
0
,
infoex2
);
}
...
...
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