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