X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FSupport%2FCrashRecoveryContext.cpp;h=899c3890d78a9940b9f1e2391f375080f70b139c;hb=49fcf571da21c6763776f00c814a5ee50bd8a923;hp=93af79bc0f564df3d360b42c5b116cac557099f2;hpb=d49e2aa5b89758b3b8841fa427e3c9e90f2e30b2;p=oota-llvm.git diff --git a/lib/Support/CrashRecoveryContext.cpp b/lib/Support/CrashRecoveryContext.cpp index 93af79bc0f5..899c3890d78 100644 --- a/lib/Support/CrashRecoveryContext.cpp +++ b/lib/Support/CrashRecoveryContext.cpp @@ -10,8 +10,8 @@ #include "llvm/Support/CrashRecoveryContext.h" #include "llvm/ADT/SmallString.h" #include "llvm/Config/config.h" -#include "llvm/System/Mutex.h" -#include "llvm/System/ThreadLocal.h" +#include "llvm/Support/Mutex.h" +#include "llvm/Support/ThreadLocal.h" #include #include using namespace llvm; @@ -57,12 +57,36 @@ public: static sys::Mutex gCrashRecoveryContexMutex; static bool gCrashRecoveryEnabled = false; +static sys::ThreadLocal + tlIsRecoveringFromCrash; + +CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() {} + CrashRecoveryContext::~CrashRecoveryContext() { + // Reclaim registered resources. + CrashRecoveryContextCleanup *i = head; + tlIsRecoveringFromCrash.set(head); + while (i) { + CrashRecoveryContextCleanup *tmp = i; + i = tmp->next; + tmp->cleanupFired = true; + tmp->recoverResources(); + delete tmp; + } + tlIsRecoveringFromCrash.erase(); + CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl; delete CRCI; } +bool CrashRecoveryContext::isRecoveringFromCrash() { + return tlIsRecoveringFromCrash.get() != 0; +} + CrashRecoveryContext *CrashRecoveryContext::GetCurrent() { + if (!gCrashRecoveryEnabled) + return 0; + const CrashRecoveryContextImpl *CRCI = CurrentContext.get(); if (!CRCI) return 0; @@ -70,6 +94,33 @@ CrashRecoveryContext *CrashRecoveryContext::GetCurrent() { return CRCI->CRC; } +void CrashRecoveryContext::registerCleanup(CrashRecoveryContextCleanup *cleanup) +{ + if (!cleanup) + return; + if (head) + head->prev = cleanup; + cleanup->next = head; + head = cleanup; +} + +void +CrashRecoveryContext::unregisterCleanup(CrashRecoveryContextCleanup *cleanup) { + if (!cleanup) + return; + if (cleanup == head) { + head = cleanup->next; + if (head) + head->prev = 0; + } + else { + cleanup->prev->next = cleanup->next; + if (cleanup->next) + cleanup->next->prev = cleanup->prev; + } + delete cleanup; +} + #ifdef LLVM_ON_WIN32 // FIXME: No real Win32 implementation currently. @@ -205,3 +256,26 @@ const std::string &CrashRecoveryContext::getBacktrace() const { assert(CRC->Failed && "No crash was detected!"); return CRC->Backtrace; } + +// + +namespace { +struct RunSafelyOnThreadInfo { + void (*UserFn)(void*); + void *UserData; + CrashRecoveryContext *CRC; + bool Result; +}; +} + +static void RunSafelyOnThread_Dispatch(void *UserData) { + RunSafelyOnThreadInfo *Info = + reinterpret_cast(UserData); + Info->Result = Info->CRC->RunSafely(Info->UserFn, Info->UserData); +} +bool CrashRecoveryContext::RunSafelyOnThread(void (*Fn)(void*), void *UserData, + unsigned RequestedStackSize) { + RunSafelyOnThreadInfo Info = { Fn, UserData, this, false }; + llvm_execute_on_thread(RunSafelyOnThread_Dispatch, &Info, RequestedStackSize); + return Info.Result; +}