brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.5 KiB · aabd361 Raw
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