blob: 51989d223aad372c8c5afea0660b71e3a346d5a1 [file] [log] [blame]
Kostya Serebryany4ad375f2012-05-10 13:48:04 +00001//===-- tsan_sync.h ---------------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file is a part of ThreadSanitizer (TSan), a race detector.
11//
12//===----------------------------------------------------------------------===//
13#ifndef TSAN_SYNC_H
14#define TSAN_SYNC_H
15
16#include "tsan_atomic.h"
17#include "tsan_clock.h"
18#include "tsan_defs.h"
19#include "tsan_mutex.h"
20
21namespace __tsan {
22
23class SlabCache;
24
25class StackTrace {
26 public:
27 StackTrace();
Dmitry Vyukovde1fd1c2012-06-22 11:08:55 +000028 // Initialized the object in "static mode",
29 // in this mode it never calls malloc/free but uses the provided buffer.
30 StackTrace(uptr *buf, uptr cnt);
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000031 ~StackTrace();
32 void Reset();
33
34 void Init(const uptr *pcs, uptr cnt);
35 void ObtainCurrent(ThreadState *thr, uptr toppc);
36 bool IsEmpty() const;
37 uptr Size() const;
38 uptr Get(uptr i) const;
39 const uptr *Begin() const;
40 void CopyFrom(const StackTrace& other);
41
42 private:
43 uptr n_;
44 uptr *s_;
Dmitry Vyukovde1fd1c2012-06-22 11:08:55 +000045 const uptr c_;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000046
47 StackTrace(const StackTrace&);
48 void operator = (const StackTrace&);
49};
50
51struct SyncVar {
52 explicit SyncVar(uptr addr);
53
54 static const int kInvalidTid = -1;
55
56 Mutex mtx;
57 const uptr addr;
58 SyncClock clock;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000059 SyncClock read_clock; // Used for rw mutexes only.
Dmitry Vyukov15710c92012-05-22 11:33:03 +000060 StackTrace creation_stack;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000061 int owner_tid; // Set only by exclusive owners.
62 int recursion;
63 bool is_rw;
64 bool is_recursive;
65 bool is_broken;
66 SyncVar *next; // In SyncTab hashtable.
Dmitry Vyukov15710c92012-05-22 11:33:03 +000067
68 uptr GetMemoryConsumption();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000069};
70
71class SyncTab {
72 public:
73 SyncTab();
74 ~SyncTab();
75
76 // If the SyncVar does not exist yet, it is created.
77 SyncVar* GetAndLock(ThreadState *thr, uptr pc,
78 uptr addr, bool write_lock);
79
80 // If the SyncVar does not exist, returns 0.
81 SyncVar* GetAndRemove(ThreadState *thr, uptr pc, uptr addr);
82
Dmitry Vyukov15710c92012-05-22 11:33:03 +000083 uptr GetMemoryConsumption(uptr *nsync);
84
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000085 private:
86 struct Part {
87 Mutex mtx;
88 SyncVar *val;
89 char pad[kCacheLineSize - sizeof(Mutex) - sizeof(SyncVar*)]; // NOLINT
90 Part();
91 };
92
93 // FIXME: Implement something more sane.
94 static const int kPartCount = 1009;
95 Part tab_[kPartCount];
96
97 int PartIdx(uptr addr);
98
99 SyncTab(const SyncTab&); // Not implemented.
100 void operator = (const SyncTab&); // Not implemented.
101};
102
103} // namespace __tsan
104
105#endif // TSAN_SYNC_H