1  //===-- tsan_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 ThreadSanitizer (TSan), a race detector.
      10  //
      11  // Public interface header for TSan.
      12  //===----------------------------------------------------------------------===//
      13  #ifndef SANITIZER_TSAN_INTERFACE_H
      14  #define SANITIZER_TSAN_INTERFACE_H
      15  
      16  #include <sanitizer/common_interface_defs.h>
      17  
      18  #ifdef __cplusplus
      19  extern "C" {
      20  #endif
      21  
      22  // __tsan_release establishes a happens-before relation with a preceding
      23  // __tsan_acquire on the same address.
      24  void __tsan_acquire(void *addr);
      25  void __tsan_release(void *addr);
      26  
      27  // Annotations for custom mutexes.
      28  // The annotations allow to get better reports (with sets of locked mutexes),
      29  // detect more types of bugs (e.g. mutex misuses, races between lock/unlock and
      30  // destruction and potential deadlocks) and improve precision and performance
      31  // (by ignoring individual atomic operations in mutex code). However, the
      32  // downside is that annotated mutex code itself is not checked for correctness.
      33  
      34  // Mutex creation flags are passed to __tsan_mutex_create annotation.
      35  // If mutex has no constructor and __tsan_mutex_create is not called,
      36  // the flags may be passed to __tsan_mutex_pre_lock/__tsan_mutex_post_lock
      37  // annotations.
      38  
      39  // Mutex has static storage duration and no-op constructor and destructor.
      40  // This effectively makes tsan ignore destroy annotation.
      41  static const unsigned __tsan_mutex_linker_init      = 1 << 0;
      42  // Mutex is write reentrant.
      43  static const unsigned __tsan_mutex_write_reentrant  = 1 << 1;
      44  // Mutex is read reentrant.
      45  static const unsigned __tsan_mutex_read_reentrant   = 1 << 2;
      46  // Mutex does not have static storage duration, and must not be used after
      47  // its destructor runs.  The opposite of __tsan_mutex_linker_init.
      48  // If this flag is passed to __tsan_mutex_destroy, then the destruction
      49  // is ignored unless this flag was previously set on the mutex.
      50  static const unsigned __tsan_mutex_not_static       = 1 << 8;
      51  
      52  // Mutex operation flags:
      53  
      54  // Denotes read lock operation.
      55  static const unsigned __tsan_mutex_read_lock        = 1 << 3;
      56  // Denotes try lock operation.
      57  static const unsigned __tsan_mutex_try_lock         = 1 << 4;
      58  // Denotes that a try lock operation has failed to acquire the mutex.
      59  static const unsigned __tsan_mutex_try_lock_failed  = 1 << 5;
      60  // Denotes that the lock operation acquires multiple recursion levels.
      61  // Number of levels is passed in recursion parameter.
      62  // This is useful for annotation of e.g. Java builtin monitors,
      63  // for which wait operation releases all recursive acquisitions of the mutex.
      64  static const unsigned __tsan_mutex_recursive_lock   = 1 << 6;
      65  // Denotes that the unlock operation releases all recursion levels.
      66  // Number of released levels is returned and later must be passed to
      67  // the corresponding __tsan_mutex_post_lock annotation.
      68  static const unsigned __tsan_mutex_recursive_unlock = 1 << 7;
      69  
      70  // Convenient composed constants.
      71  static const unsigned __tsan_mutex_try_read_lock =
      72      __tsan_mutex_read_lock | __tsan_mutex_try_lock;
      73  static const unsigned __tsan_mutex_try_read_lock_failed =
      74      __tsan_mutex_try_read_lock | __tsan_mutex_try_lock_failed;
      75  
      76  // Annotate creation of a mutex.
      77  // Supported flags: mutex creation flags.
      78  void __tsan_mutex_create(void *addr, unsigned flags);
      79  
      80  // Annotate destruction of a mutex.
      81  // Supported flags:
      82  //   - __tsan_mutex_linker_init
      83  //   - __tsan_mutex_not_static
      84  void __tsan_mutex_destroy(void *addr, unsigned flags);
      85  
      86  // Annotate start of lock operation.
      87  // Supported flags:
      88  //   - __tsan_mutex_read_lock
      89  //   - __tsan_mutex_try_lock
      90  //   - all mutex creation flags
      91  void __tsan_mutex_pre_lock(void *addr, unsigned flags);
      92  
      93  // Annotate end of lock operation.
      94  // Supported flags:
      95  //   - __tsan_mutex_read_lock (must match __tsan_mutex_pre_lock)
      96  //   - __tsan_mutex_try_lock (must match __tsan_mutex_pre_lock)
      97  //   - __tsan_mutex_try_lock_failed
      98  //   - __tsan_mutex_recursive_lock
      99  //   - all mutex creation flags
     100  void __tsan_mutex_post_lock(void *addr, unsigned flags, int recursion);
     101  
     102  // Annotate start of unlock operation.
     103  // Supported flags:
     104  //   - __tsan_mutex_read_lock
     105  //   - __tsan_mutex_recursive_unlock
     106  int __tsan_mutex_pre_unlock(void *addr, unsigned flags);
     107  
     108  // Annotate end of unlock operation.
     109  // Supported flags:
     110  //   - __tsan_mutex_read_lock (must match __tsan_mutex_pre_unlock)
     111  void __tsan_mutex_post_unlock(void *addr, unsigned flags);
     112  
     113  // Annotate start/end of notify/signal/broadcast operation.
     114  // Supported flags: none.
     115  void __tsan_mutex_pre_signal(void *addr, unsigned flags);
     116  void __tsan_mutex_post_signal(void *addr, unsigned flags);
     117  
     118  // Annotate start/end of a region of code where lock/unlock/signal operation
     119  // diverts to do something else unrelated to the mutex. This can be used to
     120  // annotate, for example, calls into cooperative scheduler or contention
     121  // profiling code.
     122  // These annotations must be called only from within
     123  // __tsan_mutex_pre/post_lock, __tsan_mutex_pre/post_unlock,
     124  // __tsan_mutex_pre/post_signal regions.
     125  // Supported flags: none.
     126  void __tsan_mutex_pre_divert(void *addr, unsigned flags);
     127  void __tsan_mutex_post_divert(void *addr, unsigned flags);
     128  
     129  // External race detection API.
     130  // Can be used by non-instrumented libraries to detect when their objects are
     131  // being used in an unsafe manner.
     132  //   - __tsan_external_read/__tsan_external_write annotates the logical reads
     133  //       and writes of the object at the specified address. 'caller_pc' should
     134  //       be the PC of the library user, which the library can obtain with e.g.
     135  //       `__builtin_return_address(0)`.
     136  //   - __tsan_external_register_tag registers a 'tag' with the specified name,
     137  //       which is later used in read/write annotations to denote the object type
     138  //   - __tsan_external_assign_tag can optionally mark a heap object with a tag
     139  void *__tsan_external_register_tag(const char *object_type);
     140  void __tsan_external_register_header(void *tag, const char *header);
     141  void __tsan_external_assign_tag(void *addr, void *tag);
     142  void __tsan_external_read(void *addr, void *caller_pc, void *tag);
     143  void __tsan_external_write(void *addr, void *caller_pc, void *tag);
     144  
     145  // Fiber switching API.
     146  //   - TSAN context for fiber can be created by __tsan_create_fiber
     147  //     and freed by __tsan_destroy_fiber.
     148  //   - TSAN context of current fiber or thread can be obtained
     149  //     by calling __tsan_get_current_fiber.
     150  //   - __tsan_switch_to_fiber should be called immediately before switch
     151  //     to fiber, such as call of swapcontext.
     152  //   - Fiber name can be set by __tsan_set_fiber_name.
     153  void *__tsan_get_current_fiber(void);
     154  void *__tsan_create_fiber(unsigned flags);
     155  void __tsan_destroy_fiber(void *fiber);
     156  void __tsan_switch_to_fiber(void *fiber, unsigned flags);
     157  void __tsan_set_fiber_name(void *fiber, const char *name);
     158  
     159  // Flags for __tsan_switch_to_fiber:
     160  // Do not establish a happens-before relation between fibers
     161  static const unsigned __tsan_switch_to_fiber_no_sync = 1 << 0;
     162  
     163  // User-provided callback invoked on TSan initialization.
     164  void __tsan_on_initialize();
     165  
     166  // User-provided callback invoked on TSan shutdown.
     167  // `failed` - Nonzero if TSan did detect issues, zero otherwise.
     168  // Return `0` if TSan should exit as if no issues were detected.  Return nonzero
     169  // if TSan should exit as if issues were detected.
     170  int __tsan_on_finalize(int failed);
     171  
     172  // Release TSan internal memory in a best-effort manner.
     173  void __tsan_flush_memory();
     174  
     175  #ifdef __cplusplus
     176  }  // extern "C"
     177  #endif
     178  
     179  #endif  // SANITIZER_TSAN_INTERFACE_H