81 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of ThreadSanitizer (TSan), a race detector.10//11//===----------------------------------------------------------------------===//12#include "tsan_mutexset.h"13 14#include "sanitizer_common/sanitizer_placement_new.h"15#include "tsan_rtl.h"16 17namespace __tsan {18 19MutexSet::MutexSet() {20}21 22void MutexSet::Reset() { internal_memset(this, 0, sizeof(*this)); }23 24void MutexSet::AddAddr(uptr addr, StackID stack_id, bool write) {25 // Look up existing mutex with the same id.26 for (uptr i = 0; i < size_; i++) {27 if (descs_[i].addr == addr) {28 descs_[i].count++;29 descs_[i].seq = seq_++;30 return;31 }32 }33 // On overflow, find the oldest mutex and drop it.34 if (size_ == kMaxSize) {35 uptr min = 0;36 for (uptr i = 0; i < size_; i++) {37 if (descs_[i].seq < descs_[min].seq)38 min = i;39 }40 RemovePos(min);41 CHECK_EQ(size_, kMaxSize - 1);42 }43 // Add new mutex descriptor.44 descs_[size_].addr = addr;45 descs_[size_].stack_id = stack_id;46 descs_[size_].write = write;47 descs_[size_].seq = seq_++;48 descs_[size_].count = 1;49 size_++;50}51 52void MutexSet::DelAddr(uptr addr, bool destroy) {53 for (uptr i = 0; i < size_; i++) {54 if (descs_[i].addr == addr) {55 if (destroy || --descs_[i].count == 0)56 RemovePos(i);57 return;58 }59 }60}61 62void MutexSet::RemovePos(uptr i) {63 CHECK_LT(i, size_);64 descs_[i] = descs_[size_ - 1];65 size_--;66}67 68uptr MutexSet::Size() const {69 return size_;70}71 72MutexSet::Desc MutexSet::Get(uptr i) const {73 CHECK_LT(i, size_);74 return descs_[i];75}76 77DynamicMutexSet::DynamicMutexSet() : ptr_(New<MutexSet>()) {}78DynamicMutexSet::~DynamicMutexSet() { DestroyAndFree(ptr_); }79 80} // namespace __tsan81