-- v3: ntdll: Implement ThreadPriorityBoost class in NtSetInformationThread. ntdll: Properly implement ThreadPriorityBoost class in NtQueryInformationThread.
From: Marc-Aurel Zent mzent@codeweavers.com
--- dlls/kernel32/tests/thread.c | 2 +- dlls/ntdll/unix/thread.c | 18 +++++++++++++----- server/protocol.def | 7 ++++--- server/thread.c | 3 +++ server/thread.h | 1 + 5 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/dlls/kernel32/tests/thread.c b/dlls/kernel32/tests/thread.c index fa25fd4e4a7..e68b9da7dc4 100644 --- a/dlls/kernel32/tests/thread.c +++ b/dlls/kernel32/tests/thread.c @@ -770,7 +770,7 @@ static VOID test_thread_priority(void) ok(access_thread!=NULL,"OpenThread returned an invalid handle\n"); if (access_thread!=NULL) { todo_wine obey_ar(pSetThreadPriorityBoost(access_thread,1)==0); - todo_wine obey_ar(pGetThreadPriorityBoost(access_thread,&disabled)==0); + obey_ar(pGetThreadPriorityBoost(access_thread, &disabled) == 0); ok(CloseHandle(access_thread),"Error Closing thread handle\n"); } } diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index ce6683e075f..5456ccdace1 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -2307,12 +2307,20 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class,
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; + SERVER_START_REQ( get_thread_info ) + { + req->handle = wine_server_obj_handle( handle ); + status = wine_server_call( req ); + if (status == STATUS_SUCCESS) + { + ULONG disable_boost = !!(reply->flags & GET_THREAD_INFO_FLAG_DISABLE_BOOST); + if (data) memcpy( data, &disable_boost, sizeof(disable_boost) ); + if (ret_len) *ret_len = sizeof(disable_boost); + } + } + SERVER_END_REQ; + return status; }
case ThreadIdealProcessorEx: diff --git a/server/protocol.def b/server/protocol.def index 22470e33ae0..2dce37de8c3 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1242,9 +1242,10 @@ struct obj_locator data_size_t desc_len; /* description length in bytes */ VARARG(desc,unicode_str); /* description string */ @END -#define GET_THREAD_INFO_FLAG_DBG_HIDDEN 0x01 -#define GET_THREAD_INFO_FLAG_TERMINATED 0x02 -#define GET_THREAD_INFO_FLAG_LAST 0x04 +#define GET_THREAD_INFO_FLAG_DBG_HIDDEN 0x01 +#define GET_THREAD_INFO_FLAG_TERMINATED 0x02 +#define GET_THREAD_INFO_FLAG_LAST 0x04 +#define GET_THREAD_INFO_FLAG_DISABLE_BOOST 0x08
/* Retrieve information about thread times */ diff --git a/server/thread.c b/server/thread.c index 05ec6a4ec00..c4f5da5a2cf 100644 --- a/server/thread.c +++ b/server/thread.c @@ -416,6 +416,7 @@ static inline void init_thread_structure( struct thread *thread ) thread->exit_code = 0; thread->priority = 0; thread->base_priority = 0; + thread->disable_boost = 0; thread->suspend = 0; thread->dbg_hidden = 0; thread->desktop_users = 0; @@ -1797,6 +1798,8 @@ DECL_HANDLER(get_thread_info) reply->flags |= GET_THREAD_INFO_FLAG_TERMINATED; if (thread->process->running_threads == 1) reply->flags |= GET_THREAD_INFO_FLAG_LAST; + if (thread->disable_boost) + reply->flags |= GET_THREAD_INFO_FLAG_DISABLE_BOOST;
if (thread->desc && get_reply_max_size()) { diff --git a/server/thread.h b/server/thread.h index 58081be7481..169abf18594 100644 --- a/server/thread.h +++ b/server/thread.h @@ -84,6 +84,7 @@ struct thread affinity_t affinity; /* affinity mask */ int priority; /* current thread priority */ int base_priority; /* base priority level (relative to process base priority class) */ + int disable_boost; /* disable thread priority boost */ int suspend; /* suspend count */ int dbg_hidden; /* hidden from debugger */ obj_handle_t desktop; /* desktop handle */
From: Marc-Aurel Zent mzent@codeweavers.com
--- dlls/kernel32/tests/thread.c | 26 ++++++++++++-------------- dlls/ntdll/unix/thread.c | 16 ++++++++++++++-- server/protocol.def | 12 +++++++----- server/thread.c | 12 ++++++++++++ server/thread.h | 1 + 5 files changed, 46 insertions(+), 21 deletions(-)
diff --git a/dlls/kernel32/tests/thread.c b/dlls/kernel32/tests/thread.c index e68b9da7dc4..090c098bcec 100644 --- a/dlls/kernel32/tests/thread.c +++ b/dlls/kernel32/tests/thread.c @@ -769,25 +769,23 @@ static VOID test_thread_priority(void) 0,curthreadId); ok(access_thread!=NULL,"OpenThread returned an invalid handle\n"); if (access_thread!=NULL) { - todo_wine obey_ar(pSetThreadPriorityBoost(access_thread,1)==0); + obey_ar(pSetThreadPriorityBoost(access_thread, 1) == 0); obey_ar(pGetThreadPriorityBoost(access_thread, &disabled) == 0); ok(CloseHandle(access_thread),"Error Closing thread handle\n"); } }
- rc = pSetThreadPriorityBoost(curthread,1); - ok( rc != 0, "error=%ld\n",GetLastError()); - todo_wine { - rc=pGetThreadPriorityBoost(curthread,&disabled); - ok(rc!=0 && disabled==1, - "rc=%d error=%ld disabled=%d\n",rc,GetLastError(),disabled); - } - - rc = pSetThreadPriorityBoost(curthread,0); - ok( rc != 0, "error=%ld\n",GetLastError()); - rc=pGetThreadPriorityBoost(curthread,&disabled); - ok(rc!=0 && disabled==0, - "rc=%d error=%ld disabled=%d\n",rc,GetLastError(),disabled); + rc = pSetThreadPriorityBoost(curthread, 1); + ok(rc != 0, "error=%ld\n", GetLastError()); + rc = pGetThreadPriorityBoost(curthread, &disabled); + ok(rc != 0 && disabled == 1, + "rc=%d error=%ld disabled=%d\n", rc, GetLastError(), disabled); + + rc = pSetThreadPriorityBoost(curthread, 0); + ok(rc != 0, "error=%ld\n", GetLastError()); + rc = pGetThreadPriorityBoost(curthread, &disabled); + ok(rc != 0 && disabled == 0, + "rc=%d error=%ld disabled=%d\n", rc, GetLastError(), disabled); }
/* check the GetThreadTimes function */ diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 5456ccdace1..6176d70de51 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -2561,8 +2561,20 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class, }
case ThreadPriorityBoost: - WARN("Unimplemented class ThreadPriorityBoost.\n"); - return STATUS_SUCCESS; + { + const DWORD *disable_boost = data; + if (length != sizeof(DWORD)) return STATUS_INVALID_PARAMETER; + if (!disable_boost) return STATUS_ACCESS_VIOLATION; + SERVER_START_REQ( set_thread_info ) + { + req->handle = wine_server_obj_handle( handle ); + req->disable_boost = *disable_boost; + req->mask = SET_THREAD_INFO_DISABLE_BOOST; + status = wine_server_call( req ); + } + SERVER_END_REQ; + return status; + }
case ThreadManageWritesToExecutableMemory: { diff --git a/server/protocol.def b/server/protocol.def index 2dce37de8c3..0ec9d441717 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1264,6 +1264,7 @@ struct obj_locator obj_handle_t handle; /* thread handle */ int priority; /* current thread priority */ int base_priority;/* base priority level (relative to process base priority class) */ + int disable_boost;/* disable thread priority boost */ affinity_t affinity; /* affinity mask */ client_ptr_t entry_point; /* thread entry point */ obj_handle_t token; /* impersonation token */ @@ -1272,11 +1273,12 @@ struct obj_locator @END #define SET_THREAD_INFO_PRIORITY 0x01 #define SET_THREAD_INFO_BASE_PRIORITY 0x02 -#define SET_THREAD_INFO_AFFINITY 0x04 -#define SET_THREAD_INFO_TOKEN 0x08 -#define SET_THREAD_INFO_ENTRYPOINT 0x10 -#define SET_THREAD_INFO_DESCRIPTION 0x20 -#define SET_THREAD_INFO_DBG_HIDDEN 0x40 +#define SET_THREAD_INFO_DISABLE_BOOST 0x04 +#define SET_THREAD_INFO_AFFINITY 0x08 +#define SET_THREAD_INFO_TOKEN 0x10 +#define SET_THREAD_INFO_ENTRYPOINT 0x20 +#define SET_THREAD_INFO_DESCRIPTION 0x40 +#define SET_THREAD_INFO_DBG_HIDDEN 0x80
/* Suspend a thread */ diff --git a/server/thread.c b/server/thread.c index c4f5da5a2cf..34a7c9a572f 100644 --- a/server/thread.c +++ b/server/thread.c @@ -860,6 +860,13 @@ unsigned int set_thread_base_priority( struct thread *thread, int base_priority return set_thread_priority( thread, priority ); }
+unsigned int set_thread_disable_boost( struct thread *thread, int disable_boost ) +{ + thread->disable_boost = disable_boost; + set_thread_priority( thread, thread->priority ); + return STATUS_SUCCESS; +} + /* set all information about a thread */ static void set_thread_info( struct thread *thread, const struct set_thread_info_request *req ) @@ -874,6 +881,11 @@ static void set_thread_info( struct thread *thread, unsigned int status = set_thread_base_priority( thread, req->base_priority ); if (status) set_error( status ); } + if (req->mask & SET_THREAD_INFO_DISABLE_BOOST) + { + unsigned int status = set_thread_disable_boost( thread, req->disable_boost ); + if (status) set_error( status ); + } if (req->mask & SET_THREAD_INFO_AFFINITY) { if ((req->affinity & thread->process->affinity) != req->affinity) diff --git a/server/thread.h b/server/thread.h index 169abf18594..d2e46b726db 100644 --- a/server/thread.h +++ b/server/thread.h @@ -127,6 +127,7 @@ extern int thread_get_inflight_fd( struct thread *thread, int client ); extern struct token *thread_get_impersonation_token( struct thread *thread ); extern unsigned int set_thread_priority( struct thread *thread, int priority ); extern unsigned int set_thread_base_priority( struct thread *thread, int base_priority ); +extern unsigned int set_thread_disable_boost( struct thread *thread, int disable_boost ); extern int set_thread_affinity( struct thread *thread, affinity_t affinity ); extern int suspend_thread( struct thread *thread ); extern int resume_thread( struct thread *thread );
v3: The test commit was split up into the respective implementation commits (and the formatting of the lines it touches was a bit improved/homogenized).