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
9d58aac4
Commit
9d58aac4
authored
Sep 23, 2015
by
Michael Müller
Committed by
Alexandre Julliard
Oct 02, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernel32: Implement Set/GetThreadGroupAffinity and add tests.
Signed-off-by:
Michael Müller
<
michael@fds-team.de
>
Signed-off-by:
Sebastian Lackner
<
sebastian@fds-team.de
>
parent
55ae0906
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
156 additions
and
36 deletions
+156
-36
kernel32.spec
dlls/kernel32/kernel32.spec
+2
-2
thread.c
dlls/kernel32/tests/thread.c
+108
-34
thread.c
dlls/kernel32/thread.c
+46
-0
No files found.
dlls/kernel32/kernel32.spec
View file @
9d58aac4
...
...
@@ -844,7 +844,7 @@
@ stdcall GetTempPathW(long ptr)
@ stdcall GetThreadContext(long ptr)
@ stdcall GetThreadErrorMode()
# @ stub GetThreadGroupAffinity
@ stdcall GetThreadGroupAffinity(long ptr)
@ stdcall GetThreadId(ptr)
# @ stub GetThreadIdealProcessorEx
@ stdcall GetThreadIOPendingFlag(long ptr)
...
...
@@ -1443,7 +1443,7 @@
@ stdcall SetThreadContext(long ptr)
@ stdcall SetThreadErrorMode(long ptr)
@ stdcall SetThreadExecutionState(long)
# @ stub SetThreadGroupAffinity
@ stdcall SetThreadGroupAffinity(long ptr ptr)
@ stdcall SetThreadIdealProcessor(long long)
# @ stub SetThreadIdealProcessorEx
@ stdcall SetThreadLocale(long)
...
...
dlls/kernel32/tests/thread.c
View file @
9d58aac4
...
...
@@ -99,6 +99,9 @@ static void (WINAPI *pSubmitThreadpoolWork)(PTP_WORK);
static
void
(
WINAPI
*
pWaitForThreadpoolWorkCallbacks
)(
PTP_WORK
,
BOOL
);
static
void
(
WINAPI
*
pCloseThreadpoolWork
)(
PTP_WORK
);
static
NTSTATUS
(
WINAPI
*
pNtQueryInformationThread
)(
HANDLE
,
THREADINFOCLASS
,
PVOID
,
ULONG
,
PULONG
);
static
BOOL
(
WINAPI
*
pGetThreadGroupAffinity
)(
HANDLE
,
GROUP_AFFINITY
*
);
static
BOOL
(
WINAPI
*
pSetThreadGroupAffinity
)(
HANDLE
,
const
GROUP_AFFINITY
*
,
GROUP_AFFINITY
*
);
static
NTSTATUS
(
WINAPI
*
pNtSetInformationThread
)(
HANDLE
,
THREADINFOCLASS
,
LPCVOID
,
ULONG
);
static
HANDLE
create_target_process
(
const
char
*
arg
)
{
...
...
@@ -877,6 +880,15 @@ static VOID test_thread_processor(void)
retMask
=
SetThreadAffinityMask
(
curthread
,
~
0
);
ok
(
broken
(
retMask
==
0
)
||
retMask
==
processMask
,
"SetThreadAffinityMask(thread,-1) failed to request all processors.
\n
"
);
if
(
retMask
==
processMask
)
{
/* Show that the "all processors" flag is handled in ntdll */
DWORD_PTR
mask
=
~
0u
;
NTSTATUS
status
=
pNtSetInformationThread
(
curthread
,
ThreadAffinityMask
,
&
mask
,
sizeof
(
mask
));
ok
(
status
==
STATUS_SUCCESS
,
"Expected STATUS_SUCCESS in NtSetInformationThread, got %x
\n
"
,
status
);
}
if
(
retMask
==
processMask
&&
sizeof
(
ULONG_PTR
)
>
sizeof
(
ULONG
))
{
/* only the low 32-bits matter */
...
...
@@ -886,41 +898,99 @@ static VOID test_thread_processor(void)
ok
(
retMask
==
processMask
,
"SetThreadAffinityMask failed
\n
"
);
}
/* NOTE: This only works on WinNT/2000/XP) */
if
(
pSetThreadIdealProcessor
)
{
SetLastError
(
0xdeadbeef
);
error
=
pSetThreadIdealProcessor
(
curthread
,
0
);
if
(
GetLastError
()
==
ERROR_CALL_NOT_IMPLEMENTED
)
{
win_skip
(
"SetThreadIdealProcessor is not implemented
\n
"
);
return
;
}
ok
(
error
!=-
1
,
"SetThreadIdealProcessor failed
\n
"
);
if
(
is_wow64
)
{
SetLastError
(
0xdeadbeef
);
error
=
pSetThreadIdealProcessor
(
curthread
,
MAXIMUM_PROCESSORS
+
1
);
todo_wine
ok
(
error
!=-
1
,
"SetThreadIdealProcessor failed for %u on Wow64
\n
"
,
MAXIMUM_PROCESSORS
+
1
);
SetLastError
(
0xdeadbeef
);
error
=
pSetThreadIdealProcessor
(
curthread
,
65
);
ok
(
error
==-
1
,
"SetThreadIdealProcessor succeeded with an illegal processor #
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Expected ERROR_INVALID_PARAMETER, got %d
\n
"
,
GetLastError
());
}
else
{
SetLastError
(
0xdeadbeef
);
error
=
pSetThreadIdealProcessor
(
curthread
,
MAXIMUM_PROCESSORS
+
1
);
ok
(
error
==-
1
,
"SetThreadIdealProcessor succeeded with an illegal processor #
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Expected ERROR_INVALID_PARAMETER, got %d
\n
"
,
GetLastError
());
}
if
(
pSetThreadIdealProcessor
)
{
SetLastError
(
0xdeadbeef
);
error
=
pSetThreadIdealProcessor
(
curthread
,
0
);
if
(
GetLastError
()
!=
ERROR_CALL_NOT_IMPLEMENTED
)
{
ok
(
error
!=-
1
,
"SetThreadIdealProcessor failed
\n
"
);
if
(
is_wow64
)
{
SetLastError
(
0xdeadbeef
);
error
=
pSetThreadIdealProcessor
(
curthread
,
MAXIMUM_PROCESSORS
+
1
);
todo_wine
ok
(
error
!=-
1
,
"SetThreadIdealProcessor failed for %u on Wow64
\n
"
,
MAXIMUM_PROCESSORS
+
1
);
SetLastError
(
0xdeadbeef
);
error
=
pSetThreadIdealProcessor
(
curthread
,
65
);
ok
(
error
==-
1
,
"SetThreadIdealProcessor succeeded with an illegal processor #
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Expected ERROR_INVALID_PARAMETER, got %d
\n
"
,
GetLastError
());
}
else
{
SetLastError
(
0xdeadbeef
);
error
=
pSetThreadIdealProcessor
(
curthread
,
MAXIMUM_PROCESSORS
+
1
);
ok
(
error
==-
1
,
"SetThreadIdealProcessor succeeded with an illegal processor #
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Expected ERROR_INVALID_PARAMETER, got %d
\n
"
,
GetLastError
());
}
error
=
pSetThreadIdealProcessor
(
curthread
,
MAXIMUM_PROCESSORS
);
ok
(
error
!=-
1
,
"SetThreadIdealProcessor failed
\n
"
);
}
else
win_skip
(
"SetThreadIdealProcessor is not implemented
\n
"
);
}
error
=
pSetThreadIdealProcessor
(
curthread
,
MAXIMUM_PROCESSORS
);
ok
(
error
!=-
1
,
"SetThreadIdealProcessor failed
\n
"
);
}
if
(
pGetThreadGroupAffinity
&&
pSetThreadGroupAffinity
)
{
GROUP_AFFINITY
affinity
,
affinity_new
;
NTSTATUS
status
;
memset
(
&
affinity
,
0
,
sizeof
(
affinity
));
ok
(
pGetThreadGroupAffinity
(
curthread
,
&
affinity
),
"GetThreadGroupAffinity failed
\n
"
);
SetLastError
(
0xdeadbeef
);
ok
(
!
pGetThreadGroupAffinity
(
curthread
,
NULL
),
"GetThreadGroupAffinity succeeded
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
||
broken
(
GetLastError
()
==
ERROR_NOACCESS
),
/* Win 7 and 8 */
"Expected ERROR_INVALID_PARAMETER, got %d
\n
"
,
GetLastError
());
ok
(
affinity
.
Group
==
0
,
"Expected group 0 got %u
\n
"
,
affinity
.
Group
);
memset
(
&
affinity_new
,
0
,
sizeof
(
affinity_new
));
affinity_new
.
Group
=
0
;
affinity_new
.
Mask
=
affinity
.
Mask
;
ok
(
pSetThreadGroupAffinity
(
curthread
,
&
affinity_new
,
&
affinity
),
"SetThreadGroupAffinity failed
\n
"
);
ok
(
affinity_new
.
Mask
==
affinity
.
Mask
,
"Expected old affinity mask %lx, got %lx
\n
"
,
affinity_new
.
Mask
,
affinity
.
Mask
);
/* show that the "all processors" flag is not supported for SetThreadGroupAffinity */
affinity_new
.
Group
=
0
;
affinity_new
.
Mask
=
~
0u
;
SetLastError
(
0xdeadbeef
);
ok
(
!
pSetThreadGroupAffinity
(
curthread
,
&
affinity_new
,
NULL
),
"SetThreadGroupAffinity succeeded
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Expected ERROR_INVALID_PARAMETER, got %d
\n
"
,
GetLastError
());
affinity_new
.
Group
=
1
;
/* assumes that you have less than 64 logical processors */
affinity_new
.
Mask
=
0x1
;
SetLastError
(
0xdeadbeef
);
ok
(
!
pSetThreadGroupAffinity
(
curthread
,
&
affinity_new
,
NULL
),
"SetThreadGroupAffinity succeeded
\n
"
);
ok
(
GetLastError
()
==
ERROR_INVALID_PARAMETER
,
"Expected ERROR_INVALID_PARAMETER, got %d
\n
"
,
GetLastError
());
SetLastError
(
0xdeadbeef
);
ok
(
!
pSetThreadGroupAffinity
(
curthread
,
NULL
,
NULL
),
"SetThreadGroupAffinity succeeded
\n
"
);
ok
(
GetLastError
()
==
ERROR_NOACCESS
,
"Expected ERROR_NOACCESS, got %d
\n
"
,
GetLastError
());
/* show that the access violation was detected in ntdll */
status
=
pNtSetInformationThread
(
curthread
,
ThreadGroupInformation
,
NULL
,
sizeof
(
affinity_new
));
ok
(
status
==
STATUS_ACCESS_VIOLATION
,
"Expected STATUS_ACCESS_VIOLATION, got %08x
\n
"
,
status
);
/* restore original mask */
affinity_new
.
Group
=
0
;
affinity_new
.
Mask
=
affinity
.
Mask
;
SetLastError
(
0xdeadbeef
);
ok
(
pSetThreadGroupAffinity
(
curthread
,
&
affinity_new
,
&
affinity
),
"SetThreadGroupAffinity failed
\n
"
);
ok
(
affinity_new
.
Mask
==
affinity
.
Mask
,
"Expected old affinity mask %lx, got %lx
\n
"
,
affinity_new
.
Mask
,
affinity
.
Mask
);
}
else
win_skip
(
"Get/SetThreadGroupAffinity not available
\n
"
);
}
static
VOID
test_GetThreadExitCode
(
void
)
...
...
@@ -1833,6 +1903,9 @@ static void init_funcs(void)
X
(
SubmitThreadpoolWork
);
X
(
WaitForThreadpoolWorkCallbacks
);
X
(
CloseThreadpoolWork
);
X
(
GetThreadGroupAffinity
);
X
(
SetThreadGroupAffinity
);
#undef X
#define X(f) p##f = (void*)GetProcAddress(ntdll, #f)
...
...
@@ -1840,6 +1913,7 @@ static void init_funcs(void)
{
X
(
NtQueryInformationThread
);
X
(
RtlGetThreadErrorMode
);
X
(
NtSetInformationThread
);
}
#undef X
}
...
...
dlls/kernel32/thread.c
View file @
9d58aac4
...
...
@@ -378,6 +378,52 @@ BOOL WINAPI SetThreadStackGuarantee(PULONG stacksize)
return
TRUE
;
}
/***********************************************************************
* GetThreadGroupAffinity (KERNEL32.@)
*/
BOOL
WINAPI
GetThreadGroupAffinity
(
HANDLE
thread
,
GROUP_AFFINITY
*
affinity
)
{
NTSTATUS
status
;
if
(
!
affinity
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
FALSE
;
}
status
=
NtQueryInformationThread
(
thread
,
ThreadGroupInformation
,
affinity
,
sizeof
(
*
affinity
),
NULL
);
if
(
status
)
{
SetLastError
(
RtlNtStatusToDosError
(
status
)
);
return
FALSE
;
}
return
TRUE
;
}
/***********************************************************************
* SetThreadGroupAffinity (KERNEL32.@)
*/
BOOL
WINAPI
SetThreadGroupAffinity
(
HANDLE
thread
,
const
GROUP_AFFINITY
*
affinity_new
,
GROUP_AFFINITY
*
affinity_old
)
{
NTSTATUS
status
;
if
(
affinity_old
&&
!
GetThreadGroupAffinity
(
thread
,
affinity_old
))
return
FALSE
;
status
=
NtSetInformationThread
(
thread
,
ThreadGroupInformation
,
affinity_new
,
sizeof
(
*
affinity_new
)
);
if
(
status
)
{
SetLastError
(
RtlNtStatusToDosError
(
status
)
);
return
FALSE
;
}
return
TRUE
;
}
/**********************************************************************
* SetThreadAffinityMask (KERNEL32.@)
*/
...
...
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