[bolt] Use llvm::sys::RWMutex instead of std::shared_timed_mutex

This has the following advantages:
- std::shared_timed_mutex is macOS 10.12+ only. llvm::sys::RWMutex
  automatically switches to a different implementation internally
  when targeting older macOS versions.
- bolt only needs std::shared_mutex, not std::shared_timed_mutex.
  llvm::sys::RWMutex automatically uses std::shared_mutex internally
  where available.

std::shared_mutex and RWMutex have the same API, so no code changes
other than types and includes are needed.

Differential Revision: https://reviews.llvm.org/D138423
This commit is contained in:
Nico Weber
2022-11-21 08:45:45 -05:00
parent 99b3849d89
commit e8ce5f1ec9
10 changed files with 29 additions and 26 deletions

View File

@@ -37,12 +37,12 @@
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/RWMutex.h"
#include "llvm/Support/raw_ostream.h"
#include <functional>
#include <list>
#include <map>
#include <set>
#include <shared_mutex>
#include <string>
#include <system_error>
#include <type_traits>
@@ -190,7 +190,7 @@ class BinaryContext {
std::map<uint64_t, BinaryFunction> BinaryFunctions;
/// A mutex that is used to control parallel accesses to BinaryFunctions
mutable std::shared_timed_mutex BinaryFunctionsMutex;
mutable llvm::sys::RWMutex BinaryFunctionsMutex;
/// Functions injected by BOLT
std::vector<BinaryFunction *> InjectedBinaryFunctions;
@@ -420,7 +420,7 @@ public:
std::unordered_map<const MCSymbol *, BinaryFunction *> SymbolToFunctionMap;
/// A mutex that is used to control parallel accesses to SymbolToFunctionMap
mutable std::shared_timed_mutex SymbolToFunctionMapMutex;
mutable llvm::sys::RWMutex SymbolToFunctionMapMutex;
/// Look up the symbol entry that contains the given \p Address (based on
/// the start address and size for each symbol). Returns a pointer to
@@ -556,9 +556,9 @@ public:
std::unique_ptr<MCContext> Ctx;
/// A mutex that is used to control parallel accesses to Ctx
mutable std::shared_timed_mutex CtxMutex;
std::unique_lock<std::shared_timed_mutex> scopeLock() const {
return std::unique_lock<std::shared_timed_mutex>(CtxMutex);
mutable llvm::sys::RWMutex CtxMutex;
std::unique_lock<llvm::sys::RWMutex> scopeLock() const {
return std::unique_lock<llvm::sys::RWMutex>(CtxMutex);
}
std::unique_ptr<DWARFContext> DwCtx;

View File

@@ -45,6 +45,7 @@
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/RWMutex.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <iterator>
@@ -1166,7 +1167,7 @@ public:
MCSymbol *&FunctionEndLabel = FunctionEndLabels[LabelIndex];
if (!FunctionEndLabel) {
std::unique_lock<std::shared_timed_mutex> Lock(BC.CtxMutex);
std::unique_lock<llvm::sys::RWMutex> Lock(BC.CtxMutex);
if (Fragment == FragmentNum::main())
FunctionEndLabel = BC.Ctx->createNamedTempSymbol("func_end");
else
@@ -1490,7 +1491,7 @@ public:
std::unique_ptr<BinaryBasicBlock>
createBasicBlock(MCSymbol *Label = nullptr) {
if (!Label) {
std::unique_lock<std::shared_timed_mutex> Lock(BC.CtxMutex);
std::unique_lock<llvm::sys::RWMutex> Lock(BC.CtxMutex);
Label = BC.Ctx->createNamedTempSymbol("BB");
}
auto BB =

View File

@@ -16,6 +16,7 @@
#define BOLT_PASSES_ALIGNER_H
#include "bolt/Passes/BinaryPasses.h"
#include "llvm/Support/RWMutex.h"
namespace llvm {
namespace bolt {
@@ -24,7 +25,7 @@ class AlignerPass : public BinaryFunctionPass {
private:
/// Stats for usage of max bytes for basic block alignment.
std::vector<uint32_t> AlignHistogram;
std::shared_timed_mutex AlignHistogramMtx;
llvm::sys::RWMutex AlignHistogramMtx;
/// Stats: execution count of blocks that were aligned.
std::atomic<uint64_t> AlignedBlocksCount{0};

View File

@@ -19,6 +19,7 @@
#include "bolt/Passes/BinaryPasses.h"
#include "bolt/Passes/InstrumentationSummary.h"
#include "llvm/Support/RWMutex.h"
namespace llvm {
namespace bolt {
@@ -109,7 +110,7 @@ private:
/// strtab indices in StringTable for each function name
std::unordered_map<const BinaryFunction *, uint32_t> FuncToStringIdx;
mutable std::shared_timed_mutex FDMutex;
mutable llvm::sys::RWMutex FDMutex;
/// The data generated during Instrumentation pass that needs to
/// be passed to the Instrument runtime library.

View File

@@ -491,7 +491,7 @@ void BinaryBasicBlock::addBranchInstruction(const BinaryBasicBlock *Successor) {
assert(isSuccessor(Successor));
BinaryContext &BC = Function->getBinaryContext();
MCInst NewInst;
std::unique_lock<std::shared_timed_mutex> Lock(BC.CtxMutex);
std::unique_lock<llvm::sys::RWMutex> Lock(BC.CtxMutex);
BC.MIB->createUncondBranch(NewInst, Successor->getLabel(), BC.Ctx.get());
Instructions.emplace_back(std::move(NewInst));
}

View File

@@ -1316,9 +1316,8 @@ void BinaryContext::foldFunction(BinaryFunction &ChildBF,
assert(!ChildBF.isMultiEntry() && !ParentBF.isMultiEntry() &&
"cannot merge functions with multiple entry points");
std::unique_lock<std::shared_timed_mutex> WriteCtxLock(CtxMutex,
std::defer_lock);
std::unique_lock<std::shared_timed_mutex> WriteSymbolMapLock(
std::unique_lock<llvm::sys::RWMutex> WriteCtxLock(CtxMutex, std::defer_lock);
std::unique_lock<llvm::sys::RWMutex> WriteSymbolMapLock(
SymbolToFunctionMapMutex, std::defer_lock);
const StringRef ChildName = ChildBF.getOneName();
@@ -1343,10 +1342,10 @@ void BinaryContext::foldFunction(BinaryFunction &ChildBF,
// continue to exist and either one can be executed.
ChildBF.mergeProfileDataInto(ParentBF);
std::shared_lock<std::shared_timed_mutex> ReadBfsLock(BinaryFunctionsMutex,
std::defer_lock);
std::unique_lock<std::shared_timed_mutex> WriteBfsLock(BinaryFunctionsMutex,
std::defer_lock);
std::shared_lock<llvm::sys::RWMutex> ReadBfsLock(BinaryFunctionsMutex,
std::defer_lock);
std::unique_lock<llvm::sys::RWMutex> WriteBfsLock(BinaryFunctionsMutex,
std::defer_lock);
// Remove ChildBF from the global set of functions in relocs mode.
ReadBfsLock.lock();
auto FI = BinaryFunctions.find(ChildBF.getAddress());
@@ -2157,7 +2156,7 @@ void BinaryContext::markAmbiguousRelocations(BinaryData &BD,
BinaryFunction *BinaryContext::getFunctionForSymbol(const MCSymbol *Symbol,
uint64_t *EntryDesc) {
std::shared_lock<std::shared_timed_mutex> Lock(SymbolToFunctionMapMutex);
std::shared_lock<llvm::sys::RWMutex> Lock(SymbolToFunctionMapMutex);
auto BFI = SymbolToFunctionMap.find(Symbol);
if (BFI == SymbolToFunctionMap.end())
return nullptr;

View File

@@ -406,7 +406,7 @@ void BinaryFunction::updateEHRanges() {
const MCSymbol *EHSymbol;
MCInst EHLabel;
{
std::unique_lock<std::shared_timed_mutex> Lock(BC.CtxMutex);
std::unique_lock<llvm::sys::RWMutex> Lock(BC.CtxMutex);
EHSymbol = BC.Ctx->createNamedTempSymbol("EH");
BC.MIB->createEHLabel(EHLabel, EHSymbol, BC.Ctx.get());
}

View File

@@ -13,10 +13,10 @@
#include "bolt/Core/ParallelUtilities.h"
#include "bolt/Core/BinaryContext.h"
#include "bolt/Core/BinaryFunction.h"
#include "llvm/Support/RWMutex.h"
#include "llvm/Support/ThreadPool.h"
#include "llvm/Support/Timer.h"
#include <mutex>
#include <shared_mutex>
#define DEBUG_TYPE "par-utils"
@@ -170,13 +170,13 @@ void runOnEachFunctionWithUniqueAllocId(
if (BC.getBinaryFunctions().size() == 0)
return;
std::shared_timed_mutex MainLock;
llvm::sys::RWMutex MainLock;
auto runBlock = [&](std::map<uint64_t, BinaryFunction>::iterator BlockBegin,
std::map<uint64_t, BinaryFunction>::iterator BlockEnd,
MCPlusBuilder::AllocatorIdTy AllocId) {
Timer T(LogName, LogName);
LLVM_DEBUG(T.startTimer());
std::shared_lock<std::shared_timed_mutex> Lock(MainLock);
std::shared_lock<llvm::sys::RWMutex> Lock(MainLock);
for (auto It = BlockBegin; It != BlockEnd; ++It) {
BinaryFunction &BF = It->second;
if (SkipPredicate && SkipPredicate(BF))
@@ -192,7 +192,7 @@ void runOnEachFunctionWithUniqueAllocId(
return;
}
// This lock is used to postpone task execution
std::unique_lock<std::shared_timed_mutex> Lock(MainLock);
std::unique_lock<llvm::sys::RWMutex> Lock(MainLock);
// Estimate the overall runtime cost using the scheduling policy
const unsigned TotalCost = estimateTotalCost(BC, SkipPredicate, SchedPolicy);

View File

@@ -143,7 +143,7 @@ void AlignerPass::alignBlocks(BinaryFunction &Function,
// Update stats.
LLVM_DEBUG(
std::unique_lock<std::shared_timed_mutex> Lock(AlignHistogramMtx);
std::unique_lock<llvm::sys::RWMutex> Lock(AlignHistogramMtx);
AlignHistogram[BytesToUse]++;
AlignedBlocksCount += BB->getKnownExecutionCount();
);

View File

@@ -15,6 +15,7 @@
#include "bolt/RuntimeLibs/InstrumentationRuntimeLibrary.h"
#include "bolt/Utils/Utils.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/RWMutex.h"
#include <stack>
#define DEBUG_TYPE "bolt-instrumentation"
@@ -298,7 +299,7 @@ void Instrumentation::instrumentFunction(BinaryFunction &Function,
FunctionDescription *FuncDesc = nullptr;
{
std::unique_lock<std::shared_timed_mutex> L(FDMutex);
std::unique_lock<llvm::sys::RWMutex> L(FDMutex);
Summary->FunctionDescriptions.emplace_back();
FuncDesc = &Summary->FunctionDescriptions.back();
}