Second part of https://gitlab.winehq.org/wine/wine/-/merge_requests/7516
From: Marc-Aurel Zent mzent@codeweavers.com
--- dlls/ntdll/tests/info.c | 8 ++++---- dlls/ntdll/unix/thread.c | 16 +++++++++++++++- server/protocol.def | 14 ++++++++------ server/thread.c | 28 ++++++++++++++++++++++------ server/thread.h | 2 ++ 5 files changed, 51 insertions(+), 17 deletions(-)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index b92d421891f..44c5bd6cd1e 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -3355,7 +3355,7 @@ static void test_priority(void) * reach in NORMAL_PRIORITY_CLASS without boost. */ nt_thread_priority = 12; status = pNtSetInformationThread( GetCurrentThread(), ThreadPriority, &nt_thread_priority, sizeof(ULONG) ); - todo_wine ok( status == STATUS_SUCCESS, "NtSetInformationThread(ThreadPriority) failed: %08lx\n", status ); + ok( status == STATUS_SUCCESS, "NtSetInformationThread(ThreadPriority) failed: %08lx\n", status ); /* Effective thread priority should be now 12, BasePriority should be * unchanged. */ status = pNtQueryInformationThread( GetCurrentThread(), ThreadBasicInformation, &tbi, sizeof(tbi), NULL ); @@ -3380,14 +3380,14 @@ static void test_priority(void) * and lower fails. */ nt_thread_priority = 42; status = pNtSetInformationThread( GetCurrentThread(), ThreadPriority, &nt_thread_priority, sizeof(ULONG) ); - todo_wine ok( status == STATUS_INVALID_PARAMETER, "got %08lx, expected STATUS_INVALID_PARAMETER.\n", status ); + ok( status == STATUS_INVALID_PARAMETER, "got %08lx, expected STATUS_INVALID_PARAMETER.\n", status ); nt_thread_priority = 0; /* 0 also fails in addition to negative values. */ status = pNtSetInformationThread( GetCurrentThread(), ThreadPriority, &nt_thread_priority, sizeof(ULONG) ); - todo_wine ok( status == STATUS_INVALID_PARAMETER, "got %08lx, expected STATUS_INVALID_PARAMETER.\n", status ); + ok( status == STATUS_INVALID_PARAMETER, "got %08lx, expected STATUS_INVALID_PARAMETER.\n", status ); /* Moving a thread into the realtime band is normally not possible in a non-realtime process. */ nt_thread_priority = 24; status = pNtSetInformationThread( GetCurrentThread(), ThreadPriority, &nt_thread_priority, sizeof(ULONG) ); - todo_wine ok( status == STATUS_PRIVILEGE_NOT_HELD, "got %08lx, expected STATUS_PRIVILEGE_NOT_HELD.\n", status ); + ok( status == STATUS_PRIVILEGE_NOT_HELD, "got %08lx, expected STATUS_PRIVILEGE_NOT_HELD.\n", status );
/* Restore thread priority and boosting behaviour back to normal */ SetThreadPriorityBoost( GetCurrentThread(), FALSE ); diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index b31f8969c21..bda23fcd9a1 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -2371,6 +2371,21 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class, return status; }
+ case ThreadPriority: + { + const DWORD *priority = data; + if (length != sizeof(DWORD)) return STATUS_INVALID_PARAMETER; + SERVER_START_REQ( set_thread_info ) + { + req->handle = wine_server_obj_handle( handle ); + req->priority = *priority; + req->mask = SET_THREAD_INFO_PRIORITY; + status = wine_server_call( req ); + } + SERVER_END_REQ; + return status; + } + case ThreadBasePriority: { const DWORD *base_priority = data; @@ -2548,7 +2563,6 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class,
case ThreadBasicInformation: case ThreadTimes: - case ThreadPriority: case ThreadDescriptorTableEntry: case ThreadEventPair_Reusable: case ThreadPerformanceCount: diff --git a/server/protocol.def b/server/protocol.def index 36056c00e24..fddc5337757 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1247,18 +1247,20 @@ struct obj_locator @REQ(set_thread_info) obj_handle_t handle; /* thread handle */ int mask; /* setting mask (see below) */ + int priority; /* current thread priority */ int base_priority;/* base priority level (relative to process base priority class) */ affinity_t affinity; /* affinity mask */ client_ptr_t entry_point; /* thread entry point */ obj_handle_t token; /* impersonation token */ VARARG(desc,unicode_str); /* description string */ @END -#define SET_THREAD_INFO_BASE_PRIORITY 0x01 -#define SET_THREAD_INFO_AFFINITY 0x02 -#define SET_THREAD_INFO_TOKEN 0x04 -#define SET_THREAD_INFO_ENTRYPOINT 0x08 -#define SET_THREAD_INFO_DESCRIPTION 0x10 -#define SET_THREAD_INFO_DBG_HIDDEN 0x20 +#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
/* Suspend a thread */ diff --git a/server/thread.c b/server/thread.c index 8797af32648..30a295a40cc 100644 --- a/server/thread.c +++ b/server/thread.c @@ -405,6 +405,7 @@ static inline void init_thread_structure( struct thread *thread ) thread->wait_fd = NULL; thread->state = RUNNING; thread->exit_code = 0; + thread->priority = 0; thread->base_priority = 0; thread->suspend = 0; thread->dbg_hidden = 0; @@ -771,6 +772,21 @@ affinity_t get_thread_affinity( struct thread *thread ) return mask; }
+unsigned int set_thread_priority( struct thread *thread, int priority ) +{ + int priority_class = thread->process->priority; + + if (priority < LOW_PRIORITY + 1 || priority > HIGH_PRIORITY) return STATUS_INVALID_PARAMETER; + if (priority_class != PROCESS_PRIOCLASS_REALTIME && priority >= LOW_REALTIME_PRIORITY) return STATUS_PRIVILEGE_NOT_HELD; + + thread->priority = priority; + + /* if thread is gone or hasn't started yet, this will be called again from init_thread with a unix_tid */ + if (thread->state == RUNNING && thread->unix_tid != -1) apply_thread_priority( thread, priority ); + + return STATUS_SUCCESS; +} + static int priority_from_class_and_level( int priority_class, int priority_level ) { /* offsets taken from https://learn.microsoft.com/en-us/windows/win32/procthread/scheduling-priori... */ @@ -812,18 +828,18 @@ unsigned int set_thread_base_priority( struct thread *thread, int base_priority return STATUS_INVALID_PARAMETER;
thread->base_priority = base_priority; - - /* if thread is gone or hasn't started yet, this will be called again from init_thread with a unix_tid */ - if (thread->state == RUNNING && thread->unix_tid != -1) - apply_thread_priority( thread, priority_from_class_and_level( priority_class, base_priority ) ); - - return STATUS_SUCCESS; + return set_thread_priority( thread, priority_from_class_and_level( priority_class, base_priority ) ); }
/* set all information about a thread */ static void set_thread_info( struct thread *thread, const struct set_thread_info_request *req ) { + if (req->mask & SET_THREAD_INFO_PRIORITY) + { + unsigned int status = set_thread_priority( thread, req->priority ); + if (status) set_error( status ); + } if (req->mask & SET_THREAD_INFO_BASE_PRIORITY) { unsigned int status = set_thread_base_priority( thread, req->base_priority ); diff --git a/server/thread.h b/server/thread.h index 33d150df9cb..7fdae3a629f 100644 --- a/server/thread.h +++ b/server/thread.h @@ -81,6 +81,7 @@ struct thread client_ptr_t teb; /* TEB address (in client address space) */ client_ptr_t entry_point; /* entry point (in client address space) */ affinity_t affinity; /* affinity mask */ + int priority; /* current thread priority */ int base_priority; /* base priority level (relative to process base priority class) */ int suspend; /* suspend count */ int dbg_hidden; /* hidden from debugger */ @@ -122,6 +123,7 @@ extern void thread_cancel_apc( struct thread *thread, struct object *owner, enum extern int thread_add_inflight_fd( struct thread *thread, int client, int server ); 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 int set_thread_affinity( struct thread *thread, affinity_t affinity ); extern int suspend_thread( struct thread *thread );
From: Marc-Aurel Zent mzent@codeweavers.com
--- dlls/ntdll/unix/thread.c | 2 +- server/protocol.def | 2 +- server/thread.c | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index bda23fcd9a1..15f5d3ae568 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -2153,7 +2153,7 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class, status = wine_server_call( req ); if (status == STATUS_SUCCESS) { - ULONG last = reply->last; + ULONG last = !!(reply->flags & GET_THREAD_INFO_FLAG_LAST); if (data) memcpy( data, &last, sizeof(last) ); if (ret_len) *ret_len = sizeof(last); } diff --git a/server/protocol.def b/server/protocol.def index fddc5337757..006410bdd4a 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1222,7 +1222,6 @@ struct obj_locator affinity_t affinity; /* thread affinity mask */ int exit_code; /* thread exit code */ int priority; /* thread priority level */ - int last; /* last thread in process */ int suspend_count; /* thread suspend count */ unsigned int flags; /* GET_THREAD_INFO_FLAG_ flags */ data_size_t desc_len; /* description length in bytes */ @@ -1230,6 +1229,7 @@ struct obj_locator @END #define GET_THREAD_INFO_FLAG_DBG_HIDDEN 0x01 #define GET_THREAD_INFO_FLAG_TERMINATED 0x02 +#define GET_THREAD_INFO_FLAG_LAST 0x04
/* Retrieve information about thread times */ diff --git a/server/thread.c b/server/thread.c index 30a295a40cc..257d756139d 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1727,7 +1727,6 @@ DECL_HANDLER(get_thread_info) reply->exit_code = (thread->state == TERMINATED) ? thread->exit_code : STATUS_PENDING; reply->priority = thread->base_priority; reply->affinity = thread->affinity; - reply->last = thread->process->running_threads == 1; reply->suspend_count = thread->suspend; reply->desc_len = thread->desc_len; reply->flags = 0; @@ -1735,6 +1734,8 @@ DECL_HANDLER(get_thread_info) reply->flags |= GET_THREAD_INFO_FLAG_DBG_HIDDEN; if (thread->state == TERMINATED) reply->flags |= GET_THREAD_INFO_FLAG_TERMINATED; + if (thread->process->running_threads == 1) + reply->flags |= GET_THREAD_INFO_FLAG_LAST;
if (thread->desc && get_reply_max_size()) {
From: Marc-Aurel Zent mzent@codeweavers.com
--- dlls/kernelbase/thread.c | 2 +- dlls/ntdll/tests/info.c | 4 ++-- dlls/ntdll/unix/thread.c | 2 +- server/process.c | 2 +- server/protocol.def | 3 ++- server/thread.c | 3 ++- 6 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/dlls/kernelbase/thread.c b/dlls/kernelbase/thread.c index 82096fd45f3..82ade671d1a 100644 --- a/dlls/kernelbase/thread.c +++ b/dlls/kernelbase/thread.c @@ -274,7 +274,7 @@ INT WINAPI DECLSPEC_HOTPATCH GetThreadPriority( HANDLE thread ) if (!set_ntstatus( NtQueryInformationThread( thread, ThreadBasicInformation, &info, sizeof(info), NULL ))) return THREAD_PRIORITY_ERROR_RETURN; - return info.Priority; + return info.BasePriority; }
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index 44c5bd6cd1e..8b3202206ce 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -3362,8 +3362,8 @@ static void test_priority(void) ok( status == STATUS_SUCCESS, "NtQueryInformationThread failed after setting priority: %08lx\n", status ); ok( THREAD_PRIORITY_LOWEST == tbi.BasePriority, "After setting, BasePriority (%ld) does not match set BasePriority THREAD_PRIORITY_LOWEST.\n", tbi.BasePriority ); - todo_wine ok( nt_thread_priority == tbi.Priority, "After setting, effective NT priority (%ld) does not match expected priority %lu.\n", - tbi.Priority, nt_thread_priority ); + ok( nt_thread_priority == tbi.Priority, "After setting, effective NT priority (%ld) does not match expected priority %lu.\n", + tbi.Priority, nt_thread_priority ); /* Changing process priority recalculates all priorities again and * overwrites our custom priority of 12. */ ret = SetPriorityClass( GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS ); diff --git a/dlls/ntdll/unix/thread.c b/dlls/ntdll/unix/thread.c index 15f5d3ae568..1dd7faecb14 100644 --- a/dlls/ntdll/unix/thread.c +++ b/dlls/ntdll/unix/thread.c @@ -2061,7 +2061,7 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class, info.ClientId.UniqueThread = ULongToHandle(reply->tid); info.AffinityMask = reply->affinity & affinity_mask; info.Priority = reply->priority; - info.BasePriority = reply->priority; /* FIXME */ + info.BasePriority = reply->base_priority; } } SERVER_END_REQ; diff --git a/server/process.c b/server/process.c index 1980e2ca777..12218e82e3d 100644 --- a/server/process.c +++ b/server/process.c @@ -2014,7 +2014,7 @@ DECL_HANDLER(list_processes) thread_info->start_time = thread->creation_time; thread_info->tid = thread->id; thread_info->base_priority = thread->base_priority; - thread_info->current_priority = thread->base_priority; /* FIXME */ + thread_info->current_priority = thread->priority; thread_info->unix_tid = thread->unix_tid; thread_info->entry_point = thread->entry_point; thread_info->teb = thread->teb; diff --git a/server/protocol.def b/server/protocol.def index 006410bdd4a..9c1124a562e 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1221,7 +1221,8 @@ struct obj_locator client_ptr_t entry_point; /* thread entry point */ affinity_t affinity; /* thread affinity mask */ int exit_code; /* thread exit code */ - int priority; /* thread priority level */ + int priority; /* current thread priority */ + int base_priority; /* base priority level (relative to process base priority class) */ int suspend_count; /* thread suspend count */ unsigned int flags; /* GET_THREAD_INFO_FLAG_ flags */ data_size_t desc_len; /* description length in bytes */ diff --git a/server/thread.c b/server/thread.c index 257d756139d..ce09a791b6e 100644 --- a/server/thread.c +++ b/server/thread.c @@ -1725,7 +1725,8 @@ DECL_HANDLER(get_thread_info) reply->teb = thread->teb; reply->entry_point = thread->entry_point; reply->exit_code = (thread->state == TERMINATED) ? thread->exit_code : STATUS_PENDING; - reply->priority = thread->base_priority; + reply->priority = thread->priority; + reply->base_priority = thread->base_priority; reply->affinity = thread->affinity; reply->suspend_count = thread->suspend; reply->desc_len = thread->desc_len;
From: Marc-Aurel Zent mzent@codeweavers.com
--- dlls/kernelbase/process.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c index df3447a9014..a47e2dcc01a 100644 --- a/dlls/kernelbase/process.c +++ b/dlls/kernelbase/process.c @@ -821,13 +821,13 @@ BOOL WINAPI DECLSPEC_HOTPATCH GetHandleInformation( HANDLE handle, DWORD *flags */ DWORD WINAPI DECLSPEC_HOTPATCH GetPriorityClass( HANDLE process ) { - PROCESS_BASIC_INFORMATION pbi; + PROCESS_PRIORITY_CLASS priority;
- if (!set_ntstatus( NtQueryInformationProcess( process, ProcessBasicInformation, - &pbi, sizeof(pbi), NULL ))) + if (!set_ntstatus( NtQueryInformationProcess( process, ProcessPriorityClass, + &priority, sizeof(priority), NULL ))) return 0;
- switch (pbi.BasePriority) + switch (priority.PriorityClass) { case PROCESS_PRIOCLASS_IDLE: return IDLE_PRIORITY_CLASS; case PROCESS_PRIOCLASS_BELOW_NORMAL: return BELOW_NORMAL_PRIORITY_CLASS;
This merge request was approved by Rémi Bernon.
From: Marc-Aurel Zent mzent@codeweavers.com
--- dlls/ntdll/tests/info.c | 12 ++++++------ dlls/ntdll/unix/process.c | 4 ++-- server/process.c | 1 + server/process.h | 1 + server/protocol.def | 1 + server/thread.c | 2 +- 6 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c index 8b3202206ce..c95da44b8cf 100644 --- a/dlls/ntdll/tests/info.c +++ b/dlls/ntdll/tests/info.c @@ -3334,8 +3334,8 @@ static void test_priority(void) thread_base_priority, tbi.BasePriority ); status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), NULL ); expected_nt_priority = pbi.BasePriority + THREAD_PRIORITY_HIGHEST; - todo_wine ok( expected_nt_priority == tbi.Priority, "After setting, effective NT priority (%ld) does not match expected priority %d.\n", - tbi.Priority, expected_nt_priority ); + ok( expected_nt_priority == tbi.Priority, "After setting, effective NT priority (%ld) does not match expected priority %d.\n", + tbi.Priority, expected_nt_priority );
/* Test setting the thread priority to THREAD_PRIORITY_LOWEST now, but using * pNtSetInformationThread, also testing NT priority directly afterwards. */ @@ -3349,8 +3349,8 @@ static void test_priority(void) ok( nt_thread_priority == tbi.BasePriority, "After setting, BasePriority (%ld) does not match set BasePriority (%ld)\n", nt_thread_priority, tbi.BasePriority ); expected_nt_priority = pbi.BasePriority + THREAD_PRIORITY_LOWEST; - todo_wine ok( expected_nt_priority == tbi.Priority, "After setting, effective NT priority (%ld) does not match expected priority %d.\n", - tbi.Priority, expected_nt_priority ); + ok( expected_nt_priority == tbi.Priority, "After setting, effective NT priority (%ld) does not match expected priority %d.\n", + tbi.Priority, expected_nt_priority ); /* Now set NT thread priority directly to 12, a value normally impossible to * reach in NORMAL_PRIORITY_CLASS without boost. */ nt_thread_priority = 12; @@ -3374,8 +3374,8 @@ static void test_priority(void) ok( status == STATUS_SUCCESS, "NtQueryInformationThread failed after setting priority: %08lx\n", status ); status = pNtQueryInformationProcess( GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), NULL ); expected_nt_priority = pbi.BasePriority + THREAD_PRIORITY_LOWEST; - todo_wine ok( expected_nt_priority == tbi.Priority, "After setting, effective NT priority (%ld) does not match expected priority %d.\n", - tbi.Priority, expected_nt_priority ); + ok( expected_nt_priority == tbi.Priority, "After setting, effective NT priority (%ld) does not match expected priority %d.\n", + tbi.Priority, expected_nt_priority ); /* Setting an out of range priority above HIGH_PRIORITY (31) or LOW_PRIORITY (0) * and lower fails. */ nt_thread_priority = 42; diff --git a/dlls/ntdll/unix/process.c b/dlls/ntdll/unix/process.c index 533940280e6..4d5d23c47bb 100644 --- a/dlls/ntdll/unix/process.c +++ b/dlls/ntdll/unix/process.c @@ -1159,7 +1159,7 @@ NTSTATUS WINAPI NtQueryInformationProcess( HANDLE handle, PROCESSINFOCLASS class pbi.ExitStatus = reply->exit_code; pbi.PebBaseAddress = wine_server_get_ptr( reply->peb ); pbi.AffinityMask = reply->affinity & affinity_mask; - pbi.BasePriority = reply->priority; + pbi.BasePriority = reply->base_priority; pbi.UniqueProcessId = reply->pid; pbi.InheritedFromUniqueProcessId = reply->ppid; if (is_old_wow64()) @@ -1653,7 +1653,7 @@ NTSTATUS WINAPI NtWow64QueryInformationProcess64( HANDLE handle, PROCESSINFOCLAS pbi.ExitStatus = reply->exit_code; pbi.PebBaseAddress = (ULONG)wine_server_get_ptr( reply->peb ); pbi.AffinityMask = reply->affinity & affinity_mask; - pbi.BasePriority = reply->priority; + pbi.BasePriority = reply->base_priority; pbi.UniqueProcessId = reply->pid; pbi.InheritedFromUniqueProcessId = reply->ppid; } diff --git a/server/process.c b/server/process.c index 12218e82e3d..b161e3394ba 100644 --- a/server/process.c +++ b/server/process.c @@ -1512,6 +1512,7 @@ DECL_HANDLER(get_process_info) reply->ppid = process->parent_id; reply->exit_code = process->exit_code; reply->priority = process->priority; + reply->base_priority = priority_from_class_and_level( process->priority, THREAD_PRIORITY_NORMAL ); reply->affinity = process->affinity; reply->peb = process->peb; reply->start_time = process->start_time; diff --git a/server/process.h b/server/process.h index 9238d638f15..e49529b06fa 100644 --- a/server/process.h +++ b/server/process.h @@ -116,6 +116,7 @@ extern void kill_process( struct process *process, int violent_death ); extern void kill_console_processes( struct thread *renderer, int exit_code ); extern void detach_debugged_processes( struct debug_obj *debug_obj, int exit_code ); extern void enum_processes( int (*cb)(struct process*, void*), void *user); +extern int priority_from_class_and_level( int priority_class, int priority_level ); extern void set_process_priority( struct process *process, int priority );
/* console functions */ diff --git a/server/protocol.def b/server/protocol.def index 9c1124a562e..5e3889d7750 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -1158,6 +1158,7 @@ struct obj_locator unsigned int session_id; /* process session id */ int exit_code; /* process exit code */ int priority; /* priority class */ + unsigned short base_priority; /* process base priority */ unsigned short machine; /* process architecture */ VARARG(image,pe_image_info); /* image info for main exe */ @END diff --git a/server/thread.c b/server/thread.c index ce09a791b6e..27a40ce38ad 100644 --- a/server/thread.c +++ b/server/thread.c @@ -787,7 +787,7 @@ unsigned int set_thread_priority( struct thread *thread, int priority ) return STATUS_SUCCESS; }
-static int priority_from_class_and_level( int priority_class, int priority_level ) +int priority_from_class_and_level( int priority_class, int priority_level ) { /* offsets taken from https://learn.microsoft.com/en-us/windows/win32/procthread/scheduling-priori... */ static const int class_offsets[] = { 4, 8, 13, 24, 6, 10 };
The mscoree test failures seem unrelated and happening in master already.