1#ifndef CLANG_TSA_H 2#define CLANG_TSA_H 3 4/* 5 * Copyright 2018 Jarkko Hietaniemi <jhi@iki.fi> 6 * 7 * Permission is hereby granted, free of charge, to any person obtaining 8 * a copy of this software and associated documentation files (the "Software"), 9 * to deal in the Software without restriction, including without 10 * limitation the rights to use, copy, modify, merge, publish, 11 * distribute, sublicense, and/or sell copies of the Software, and to 12 * permit persons to whom the Software is furnished to do so, subject to 13 * the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be 16 * included in all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 */ 26 27/* http://clang.llvm.org/docs/ThreadSafetyAnalysis.html 28 * 29 * TSA is available since clang 3.6-ish. 30 */ 31#ifdef __clang__ 32# define TSA(x) __attribute__((x)) 33#else 34# define TSA(x) /* No TSA, make TSA attributes no-ops. */ 35#endif 36 37/* TSA_CAPABILITY() is used to annotate typedefs: 38 * 39 * typedef pthread_mutex_t TSA_CAPABILITY("mutex") tsa_mutex; 40 */ 41#define TSA_CAPABILITY(x) TSA(capability(x)) 42 43/* TSA_GUARDED_BY() is used to annotate global variables, 44 * the data is guarded: 45 * 46 * Foo foo TSA_GUARDED_BY(mutex); 47 */ 48#define TSA_GUARDED_BY(x) TSA(guarded_by(x)) 49 50/* TSA_PT_GUARDED_BY() is used to annotate global pointers, the data 51 * behind the pointer is guarded. 52 * 53 * Foo* ptr TSA_PT_GUARDED_BY(mutex); 54 */ 55#define TSA_PT_GUARDED_BY(x) TSA(pt_guarded_by(x)) 56 57/* The TSA_REQUIRES() is used to annotate functions: the caller of the 58 * function MUST hold the resource, the function will NOT release it. 59 * 60 * More than one mutex may be specified, comma-separated. 61 * 62 * void Foo(void) TSA_REQUIRES(mutex); 63 */ 64#define TSA_REQUIRES(...) TSA(requires_capability(__VA_ARGS__)) 65#define TSA_REQUIRES_SHARED(...) TSA(requires_shared_capability(__VA_ARGS__)) 66 67/* TSA_EXCLUDES() is used to annotate functions: the caller of the 68 * function MUST NOT hold resource, the function first acquires the 69 * resource, and then releases it. 70 * 71 * More than one mutex may be specified, comma-separated. 72 * 73 * void Foo(void) TSA_EXCLUDES(mutex); 74 */ 75#define TSA_EXCLUDES(...) TSA(locks_excluded(__VA_ARGS__)) 76 77/* TSA_ACQUIRE() is used to annotate functions: the caller of the 78 * function MUST NOT hold the resource, the function will acquire the 79 * resource, but NOT release it. 80 * 81 * More than one mutex may be specified, comma-separated. 82 * 83 * void Foo(void) TSA_ACQUIRE(mutex); 84 */ 85#define TSA_ACQUIRE(...) TSA(acquire_capability(__VA_ARGS__)) 86#define TSA_ACQUIRE_SHARED(...) TSA(acquire_shared_capability(__VA_ARGS__)) 87 88/* TSA_RELEASE() is used to annotate functions: the caller of the 89 * function MUST hold the resource, but the function will then release it. 90 * 91 * More than one mutex may be specified, comma-separated. 92 * 93 * void Foo(void) TSA_RELEASE(mutex); 94 */ 95#define TSA_RELEASE(...) TSA(release_capability(__VA_ARGS__)) 96#define TSA_RELEASE_SHARED(...) TSA(release_shared_capability(__VA_ARGS__)) 97 98/* TSA_NO_TSA is used to annotate functions. Use only when you need to. 99 * 100 * void Foo(void) TSA_NO_TSA; 101 */ 102#define TSA_NO_TSA TSA(no_thread_safety_analysis) 103 104/* 105 * TSA_ASSERT() is used to annotate functions: This function will assert that 106 * the lock is held. When it returns, the caller of the function is assumed to 107 * already hold the resource. 108 * 109 * More than one mutex may be specified, comma-separated. 110 */ 111#define TSA_ASSERT(...) TSA(assert_capability(__VA_ARGS__)) 112#define TSA_ASSERT_SHARED(...) TSA(assert_shared_capability(__VA_ARGS__)) 113 114#endif /* #ifndef CLANG_TSA_H */ 115