tsan: refactor SyncClock code
authorDmitry Vyukov <dvyukov@google.com>
Wed, 12 Jul 2017 12:50:36 +0000 (12:50 +0000)
committerDmitry Vyukov <dvyukov@google.com>
Wed, 12 Jul 2017 12:50:36 +0000 (12:50 +0000)
1. Add SyncClock::ResetImpl which removes code
   duplication between ctor and Reset.
2. Move SyncClock::Resize to SyncClock methods,
   currently it's defined between ThreadClock methods.

llvm-svn: 307785

compiler-rt/lib/tsan/rtl/tsan_clock.cc
compiler-rt/lib/tsan/rtl/tsan_clock.h

index 3629218..4a91683 100644 (file)
@@ -300,53 +300,6 @@ bool ThreadClock::IsAlreadyAcquired(const SyncClock *src) const {
   return true;
 }
 
-void SyncClock::Resize(ClockCache *c, uptr nclk) {
-  CPP_STAT_INC(StatClockReleaseResize);
-  if (RoundUpTo(nclk, ClockBlock::kClockCount) <=
-      RoundUpTo(size_, ClockBlock::kClockCount)) {
-    // Growing within the same block.
-    // Memory is already allocated, just increase the size.
-    size_ = nclk;
-    return;
-  }
-  if (nclk <= ClockBlock::kClockCount) {
-    // Grow from 0 to one-level table.
-    CHECK_EQ(size_, 0);
-    CHECK_EQ(tab_, 0);
-    CHECK_EQ(tab_idx_, 0);
-    size_ = nclk;
-    tab_idx_ = ctx->clock_alloc.Alloc(c);
-    tab_ = ctx->clock_alloc.Map(tab_idx_);
-    internal_memset(tab_, 0, sizeof(*tab_));
-    return;
-  }
-  // Growing two-level table.
-  if (size_ == 0) {
-    // Allocate first level table.
-    tab_idx_ = ctx->clock_alloc.Alloc(c);
-    tab_ = ctx->clock_alloc.Map(tab_idx_);
-    internal_memset(tab_, 0, sizeof(*tab_));
-  } else if (size_ <= ClockBlock::kClockCount) {
-    // Transform one-level table to two-level table.
-    u32 old = tab_idx_;
-    tab_idx_ = ctx->clock_alloc.Alloc(c);
-    tab_ = ctx->clock_alloc.Map(tab_idx_);
-    internal_memset(tab_, 0, sizeof(*tab_));
-    tab_->table[0] = old;
-  }
-  // At this point we have first level table allocated.
-  // Add second level tables as necessary.
-  for (uptr i = RoundUpTo(size_, ClockBlock::kClockCount);
-      i < nclk; i += ClockBlock::kClockCount) {
-    u32 idx = ctx->clock_alloc.Alloc(c);
-    ClockBlock *cb = ctx->clock_alloc.Map(idx);
-    internal_memset(cb, 0, sizeof(*cb));
-    CHECK_EQ(tab_->table[i/ClockBlock::kClockCount], 0);
-    tab_->table[i/ClockBlock::kClockCount] = idx;
-  }
-  size_ = nclk;
-}
-
 // Sets a single element in the vector clock.
 // This function is called only from weird places like AcquireGlobal.
 void ThreadClock::set(ClockCache *c, unsigned tid, u64 v) {
@@ -369,14 +322,8 @@ void ThreadClock::DebugDump(int(*printf)(const char *s, ...)) {
       tid_, reused_, last_acquire_);
 }
 
-SyncClock::SyncClock()
-    : release_store_tid_(kInvalidTid)
-    , release_store_reused_()
-    , tab_()
-    , tab_idx_()
-    , size_() {
-  for (uptr i = 0; i < kDirtyTids; i++)
-    dirty_tids_[i] = kInvalidTid;
+SyncClock::SyncClock() {
+  ResetImpl();
 }
 
 SyncClock::~SyncClock() {
@@ -398,6 +345,10 @@ void SyncClock::Reset(ClockCache *c) {
       ctx->clock_alloc.Free(c, tab_->table[i / ClockBlock::kClockCount]);
     ctx->clock_alloc.Free(c, tab_idx_);
   }
+  ResetImpl();
+}
+
+void SyncClock::ResetImpl() {
   tab_ = 0;
   tab_idx_ = 0;
   size_ = 0;
@@ -407,6 +358,53 @@ void SyncClock::Reset(ClockCache *c) {
     dirty_tids_[i] = kInvalidTid;
 }
 
+void SyncClock::Resize(ClockCache *c, uptr nclk) {
+  CPP_STAT_INC(StatClockReleaseResize);
+  if (RoundUpTo(nclk, ClockBlock::kClockCount) <=
+      RoundUpTo(size_, ClockBlock::kClockCount)) {
+    // Growing within the same block.
+    // Memory is already allocated, just increase the size.
+    size_ = nclk;
+    return;
+  }
+  if (nclk <= ClockBlock::kClockCount) {
+    // Grow from 0 to one-level table.
+    CHECK_EQ(size_, 0);
+    CHECK_EQ(tab_, 0);
+    CHECK_EQ(tab_idx_, 0);
+    size_ = nclk;
+    tab_idx_ = ctx->clock_alloc.Alloc(c);
+    tab_ = ctx->clock_alloc.Map(tab_idx_);
+    internal_memset(tab_, 0, sizeof(*tab_));
+    return;
+  }
+  // Growing two-level table.
+  if (size_ == 0) {
+    // Allocate first level table.
+    tab_idx_ = ctx->clock_alloc.Alloc(c);
+    tab_ = ctx->clock_alloc.Map(tab_idx_);
+    internal_memset(tab_, 0, sizeof(*tab_));
+  } else if (size_ <= ClockBlock::kClockCount) {
+    // Transform one-level table to two-level table.
+    u32 old = tab_idx_;
+    tab_idx_ = ctx->clock_alloc.Alloc(c);
+    tab_ = ctx->clock_alloc.Map(tab_idx_);
+    internal_memset(tab_, 0, sizeof(*tab_));
+    tab_->table[0] = old;
+  }
+  // At this point we have first level table allocated.
+  // Add second level tables as necessary.
+  for (uptr i = RoundUpTo(size_, ClockBlock::kClockCount);
+      i < nclk; i += ClockBlock::kClockCount) {
+    u32 idx = ctx->clock_alloc.Alloc(c);
+    ClockBlock *cb = ctx->clock_alloc.Map(idx);
+    internal_memset(cb, 0, sizeof(*cb));
+    CHECK_EQ(tab_->table[i/ClockBlock::kClockCount], 0);
+    tab_->table[i/ClockBlock::kClockCount] = idx;
+  }
+  size_ = nclk;
+}
+
 ClockElem &SyncClock::elem(unsigned tid) const {
   DCHECK_LT(tid, size_);
   if (size_ <= ClockBlock::kClockCount)
index 90eaca2..378b550 100644 (file)
@@ -74,6 +74,7 @@ class SyncClock {
   u32 tab_idx_;
   u32 size_;
 
+  void ResetImpl();
   ClockElem &elem(unsigned tid) const;
 };