1 // Copyright (C) 2019 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // This file is a port of absl::thread_annotations. 16 // 17 // This header file contains macro definitions for thread safety annotations 18 // that allow developers to document the locking policies of multi-threaded 19 // code. The annotations can also help program analysis tools to identify 20 // potential thread safety issues. 21 // 22 // These annotations are implemented using compiler attributes. Using the macros 23 // defined here instead of raw attributes allow for portability and future 24 // compatibility. 25 // 26 // When referring to mutexes in the arguments of the attributes, you should 27 // use variable names or more complex expressions (e.g. my_object->mutex_) 28 // that evaluate to a concrete mutex object whenever possible. If the mutex 29 // you want to refer to is not in scope, you may use a member pointer 30 // (e.g. &MyClass::mutex_) to refer to a mutex in some (unknown) object. 31 32 #ifndef ICING_ABSL_PORTS_THREAD_ANNOTATIONS_H_ 33 #define ICING_ABSL_PORTS_THREAD_ANNOTATIONS_H_ 34 35 #if defined(__clang__) 36 #define ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(x) __attribute__((x)) 37 #else 38 #define ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(x) // no-op 39 #endif 40 41 // ICING_GUARDED_BY() 42 // 43 // Documents if a shared field or global variable needs to be protected by a 44 // mutex. ICING_GUARDED_BY() allows the user to specify a particular mutex that 45 // should be held when accessing the annotated variable. 46 // 47 // Although this annotation (and ICING_PT_GUARDED_BY, below) cannot be applied 48 // to local variables, a local variable and its associated mutex can often be 49 // combined into a small class or struct, thereby allowing the annotation. 50 // 51 // Example: 52 // 53 // class Foo { 54 // Mutex mu_; 55 // int p1_ ICING_GUARDED_BY(mu_); 56 // ... 57 // }; 58 #define ICING_GUARDED_BY(x) \ 59 ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(guarded_by(x)) 60 61 // ICING_PT_GUARDED_BY() 62 // 63 // Documents if the memory location pointed to by a pointer should be guarded 64 // by a mutex when dereferencing the pointer. 65 // 66 // Example: 67 // class Foo { 68 // Mutex mu_; 69 // int *p1_ ICING_PT_GUARDED_BY(mu_); 70 // ... 71 // }; 72 // 73 // Note that a pointer variable to a shared memory location could itself be a 74 // shared variable. 75 // 76 // Example: 77 // 78 // // `q_`, guarded by `mu1_`, points to a shared memory location that is 79 // // guarded by `mu2_`: 80 // int *q_ ICING_GUARDED_BY(mu1_) ICING_PT_GUARDED_BY(mu2_); 81 #define ICING_PT_GUARDED_BY(x) \ 82 ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(pt_guarded_by(x)) 83 84 // ICING_ACQUIRED_AFTER() / ICING_ACQUIRED_BEFORE() 85 // 86 // Documents the acquisition order between locks that can be held 87 // simultaneously by a thread. For any two locks that need to be annotated 88 // to establish an acquisition order, only one of them needs the annotation. 89 // (i.e. You don't have to annotate both locks with both ICING_ACQUIRED_AFTER 90 // and ICING_ACQUIRED_BEFORE.) 91 // 92 // As with ICING_GUARDED_BY, this is only applicable to mutexes that are shared 93 // fields or global variables. 94 // 95 // Example: 96 // 97 // Mutex m1_; 98 // Mutex m2_ ICING_ACQUIRED_AFTER(m1_); 99 #define ICING_ACQUIRED_AFTER(...) \ 100 ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(acquired_after(__VA_ARGS__)) 101 102 #define ICING_ACQUIRED_BEFORE(...) \ 103 ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(acquired_before(__VA_ARGS__)) 104 105 // ICING_EXCLUSIVE_LOCKS_REQUIRED() / ICING_SHARED_LOCKS_REQUIRED() 106 // 107 // Documents a function that expects a mutex to be held prior to entry. 108 // The mutex is expected to be held both on entry to, and exit from, the 109 // function. 110 // 111 // An exclusive lock allows read-write access to the guarded data member(s), and 112 // only one thread can acquire a lock exclusively at any one time. A shared lock 113 // allows read-only access, and any number of threads can acquire a shared lock 114 // concurrently. 115 // 116 // Generally, non-const methods should be annotated with 117 // ICING_EXCLUSIVE_LOCKS_REQUIRED, while const methods should be annotated with 118 // ICING_SHARED_LOCKS_REQUIRED. 119 // 120 // Example: 121 // 122 // Mutex mu1, mu2; 123 // int a ICING_GUARDED_BY(mu1); 124 // int b ICING_GUARDED_BY(mu2); 125 // 126 // void foo() ICING_EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2) { ... } 127 // void bar() const ICING_SHARED_LOCKS_REQUIRED(mu1, mu2) { ... } 128 #define ICING_EXCLUSIVE_LOCKS_REQUIRED(...) \ 129 ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \ 130 exclusive_locks_required(__VA_ARGS__)) 131 132 #define ICING_SHARED_LOCKS_REQUIRED(...) \ 133 ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(shared_locks_required(__VA_ARGS__)) 134 135 // ICING_LOCKS_EXCLUDED() 136 // 137 // Documents the locks acquired in the body of the function. These locks 138 // cannot be held when calling this function. 139 #define ICING_LOCKS_EXCLUDED(...) \ 140 ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(locks_excluded(__VA_ARGS__)) 141 142 // ICING_LOCK_RETURNED() 143 // 144 // Documents a function that returns a mutex without acquiring it. For example, 145 // a public getter method that returns a pointer to a private mutex should 146 // be annotated with ICING_LOCK_RETURNED. 147 #define ICING_LOCK_RETURNED(x) \ 148 ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(lock_returned(x)) 149 150 // ICING_LOCKABLE 151 // 152 // Documents if a class/type is a lockable type. 153 #define ICING_LOCKABLE \ 154 ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(lockable) 155 156 // ICING_SCOPED_LOCKABLE 157 // 158 // Documents if a class does RAII locking. 159 // The constructor should use `ICING_LOCK_FUNCTION()` to specify the mutex that 160 // is acquired, and the destructor should use `ICING_UNLOCK_FUNCTION()` with no 161 // arguments; the analysis will assume that the destructor unlocks whatever the 162 // constructor locked. 163 #define ICING_SCOPED_LOCKABLE \ 164 ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(scoped_lockable) 165 166 // ICING_EXCLUSIVE_LOCK_FUNCTION() 167 // 168 // Documents functions that acquire a lock in the body of a function, and do 169 // not release it. 170 #define ICING_EXCLUSIVE_LOCK_FUNCTION(...) \ 171 ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \ 172 exclusive_lock_function(__VA_ARGS__)) 173 174 // ICING_SHARED_LOCK_FUNCTION() 175 // 176 // Documents functions that acquire a shared (reader) lock in the body of a 177 // function, and do not release it. 178 #define ICING_SHARED_LOCK_FUNCTION(...) \ 179 ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(shared_lock_function(__VA_ARGS__)) 180 181 // ICING_UNLOCK_FUNCTION() 182 // 183 // Documents functions that expect a lock to be held on entry to the function, 184 // and release it in the body of the function. 185 #define ICING_UNLOCK_FUNCTION(...) \ 186 ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(unlock_function(__VA_ARGS__)) 187 188 // ICING_EXCLUSIVE_TRYLOCK_FUNCTION() / ICING_SHARED_TRYLOCK_FUNCTION() 189 // 190 // Documents functions that try to acquire a lock, and return success or failure 191 // (or a non-boolean value that can be interpreted as a boolean). 192 // The first argument should be `true` for functions that return `true` on 193 // success, or `false` for functions that return `false` on success. The second 194 // argument specifies the mutex that is locked on success. If unspecified, this 195 // mutex is assumed to be `this`. 196 #define ICING_EXCLUSIVE_TRYLOCK_FUNCTION(...) \ 197 ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \ 198 exclusive_trylock_function(__VA_ARGS__)) 199 200 #define ICING_SHARED_TRYLOCK_FUNCTION(...) \ 201 ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE( \ 202 shared_trylock_function(__VA_ARGS__)) 203 204 // ICING_ASSERT_EXCLUSIVE_LOCK() / ICING_ASSERT_SHARED_LOCK() 205 // 206 // Documents functions that dynamically check to see if a lock is held, and fail 207 // if it is not held. 208 #define ICING_ASSERT_EXCLUSIVE_LOCK(...) \ 209 ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(assert_exclusive_lock(__VA_ARGS__)) 210 211 #define ICING_ASSERT_SHARED_LOCK(...) \ 212 ICING_INTERNAL_THREAD_ANNOTATION_ATTRIBUTE(assert_shared_lock(__VA_ARGS__)) 213 214 #endif // ICING_ABSL_PORTS_THREAD_ANNOTATIONS_H_ 215