92 lines · c
1//===-- tsan_mutexset.h -----------------------------------------*- C++ -*-===//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// MutexSet holds the set of mutexes currently held by a thread.12//===----------------------------------------------------------------------===//13#ifndef TSAN_MUTEXSET_H14#define TSAN_MUTEXSET_H15 16#include "tsan_defs.h"17 18namespace __tsan {19 20class MutexSet {21 public:22 // Holds limited number of mutexes.23 // The oldest mutexes are discarded on overflow.24 static constexpr uptr kMaxSize = 16;25 struct Desc {26 uptr addr;27 StackID stack_id;28 u32 seq;29 u32 count;30 bool write;31 32 Desc() { internal_memset(this, 0, sizeof(*this)); }33 Desc(const Desc& other) { *this = other; }34 Desc& operator=(const MutexSet::Desc& other) {35 internal_memcpy(this, &other, sizeof(*this));36 return *this;37 }38 };39 40 MutexSet();41 void Reset();42 void AddAddr(uptr addr, StackID stack_id, bool write);43 void DelAddr(uptr addr, bool destroy = false);44 uptr Size() const;45 Desc Get(uptr i) const;46 47 private:48#if !SANITIZER_GO49 u32 seq_ = 0;50 uptr size_ = 0;51 Desc descs_[kMaxSize];52 53 void RemovePos(uptr i);54#endif55};56 57// MutexSet is too large to live on stack.58// DynamicMutexSet can be use used to create local MutexSet's.59class DynamicMutexSet {60 public:61 DynamicMutexSet();62 ~DynamicMutexSet();63 MutexSet* operator->() { return ptr_; }64 operator MutexSet*() { return ptr_; }65 DynamicMutexSet(const DynamicMutexSet&) = delete;66 DynamicMutexSet& operator=(const DynamicMutexSet&) = delete;67 68 private:69 MutexSet* ptr_;70#if SANITIZER_GO71 MutexSet set_;72#endif73};74 75// Go does not have mutexes, so do not spend memory and time.76// (Go sync.Mutex is actually a semaphore -- can be unlocked77// in different goroutine).78#if SANITIZER_GO79MutexSet::MutexSet() {}80void MutexSet::Reset() {}81void MutexSet::AddAddr(uptr addr, StackID stack_id, bool write) {}82void MutexSet::DelAddr(uptr addr, bool destroy) {}83uptr MutexSet::Size() const { return 0; }84MutexSet::Desc MutexSet::Get(uptr i) const { return Desc(); }85DynamicMutexSet::DynamicMutexSet() : ptr_(&set_) {}86DynamicMutexSet::~DynamicMutexSet() {}87#endif88 89} // namespace __tsan90 91#endif // TSAN_MUTEXSET_H92