forked from OSchip/llvm-project
[tsan] Remove special SyncClock::kInvalidTid
Followup for D101428. Reviewed By: dvyukov Differential Revision: https://reviews.llvm.org/D101604
This commit is contained in:
parent
82e99f5035
commit
f0c9d1e95f
|
@ -150,7 +150,7 @@ void ThreadClock::acquire(ClockCache *c, SyncClock *src) {
|
||||||
bool acquired = false;
|
bool acquired = false;
|
||||||
for (unsigned i = 0; i < kDirtyTids; i++) {
|
for (unsigned i = 0; i < kDirtyTids; i++) {
|
||||||
SyncClock::Dirty dirty = src->dirty_[i];
|
SyncClock::Dirty dirty = src->dirty_[i];
|
||||||
unsigned tid = dirty.tid;
|
unsigned tid = dirty.tid();
|
||||||
if (tid != kInvalidTid) {
|
if (tid != kInvalidTid) {
|
||||||
if (clk_[tid] < dirty.epoch) {
|
if (clk_[tid] < dirty.epoch) {
|
||||||
clk_[tid] = dirty.epoch;
|
clk_[tid] = dirty.epoch;
|
||||||
|
@ -299,10 +299,10 @@ void ThreadClock::ReleaseStore(ClockCache *c, SyncClock *dst) {
|
||||||
dst->tab_idx_ = cached_idx_;
|
dst->tab_idx_ = cached_idx_;
|
||||||
dst->size_ = cached_size_;
|
dst->size_ = cached_size_;
|
||||||
dst->blocks_ = cached_blocks_;
|
dst->blocks_ = cached_blocks_;
|
||||||
CHECK_EQ(dst->dirty_[0].tid, kInvalidTid);
|
CHECK_EQ(dst->dirty_[0].tid(), kInvalidTid);
|
||||||
// The cached clock is shared (immutable),
|
// The cached clock is shared (immutable),
|
||||||
// so this is where we store the current clock.
|
// so this is where we store the current clock.
|
||||||
dst->dirty_[0].tid = tid_;
|
dst->dirty_[0].set_tid(tid_);
|
||||||
dst->dirty_[0].epoch = clk_[tid_];
|
dst->dirty_[0].epoch = clk_[tid_];
|
||||||
dst->release_store_tid_ = tid_;
|
dst->release_store_tid_ = tid_;
|
||||||
dst->release_store_reused_ = reused_;
|
dst->release_store_reused_ = reused_;
|
||||||
|
@ -336,8 +336,7 @@ void ThreadClock::ReleaseStore(ClockCache *c, SyncClock *dst) {
|
||||||
ce.reused = 0;
|
ce.reused = 0;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
for (uptr i = 0; i < kDirtyTids; i++)
|
for (uptr i = 0; i < kDirtyTids; i++) dst->dirty_[i].set_tid(kInvalidTid);
|
||||||
dst->dirty_[i].tid = kInvalidTid;
|
|
||||||
dst->release_store_tid_ = tid_;
|
dst->release_store_tid_ = tid_;
|
||||||
dst->release_store_reused_ = reused_;
|
dst->release_store_reused_ = reused_;
|
||||||
// Rememeber that we don't need to acquire it in future.
|
// Rememeber that we don't need to acquire it in future.
|
||||||
|
@ -369,10 +368,10 @@ void ThreadClock::UpdateCurrentThread(ClockCache *c, SyncClock *dst) const {
|
||||||
// Update the threads time, but preserve 'acquired' flag.
|
// Update the threads time, but preserve 'acquired' flag.
|
||||||
for (unsigned i = 0; i < kDirtyTids; i++) {
|
for (unsigned i = 0; i < kDirtyTids; i++) {
|
||||||
SyncClock::Dirty *dirty = &dst->dirty_[i];
|
SyncClock::Dirty *dirty = &dst->dirty_[i];
|
||||||
const unsigned tid = dirty->tid;
|
const unsigned tid = dirty->tid();
|
||||||
if (tid == tid_ || tid == kInvalidTid) {
|
if (tid == tid_ || tid == kInvalidTid) {
|
||||||
CPP_STAT_INC(StatClockReleaseFast);
|
CPP_STAT_INC(StatClockReleaseFast);
|
||||||
dirty->tid = tid_;
|
dirty->set_tid(tid_);
|
||||||
dirty->epoch = clk_[tid_];
|
dirty->epoch = clk_[tid_];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -393,8 +392,8 @@ bool ThreadClock::IsAlreadyAcquired(const SyncClock *src) const {
|
||||||
return false;
|
return false;
|
||||||
for (unsigned i = 0; i < kDirtyTids; i++) {
|
for (unsigned i = 0; i < kDirtyTids; i++) {
|
||||||
SyncClock::Dirty dirty = src->dirty_[i];
|
SyncClock::Dirty dirty = src->dirty_[i];
|
||||||
if (dirty.tid != kInvalidTid) {
|
if (dirty.tid() != kInvalidTid) {
|
||||||
if (clk_[dirty.tid] < dirty.epoch)
|
if (clk_[dirty.tid()] < dirty.epoch)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -453,8 +452,7 @@ void SyncClock::ResetImpl() {
|
||||||
blocks_ = 0;
|
blocks_ = 0;
|
||||||
release_store_tid_ = kInvalidTid;
|
release_store_tid_ = kInvalidTid;
|
||||||
release_store_reused_ = 0;
|
release_store_reused_ = 0;
|
||||||
for (uptr i = 0; i < kDirtyTids; i++)
|
for (uptr i = 0; i < kDirtyTids; i++) dirty_[i].set_tid(kInvalidTid);
|
||||||
dirty_[i].tid = kInvalidTid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncClock::Resize(ClockCache *c, uptr nclk) {
|
void SyncClock::Resize(ClockCache *c, uptr nclk) {
|
||||||
|
@ -503,10 +501,10 @@ void SyncClock::Resize(ClockCache *c, uptr nclk) {
|
||||||
void SyncClock::FlushDirty() {
|
void SyncClock::FlushDirty() {
|
||||||
for (unsigned i = 0; i < kDirtyTids; i++) {
|
for (unsigned i = 0; i < kDirtyTids; i++) {
|
||||||
Dirty *dirty = &dirty_[i];
|
Dirty *dirty = &dirty_[i];
|
||||||
if (dirty->tid != kInvalidTid) {
|
if (dirty->tid() != kInvalidTid) {
|
||||||
CHECK_LT(dirty->tid, size_);
|
CHECK_LT(dirty->tid(), size_);
|
||||||
elem(dirty->tid).epoch = dirty->epoch;
|
elem(dirty->tid()).epoch = dirty->epoch;
|
||||||
dirty->tid = kInvalidTid;
|
dirty->set_tid(kInvalidTid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -559,7 +557,7 @@ ALWAYS_INLINE bool SyncClock::Cachable() const {
|
||||||
if (size_ == 0)
|
if (size_ == 0)
|
||||||
return false;
|
return false;
|
||||||
for (unsigned i = 0; i < kDirtyTids; i++) {
|
for (unsigned i = 0; i < kDirtyTids; i++) {
|
||||||
if (dirty_[i].tid != kInvalidTid)
|
if (dirty_[i].tid() != kInvalidTid)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return atomic_load_relaxed(ref_ptr(tab_)) == 1;
|
return atomic_load_relaxed(ref_ptr(tab_)) == 1;
|
||||||
|
@ -606,7 +604,7 @@ ALWAYS_INLINE void SyncClock::append_block(u32 idx) {
|
||||||
u64 SyncClock::get(unsigned tid) const {
|
u64 SyncClock::get(unsigned tid) const {
|
||||||
for (unsigned i = 0; i < kDirtyTids; i++) {
|
for (unsigned i = 0; i < kDirtyTids; i++) {
|
||||||
Dirty dirty = dirty_[i];
|
Dirty dirty = dirty_[i];
|
||||||
if (dirty.tid == tid)
|
if (dirty.tid() == tid)
|
||||||
return dirty.epoch;
|
return dirty.epoch;
|
||||||
}
|
}
|
||||||
return elem(tid).epoch;
|
return elem(tid).epoch;
|
||||||
|
@ -625,9 +623,8 @@ void SyncClock::DebugDump(int(*printf)(const char *s, ...)) {
|
||||||
for (uptr i = 0; i < size_; i++)
|
for (uptr i = 0; i < size_; i++)
|
||||||
printf("%s%llu", i == 0 ? "" : ",", elem(i).reused);
|
printf("%s%llu", i == 0 ? "" : ",", elem(i).reused);
|
||||||
printf("] release_store_tid=%d/%d dirty_tids=%d[%llu]/%d[%llu]",
|
printf("] release_store_tid=%d/%d dirty_tids=%d[%llu]/%d[%llu]",
|
||||||
release_store_tid_, release_store_reused_,
|
release_store_tid_, release_store_reused_, dirty_[0].tid(),
|
||||||
dirty_[0].tid, dirty_[0].epoch,
|
dirty_[0].epoch, dirty_[1].tid(), dirty_[1].epoch);
|
||||||
dirty_[1].tid, dirty_[1].epoch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SyncClock::Iter::Next() {
|
void SyncClock::Iter::Next() {
|
||||||
|
|
|
@ -63,14 +63,22 @@ class SyncClock {
|
||||||
friend class ThreadClock;
|
friend class ThreadClock;
|
||||||
friend class Iter;
|
friend class Iter;
|
||||||
static const uptr kDirtyTids = 2;
|
static const uptr kDirtyTids = 2;
|
||||||
// Full kInvalidTid won't fit into Dirty::tid.
|
|
||||||
static const u64 kInvalidTid = (1ull << (64 - kClkBits)) - 1;
|
|
||||||
|
|
||||||
struct Dirty {
|
struct Dirty {
|
||||||
u64 epoch : kClkBits;
|
u32 tid() const { return tid_ == kShortInvalidTid ? kInvalidTid : tid_; }
|
||||||
u64 tid : 64 - kClkBits; // kInvalidId if not active
|
void set_tid(u32 tid) {
|
||||||
|
tid_ = tid == kInvalidTid ? kShortInvalidTid : tid;
|
||||||
|
}
|
||||||
|
u64 epoch : kClkBits;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Full kInvalidTid won't fit into Dirty::tid.
|
||||||
|
static const u64 kShortInvalidTid = (1ull << (64 - kClkBits)) - 1;
|
||||||
|
u64 tid_ : 64 - kClkBits; // kInvalidId if not active
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(Dirty) == 8, "Dirty is not 64bit");
|
||||||
|
|
||||||
unsigned release_store_tid_;
|
unsigned release_store_tid_;
|
||||||
unsigned release_store_reused_;
|
unsigned release_store_reused_;
|
||||||
Dirty dirty_[kDirtyTids];
|
Dirty dirty_[kDirtyTids];
|
||||||
|
@ -148,7 +156,6 @@ class ThreadClock {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const uptr kDirtyTids = SyncClock::kDirtyTids;
|
static const uptr kDirtyTids = SyncClock::kDirtyTids;
|
||||||
static const u64 kInvalidTid = SyncClock::kInvalidTid;
|
|
||||||
// Index of the thread associated with he clock ("current thread").
|
// Index of the thread associated with he clock ("current thread").
|
||||||
const unsigned tid_;
|
const unsigned tid_;
|
||||||
const unsigned reused_; // tid_ reuse count.
|
const unsigned reused_; // tid_ reuse count.
|
||||||
|
|
Loading…
Reference in New Issue