For CrashRecoveryContext::RunSafelyOnThread, propagate Darwin's PRIO_DARWIN_BG to the new thread if it is

set on the calling thread.

This allows libclang's indexing threads to propagate their priority to the clang module building threads.

rdar://17459872


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@211747 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Argyrios Kyrtzidis 2014-06-25 23:54:50 +00:00
parent f36f20ae7a
commit ce6e7c7a59
2 changed files with 24 additions and 2 deletions

View File

@ -87,6 +87,9 @@ public:
/// requested stack size). /// requested stack size).
/// ///
/// See RunSafely() and llvm_execute_on_thread(). /// See RunSafely() and llvm_execute_on_thread().
///
/// On Darwin, if PRIO_DARWIN_BG is set on the calling thread, it will be
/// propagated to the new thread as well.
bool RunSafelyOnThread(function_ref<void()>, unsigned RequestedStackSize = 0); bool RunSafelyOnThread(function_ref<void()>, unsigned RequestedStackSize = 0);
bool RunSafelyOnThread(void (*Fn)(void*), void *UserData, bool RunSafelyOnThread(void (*Fn)(void*), void *UserData,
unsigned RequestedStackSize = 0) { unsigned RequestedStackSize = 0) {

View File

@ -332,12 +332,26 @@ const std::string &CrashRecoveryContext::getBacktrace() const {
return CRC->Backtrace; return CRC->Backtrace;
} }
// // FIXME: Portability.
static void setThreadBackgroundPriority() {
#ifdef __APPLE__
setpriority(PRIO_DARWIN_THREAD, 0, PRIO_DARWIN_BG);
#endif
}
static bool hasThreadBackgroundPriority() {
#ifdef __APPLE__
return getpriority(PRIO_DARWIN_THREAD, 0) == 1;
#else
return false;
#endif
}
namespace { namespace {
struct RunSafelyOnThreadInfo { struct RunSafelyOnThreadInfo {
function_ref<void()> Fn; function_ref<void()> Fn;
CrashRecoveryContext *CRC; CrashRecoveryContext *CRC;
bool UseBackgroundPriority;
bool Result; bool Result;
}; };
} }
@ -345,11 +359,16 @@ struct RunSafelyOnThreadInfo {
static void RunSafelyOnThread_Dispatch(void *UserData) { static void RunSafelyOnThread_Dispatch(void *UserData) {
RunSafelyOnThreadInfo *Info = RunSafelyOnThreadInfo *Info =
reinterpret_cast<RunSafelyOnThreadInfo*>(UserData); reinterpret_cast<RunSafelyOnThreadInfo*>(UserData);
if (Info->UseBackgroundPriority)
setThreadBackgroundPriority();
Info->Result = Info->CRC->RunSafely(Info->Fn); Info->Result = Info->CRC->RunSafely(Info->Fn);
} }
bool CrashRecoveryContext::RunSafelyOnThread(function_ref<void()> Fn, bool CrashRecoveryContext::RunSafelyOnThread(function_ref<void()> Fn,
unsigned RequestedStackSize) { unsigned RequestedStackSize) {
RunSafelyOnThreadInfo Info = { Fn, this, false }; bool UseBackgroundPriority = hasThreadBackgroundPriority();
RunSafelyOnThreadInfo Info = { Fn, this, UseBackgroundPriority, false };
llvm_execute_on_thread(RunSafelyOnThread_Dispatch, &Info, RequestedStackSize); llvm_execute_on_thread(RunSafelyOnThread_Dispatch, &Info, RequestedStackSize);
if (CrashRecoveryContextImpl *CRC = (CrashRecoveryContextImpl *)Impl) if (CrashRecoveryContextImpl *CRC = (CrashRecoveryContextImpl *)Impl)
CRC->setSwitchedThread(); CRC->setSwitchedThread();