1 //===-- sanitizer_deadlock_detector_interface.h -----------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file is a part of Sanitizer runtime. 10 // Abstract deadlock detector interface. 11 // FIXME: this is work in progress, nothing really works yet. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H 16 #define SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H 17 18 #ifndef SANITIZER_DEADLOCK_DETECTOR_VERSION 19 # define SANITIZER_DEADLOCK_DETECTOR_VERSION 1 20 #endif 21 22 #include "sanitizer_internal_defs.h" 23 #include "sanitizer_atomic.h" 24 25 namespace __sanitizer { 26 27 // dd - deadlock detector. 28 // lt - logical (user) thread. 29 // pt - physical (OS) thread. 30 31 struct DDPhysicalThread; 32 struct DDLogicalThread; 33 34 struct DDMutex { 35 #if SANITIZER_DEADLOCK_DETECTOR_VERSION == 1 36 uptr id; 37 u32 stk; // creation stack 38 #elif SANITIZER_DEADLOCK_DETECTOR_VERSION == 2 39 u32 id; 40 u32 recursion; 41 atomic_uintptr_t owner; 42 #else 43 # error "BAD SANITIZER_DEADLOCK_DETECTOR_VERSION" 44 #endif 45 u64 ctx; 46 }; 47 48 struct DDFlags { 49 bool second_deadlock_stack; 50 }; 51 52 struct DDReport { 53 enum { kMaxLoopSize = 20 }; 54 int n; // number of entries in loop 55 struct { 56 u64 thr_ctx; // user thread context 57 u64 mtx_ctx0; // user mutex context, start of the edge 58 u64 mtx_ctx1; // user mutex context, end of the edge 59 u32 stk[2]; // stack ids for the edge 60 } loop[kMaxLoopSize]; 61 }; 62 63 struct DDCallback { 64 DDPhysicalThread *pt; 65 DDLogicalThread *lt; 66 UnwindDDCallback67 virtual u32 Unwind() { return 0; } UniqueTidDDCallback68 virtual int UniqueTid() { return 0; } 69 70 protected: ~DDCallbackDDCallback71 ~DDCallback() {} 72 }; 73 74 struct DDetector { 75 static DDetector *Create(const DDFlags *flags); 76 CreatePhysicalThreadDDetector77 virtual DDPhysicalThread* CreatePhysicalThread() { return nullptr; } DestroyPhysicalThreadDDetector78 virtual void DestroyPhysicalThread(DDPhysicalThread *pt) {} 79 CreateLogicalThreadDDetector80 virtual DDLogicalThread* CreateLogicalThread(u64 ctx) { return nullptr; } DestroyLogicalThreadDDetector81 virtual void DestroyLogicalThread(DDLogicalThread *lt) {} 82 MutexInitDDetector83 virtual void MutexInit(DDCallback *cb, DDMutex *m) {} MutexBeforeLockDDetector84 virtual void MutexBeforeLock(DDCallback *cb, DDMutex *m, bool wlock) {} MutexAfterLockDDetector85 virtual void MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock, 86 bool trylock) {} MutexBeforeUnlockDDetector87 virtual void MutexBeforeUnlock(DDCallback *cb, DDMutex *m, bool wlock) {} MutexDestroyDDetector88 virtual void MutexDestroy(DDCallback *cb, DDMutex *m) {} 89 GetReportDDetector90 virtual DDReport *GetReport(DDCallback *cb) { return nullptr; } 91 92 protected: ~DDetectorDDetector93 ~DDetector() {} 94 }; 95 96 } // namespace __sanitizer 97 98 #endif // SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H 99