(root)/
gcc-13.2.0/
libsanitizer/
sanitizer_common/
sanitizer_deadlock_detector_interface.h
       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  
      67    virtual u32 Unwind() { return 0; }
      68    virtual int UniqueTid() { return 0; }
      69  
      70   protected:
      71    ~DDCallback() {}
      72  };
      73  
      74  struct 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