aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/libsanitizer/tsan/tsan_sync.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/libsanitizer/tsan/tsan_sync.h')
-rw-r--r--gcc-4.9/libsanitizer/tsan/tsan_sync.h125
1 files changed, 125 insertions, 0 deletions
diff --git a/gcc-4.9/libsanitizer/tsan/tsan_sync.h b/gcc-4.9/libsanitizer/tsan/tsan_sync.h
new file mode 100644
index 000000000..2867a8ac7
--- /dev/null
+++ b/gcc-4.9/libsanitizer/tsan/tsan_sync.h
@@ -0,0 +1,125 @@
+//===-- tsan_sync.h ---------------------------------------------*- C++ -*-===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of ThreadSanitizer (TSan), a race detector.
+//
+//===----------------------------------------------------------------------===//
+#ifndef TSAN_SYNC_H
+#define TSAN_SYNC_H
+
+#include "sanitizer_common/sanitizer_atomic.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "tsan_clock.h"
+#include "tsan_defs.h"
+#include "tsan_mutex.h"
+
+namespace __tsan {
+
+class SlabCache;
+
+class StackTrace {
+ public:
+ StackTrace();
+ // Initialized the object in "static mode",
+ // in this mode it never calls malloc/free but uses the provided buffer.
+ StackTrace(uptr *buf, uptr cnt);
+ ~StackTrace();
+ void Reset();
+
+ void Init(const uptr *pcs, uptr cnt);
+ void ObtainCurrent(ThreadState *thr, uptr toppc);
+ bool IsEmpty() const;
+ uptr Size() const;
+ uptr Get(uptr i) const;
+ const uptr *Begin() const;
+ void CopyFrom(const StackTrace& other);
+
+ private:
+ uptr n_;
+ uptr *s_;
+ const uptr c_;
+
+ StackTrace(const StackTrace&);
+ void operator = (const StackTrace&);
+};
+
+struct SyncVar {
+ explicit SyncVar(uptr addr, u64 uid);
+
+ static const int kInvalidTid = -1;
+
+ Mutex mtx;
+ uptr addr;
+ const u64 uid; // Globally unique id.
+ SyncClock clock;
+ SyncClock read_clock; // Used for rw mutexes only.
+ u32 creation_stack_id;
+ int owner_tid; // Set only by exclusive owners.
+ u64 last_lock;
+ int recursion;
+ bool is_rw;
+ bool is_recursive;
+ bool is_broken;
+ bool is_linker_init;
+ SyncVar *next; // In SyncTab hashtable.
+
+ uptr GetMemoryConsumption();
+ u64 GetId() const {
+ // 47 lsb is addr, then 14 bits is low part of uid, then 3 zero bits.
+ return GetLsb((u64)addr | (uid << 47), 61);
+ }
+ bool CheckId(u64 uid) const {
+ CHECK_EQ(uid, GetLsb(uid, 14));
+ return GetLsb(this->uid, 14) == uid;
+ }
+ static uptr SplitId(u64 id, u64 *uid) {
+ *uid = id >> 47;
+ return (uptr)GetLsb(id, 47);
+ }
+};
+
+class SyncTab {
+ public:
+ SyncTab();
+ ~SyncTab();
+
+ SyncVar* GetOrCreateAndLock(ThreadState *thr, uptr pc,
+ uptr addr, bool write_lock);
+ SyncVar* GetIfExistsAndLock(uptr addr, bool write_lock);
+
+ // If the SyncVar does not exist, returns 0.
+ SyncVar* GetAndRemove(ThreadState *thr, uptr pc, uptr addr);
+
+ SyncVar* Create(ThreadState *thr, uptr pc, uptr addr);
+
+ uptr GetMemoryConsumption(uptr *nsync);
+
+ private:
+ struct Part {
+ Mutex mtx;
+ SyncVar *val;
+ char pad[kCacheLineSize - sizeof(Mutex) - sizeof(SyncVar*)]; // NOLINT
+ Part();
+ };
+
+ // FIXME: Implement something more sane.
+ static const int kPartCount = 1009;
+ Part tab_[kPartCount];
+ atomic_uint64_t uid_gen_;
+
+ int PartIdx(uptr addr);
+
+ SyncVar* GetAndLock(ThreadState *thr, uptr pc,
+ uptr addr, bool write_lock, bool create);
+
+ SyncTab(const SyncTab&); // Not implemented.
+ void operator = (const SyncTab&); // Not implemented.
+};
+
+} // namespace __tsan
+
+#endif // TSAN_SYNC_H