1276789Sdim//===-- sanitizer_deadlock_detector_interface.h -----------------*- C++ -*-===//
2276789Sdim//
3276789Sdim//                     The LLVM Compiler Infrastructure
4276789Sdim//
5276789Sdim// This file is distributed under the University of Illinois Open Source
6276789Sdim// License. See LICENSE.TXT for details.
7276789Sdim//
8276789Sdim//===----------------------------------------------------------------------===//
9276789Sdim//
10276789Sdim// This file is a part of Sanitizer runtime.
11276789Sdim// Abstract deadlock detector interface.
12276789Sdim// FIXME: this is work in progress, nothing really works yet.
13276789Sdim//
14276789Sdim//===----------------------------------------------------------------------===//
15276789Sdim
16276789Sdim#ifndef SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H
17276789Sdim#define SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H
18276789Sdim
19276789Sdim#ifndef SANITIZER_DEADLOCK_DETECTOR_VERSION
20276789Sdim# define SANITIZER_DEADLOCK_DETECTOR_VERSION 1
21276789Sdim#endif
22276789Sdim
23276789Sdim#include "sanitizer_internal_defs.h"
24276789Sdim#include "sanitizer_atomic.h"
25276789Sdim
26276789Sdimnamespace __sanitizer {
27276789Sdim
28276789Sdim// dd - deadlock detector.
29276789Sdim// lt - logical (user) thread.
30276789Sdim// pt - physical (OS) thread.
31276789Sdim
32276789Sdimstruct DDPhysicalThread;
33276789Sdimstruct DDLogicalThread;
34276789Sdim
35276789Sdimstruct DDMutex {
36276789Sdim#if SANITIZER_DEADLOCK_DETECTOR_VERSION == 1
37276789Sdim  uptr id;
38276789Sdim  u32  stk;  // creation stack
39276789Sdim#elif SANITIZER_DEADLOCK_DETECTOR_VERSION == 2
40276789Sdim  u32              id;
41276789Sdim  u32              recursion;
42276789Sdim  atomic_uintptr_t owner;
43276789Sdim#else
44276789Sdim# error "BAD SANITIZER_DEADLOCK_DETECTOR_VERSION"
45276789Sdim#endif
46276789Sdim  u64  ctx;
47276789Sdim};
48276789Sdim
49276789Sdimstruct DDFlags {
50276789Sdim  bool second_deadlock_stack;
51276789Sdim};
52276789Sdim
53276789Sdimstruct DDReport {
54276789Sdim  enum { kMaxLoopSize = 8 };
55276789Sdim  int n;  // number of entries in loop
56276789Sdim  struct {
57276789Sdim    u64 thr_ctx;   // user thread context
58276789Sdim    u64 mtx_ctx0;  // user mutex context, start of the edge
59276789Sdim    u64 mtx_ctx1;  // user mutex context, end of the edge
60276789Sdim    u32 stk[2];  // stack ids for the edge
61276789Sdim  } loop[kMaxLoopSize];
62276789Sdim};
63276789Sdim
64276789Sdimstruct DDCallback {
65276789Sdim  DDPhysicalThread *pt;
66276789Sdim  DDLogicalThread  *lt;
67276789Sdim
68276789Sdim  virtual u32 Unwind() { return 0; }
69276789Sdim  virtual int UniqueTid() { return 0; }
70276789Sdim};
71276789Sdim
72276789Sdimstruct DDetector {
73276789Sdim  static DDetector *Create(const DDFlags *flags);
74276789Sdim
75296417Sdim  virtual DDPhysicalThread* CreatePhysicalThread() { return nullptr; }
76276789Sdim  virtual void DestroyPhysicalThread(DDPhysicalThread *pt) {}
77276789Sdim
78296417Sdim  virtual DDLogicalThread* CreateLogicalThread(u64 ctx) { return nullptr; }
79276789Sdim  virtual void DestroyLogicalThread(DDLogicalThread *lt) {}
80276789Sdim
81276789Sdim  virtual void MutexInit(DDCallback *cb, DDMutex *m) {}
82276789Sdim  virtual void MutexBeforeLock(DDCallback *cb, DDMutex *m, bool wlock) {}
83276789Sdim  virtual void MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock,
84276789Sdim      bool trylock) {}
85276789Sdim  virtual void MutexBeforeUnlock(DDCallback *cb, DDMutex *m, bool wlock) {}
86276789Sdim  virtual void MutexDestroy(DDCallback *cb, DDMutex *m) {}
87276789Sdim
88296417Sdim  virtual DDReport *GetReport(DDCallback *cb) { return nullptr; }
89276789Sdim};
90276789Sdim
91276789Sdim} // namespace __sanitizer
92276789Sdim
93276789Sdim#endif // SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H
94