summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Ziller <eike.ziller@qt.io>2021-11-17 09:47:27 +0100
committerEike Ziller <eike.ziller@qt.io>2022-03-02 10:21:28 +0000
commita8ed6c28965138fa1f2449e4ce3e9f391380d17b (patch)
treed57ef990bebd0b5937a2e6ccba720dd2ef8a4d61
parent32cfcdbec2082cc01d2b4c0b01590a7996c5969c (diff)
Fix performance issue on macOSrelease_140-based
From the getpriority manpage: "When a thread or process is in a background state the scheduling priority is set to the lowest value, disk IO is throttled, and network IO is throttled for any sockets opened after going into background state.". The IO throttling when putting threads into background state absolutely kills the indexing performance, and makes the multi-threading ineffective. Independent of the number of working threads, the actual performance was reduced to something similar to a single thread. Instead of putting the indexing threads into background state, just set their scheduling priority to the minimum. Change-Id: Id5069df9c88ff1c00d2f6810fcddd4cff745feeb Reviewed-by: Cristian Adam <cristian.adam@qt.io>
-rw-r--r--llvm/lib/Support/Unix/Threading.inc52
1 files changed, 24 insertions, 28 deletions
diff --git a/llvm/lib/Support/Unix/Threading.inc b/llvm/lib/Support/Unix/Threading.inc
index 5de1cf071ba9..c1c266c0ab4f 100644
--- a/llvm/lib/Support/Unix/Threading.inc
+++ b/llvm/lib/Support/Unix/Threading.inc
@@ -247,38 +247,34 @@ void llvm::get_thread_name(SmallVectorImpl<char> &Name) {
}
SetThreadPriorityResult llvm::set_thread_priority(ThreadPriority Priority) {
-#if defined(__linux__) && defined(SCHED_IDLE)
- // Some *really* old glibcs are missing SCHED_IDLE.
+#if defined(__linux__) || defined(__APPLE__)
+ int policy;
+ sched_param priority;
+#if defined(SCHED_IDLE)
// http://man7.org/linux/man-pages/man3/pthread_setschedparam.3.html
// http://man7.org/linux/man-pages/man2/sched_setscheduler.2.html
- sched_param priority;
- // For each of the above policies, param->sched_priority must be 0.
- priority.sched_priority = 0;
// SCHED_IDLE for running very low priority background jobs.
// SCHED_OTHER the standard round-robin time-sharing policy;
- return !pthread_setschedparam(
- pthread_self(),
- Priority == ThreadPriority::Background ? SCHED_IDLE : SCHED_OTHER,
- &priority)
- ? SetThreadPriorityResult::SUCCESS
- : SetThreadPriorityResult::FAILURE;
-#elif defined(__APPLE__)
- // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getpriority.2.html
- // When setting a thread into background state the scheduling priority is set
- // to lowest value, disk and network IO are throttled. Network IO will be
- // throttled for any sockets the thread opens after going into background
- // state. Any previously opened sockets are not affected.
-
- // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man3/getiopolicy_np.3.html
- // I/Os with THROTTLE policy are called THROTTLE I/Os. If a THROTTLE I/O
- // request occurs within a small time window (usually a fraction of a second)
- // of another NORMAL I/O request, the thread that issues the THROTTLE I/O is
- // forced to sleep for a certain interval. This slows down the thread that
- // issues the THROTTLE I/O so that NORMAL I/Os can utilize most of the disk
- // I/O bandwidth.
- return !setpriority(PRIO_DARWIN_THREAD, 0,
- Priority == ThreadPriority::Background ? PRIO_DARWIN_BG
- : 0)
+ policy = Priority == ThreadPriority::Background ? SCHED_IDLE : SCHED_OTHER;
+ // For each of the above policies, param->sched_priority must be 0.
+ priority.sched_priority = 0;
+#else
+ // Apple, and some *really* old glibcs are missing SCHED_IDLE.
+ if (pthread_getschedparam(pthread_self(), &policy, &priority) != 0) {
+ return SetThreadPriorityResult::FAILURE;
+ }
+ // Keep the policy. Set priority depending on ThreadPriority
+ if (Priority == ThreadPriority::Background) {
+ // low priority
+ priority.sched_priority = sched_get_priority_min(policy);
+ } else {
+ // middle priority
+ const int minPrio = sched_get_priority_min(policy);
+ const int maxPrio = sched_get_priority_max(policy);
+ priority.sched_priority = std::max(0, maxPrio - minPrio) / 2 + minPrio;
+ }
+#endif
+ return !pthread_setschedparam(pthread_self(), policy, &priority)
? SetThreadPriorityResult::SUCCESS
: SetThreadPriorityResult::FAILURE;
#endif