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 71struct DDetector { 72 static DDetector *Create(const DDFlags *flags); 73 74 virtual DDPhysicalThread* CreatePhysicalThread() { return nullptr; } 75 virtual void DestroyPhysicalThread(DDPhysicalThread *pt) {} 76 77 virtual DDLogicalThread* CreateLogicalThread(u64 ctx) { return nullptr; } 78 virtual void DestroyLogicalThread(DDLogicalThread *lt) {} 79 80 virtual void MutexInit(DDCallback *cb, DDMutex *m) {} 81 virtual void MutexBeforeLock(DDCallback *cb, DDMutex *m, bool wlock) {} 82 virtual void MutexAfterLock(DDCallback *cb, DDMutex *m, bool wlock, 83 bool trylock) {} 84 virtual void MutexBeforeUnlock(DDCallback *cb, DDMutex *m, bool wlock) {} 85 virtual void MutexDestroy(DDCallback *cb, DDMutex *m) {} 86 87 virtual DDReport *GetReport(DDCallback *cb) { return nullptr; } 88}; 89 90} // namespace __sanitizer 91 92#endif // SANITIZER_DEADLOCK_DETECTOR_INTERFACE_H 93