stefanhaller created this revision. Herald added subscribers: dexonsmith, usaxena95, kadircet, arphaman, hiraditya. Herald added a project: All. stefanhaller requested review of this revision. Herald added subscribers: cfe-commits, llvm-commits, ilya-biryukov. Herald added projects: clang, LLVM, clang-tools-extra.
On Apple Silicon Macs, using a Darwin thread priority of PRIO_DARWIN_BG seems to map directly to the QoS class Background. With this priority, the thread is confined to efficiency cores only, which makes background indexing take forever. Change this to use QoS class Utility instead; this makes the thread run on all cores, but still lowers priority enough to keep the machine responsive, and not interfere with user-initiated actions. Also, rename ThreadPriority::Background to ThreadPriority::Low; this avoids confusion with the QoS class Background, and allows to reintroduce ThreadPriority::Background later, should there be a need for it. We might consider changing the Windows and Linux implementations too (e.g. using SCHED_BATCH instead of SCHED_IDLE on Linux). I didn't do that here because I don't have access to these systems to test it on. See also https://github.com/clangd/clangd/issues/1119. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D124715 Files: clang-tools-extra/clangd/index/Background.h clang/tools/libclang/CIndex.cpp llvm/include/llvm/Support/Threading.h llvm/lib/Support/Unix/Threading.inc llvm/lib/Support/Windows/Threading.inc
Index: llvm/lib/Support/Windows/Threading.inc =================================================================== --- llvm/lib/Support/Windows/Threading.inc +++ 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::Low ? THREAD_MODE_BACKGROUND_BEGIN : THREAD_MODE_BACKGROUND_END) ? SetThreadPriorityResult::SUCCESS Index: llvm/lib/Support/Unix/Threading.inc =================================================================== --- llvm/lib/Support/Unix/Threading.inc +++ llvm/lib/Support/Unix/Threading.inc @@ -18,6 +18,7 @@ #if defined(__APPLE__) #include <mach/mach_init.h> #include <mach/mach_port.h> +#include <pthread/qos.h> #endif #include <pthread.h> @@ -258,27 +259,20 @@ // SCHED_OTHER the standard round-robin time-sharing policy; return !pthread_setschedparam( pthread_self(), - Priority == ThreadPriority::Background ? SCHED_IDLE : SCHED_OTHER, + Priority == ThreadPriority::Low ? 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) + // https://developer.apple.com/documentation/apple-silicon/tuning-your-code-s-performance-for-apple-silicon + // 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. + return !pthread_set_qos_class_self_np(Priority == ThreadPriority::Low + ? QOS_CLASS_UTILITY + : QOS_CLASS_DEFAULT, + 0) ? SetThreadPriorityResult::SUCCESS : SetThreadPriorityResult::FAILURE; #endif Index: llvm/include/llvm/Support/Threading.h =================================================================== --- llvm/include/llvm/Support/Threading.h +++ llvm/include/llvm/Support/Threading.h @@ -233,7 +233,7 @@ unsigned get_cpus(); enum class ThreadPriority { - Background = 0, + Low = 0, Default = 1, }; /// If priority is Background tries to lower current threads priority such Index: clang/tools/libclang/CIndex.cpp =================================================================== --- clang/tools/libclang/CIndex.cpp +++ 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 } Index: clang-tools-extra/clangd/index/Background.h =================================================================== --- clang-tools-extra/clangd/index/Background.h +++ clang-tools-extra/clangd/index/Background.h @@ -72,7 +72,7 @@ explicit Task(std::function<void()> Run) : Run(std::move(Run)) {} std::function<void()> 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.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits