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