blob: 516e46b66e224cb8649e99fa0d0a04aca16aff52 [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();
28 ~StackTrace();
29 void Reset();
30
31 void Init(const uptr *pcs, uptr cnt);
32 void ObtainCurrent(ThreadState *thr, uptr toppc);
33 bool IsEmpty() const;
34 uptr Size() const;
35 uptr Get(uptr i) const;
36 const uptr *Begin() const;
37 void CopyFrom(const StackTrace& other);
38
39 private:
40 uptr n_;
41 uptr *s_;
42
43 StackTrace(const StackTrace&);
44 void operator = (const StackTrace&);
45};
46
47struct SyncVar {
48 explicit SyncVar(uptr addr);
49
50 static const int kInvalidTid = -1;
51
52 Mutex mtx;
53 const uptr addr;
54 SyncClock clock;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000055 SyncClock read_clock; // Used for rw mutexes only.
Dmitry Vyukov15710c92012-05-22 11:33:03 +000056 StackTrace creation_stack;
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000057 int owner_tid; // Set only by exclusive owners.
58 int recursion;
59 bool is_rw;
60 bool is_recursive;
61 bool is_broken;
62 SyncVar *next; // In SyncTab hashtable.
Dmitry Vyukov15710c92012-05-22 11:33:03 +000063
64 uptr GetMemoryConsumption();
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000065};
66
67class SyncTab {
68 public:
69 SyncTab();
70 ~SyncTab();
71
72 // If the SyncVar does not exist yet, it is created.
73 SyncVar* GetAndLock(ThreadState *thr, uptr pc,
74 uptr addr, bool write_lock);
75
76 // If the SyncVar does not exist, returns 0.
77 SyncVar* GetAndRemove(ThreadState *thr, uptr pc, uptr addr);
78
Dmitry Vyukov15710c92012-05-22 11:33:03 +000079 uptr GetMemoryConsumption(uptr *nsync);
80
Kostya Serebryany4ad375f2012-05-10 13:48:04 +000081 private:
82 struct Part {
83 Mutex mtx;
84 SyncVar *val;
85 char pad[kCacheLineSize - sizeof(Mutex) - sizeof(SyncVar*)]; // NOLINT
86 Part();
87 };
88
89 // FIXME: Implement something more sane.
90 static const int kPartCount = 1009;
91 Part tab_[kPartCount];
92
93 int PartIdx(uptr addr);
94
95 SyncTab(const SyncTab&); // Not implemented.
96 void operator = (const SyncTab&); // Not implemented.
97};
98
99} // namespace __tsan
100
101#endif // TSAN_SYNC_H