13cab2bb3Spatrick //===-- tsan_interface.h ----------------------------------------*- C++ -*-===// 23cab2bb3Spatrick // 33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information. 53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 63cab2bb3Spatrick // 73cab2bb3Spatrick //===----------------------------------------------------------------------===// 83cab2bb3Spatrick // 93cab2bb3Spatrick // This file is a part of ThreadSanitizer (TSan), a race detector. 103cab2bb3Spatrick // 113cab2bb3Spatrick // Public interface header for TSan. 123cab2bb3Spatrick //===----------------------------------------------------------------------===// 133cab2bb3Spatrick #ifndef SANITIZER_TSAN_INTERFACE_H 143cab2bb3Spatrick #define SANITIZER_TSAN_INTERFACE_H 153cab2bb3Spatrick 163cab2bb3Spatrick #include <sanitizer/common_interface_defs.h> 173cab2bb3Spatrick 183cab2bb3Spatrick #ifdef __cplusplus 193cab2bb3Spatrick extern "C" { 203cab2bb3Spatrick #endif 213cab2bb3Spatrick 223cab2bb3Spatrick // __tsan_release establishes a happens-before relation with a preceding 233cab2bb3Spatrick // __tsan_acquire on the same address. 243cab2bb3Spatrick void __tsan_acquire(void *addr); 253cab2bb3Spatrick void __tsan_release(void *addr); 263cab2bb3Spatrick 273cab2bb3Spatrick // Annotations for custom mutexes. 283cab2bb3Spatrick // The annotations allow to get better reports (with sets of locked mutexes), 293cab2bb3Spatrick // detect more types of bugs (e.g. mutex misuses, races between lock/unlock and 303cab2bb3Spatrick // destruction and potential deadlocks) and improve precision and performance 313cab2bb3Spatrick // (by ignoring individual atomic operations in mutex code). However, the 323cab2bb3Spatrick // downside is that annotated mutex code itself is not checked for correctness. 333cab2bb3Spatrick 343cab2bb3Spatrick // Mutex creation flags are passed to __tsan_mutex_create annotation. 353cab2bb3Spatrick // If mutex has no constructor and __tsan_mutex_create is not called, 363cab2bb3Spatrick // the flags may be passed to __tsan_mutex_pre_lock/__tsan_mutex_post_lock 373cab2bb3Spatrick // annotations. 383cab2bb3Spatrick 393cab2bb3Spatrick // Mutex has static storage duration and no-op constructor and destructor. 403cab2bb3Spatrick // This effectively makes tsan ignore destroy annotation. 411f9cb04fSpatrick static const unsigned __tsan_mutex_linker_init = 1 << 0; 423cab2bb3Spatrick // Mutex is write reentrant. 431f9cb04fSpatrick static const unsigned __tsan_mutex_write_reentrant = 1 << 1; 443cab2bb3Spatrick // Mutex is read reentrant. 451f9cb04fSpatrick static const unsigned __tsan_mutex_read_reentrant = 1 << 2; 463cab2bb3Spatrick // Mutex does not have static storage duration, and must not be used after 473cab2bb3Spatrick // its destructor runs. The opposite of __tsan_mutex_linker_init. 483cab2bb3Spatrick // If this flag is passed to __tsan_mutex_destroy, then the destruction 493cab2bb3Spatrick // is ignored unless this flag was previously set on the mutex. 501f9cb04fSpatrick static const unsigned __tsan_mutex_not_static = 1 << 8; 513cab2bb3Spatrick 523cab2bb3Spatrick // Mutex operation flags: 533cab2bb3Spatrick 543cab2bb3Spatrick // Denotes read lock operation. 551f9cb04fSpatrick static const unsigned __tsan_mutex_read_lock = 1 << 3; 563cab2bb3Spatrick // Denotes try lock operation. 571f9cb04fSpatrick static const unsigned __tsan_mutex_try_lock = 1 << 4; 583cab2bb3Spatrick // Denotes that a try lock operation has failed to acquire the mutex. 591f9cb04fSpatrick static const unsigned __tsan_mutex_try_lock_failed = 1 << 5; 603cab2bb3Spatrick // Denotes that the lock operation acquires multiple recursion levels. 613cab2bb3Spatrick // Number of levels is passed in recursion parameter. 623cab2bb3Spatrick // This is useful for annotation of e.g. Java builtin monitors, 633cab2bb3Spatrick // for which wait operation releases all recursive acquisitions of the mutex. 641f9cb04fSpatrick static const unsigned __tsan_mutex_recursive_lock = 1 << 6; 653cab2bb3Spatrick // Denotes that the unlock operation releases all recursion levels. 663cab2bb3Spatrick // Number of released levels is returned and later must be passed to 673cab2bb3Spatrick // the corresponding __tsan_mutex_post_lock annotation. 681f9cb04fSpatrick static const unsigned __tsan_mutex_recursive_unlock = 1 << 7; 693cab2bb3Spatrick 70d89ec533Spatrick // Convenient composed constants. 71d89ec533Spatrick static const unsigned __tsan_mutex_try_read_lock = 72d89ec533Spatrick __tsan_mutex_read_lock | __tsan_mutex_try_lock; 73d89ec533Spatrick static const unsigned __tsan_mutex_try_read_lock_failed = 74d89ec533Spatrick __tsan_mutex_try_read_lock | __tsan_mutex_try_lock_failed; 75d89ec533Spatrick 763cab2bb3Spatrick // Annotate creation of a mutex. 773cab2bb3Spatrick // Supported flags: mutex creation flags. 783cab2bb3Spatrick void __tsan_mutex_create(void *addr, unsigned flags); 793cab2bb3Spatrick 803cab2bb3Spatrick // Annotate destruction of a mutex. 813cab2bb3Spatrick // Supported flags: 823cab2bb3Spatrick // - __tsan_mutex_linker_init 833cab2bb3Spatrick // - __tsan_mutex_not_static 843cab2bb3Spatrick void __tsan_mutex_destroy(void *addr, unsigned flags); 853cab2bb3Spatrick 863cab2bb3Spatrick // Annotate start of lock operation. 873cab2bb3Spatrick // Supported flags: 883cab2bb3Spatrick // - __tsan_mutex_read_lock 893cab2bb3Spatrick // - __tsan_mutex_try_lock 903cab2bb3Spatrick // - all mutex creation flags 913cab2bb3Spatrick void __tsan_mutex_pre_lock(void *addr, unsigned flags); 923cab2bb3Spatrick 933cab2bb3Spatrick // Annotate end of lock operation. 943cab2bb3Spatrick // Supported flags: 953cab2bb3Spatrick // - __tsan_mutex_read_lock (must match __tsan_mutex_pre_lock) 963cab2bb3Spatrick // - __tsan_mutex_try_lock (must match __tsan_mutex_pre_lock) 973cab2bb3Spatrick // - __tsan_mutex_try_lock_failed 983cab2bb3Spatrick // - __tsan_mutex_recursive_lock 993cab2bb3Spatrick // - all mutex creation flags 1003cab2bb3Spatrick void __tsan_mutex_post_lock(void *addr, unsigned flags, int recursion); 1013cab2bb3Spatrick 1023cab2bb3Spatrick // Annotate start of unlock operation. 1033cab2bb3Spatrick // Supported flags: 1043cab2bb3Spatrick // - __tsan_mutex_read_lock 1053cab2bb3Spatrick // - __tsan_mutex_recursive_unlock 1063cab2bb3Spatrick int __tsan_mutex_pre_unlock(void *addr, unsigned flags); 1073cab2bb3Spatrick 1083cab2bb3Spatrick // Annotate end of unlock operation. 1093cab2bb3Spatrick // Supported flags: 1103cab2bb3Spatrick // - __tsan_mutex_read_lock (must match __tsan_mutex_pre_unlock) 1113cab2bb3Spatrick void __tsan_mutex_post_unlock(void *addr, unsigned flags); 1123cab2bb3Spatrick 1133cab2bb3Spatrick // Annotate start/end of notify/signal/broadcast operation. 1143cab2bb3Spatrick // Supported flags: none. 1153cab2bb3Spatrick void __tsan_mutex_pre_signal(void *addr, unsigned flags); 1163cab2bb3Spatrick void __tsan_mutex_post_signal(void *addr, unsigned flags); 1173cab2bb3Spatrick 1183cab2bb3Spatrick // Annotate start/end of a region of code where lock/unlock/signal operation 1193cab2bb3Spatrick // diverts to do something else unrelated to the mutex. This can be used to 1203cab2bb3Spatrick // annotate, for example, calls into cooperative scheduler or contention 1213cab2bb3Spatrick // profiling code. 1223cab2bb3Spatrick // These annotations must be called only from within 1233cab2bb3Spatrick // __tsan_mutex_pre/post_lock, __tsan_mutex_pre/post_unlock, 1243cab2bb3Spatrick // __tsan_mutex_pre/post_signal regions. 1253cab2bb3Spatrick // Supported flags: none. 1263cab2bb3Spatrick void __tsan_mutex_pre_divert(void *addr, unsigned flags); 1273cab2bb3Spatrick void __tsan_mutex_post_divert(void *addr, unsigned flags); 1283cab2bb3Spatrick 1293cab2bb3Spatrick // External race detection API. 1303cab2bb3Spatrick // Can be used by non-instrumented libraries to detect when their objects are 1313cab2bb3Spatrick // being used in an unsafe manner. 1323cab2bb3Spatrick // - __tsan_external_read/__tsan_external_write annotates the logical reads 1333cab2bb3Spatrick // and writes of the object at the specified address. 'caller_pc' should 1343cab2bb3Spatrick // be the PC of the library user, which the library can obtain with e.g. 1353cab2bb3Spatrick // `__builtin_return_address(0)`. 1363cab2bb3Spatrick // - __tsan_external_register_tag registers a 'tag' with the specified name, 1373cab2bb3Spatrick // which is later used in read/write annotations to denote the object type 1383cab2bb3Spatrick // - __tsan_external_assign_tag can optionally mark a heap object with a tag 1393cab2bb3Spatrick void *__tsan_external_register_tag(const char *object_type); 1403cab2bb3Spatrick void __tsan_external_register_header(void *tag, const char *header); 1413cab2bb3Spatrick void __tsan_external_assign_tag(void *addr, void *tag); 1423cab2bb3Spatrick void __tsan_external_read(void *addr, void *caller_pc, void *tag); 1433cab2bb3Spatrick void __tsan_external_write(void *addr, void *caller_pc, void *tag); 1443cab2bb3Spatrick 1453cab2bb3Spatrick // Fiber switching API. 1463cab2bb3Spatrick // - TSAN context for fiber can be created by __tsan_create_fiber 1473cab2bb3Spatrick // and freed by __tsan_destroy_fiber. 1483cab2bb3Spatrick // - TSAN context of current fiber or thread can be obtained 1493cab2bb3Spatrick // by calling __tsan_get_current_fiber. 150d89ec533Spatrick // - __tsan_switch_to_fiber should be called immediately before switch 1513cab2bb3Spatrick // to fiber, such as call of swapcontext. 1523cab2bb3Spatrick // - Fiber name can be set by __tsan_set_fiber_name. 1533cab2bb3Spatrick void *__tsan_get_current_fiber(void); 1543cab2bb3Spatrick void *__tsan_create_fiber(unsigned flags); 1553cab2bb3Spatrick void __tsan_destroy_fiber(void *fiber); 1563cab2bb3Spatrick void __tsan_switch_to_fiber(void *fiber, unsigned flags); 1573cab2bb3Spatrick void __tsan_set_fiber_name(void *fiber, const char *name); 1583cab2bb3Spatrick 1593cab2bb3Spatrick // Flags for __tsan_switch_to_fiber: 1603cab2bb3Spatrick // Do not establish a happens-before relation between fibers 1611f9cb04fSpatrick static const unsigned __tsan_switch_to_fiber_no_sync = 1 << 0; 1623cab2bb3Spatrick 163d89ec533Spatrick // User-provided callback invoked on TSan initialization. 164d89ec533Spatrick void __tsan_on_initialize(); 165d89ec533Spatrick 166d89ec533Spatrick // User-provided callback invoked on TSan shutdown. 167d89ec533Spatrick // `failed` - Nonzero if TSan did detect issues, zero otherwise. 168d89ec533Spatrick // Return `0` if TSan should exit as if no issues were detected. Return nonzero 169d89ec533Spatrick // if TSan should exit as if issues were detected. 170d89ec533Spatrick int __tsan_on_finalize(int failed); 171d89ec533Spatrick 172*810390e3Srobert // Release TSan internal memory in a best-effort manner. 173*810390e3Srobert void __tsan_flush_memory(); 174*810390e3Srobert 1753cab2bb3Spatrick #ifdef __cplusplus 1763cab2bb3Spatrick } // extern "C" 1773cab2bb3Spatrick #endif 1783cab2bb3Spatrick 1793cab2bb3Spatrick #endif // SANITIZER_TSAN_INTERFACE_H 180