[llvm][Support] Provide interface to set thread priorities

Summary:
We have a multi-platform thread priority setting function(last piece
landed with D58683), I wanted to make this available to all llvm community,
there seem to be other users of such functionality with portability fixmes:
lib/Support/CrashRecoveryContext.cpp
tools/clang/tools/libclang/CIndex.cpp

Reviewers: gribozavr, ioeric

Subscribers: krytarowski, jfb, kristina, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D59130

llvm-svn: 358494
This commit is contained in:
Kadir Cetinkaya 2019-04-16 14:32:43 +00:00
parent 3e8124631e
commit 8fdc5abffe
3 changed files with 68 additions and 0 deletions

View File

@ -167,6 +167,19 @@ void llvm_execute_on_thread(void (*UserFn)(void *), void *UserData,
/// purposes, and as with setting a thread's name no indication of whether
/// the operation succeeded or failed is returned.
void get_thread_name(SmallVectorImpl<char> &Name);
enum class ThreadPriority {
Background = 0,
Default = 1,
};
/// 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);
}
#endif

View File

@ -217,3 +217,42 @@ void llvm::get_thread_name(SmallVectorImpl<char> &Name) {
#endif
#endif
}
SetThreadPriorityResult llvm::set_thread_priority(ThreadPriority Priority) {
#if defined(__linux__) && defined(SCHED_IDLE)
// Some *really* old glibcs are missing 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)
? SetThreadPriorityResult::SUCCESS
: SetThreadPriorityResult::FAILURE;
#endif
return SetThreadPriorityResult::FAILURE;
}

View File

@ -106,3 +106,19 @@ void llvm::get_thread_name(SmallVectorImpl<char> &Name) {
// value.
Name.clear();
}
SetThreadPriorityResult llvm::set_thread_priority(ThreadPriority Priority) {
// https://docs.microsoft.com/en-us/windows/desktop/api/processthreadsapi/nf-processthreadsapi-setthreadpriority
// Begin background processing mode. The system lowers the resource scheduling
// priorities of the thread so that it can perform background work without
// significantly affecting activity in the foreground.
// End background processing mode. The system restores the resource scheduling
// priorities of the thread as they were before the thread entered background
// processing mode.
return SetThreadPriority(GetCurrentThread(),
Priority == ThreadPriority::Background
? THREAD_MODE_BACKGROUND_BEGIN
: THREAD_MODE_BACKGROUND_END)
? SetThreadPriorityResult::SUCCESS
: SetThreadPriorityResult::FAILURE;
}