Home | History | Annotate | Download | only in sanitizer_common
      1 //===-- sanitizer_deadlock_detector_interface.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 Sanitizer runtime.
     11 // Abstract deadlock detector interface.
     12 // FIXME: this is work in progress, nothing really works yet.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #ifndef SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H
     17 #define SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H
     18 
     19 #ifndef SANITIZER_DEADLOCK_DETECTOR_VERSION
     20 # define SANITIZER_DEADLOCK_DETECTOR_VERSION 1
     21 #endif
     22 
     23 #include "sanitizer_internal_defs.h"
     24 #include "sanitizer_atomic.h"
     25 
     26 namespace __sanitizer {
     27 
     28 // dd - deadlock detector.
     29 // lt - logical (user) thread.
     30 // pt - physical (OS) thread.
     31 
     32 struct DDPhysicalThread;
     33 struct DDLogicalThread;
     34 
     35 struct DDMutex {
     36 #if SANITIZER_DEADLOCK_DETECTOR_VERSION == 1
     37   uptr id;
     38   u32  stk;  // creation stack
     39 #elif SANITIZER_DEADLOCK_DETECTOR_VERSION == 2
     40   u32              id;
     41   u32              recursion;
     42   atomic_uintptr_t owner;
     43 #else
     44 # error "BAD SANITIZER_DEADLOCK_DETECTOR_VERSION"
     45 #endif
     46   u64  ctx;
     47 };
     48 
     49 struct DDFlags {
     50   bool second_deadlock_stack;
     51 };
     52 
     53 struct DDReport {
     54   enum { kMaxLoopSize = 8 };
     55   int n;  // number of entries in loop
     56   struct {
     57     u64 thr_ctx;   // user thread context
     58     u64 mtx_ctx0;  // user mutex context, start of the edge
     59     u64 mtx_ctx1;  // user mutex context, end of the edge
     60     u32 stk[2];  // stack ids for the edge
     61   } loop[kMaxLoopSize];
     62 };
     63 
     64 struct DDCallback {
     65   DDPhysicalThread *pt;
     66   DDLogicalThread  *lt;
     67 
     68   virtual u32 Unwind() { return 0; }
     69   virtual int UniqueTid() { return 0; }
     70 };
     71 
     72 struct DDetector {
     73   static DDetector *Create(const DDFlags *flags);
     74 
     75   virtual DDPhysicalThread* CreatePhysicalThread() { return nullptr; }
     76   virtual void DestroyPhysicalThread(DDPhysicalThread *pt) {}
     77 
     78   virtual DDLogicalThread* CreateLogicalThread(u64 ctx) { return nullptr; }
     79   virtual void DestroyLogicalThread(DDLogicalThread *lt) {}
     80 
     81   virtual void MutexInit(DDCallback *cb, DDMutex *m) {}
     82   virtual void MutexBeforeLock(DDCallback *cb, DDMutex *m, bool wlock) {}
     83   virtual void MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock,
     84       bool trylock) {}
     85   virtual void MutexBeforeUnlock(DDCallback *cb, DDMutex *m, bool wlock) {}
     86   virtual void MutexDestroy(DDCallback *cb, DDMutex *m) {}
     87 
     88   virtual DDReport *GetReport(DDCallback *cb) { return nullptr; }
     89 };
     90 
     91 } // namespace __sanitizer
     92 
     93 #endif // SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H
     94