From ef4c1766d2a363b3b51ac603e935a0c0b21e6570 Mon Sep 17 00:00:00 2001 From: akallabeth Date: Fri, 24 May 2024 11:04:07 +0200 Subject: [PATCH] [winpr,thread] implement SetThreadPriority --- winpr/include/winpr/thread.h | 11 ++++++ winpr/libwinpr/CMakeLists.txt | 5 +++ winpr/libwinpr/thread/thread.c | 65 +++++++++++++++++++++++++++++++++- 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/winpr/include/winpr/thread.h b/winpr/include/winpr/thread.h index b0bad74d1..97c7eec09 100644 --- a/winpr/include/winpr/thread.h +++ b/winpr/include/winpr/thread.h @@ -194,6 +194,17 @@ extern "C" #endif /* Thread */ +#define THREAD_MODE_BACKGROUND_BEGIN 0x00010000 +#define THREAD_MODE_BACKGROUND_END 0x00020000 +#define THREAD_PRIORITY_ABOVE_NORMAL 1 +#define THREAD_PRIORITY_BELOW_NORMAL -1 +#define THREAD_PRIORITY_HIGHEST 2 +#define THREAD_PRIORITY_IDLE -15 +#define THREAD_PRIORITY_LOWEST -2 +#define THREAD_PRIORITY_NORMAL 0 +#define THREAD_PRIORITY_TIME_CRITICAL 15 + + WINPR_API BOOL SetThreadPriority(HANDLE hThread, int nPriority); #define CREATE_SUSPENDED 0x00000004 #define STACK_SIZE_PARAM_IS_A_RESERVATION 0x00010000 diff --git a/winpr/libwinpr/CMakeLists.txt b/winpr/libwinpr/CMakeLists.txt index 91d0e0176..725a8227e 100644 --- a/winpr/libwinpr/CMakeLists.txt +++ b/winpr/libwinpr/CMakeLists.txt @@ -131,6 +131,11 @@ if(NOT IOS) endif() endif() +check_function_exists(pthread_setschedprio PTHREAD_SETSCHEDPRIO) +if (PTHREAD_SETSCHEDPRIO) + winpr_definition_add(-DPTHREAD_SETSCHEDPRIO) +endif() + if (ANDROID) winpr_library_add_private(log) endif() diff --git a/winpr/libwinpr/thread/thread.c b/winpr/libwinpr/thread/thread.c index edf5639ce..b7cbdbe9e 100644 --- a/winpr/libwinpr/thread/thread.c +++ b/winpr/libwinpr/thread/thread.c @@ -28,6 +28,14 @@ #include +#ifndef MIN +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#endif + +#ifndef MAX +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) +#endif + /** * api-ms-win-core-processthreads-l1-1-1.dll * @@ -73,6 +81,7 @@ #include #include +#include #ifdef WINPR_HAVE_UNISTD_H #include #endif @@ -605,6 +614,60 @@ error: return rc; } +BOOL SetThreadPriority(HANDLE hThread, int nPriority) +{ + ULONG Type = 0; + WINPR_HANDLE* Object = NULL; + + if (!winpr_Handle_GetInfo(hThread, &Type, &Object) || Object->Type != HANDLE_TYPE_THREAD) + return FALSE; + + WINPR_THREAD* thread = (WINPR_THREAD*)Object; + + const int min = 19; + const int max = 0; + const int diff = (max - min); + const int normal = min + diff / 2; + const int off = MIN(1, diff / 4); + int sched_priority = -1; + + switch (nPriority & ~(THREAD_MODE_BACKGROUND_BEGIN | THREAD_MODE_BACKGROUND_END)) + { + case THREAD_PRIORITY_ABOVE_NORMAL: + sched_priority = MIN(normal + off, max); + break; + case THREAD_PRIORITY_BELOW_NORMAL: + sched_priority = MAX(normal - off, min); + break; + case THREAD_PRIORITY_HIGHEST: + sched_priority = max; + break; + case THREAD_PRIORITY_IDLE: + sched_priority = min; + break; + case THREAD_PRIORITY_LOWEST: + sched_priority = min; + break; + case THREAD_PRIORITY_TIME_CRITICAL: + sched_priority = max; + break; + default: + case THREAD_PRIORITY_NORMAL: + sched_priority = normal; + break; + } +#if defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 200809L) && defined(PTHREAD_SETSCHEDPRIO) + const int rc = pthread_setschedprio(thread->thread, sched_priority); + if (rc != 0) + WLog_ERR(TAG, "pthread_setschedprio(%d) %s [%d]", sched_priority, strerror(rc), rc); + return rc == 0; +#else + WLog_WARN(TAG, "pthread_setschedprio(%d) not implemented, requires POSIX 2008 or later", + sched_priority); + return TRUE; +#endif +} + HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId) @@ -952,7 +1015,7 @@ BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode) WINPR_HANDLE* Object = NULL; WINPR_THREAD* thread = NULL; - if (!winpr_Handle_GetInfo(hThread, &Type, &Object)) + if (!winpr_Handle_GetInfo(hThread, &Type, &Object) || Object->Type != HANDLE_TYPE_THREAD) return FALSE; thread = (WINPR_THREAD*)Object;