Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
-- v2: kernelbase: Forward GetThreadIdealProcessorEx() to ntdll. kernelbase: Forward thread priority boost functions to ntdll. kernel32/tests: Remove workarounds for SetThreadIdealProcessor(). kernelbase: Forward SetThreadIdealProcessor() to ntdll.
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/kernelbase/thread.c | 14 +++++++------- dlls/ntdll/tests/info.c | 22 ++++++++++++++++++++++ dlls/ntdll/unix/thread.c | 13 +++++++++++-- dlls/wow64/process.c | 1 + 4 files changed, 41 insertions(+), 9 deletions(-)
diff --git a/dlls/kernelbase/thread.c b/dlls/kernelbase/thread.c index f11d17748fe..a817609a385 100644 --- a/dlls/kernelbase/thread.c +++ b/dlls/kernelbase/thread.c @@ -512,13 +512,13 @@ BOOL WINAPI DECLSPEC_HOTPATCH SetThreadGroupAffinity( HANDLE thread, const GROUP */ DWORD WINAPI DECLSPEC_HOTPATCH SetThreadIdealProcessor( HANDLE thread, DWORD proc ) { - FIXME( "(%p %lu): stub\n", thread, proc ); - if (proc > MAXIMUM_PROCESSORS) - { - SetLastError( ERROR_INVALID_PARAMETER ); - return ~0u; - } - return 0; + NTSTATUS status; + + status = NtSetInformationThread( thread, ThreadIdealProcessor, &proc, sizeof(proc) ); + if (NT_SUCCESS(status)) return status; + + SetLastError( RtlNtStatusToDosError( status )); + return ~0u; }
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index bef982b20b0..c3c40d8f99c 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -3356,6 +3356,27 @@ static void test_thread_lookup(void) ok( !handle || broken(handle == (HANDLE)0xdeadbeef) /* vista */, "handle set %p\n", handle ); }
+static void test_thread_ideal_processor(void) +{ + ULONG number, len; + NTSTATUS status; + + number = 0; + status = pNtSetInformationThread( GetCurrentThread(), ThreadIdealProcessor, &number, sizeof(number) ); + ok(NT_SUCCESS(status), "Unexpected status %#lx.\n", status); + + number = 64 + 1; + status = pNtSetInformationThread( GetCurrentThread(), ThreadIdealProcessor, &number, sizeof(number) ); + ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %#lx.\n", status); + + number = 0; + status = pNtSetInformationThread( GetCurrentThread(), ThreadIdealProcessor, &number, sizeof(number) ); + ok(!status, "Unexpected status %#lx.\n", status); + + status = pNtQueryInformationThread( GetCurrentThread(), ThreadIdealProcessor, &number, sizeof(number), &len ); + ok(status == STATUS_INVALID_INFO_CLASS, "Unexpected status %#lx.\n", status); +} + static void test_thread_info(void) { NTSTATUS status; @@ -3613,6 +3634,7 @@ START_TEST(info) test_HideFromDebugger(); test_thread_start_address(); test_thread_lookup(); + test_thread_ideal_processor();
test_affinity(); test_debug_object(); diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 27f6f916220..05c575cfdaa 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -2177,6 +2177,7 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class, if (ret_len) *ret_len = sizeof(BOOLEAN); return STATUS_SUCCESS;
+ case ThreadIdealProcessor: case ThreadEnableAlignmentFaultFixup: return STATUS_INVALID_INFO_CLASS;
@@ -2186,7 +2187,6 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class, case ThreadEventPair_Reusable: case ThreadZeroTlsCell: case ThreadPerformanceCount: - case ThreadIdealProcessor: case ThreadPriorityBoost: case ThreadSetTlsArrayAddress: default: @@ -2379,6 +2379,16 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class, FIXME( "ThreadPowerThrottling stub!\n" ); return STATUS_SUCCESS;
+ case ThreadIdealProcessor: + { + const ULONG *number = data; + + if (length != sizeof(*number)) return STATUS_INFO_LENGTH_MISMATCH; + if (*number > MAXIMUM_PROCESSORS) return STATUS_INVALID_PARAMETER; + FIXME( "ThreadIdealProcessor stub!\n" ); + return STATUS_SUCCESS; + } + case ThreadBasicInformation: case ThreadTimes: case ThreadPriority: @@ -2386,7 +2396,6 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class, case ThreadEventPair_Reusable: case ThreadPerformanceCount: case ThreadAmILastThread: - case ThreadIdealProcessor: case ThreadPriorityBoost: case ThreadSetTlsArrayAddress: case ThreadIsIoPending: diff --git a/dlls/wow64/process.c b/dlls/wow64/process.c index ea7a1beb5e3..61ecc68724c 100644 --- a/dlls/wow64/process.c +++ b/dlls/wow64/process.c @@ -1162,6 +1162,7 @@ NTSTATUS WINAPI wow64_NtSetInformationThread( UINT *args ) case ThreadHideFromDebugger: /* void */ case ThreadEnableAlignmentFaultFixup: /* BOOLEAN */ case ThreadPowerThrottlingState: /* THREAD_POWER_THROTTLING_STATE */ + case ThreadIdealProcessor: /* ULONG */ return NtSetInformationThread( handle, class, ptr, len );
case ThreadImpersonationToken: /* HANDLE */
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/kernel32/tests/thread.c | 62 +++++++++++++++--------------------- 1 file changed, 25 insertions(+), 37 deletions(-)
diff --git a/dlls/kernel32/tests/thread.c b/dlls/kernel32/tests/thread.c index 25e5a0dc1da..cabc747fdbd 100644 --- a/dlls/kernel32/tests/thread.c +++ b/dlls/kernel32/tests/thread.c @@ -79,7 +79,6 @@ static void (WINAPI *pGetCurrentThreadStackLimits)(PULONG_PTR,PULONG_PTR); static BOOL (WINAPI *pGetThreadPriorityBoost)(HANDLE,PBOOL); static HANDLE (WINAPI *pOpenThread)(DWORD,BOOL,DWORD); static BOOL (WINAPI *pQueueUserWorkItem)(LPTHREAD_START_ROUTINE,PVOID,ULONG); -static DWORD (WINAPI *pSetThreadIdealProcessor)(HANDLE,DWORD); static BOOL (WINAPI *pSetThreadPriorityBoost)(HANDLE,BOOL); static BOOL (WINAPI *pSetThreadStackGuarantee)(ULONG*); static BOOL (WINAPI *pRegisterWaitForSingleObject)(PHANDLE,HANDLE,WAITORTIMERCALLBACK,PVOID,ULONG,ULONG); @@ -854,8 +853,8 @@ static VOID test_thread_processor(void) HANDLE curthread,curproc; DWORD_PTR processMask,systemMask,retMask; SYSTEM_INFO sysInfo; - int error=0; BOOL is_wow64; + DWORD ret;
if (!pIsWow64Process || !pIsWow64Process( GetCurrentProcess(), &is_wow64 )) is_wow64 = FALSE;
@@ -896,44 +895,34 @@ static VOID test_thread_processor(void) retMask = SetThreadAffinityMask(curthread,~(ULONG_PTR)0 >> 3); ok(retMask == processMask, "SetThreadAffinityMask failed\n"); } -/* NOTE: This only works on WinNT/2000/XP) */ - if (pSetThreadIdealProcessor) + + SetLastError(0xdeadbeef); + ret = SetThreadIdealProcessor(GetCurrentThread(), 0); + ok(ret != ~0u, "Unexpected return value %lu.\n", ret); + + if (is_wow64) { 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 %ld\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 %ld\n", GetLastError()); - } - - error=pSetThreadIdealProcessor(curthread,MAXIMUM_PROCESSORS); - ok(error!=-1, "SetThreadIdealProcessor failed\n"); - } - else - win_skip("SetThreadIdealProcessor is not implemented\n"); + ret = SetThreadIdealProcessor(GetCurrentThread(), MAXIMUM_PROCESSORS + 1); + todo_wine + ok(ret != ~0u, "Unexpected return value %lu.\n", ret); + + SetLastError(0xdeadbeef); + ret = SetThreadIdealProcessor(GetCurrentThread(), 65); + ok(ret == ~0u, "Unexpected return value %lu.\n", ret); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Unexpected error %ld.\n", GetLastError()); + } + else + { + SetLastError(0xdeadbeef); + ret = SetThreadIdealProcessor(GetCurrentThread(), MAXIMUM_PROCESSORS+1); + ok(ret == ~0u, "Unexpected return value %lu.\n", ret); + ok(GetLastError() == ERROR_INVALID_PARAMETER, "Unexpected error %ld.\n", GetLastError()); }
+ ret = SetThreadIdealProcessor(GetCurrentThread(), MAXIMUM_PROCESSORS); + ok(ret != ~0u, "Unexpected return value %lu.\n", ret); + if (pGetThreadGroupAffinity && pSetThreadGroupAffinity) { GROUP_AFFINITY affinity, affinity_new; @@ -2583,7 +2572,6 @@ static void init_funcs(void) X(GetThreadPriorityBoost); X(OpenThread); X(QueueUserWorkItem); - X(SetThreadIdealProcessor); X(SetThreadPriorityBoost); X(SetThreadStackGuarantee); X(RegisterWaitForSingleObject);
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/kernelbase/thread.c | 5 ++--- dlls/ntdll/unix/thread.c | 16 ++++++++++++++-- dlls/wow64/process.c | 2 ++ 3 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/dlls/kernelbase/thread.c b/dlls/kernelbase/thread.c index a817609a385..be3d38c04ff 100644 --- a/dlls/kernelbase/thread.c +++ b/dlls/kernelbase/thread.c @@ -286,8 +286,7 @@ INT WINAPI DECLSPEC_HOTPATCH GetThreadPriority( HANDLE thread ) */ BOOL WINAPI DECLSPEC_HOTPATCH GetThreadPriorityBoost( HANDLE thread, BOOL *state ) { - if (state) *state = FALSE; - return TRUE; + return set_ntstatus( NtQueryInformationThread( thread, ThreadPriorityBoost, state, sizeof(*state), NULL )); }
@@ -568,7 +567,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH SetThreadPriority( HANDLE thread, INT priority ) */ BOOL WINAPI DECLSPEC_HOTPATCH SetThreadPriorityBoost( HANDLE thread, BOOL disable ) { - return TRUE; + return set_ntstatus( NtSetInformationThread( thread, ThreadPriorityBoost, &disable, sizeof(disable) )); }
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 05c575cfdaa..d56962e1721 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -2177,6 +2177,16 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class, if (ret_len) *ret_len = sizeof(BOOLEAN); return STATUS_SUCCESS;
+ case ThreadPriorityBoost: + { + DWORD *value = data; + + if (length != sizeof(ULONG)) return STATUS_INFO_LENGTH_MISMATCH; + if (ret_len) *ret_len = sizeof(ULONG); + *value = 0; + return STATUS_SUCCESS; + } + case ThreadIdealProcessor: case ThreadEnableAlignmentFaultFixup: return STATUS_INVALID_INFO_CLASS; @@ -2187,7 +2197,6 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class, case ThreadEventPair_Reusable: case ThreadZeroTlsCell: case ThreadPerformanceCount: - case ThreadPriorityBoost: case ThreadSetTlsArrayAddress: default: FIXME( "info class %d not supported yet\n", class ); @@ -2389,6 +2398,10 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class, return STATUS_SUCCESS; }
+ case ThreadPriorityBoost: + WARN("Unimplemented class ThreadPriorityBoost.\n"); + return STATUS_SUCCESS; + case ThreadBasicInformation: case ThreadTimes: case ThreadPriority: @@ -2396,7 +2409,6 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class, case ThreadEventPair_Reusable: case ThreadPerformanceCount: case ThreadAmILastThread: - case ThreadPriorityBoost: case ThreadSetTlsArrayAddress: case ThreadIsIoPending: default: diff --git a/dlls/wow64/process.c b/dlls/wow64/process.c index 61ecc68724c..97dbfdef761 100644 --- a/dlls/wow64/process.c +++ b/dlls/wow64/process.c @@ -899,6 +899,7 @@ NTSTATUS WINAPI wow64_NtQueryInformationThread( UINT *args ) case ThreadIsIoPending: /* ULONG */ case ThreadHideFromDebugger: /* BOOLEAN */ case ThreadSuspendCount: /* ULONG */ + case ThreadPriorityBoost: /* ULONG */ /* FIXME: check buffer alignment */ return NtQueryInformationThread( handle, class, ptr, len, retlen );
@@ -1163,6 +1164,7 @@ NTSTATUS WINAPI wow64_NtSetInformationThread( UINT *args ) case ThreadEnableAlignmentFaultFixup: /* BOOLEAN */ case ThreadPowerThrottlingState: /* THREAD_POWER_THROTTLING_STATE */ case ThreadIdealProcessor: /* ULONG */ + case ThreadPriorityBoost: /* ULONG */ return NtSetInformationThread( handle, class, ptr, len );
case ThreadImpersonationToken: /* HANDLE */
From: Nikolay Sivov nsivov@codeweavers.com
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/kernelbase/thread.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/dlls/kernelbase/thread.c b/dlls/kernelbase/thread.c index be3d38c04ff..4a5684038a6 100644 --- a/dlls/kernelbase/thread.c +++ b/dlls/kernelbase/thread.c @@ -250,9 +250,7 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetThreadId( HANDLE thread ) */ BOOL WINAPI /* DECLSPEC_HOTPATCH */ GetThreadIdealProcessorEx( HANDLE thread, PROCESSOR_NUMBER *ideal ) { - FIXME( "(%p %p): stub\n", thread, ideal ); - SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); - return FALSE; + return set_ntstatus( NtQueryInformationThread( thread, ThreadIdealProcessorEx, ideal, sizeof(*ideal), NULL)); }