diff options
author | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-10-10 21:57:12 +0000 |
---|---|---|
committer | Argyrios Kyrtzidis <akyrtzi@gmail.com> | 2011-10-10 21:57:12 +0000 |
commit | ebf0136956c829b27520a05706d2f24abd26efe9 (patch) | |
tree | 57f3db704fdc318a79dc58c333d8227af38dd098 | |
parent | 7989460a1fba308128a7993cbabd178d2cc5ffa8 (diff) | |
download | bcm5719-llvm-ebf0136956c829b27520a05706d2f24abd26efe9.tar.gz bcm5719-llvm-ebf0136956c829b27520a05706d2f24abd26efe9.zip |
[libclang] Implement ConcurrencyCheck using a recursive mutex to allow re-entrancy in the same thread.
The checks are performed only in DEBUG, it becomes no-op in release mode.
llvm-svn: 141582
-rw-r--r-- | clang/include/clang/Frontend/ASTUnit.h | 38 | ||||
-rw-r--r-- | clang/lib/Frontend/ASTUnit.cpp | 30 |
2 files changed, 50 insertions, 18 deletions
diff --git a/clang/include/clang/Frontend/ASTUnit.h b/clang/include/clang/Frontend/ASTUnit.h index 074b4174be1..91c4398d0f1 100644 --- a/clang/include/clang/Frontend/ASTUnit.h +++ b/clang/include/clang/Frontend/ASTUnit.h @@ -151,16 +151,6 @@ private: /// destroyed. SmallVector<llvm::sys::Path, 4> TemporaryFiles; - /// \brief Simple hack to allow us to assert that ASTUnit is not being - /// used concurrently, which is not supported. - /// - /// Clients should create instances of the ConcurrencyCheck class whenever - /// using the ASTUnit in a way that isn't intended to be concurrent, which is - /// just about any usage. - unsigned int ConcurrencyCheckValue; - static const unsigned int CheckLocked = 28573289; - static const unsigned int CheckUnlocked = 9803453; - /// \brief Counter that determines when we want to try building a /// precompiled preamble. /// @@ -406,21 +396,37 @@ private: unsigned MaxLines = 0); void RealizeTopLevelDeclsFromPreamble(); + /// \brief Allows us to assert that ASTUnit is not being used concurrently, + /// which is not supported. + /// + /// Clients should create instances of the ConcurrencyCheck class whenever + /// using the ASTUnit in a way that isn't intended to be concurrent, which is + /// just about any usage. + /// Becomes a noop in release mode; only useful for debug mode checking. + class ConcurrencyState { + void *Mutex; // a llvm::sys::MutexImpl in debug; + + public: + ConcurrencyState(); + ~ConcurrencyState(); + + void start(); + void finish(); + }; + ConcurrencyState ConcurrencyCheckValue; + public: class ConcurrencyCheck { - volatile ASTUnit &Self; + ASTUnit &Self; public: explicit ConcurrencyCheck(ASTUnit &Self) : Self(Self) { - assert(Self.ConcurrencyCheckValue == CheckUnlocked && - "Concurrent access to ASTUnit!"); - Self.ConcurrencyCheckValue = CheckLocked; + Self.ConcurrencyCheckValue.start(); } - ~ConcurrencyCheck() { - Self.ConcurrencyCheckValue = CheckUnlocked; + Self.ConcurrencyCheckValue.finish(); } }; friend class ConcurrencyCheck; diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index e84f8bd6e29..c2c67c12291 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -45,6 +45,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Timer.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Mutex.h" #include "llvm/Support/CrashRecoveryContext.h" #include <cstdlib> #include <cstdio> @@ -99,7 +100,6 @@ ASTUnit::ASTUnit(bool _MainFileIsAST) TUKind(TU_Complete), WantTiming(getenv("LIBCLANG_TIMING")), OwnsRemappedFileBuffers(true), NumStoredDiagnosticsFromDriver(0), - ConcurrencyCheckValue(CheckUnlocked), PreambleRebuildCounter(0), SavedMainFileBuffer(0), PreambleBuffer(0), ShouldCacheCodeCompletionResults(false), NestedMacroExpansions(true), @@ -114,7 +114,6 @@ ASTUnit::ASTUnit(bool _MainFileIsAST) } ASTUnit::~ASTUnit() { - ConcurrencyCheckValue = CheckLocked; CleanTemporaryFiles(); if (!PreambleFile.empty()) llvm::sys::Path(PreambleFile).eraseFromDisk(); @@ -2414,3 +2413,30 @@ void ASTUnit::PreambleData::countLines() const { if (Buffer.back() != '\n') ++NumLines; } + +#ifndef NDEBUG +ASTUnit::ConcurrencyState::ConcurrencyState() { + Mutex = new llvm::sys::MutexImpl(/*recursive=*/true); +} + +ASTUnit::ConcurrencyState::~ConcurrencyState() { + delete static_cast<llvm::sys::MutexImpl *>(Mutex); +} + +void ASTUnit::ConcurrencyState::start() { + bool acquired = static_cast<llvm::sys::MutexImpl *>(Mutex)->tryacquire(); + assert(acquired && "Concurrent access to ASTUnit!"); +} + +void ASTUnit::ConcurrencyState::finish() { + static_cast<llvm::sys::MutexImpl *>(Mutex)->release(); +} + +#else // NDEBUG + +ASTUnit::ConcurrencyState::ConcurrencyState() {} +ASTUnit::ConcurrencyState::~ConcurrencyState() {} +void ASTUnit::ConcurrencyState::start() {} +void ASTUnit::ConcurrencyState::finish() {} + +#endif |