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 25namespace __sanitizer { 26 27// dd - deadlock detector. 28// lt - logical (user) thread. 29// pt - physical (OS) thread. 30 31struct DDPhysicalThread; 32struct DDLogicalThread; 33 34struct 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 48struct DDFlags { 49 bool second_deadlock_stack; 50}; 51 52struct 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 63struct DDCallback { 64 DDPhysicalThread *pt; 65 DDLogicalThread *lt; 66 67 virtual u32 Unwind() { return 0; } 68 virtual int UniqueTid() { return 0; } 69 70 protected: 71 ~DDCallback() {} 72}; 73 74struct DDetector { 75 static DDetector *Create(const DDFlags *flags); 76 77 virtual DDPhysicalThread* CreatePhysicalThread() { return nullptr; } 78 virtual void DestroyPhysicalThread(DDPhysicalThread *pt) {} 79 80 virtual DDLogicalThread* CreateLogicalThread(u64 ctx) { return nullptr; } 81 virtual void DestroyLogicalThread(DDLogicalThread *lt) {} 82 83 virtual void MutexInit(DDCallback *cb, DDMutex *m) {} 84 virtual void MutexBeforeLock(DDCallback *cb, DDMutex *m, bool wlock) {} 85 virtual void MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock, 86 bool trylock) {} 87 virtual void MutexBeforeUnlock(DDCallback *cb, DDMutex *m, bool wlock) {} 88 virtual void MutexDestroy(DDCallback *cb, DDMutex *m) {} 89 90 virtual DDReport *GetReport(DDCallback *cb) { return nullptr; } 91 92 protected: 93 ~DDetector() {} 94}; 95 96} // namespace __sanitizer 97 98#endif // SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H 99