diff --git a/clang-tools-extra/clangd/index/Background.h b/clang-tools-extra/clangd/index/Background.h --- a/clang-tools-extra/clangd/index/Background.h +++ b/clang-tools-extra/clangd/index/Background.h @@ -72,7 +72,7 @@ explicit Task(std::function Run) : Run(std::move(Run)) {} std::function Run; - llvm::ThreadPriority ThreadPri = llvm::ThreadPriority::Background; + llvm::ThreadPriority ThreadPri = llvm::ThreadPriority::Low; unsigned QueuePri = 0; // Higher-priority tasks will run first. std::string Tag; // Allows priority to be boosted later. uint64_t Key = 0; // If the key matches a previous task, drop this one. diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -9025,7 +9025,7 @@ return; #if LLVM_ENABLE_THREADS - llvm::set_thread_priority(llvm::ThreadPriority::Background); + llvm::set_thread_priority(llvm::ThreadPriority::Low); #endif } diff --git a/llvm/include/llvm/Support/Threading.h b/llvm/include/llvm/Support/Threading.h --- a/llvm/include/llvm/Support/Threading.h +++ b/llvm/include/llvm/Support/Threading.h @@ -233,15 +233,20 @@ unsigned get_cpus(); enum class ThreadPriority { + /// Try to lower current thread's priority as much as possible. Can be used + /// for long-running tasks that are not time critical; more energy-efficient + /// than Low. Background = 0, - Default = 1, + + /// Try to lower current thread's priority such that it does not affect + /// foreground tasks significantly. This is a good default for long-running, + /// latency-insensitive tasks to make sure cpu is not hogged by this task. + Low = 1, + + /// Try to restore current thread's priority to default scheduling + /// priority. + Default = 2, }; - /// If priority is Background tries to lower current threads priority such - /// that it does not affect foreground tasks significantly. Can be used for - /// long-running, latency-insensitive tasks to make sure cpu is not hogged by - /// this task. - /// If the priority is default tries to restore current threads priority to - /// default scheduling priority. enum class SetThreadPriorityResult { FAILURE, SUCCESS }; SetThreadPriorityResult set_thread_priority(ThreadPriority Priority); } diff --git a/llvm/lib/Support/Unix/Threading.inc b/llvm/lib/Support/Unix/Threading.inc --- a/llvm/lib/Support/Unix/Threading.inc +++ b/llvm/lib/Support/Unix/Threading.inc @@ -18,6 +18,7 @@ #if defined(__APPLE__) #include #include +#include #endif #include @@ -258,27 +259,28 @@ // SCHED_OTHER the standard round-robin time-sharing policy; return !pthread_setschedparam( pthread_self(), - Priority == ThreadPriority::Background ? SCHED_IDLE : SCHED_OTHER, + Priority == ThreadPriority::Default ? SCHED_OTHER : SCHED_IDLE, &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) + // https://developer.apple.com/documentation/apple-silicon/tuning-your-code-s-performance-for-apple-silicon + // + // Background - Applies to work that isn’t visible to the user and may take significant + // time to complete. Examples include indexing, backing up, or synchronizing data. This + // class emphasizes energy efficiency. + // + // Utility - Applies to work that takes anywhere from a few seconds to a few minutes to + // complete. Examples include downloading a document or importing data. This class + // offers a balance between responsiveness, performance, and energy efficiency. + const auto qosClass = [&](){ + switch (Priority) { + case ThreadPriority::Background: return QOS_CLASS_BACKGROUND; + case ThreadPriority::Low: return QOS_CLASS_UTILITY; + case ThreadPriority::Default: return QOS_CLASS_DEFAULT; + } + }(); + return !pthread_set_qos_class_self_np(qosClass, 0) ? SetThreadPriorityResult::SUCCESS : SetThreadPriorityResult::FAILURE; #endif diff --git a/llvm/lib/Support/Windows/Threading.inc b/llvm/lib/Support/Windows/Threading.inc --- a/llvm/lib/Support/Windows/Threading.inc +++ b/llvm/lib/Support/Windows/Threading.inc @@ -121,7 +121,7 @@ // priorities of the thread as they were before the thread entered background // processing mode. return SetThreadPriority(GetCurrentThread(), - Priority == ThreadPriority::Background + Priority != ThreadPriority::Default ? THREAD_MODE_BACKGROUND_BEGIN : THREAD_MODE_BACKGROUND_END) ? SetThreadPriorityResult::SUCCESS