diff --git a/include/bitcoin/network/async/thread.hpp b/include/bitcoin/network/async/thread.hpp index b80141b45..9bd01b640 100644 --- a/include/bitcoin/network/async/thread.hpp +++ b/include/bitcoin/network/async/thread.hpp @@ -28,6 +28,7 @@ namespace network { enum class thread_priority { + highest, high, normal, low, diff --git a/src/async/thread.cpp b/src/async/thread.cpp index 0c93195ed..a3fd0969c 100644 --- a/src/async/thread.cpp +++ b/src/async/thread.cpp @@ -22,18 +22,24 @@ #ifdef HAVE_MSC #include + // #define THREAD_PRIORITY_IDLE -15 + // #define THREAD_PRIORITY_LOWEST -2 + // #define THREAD_PRIORITY_BELOW_NORMAL -1 + // #define THREAD_PRIORITY_NORMAL 0 + // #define THREAD_PRIORITY_ABOVE_NORMAL 1 + // #define THREAD_PRIORITY_HIGHEST 2 + // #define THREAD_PRIORITY_TIME_CRITICAL 15 + // #define THREAD_PRIORITY_ERROR_RETURN (MAXLONG) #else #include #include #include #include - #ifndef PRIO_MAX - #define PRIO_MAX 20 - #endif - #define THREAD_PRIORITY_ABOVE_NORMAL (-2) - #define THREAD_PRIORITY_NORMAL 0 - #define THREAD_PRIORITY_BELOW_NORMAL 2 - #define THREAD_PRIORITY_LOWEST PRIO_MAX + #define THREAD_PRIORITY_HIGHEST -20 + #define THREAD_PRIORITY_ABOVE_NORMAL -2 + #define THREAD_PRIORITY_NORMAL 0 + #define THREAD_PRIORITY_BELOW_NORMAL 2 + #define THREAD_PRIORITY_LOWEST 20 #endif namespace libbitcoin { @@ -50,22 +56,36 @@ static int get_priority(thread_priority priority) NOEXCEPT return THREAD_PRIORITY_BELOW_NORMAL; case thread_priority::high: return THREAD_PRIORITY_ABOVE_NORMAL; + case thread_priority::highest: + return THREAD_PRIORITY_HIGHEST; default: case thread_priority::normal: return THREAD_PRIORITY_NORMAL; } } -// Set the thread priority (or process if thread priority is not available). +// Set the thread priority. +// TODO: handle error conditions. +// TODO: handle potential lack of PRIO_THREAD +// TODO: use proper non-win32 priority levels. +// TODO: Linux: pthread_setschedprio() +// TOOD: macOS: somethign else. void set_priority(thread_priority priority) NOEXCEPT { const auto prioritization = get_priority(priority); #if defined(HAVE_MSC) + // learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/ + // nf-processthreadsapi-getthreadpriority SetThreadPriority(GetCurrentThread(), prioritization); + #elif defined(PRIO_THREAD) + // lore.kernel.org/lkml/1220278355.3866.21.camel@localhost.localdomain/ setpriority(PRIO_THREAD, pthread_self(), prioritization); + #else + // BUGBUG: This will set all threads in the process. + // man7.org/linux/man-pages/man3/pthread_self.3.html setpriority(PRIO_PROCESS, getpid(), prioritization); #endif } diff --git a/test/async/thread.cpp b/test/async/thread.cpp index eb1caa455..cfa3b6293 100644 --- a/test/async/thread.cpp +++ b/test/async/thread.cpp @@ -65,6 +65,8 @@ BOOST_AUTO_TEST_CASE(thread__set_thread_priorites__all__set_as_expected) // Save so we can restore at the end of this test case. const int save = get_thread_priority_test(); + set_priority(thread_priority::highest); + BOOST_REQUIRE_EQUAL(THREAD_PRIORITY_HIGHEST, get_thread_priority_test()); set_priority(thread_priority::high); BOOST_REQUIRE_EQUAL(THREAD_PRIORITY_ABOVE_NORMAL, get_thread_priority_test()); set_priority(thread_priority::normal); @@ -87,6 +89,7 @@ BOOST_AUTO_TEST_CASE(thread__set_thread_priorites__all__set_as_expected) const int save = get_thread_priority_test(); // Haven't had any luck matching the set and get priority calls as in win. + BOOST_REQUIRE_NO_THROW(set_priority(thread_priority::highest)); BOOST_REQUIRE_NO_THROW(set_priority(thread_priority::high)); BOOST_REQUIRE_NO_THROW(set_priority(thread_priority::normal)); BOOST_REQUIRE_NO_THROW(set_priority(thread_priority::low));