18808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf//===-- tsan_mutexset.h -----------------------------------------*- C++ -*-===// 28808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf// 38808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf// The LLVM Compiler Infrastructure 48808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf// 58808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf// This file is distributed under the University of Illinois Open Source 68808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf// License. See LICENSE.TXT for details. 78808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf// 88808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf//===----------------------------------------------------------------------===// 98808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf// 108808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf// This file is a part of ThreadSanitizer (TSan), a race detector. 118808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf// 128808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf// MutexSet holds the set of mutexes currently held by a thread. 138808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf//===----------------------------------------------------------------------===// 148808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#ifndef TSAN_MUTEXSET_H 158808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#define TSAN_MUTEXSET_H 168808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf 178808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#include "tsan_defs.h" 188808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf 198808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Grafnamespace __tsan { 208808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf 218808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Grafclass MutexSet { 228808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf public: 238808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf // Holds limited number of mutexes. 248808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf // The oldest mutexes are discarded on overflow. 258808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf static const uptr kMaxSize = 16; 268808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf struct Desc { 278808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf u64 id; 288808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf u64 epoch; 298808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf int count; 308808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf bool write; 318808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf }; 328808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf 338808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf MutexSet(); 348808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf // The 'id' is obtained from SyncVar::GetId(). 358808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf void Add(u64 id, bool write, u64 epoch); 368808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf void Del(u64 id, bool write); 378808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf void Remove(u64 id); // Removes the mutex completely (if it's destroyed). 388808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf uptr Size() const; 398808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf Desc Get(uptr i) const; 408808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf 418808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf void operator=(const MutexSet &other) { 428808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf internal_memcpy(this, &other, sizeof(*this)); 438808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf } 448808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf 458808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf private: 468808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#ifndef TSAN_GO 478808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf uptr size_; 488808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf Desc descs_[kMaxSize]; 498808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#endif 508808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf 518808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf void RemovePos(uptr i); 528808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf MutexSet(const MutexSet&); 538808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf}; 548808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf 558808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf// Go does not have mutexes, so do not spend memory and time. 568808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf// (Go sync.Mutex is actually a semaphore -- can be unlocked 578808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf// in different goroutine). 588808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#ifdef TSAN_GO 598808743839b0f459394ecd00cb0f7c1896c0ab7aThomas GrafMutexSet::MutexSet() {} 608808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Grafvoid MutexSet::Add(u64 id, bool write, u64 epoch) {} 618808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Grafvoid MutexSet::Del(u64 id, bool write) {} 628808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Grafvoid MutexSet::Remove(u64 id) {} 638808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Grafvoid MutexSet::RemovePos(uptr i) {} 648808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Grafuptr MutexSet::Size() const { return 0; } 658808743839b0f459394ecd00cb0f7c1896c0ab7aThomas GrafMutexSet::Desc MutexSet::Get(uptr i) const { return Desc(); } 668808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#endif 678808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf 688808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf} // namespace __tsan 698808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf 708808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#endif // TSAN_MUTEXSET_H 718808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf