1*7c3d14c8STreehugger Robot //===-- tsan_mutexset.h -----------------------------------------*- C++ -*-===//
2*7c3d14c8STreehugger Robot //
3*7c3d14c8STreehugger Robot // The LLVM Compiler Infrastructure
4*7c3d14c8STreehugger Robot //
5*7c3d14c8STreehugger Robot // This file is distributed under the University of Illinois Open Source
6*7c3d14c8STreehugger Robot // License. See LICENSE.TXT for details.
7*7c3d14c8STreehugger Robot //
8*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
9*7c3d14c8STreehugger Robot //
10*7c3d14c8STreehugger Robot // This file is a part of ThreadSanitizer (TSan), a race detector.
11*7c3d14c8STreehugger Robot //
12*7c3d14c8STreehugger Robot // MutexSet holds the set of mutexes currently held by a thread.
13*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
14*7c3d14c8STreehugger Robot #ifndef TSAN_MUTEXSET_H
15*7c3d14c8STreehugger Robot #define TSAN_MUTEXSET_H
16*7c3d14c8STreehugger Robot
17*7c3d14c8STreehugger Robot #include "tsan_defs.h"
18*7c3d14c8STreehugger Robot
19*7c3d14c8STreehugger Robot namespace __tsan {
20*7c3d14c8STreehugger Robot
21*7c3d14c8STreehugger Robot class MutexSet {
22*7c3d14c8STreehugger Robot public:
23*7c3d14c8STreehugger Robot // Holds limited number of mutexes.
24*7c3d14c8STreehugger Robot // The oldest mutexes are discarded on overflow.
25*7c3d14c8STreehugger Robot static const uptr kMaxSize = 16;
26*7c3d14c8STreehugger Robot struct Desc {
27*7c3d14c8STreehugger Robot u64 id;
28*7c3d14c8STreehugger Robot u64 epoch;
29*7c3d14c8STreehugger Robot int count;
30*7c3d14c8STreehugger Robot bool write;
31*7c3d14c8STreehugger Robot };
32*7c3d14c8STreehugger Robot
33*7c3d14c8STreehugger Robot MutexSet();
34*7c3d14c8STreehugger Robot // The 'id' is obtained from SyncVar::GetId().
35*7c3d14c8STreehugger Robot void Add(u64 id, bool write, u64 epoch);
36*7c3d14c8STreehugger Robot void Del(u64 id, bool write);
37*7c3d14c8STreehugger Robot void Remove(u64 id); // Removes the mutex completely (if it's destroyed).
38*7c3d14c8STreehugger Robot uptr Size() const;
39*7c3d14c8STreehugger Robot Desc Get(uptr i) const;
40*7c3d14c8STreehugger Robot
41*7c3d14c8STreehugger Robot void operator=(const MutexSet &other) {
42*7c3d14c8STreehugger Robot internal_memcpy(this, &other, sizeof(*this));
43*7c3d14c8STreehugger Robot }
44*7c3d14c8STreehugger Robot
45*7c3d14c8STreehugger Robot private:
46*7c3d14c8STreehugger Robot #ifndef SANITIZER_GO
47*7c3d14c8STreehugger Robot uptr size_;
48*7c3d14c8STreehugger Robot Desc descs_[kMaxSize];
49*7c3d14c8STreehugger Robot #endif
50*7c3d14c8STreehugger Robot
51*7c3d14c8STreehugger Robot void RemovePos(uptr i);
52*7c3d14c8STreehugger Robot MutexSet(const MutexSet&);
53*7c3d14c8STreehugger Robot };
54*7c3d14c8STreehugger Robot
55*7c3d14c8STreehugger Robot // Go does not have mutexes, so do not spend memory and time.
56*7c3d14c8STreehugger Robot // (Go sync.Mutex is actually a semaphore -- can be unlocked
57*7c3d14c8STreehugger Robot // in different goroutine).
58*7c3d14c8STreehugger Robot #ifdef SANITIZER_GO
MutexSet()59*7c3d14c8STreehugger Robot MutexSet::MutexSet() {}
Add(u64 id,bool write,u64 epoch)60*7c3d14c8STreehugger Robot void MutexSet::Add(u64 id, bool write, u64 epoch) {}
Del(u64 id,bool write)61*7c3d14c8STreehugger Robot void MutexSet::Del(u64 id, bool write) {}
Remove(u64 id)62*7c3d14c8STreehugger Robot void MutexSet::Remove(u64 id) {}
RemovePos(uptr i)63*7c3d14c8STreehugger Robot void MutexSet::RemovePos(uptr i) {}
Size()64*7c3d14c8STreehugger Robot uptr MutexSet::Size() const { return 0; }
Get(uptr i)65*7c3d14c8STreehugger Robot MutexSet::Desc MutexSet::Get(uptr i) const { return Desc(); }
66*7c3d14c8STreehugger Robot #endif
67*7c3d14c8STreehugger Robot
68*7c3d14c8STreehugger Robot } // namespace __tsan
69*7c3d14c8STreehugger Robot
70*7c3d14c8STreehugger Robot #endif // TSAN_MUTEXSET_H
71