[compiler-rt] d9afba9 - tsan: extend MutexSet to memorize mutex address/stack_id
Dmitry Vyukov via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 12 04:18:48 PDT 2021
Author: Dmitry Vyukov
Date: 2021-08-12T13:18:43+02:00
New Revision: d9afba9000a73ea4b800cb748114c821a2ca0394
URL: https://github.com/llvm/llvm-project/commit/d9afba9000a73ea4b800cb748114c821a2ca0394
DIFF: https://github.com/llvm/llvm-project/commit/d9afba9000a73ea4b800cb748114c821a2ca0394.diff
LOG: tsan: extend MutexSet to memorize mutex address/stack_id
We currently memorize u64 id + epoch for each mutex.
The new tsan runtime will memorize address + stack_id instead.
But switching to address + stack_id requires new trace,
which in turn requires new MutexSet and some other changes.
Extend MutexSet to support both new and old info to break
the dependency cycles. The plan is to remove the old
info/methods after switching to the new runtime.
Reviewed By: vitalybuka, melver
Differential Revision: https://reviews.llvm.org/D107910
Added:
Modified:
compiler-rt/lib/tsan/rtl/tsan_mutexset.cpp
compiler-rt/lib/tsan/rtl/tsan_mutexset.h
Removed:
################################################################################
diff --git a/compiler-rt/lib/tsan/rtl/tsan_mutexset.cpp b/compiler-rt/lib/tsan/rtl/tsan_mutexset.cpp
index 813fa3bca9366..d76febff2764b 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_mutexset.cpp
+++ b/compiler-rt/lib/tsan/rtl/tsan_mutexset.cpp
@@ -17,7 +17,6 @@ namespace __tsan {
const uptr MutexSet::kMaxSize;
MutexSet::MutexSet() {
- size_ = 0;
internal_memset(&descs_, 0, sizeof(descs_));
}
@@ -44,9 +43,12 @@ void MutexSet::Add(u64 id, bool write, u64 epoch) {
CHECK_EQ(size_, kMaxSize - 1);
}
// Add new mutex descriptor.
+ descs_[size_].addr = 0;
+ descs_[size_].stack_id = kInvalidStackID;
descs_[size_].id = id;
descs_[size_].write = write;
descs_[size_].epoch = epoch;
+ descs_[size_].seq = seq_++;
descs_[size_].count = 1;
size_++;
}
@@ -70,6 +72,46 @@ void MutexSet::Remove(u64 id) {
}
}
+void MutexSet::AddAddr(uptr addr, StackID stack_id, bool write) {
+ // Look up existing mutex with the same id.
+ for (uptr i = 0; i < size_; i++) {
+ if (descs_[i].addr == addr) {
+ descs_[i].count++;
+ descs_[i].seq = seq_++;
+ return;
+ }
+ }
+ // On overflow, find the oldest mutex and drop it.
+ if (size_ == kMaxSize) {
+ uptr min = 0;
+ for (uptr i = 0; i < size_; i++) {
+ if (descs_[i].seq < descs_[min].seq)
+ min = i;
+ }
+ RemovePos(min);
+ CHECK_EQ(size_, kMaxSize - 1);
+ }
+ // Add new mutex descriptor.
+ descs_[size_].addr = addr;
+ descs_[size_].stack_id = stack_id;
+ descs_[size_].id = 0;
+ descs_[size_].write = write;
+ descs_[size_].epoch = 0;
+ descs_[size_].seq = seq_++;
+ descs_[size_].count = 1;
+ size_++;
+}
+
+void MutexSet::DelAddr(uptr addr, bool destroy) {
+ for (uptr i = 0; i < size_; i++) {
+ if (descs_[i].addr == addr) {
+ if (destroy || --descs_[i].count == 0)
+ RemovePos(i);
+ return;
+ }
+ }
+}
+
void MutexSet::RemovePos(uptr i) {
CHECK_LT(i, size_);
descs_[i] = descs_[size_ - 1];
diff --git a/compiler-rt/lib/tsan/rtl/tsan_mutexset.h b/compiler-rt/lib/tsan/rtl/tsan_mutexset.h
index d63881f402909..606106f711453 100644
--- a/compiler-rt/lib/tsan/rtl/tsan_mutexset.h
+++ b/compiler-rt/lib/tsan/rtl/tsan_mutexset.h
@@ -23,9 +23,12 @@ class MutexSet {
// The oldest mutexes are discarded on overflow.
static const uptr kMaxSize = 16;
struct Desc {
+ uptr addr;
+ StackID stack_id;
u64 id;
u64 epoch;
- int count;
+ u32 seq;
+ u32 count;
bool write;
};
@@ -34,21 +37,24 @@ class MutexSet {
void Add(u64 id, bool write, u64 epoch);
void Del(u64 id, bool write);
void Remove(u64 id); // Removes the mutex completely (if it's destroyed).
+ void AddAddr(uptr addr, StackID stack_id, bool write);
+ void DelAddr(uptr addr, bool destroy = false);
uptr Size() const;
Desc Get(uptr i) const;
+ MutexSet(const MutexSet& other) { *this = other; }
void operator=(const MutexSet &other) {
internal_memcpy(this, &other, sizeof(*this));
}
private:
#if !SANITIZER_GO
- uptr size_;
+ u32 seq_ = 0;
+ uptr size_ = 0;
Desc descs_[kMaxSize];
-#endif
void RemovePos(uptr i);
- MutexSet(const MutexSet&);
+#endif
};
// Go does not have mutexes, so do not spend memory and time.
@@ -59,7 +65,8 @@ MutexSet::MutexSet() {}
void MutexSet::Add(u64 id, bool write, u64 epoch) {}
void MutexSet::Del(u64 id, bool write) {}
void MutexSet::Remove(u64 id) {}
-void MutexSet::RemovePos(uptr i) {}
+void MutexSet::AddAddr(uptr addr, StackID stack_id, bool write) {}
+void MutexSet::DelAddr(uptr addr, bool destroy) {}
uptr MutexSet::Size() const { return 0; }
MutexSet::Desc MutexSet::Get(uptr i) const { return Desc(); }
#endif
More information about the llvm-commits
mailing list