This switches CrashRecoveryContext to using ManagedStatic for its global Mutex and

global ThreadLocals, thereby getting rid of the load-time initialization of those 
objects and also getting rid of their destruction unless the LLVM client calls 
llvm_shutdown.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190617 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Filip Pizlo 2013-09-12 17:46:57 +00:00
parent 1f1bd9a54d
commit 63fe0669ad

View File

@ -11,6 +11,7 @@
#include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallString.h"
#include "llvm/Config/config.h" #include "llvm/Config/config.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Mutex.h" #include "llvm/Support/Mutex.h"
#include "llvm/Support/ThreadLocal.h" #include "llvm/Support/ThreadLocal.h"
#include <cstdio> #include <cstdio>
@ -21,7 +22,7 @@ namespace {
struct CrashRecoveryContextImpl; struct CrashRecoveryContextImpl;
static sys::ThreadLocal<const CrashRecoveryContextImpl> CurrentContext; static ManagedStatic<sys::ThreadLocal<const CrashRecoveryContextImpl> > CurrentContext;
struct CrashRecoveryContextImpl { struct CrashRecoveryContextImpl {
CrashRecoveryContext *CRC; CrashRecoveryContext *CRC;
@ -34,11 +35,11 @@ public:
CrashRecoveryContextImpl(CrashRecoveryContext *CRC) : CRC(CRC), CrashRecoveryContextImpl(CrashRecoveryContext *CRC) : CRC(CRC),
Failed(false), Failed(false),
SwitchedThread(false) { SwitchedThread(false) {
CurrentContext.set(this); CurrentContext->set(this);
} }
~CrashRecoveryContextImpl() { ~CrashRecoveryContextImpl() {
if (!SwitchedThread) if (!SwitchedThread)
CurrentContext.erase(); CurrentContext->erase();
} }
/// \brief Called when the separate crash-recovery thread was finished, to /// \brief Called when the separate crash-recovery thread was finished, to
@ -48,7 +49,7 @@ public:
void HandleCrash() { void HandleCrash() {
// Eliminate the current context entry, to avoid re-entering in case the // Eliminate the current context entry, to avoid re-entering in case the
// cleanup code crashes. // cleanup code crashes.
CurrentContext.erase(); CurrentContext->erase();
assert(!Failed && "Crash recovery context already failed!"); assert(!Failed && "Crash recovery context already failed!");
Failed = true; Failed = true;
@ -62,10 +63,10 @@ public:
} }
static sys::Mutex gCrashRecoveryContexMutex; static ManagedStatic<sys::Mutex> gCrashRecoveryContextMutex;
static bool gCrashRecoveryEnabled = false; static bool gCrashRecoveryEnabled = false;
static sys::ThreadLocal<const CrashRecoveryContextCleanup> static ManagedStatic<sys::ThreadLocal<const CrashRecoveryContextCleanup> >
tlIsRecoveringFromCrash; tlIsRecoveringFromCrash;
CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() {} CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() {}
@ -73,7 +74,7 @@ CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() {}
CrashRecoveryContext::~CrashRecoveryContext() { CrashRecoveryContext::~CrashRecoveryContext() {
// Reclaim registered resources. // Reclaim registered resources.
CrashRecoveryContextCleanup *i = head; CrashRecoveryContextCleanup *i = head;
tlIsRecoveringFromCrash.set(head); tlIsRecoveringFromCrash->set(head);
while (i) { while (i) {
CrashRecoveryContextCleanup *tmp = i; CrashRecoveryContextCleanup *tmp = i;
i = tmp->next; i = tmp->next;
@ -81,21 +82,21 @@ CrashRecoveryContext::~CrashRecoveryContext() {
tmp->recoverResources(); tmp->recoverResources();
delete tmp; delete tmp;
} }
tlIsRecoveringFromCrash.erase(); tlIsRecoveringFromCrash->erase();
CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl; CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl;
delete CRCI; delete CRCI;
} }
bool CrashRecoveryContext::isRecoveringFromCrash() { bool CrashRecoveryContext::isRecoveringFromCrash() {
return tlIsRecoveringFromCrash.get() != 0; return tlIsRecoveringFromCrash->get() != 0;
} }
CrashRecoveryContext *CrashRecoveryContext::GetCurrent() { CrashRecoveryContext *CrashRecoveryContext::GetCurrent() {
if (!gCrashRecoveryEnabled) if (!gCrashRecoveryEnabled)
return 0; return 0;
const CrashRecoveryContextImpl *CRCI = CurrentContext.get(); const CrashRecoveryContextImpl *CRCI = CurrentContext->get();
if (!CRCI) if (!CRCI)
return 0; return 0;
@ -154,7 +155,7 @@ CrashRecoveryContext::unregisterCleanup(CrashRecoveryContextCleanup *cleanup) {
static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo)
{ {
// Lookup the current thread local recovery object. // Lookup the current thread local recovery object.
const CrashRecoveryContextImpl *CRCI = CurrentContext.get(); const CrashRecoveryContextImpl *CRCI = CurrentContext->get();
if (!CRCI) { if (!CRCI) {
// Something has gone horribly wrong, so let's just tell everyone // Something has gone horribly wrong, so let's just tell everyone
@ -182,7 +183,7 @@ static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo)
static sys::ThreadLocal<const void> sCurrentExceptionHandle; static sys::ThreadLocal<const void> sCurrentExceptionHandle;
void CrashRecoveryContext::Enable() { void CrashRecoveryContext::Enable() {
sys::ScopedLock L(gCrashRecoveryContexMutex); sys::ScopedLock L(*gCrashRecoveryContextMutex);
if (gCrashRecoveryEnabled) if (gCrashRecoveryEnabled)
return; return;
@ -198,7 +199,7 @@ void CrashRecoveryContext::Enable() {
} }
void CrashRecoveryContext::Disable() { void CrashRecoveryContext::Disable() {
sys::ScopedLock L(gCrashRecoveryContexMutex); sys::ScopedLock L(*gCrashRecoveryContextMutex);
if (!gCrashRecoveryEnabled) if (!gCrashRecoveryEnabled)
return; return;
@ -236,7 +237,7 @@ static struct sigaction PrevActions[NumSignals];
static void CrashRecoverySignalHandler(int Signal) { static void CrashRecoverySignalHandler(int Signal) {
// Lookup the current thread local recovery object. // Lookup the current thread local recovery object.
const CrashRecoveryContextImpl *CRCI = CurrentContext.get(); const CrashRecoveryContextImpl *CRCI = CurrentContext->get();
if (!CRCI) { if (!CRCI) {
// We didn't find a crash recovery context -- this means either we got a // We didn't find a crash recovery context -- this means either we got a
@ -267,7 +268,7 @@ static void CrashRecoverySignalHandler(int Signal) {
} }
void CrashRecoveryContext::Enable() { void CrashRecoveryContext::Enable() {
sys::ScopedLock L(gCrashRecoveryContexMutex); sys::ScopedLock L(*gCrashRecoveryContextMutex);
if (gCrashRecoveryEnabled) if (gCrashRecoveryEnabled)
return; return;
@ -286,7 +287,7 @@ void CrashRecoveryContext::Enable() {
} }
void CrashRecoveryContext::Disable() { void CrashRecoveryContext::Disable() {
sys::ScopedLock L(gCrashRecoveryContexMutex); sys::ScopedLock L(*gCrashRecoveryContextMutex);
if (!gCrashRecoveryEnabled) if (!gCrashRecoveryEnabled)
return; return;