1 //===-- tsan_mutexset.cc --------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file is a part of ThreadSanitizer (TSan), a race detector. 11 // 12 //===----------------------------------------------------------------------===// 13 #include "tsan_mutexset.h" 14 #include "tsan_rtl.h" 15 16 namespace __tsan { 17 18 const uptr MutexSet::kMaxSize; 19 20 MutexSet::MutexSet() { 21 size_ = 0; 22 internal_memset(&descs_, 0, sizeof(descs_)); 23 } 24 25 void MutexSet::Add(u64 id, bool write, u64 epoch) { 26 // Look up existing mutex with the same id. 27 for (uptr i = 0; i < size_; i++) { 28 if (descs_[i].id == id) { 29 descs_[i].count++; 30 descs_[i].epoch = epoch; 31 return; 32 } 33 } 34 // On overflow, find the oldest mutex and drop it. 35 if (size_ == kMaxSize) { 36 u64 minepoch = (u64)-1; 37 u64 mini = (u64)-1; 38 for (uptr i = 0; i < size_; i++) { 39 if (descs_[i].epoch < minepoch) { 40 minepoch = descs_[i].epoch; 41 mini = i; 42 } 43 } 44 RemovePos(mini); 45 CHECK_EQ(size_, kMaxSize - 1); 46 } 47 // Add new mutex descriptor. 48 descs_[size_].id = id; 49 descs_[size_].write = write; 50 descs_[size_].epoch = epoch; 51 descs_[size_].count = 1; 52 size_++; 53 } 54 55 void MutexSet::Del(u64 id, bool write) { 56 for (uptr i = 0; i < size_; i++) { 57 if (descs_[i].id == id) { 58 if (--descs_[i].count == 0) 59 RemovePos(i); 60 return; 61 } 62 } 63 } 64 65 void MutexSet::Remove(u64 id) { 66 for (uptr i = 0; i < size_; i++) { 67 if (descs_[i].id == id) { 68 RemovePos(i); 69 return; 70 } 71 } 72 } 73 74 void MutexSet::RemovePos(uptr i) { 75 CHECK_LT(i, size_); 76 descs_[i] = descs_[size_ - 1]; 77 size_--; 78 } 79 80 uptr MutexSet::Size() const { 81 return size_; 82 } 83 84 MutexSet::Desc MutexSet::Get(uptr i) const { 85 CHECK_LT(i, size_); 86 return descs_[i]; 87 } 88 89 } // namespace __tsan 90