1 // Copyright 2021 The Pigweed Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not 4 // use this file except in compliance with the License. You may obtain a copy of 5 // the License at 6 // 7 // https://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, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations under 13 // the License. 14 // 15 // This header file contains macro definitions for thread safety annotations 16 // that allow developers to document the locking policies of multi-threaded 17 // code. The annotations can also help program analysis tools to identify 18 // potential thread safety issues. 19 // 20 // These annotations are implemented using compiler attributes. Using the macros 21 // defined here instead of raw attributes allow for portability and future 22 // compatibility. 23 // 24 // The thread safety analysis system is documented at 25 // http://clang.llvm.org/docs/ThreadSafetyAnalysis.html 26 // 27 // When referring to locks in the arguments of the attributes, you should 28 // use variable names or more complex expressions (e.g. my_object->lock_) 29 // that evaluate to a concrete lock object whenever possible. If the lock 30 // you want to refer to is not in scope, you may use a member pointer 31 // (e.g. &MyClass::lock_) to refer to a lock in some (unknown) object. 32 33 #pragma once 34 35 #include "pw_preprocessor/compiler.h" 36 37 // PW_GUARDED_BY() 38 // 39 // Documents if a shared field or global variable needs to be protected by a 40 // lock. PW_GUARDED_BY() allows the user to specify a particular lock that 41 // should be held when accessing the annotated variable. 42 // 43 // Although this annotation (and PW_PT_GUARDED_BY, below) cannot be applied to 44 // local variables, a local variable and its associated lock can often be 45 // combined into a small class or struct, thereby allowing the annotation. 46 // 47 // Example: 48 // 49 // class Foo { 50 // Mutex mu_; 51 // int p1_ PW_GUARDED_BY(mu_); 52 // ... 53 // }; 54 #if PW_HAVE_ATTRIBUTE(guarded_by) 55 #define PW_GUARDED_BY(x) __attribute__((guarded_by(x))) 56 #else 57 #define PW_GUARDED_BY(x) 58 #endif 59 60 // PW_PT_GUARDED_BY() 61 // 62 // Documents if the memory location pointed to by a pointer should be guarded 63 // by a lock when dereferencing the pointer. 64 // 65 // Example: 66 // class Foo { 67 // Mutex mu_; 68 // int *p1_ PW_PT_GUARDED_BY(mu_); 69 // ... 70 // }; 71 // 72 // Note that a pointer variable to a shared memory location could itself be a 73 // shared variable. 74 // 75 // Example: 76 // 77 // // `q_`, guarded by `mu1_`, points to a shared memory location that is 78 // // guarded by `mu2_`: 79 // int *q_ PW_GUARDED_BY(mu1_) PW_PT_GUARDED_BY(mu2_); 80 #if PW_HAVE_ATTRIBUTE(pt_guarded_by) 81 #define PW_PT_GUARDED_BY(x) __attribute__((pt_guarded_by(x))) 82 #else 83 #define PW_PT_GUARDED_BY(x) 84 #endif 85 86 // PW_ACQUIRED_AFTER() / PW_ACQUIRED_BEFORE() 87 // 88 // Documents the acquisition order between locks that can be held 89 // simultaneously by a thread. For any two locks that need to be annotated 90 // to establish an acquisition order, only one of them needs the annotation. 91 // (i.e. You don't have to annotate both locks with both PW_ACQUIRED_AFTER 92 // and PW_ACQUIRED_BEFORE.) 93 // 94 // As with PW_GUARDED_BY, this is only applicable to locks that are shared 95 // fields or global variables. 96 // 97 // Example: 98 // 99 // Mutex m1_; 100 // Mutex m2_ PW_ACQUIRED_AFTER(m1_); 101 #if PW_HAVE_ATTRIBUTE(acquired_after) 102 #define PW_ACQUIRED_AFTER(...) __attribute__((acquired_after(__VA_ARGS__))) 103 #else 104 #define PW_ACQUIRED_AFTER(...) 105 #endif 106 107 #if PW_HAVE_ATTRIBUTE(acquired_before) 108 #define PW_ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__))) 109 #else 110 #define PW_ACQUIRED_BEFORE(...) 111 #endif 112 113 // PW_EXCLUSIVE_LOCKS_REQUIRED() / PW_SHARED_LOCKS_REQUIRED() 114 // 115 // Documents a function that expects a lock to be held prior to entry. 116 // The lock is expected to be held both on entry to, and exit from, the 117 // function. 118 // 119 // An exclusive lock allows read-write access to the guarded data member(s), and 120 // only one thread can acquire a lock exclusively at any one time. A shared lock 121 // allows read-only access, and any number of threads can acquire a shared lock 122 // concurrently. 123 // 124 // Generally, non-const methods should be annotated with 125 // PW_EXCLUSIVE_LOCKS_REQUIRED, while const methods should be annotated with 126 // PW_SHARED_LOCKS_REQUIRED. 127 // 128 // Example: 129 // 130 // Mutex mu1, mu2; 131 // int a PW_GUARDED_BY(mu1); 132 // int b PW_GUARDED_BY(mu2); 133 // 134 // void foo() PW_EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2) { ... } 135 // void bar() const PW_SHARED_LOCKS_REQUIRED(mu1, mu2) { ... } 136 #if PW_HAVE_ATTRIBUTE(exclusive_locks_required) 137 #define PW_EXCLUSIVE_LOCKS_REQUIRED(...) \ 138 __attribute__((exclusive_locks_required(__VA_ARGS__))) 139 #else 140 #define PW_EXCLUSIVE_LOCKS_REQUIRED(...) 141 #endif 142 143 #if PW_HAVE_ATTRIBUTE(shared_locks_required) 144 #define PW_SHARED_LOCKS_REQUIRED(...) \ 145 __attribute__((shared_locks_required(__VA_ARGS__))) 146 #else 147 #define PW_SHARED_LOCKS_REQUIRED(...) 148 #endif 149 150 // PW_LOCKS_EXCLUDED() 151 // 152 // Documents the locks acquired in the body of the function. These locks 153 // cannot be held when calling this function (as Pigweed's default locks are 154 // non-reentrant). 155 #if PW_HAVE_ATTRIBUTE(locks_excluded) 156 #define PW_LOCKS_EXCLUDED(...) __attribute__((locks_excluded(__VA_ARGS__))) 157 #else 158 #define PW_LOCKS_EXCLUDED(...) 159 #endif 160 161 // PW_LOCK_RETURNED() 162 // 163 // Documents a function that returns a lock without acquiring it. For example, 164 // a public getter method that returns a pointer to a private lock should 165 // be annotated with PW_LOCK_RETURNED. 166 #if PW_HAVE_ATTRIBUTE(lock_returned) 167 #define PW_LOCK_RETURNED(x) __attribute__((lock_returned(x))) 168 #else 169 #define PW_LOCK_RETURNED(x) 170 #endif 171 172 // PW_LOCKABLE(name) 173 // 174 // Documents if a class/type is a lockable type (such as the `pw::sync::Mutex` 175 // class). The name is used in the warning messages. 176 #if PW_HAVE_ATTRIBUTE(capability) 177 #define PW_LOCKABLE(name) __attribute__((capability(name))) 178 #elif PW_HAVE_ATTRIBUTE(lockable) 179 #define PW_LOCKABLE(name) __attribute__((lockable)) 180 #else 181 #define PW_LOCKABLE(name) 182 #endif 183 184 // PW_SCOPED_LOCKABLE 185 // 186 // Documents if a class does RAII locking. The name is used in the warning 187 // messages. 188 // 189 // The constructor should use `LOCK_FUNCTION()` to specify the lock that is 190 // acquired, and the destructor should use `UNLOCK_FUNCTION()` with no 191 // arguments; the analysis will assume that the destructor unlocks whatever the 192 // constructor locked. 193 #if PW_HAVE_ATTRIBUTE(scoped_lockable) 194 #define PW_SCOPED_LOCKABLE __attribute__((scoped_lockable)) 195 #else 196 #define PW_SCOPED_LOCKABLE 197 #endif 198 199 // PW_EXCLUSIVE_LOCK_FUNCTION() 200 // 201 // Documents functions that acquire a lock in the body of a function, and do 202 // not release it. 203 #if PW_HAVE_ATTRIBUTE(exclusive_lock_function) 204 #define PW_EXCLUSIVE_LOCK_FUNCTION(...) \ 205 __attribute__((exclusive_lock_function(__VA_ARGS__))) 206 #else 207 #define PW_EXCLUSIVE_LOCK_FUNCTION(...) 208 #endif 209 210 // PW_SHARED_LOCK_FUNCTION() 211 // 212 // Documents functions that acquire a shared (reader) lock in the body of a 213 // function, and do not release it. 214 #if PW_HAVE_ATTRIBUTE(shared_lock_function) 215 #define PW_SHARED_LOCK_FUNCTION(...) \ 216 __attribute__((shared_lock_function(__VA_ARGS__))) 217 #else 218 #define PW_SHARED_LOCK_FUNCTION(...) 219 #endif 220 221 // PW_UNLOCK_FUNCTION() 222 // 223 // Documents functions that expect a lock to be held on entry to the function, 224 // and release it in the body of the function. 225 #if PW_HAVE_ATTRIBUTE(unlock_function) 226 #define PW_UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__))) 227 #else 228 #define PW_UNLOCK_FUNCTION(...) 229 #endif 230 231 // PW_EXCLUSIVE_TRYLOCK_FUNCTION() / PW_SHARED_TRYLOCK_FUNCTION() 232 // 233 // Documents functions that try to acquire a lock, and return success or failure 234 // (or a non-boolean value that can be interpreted as a boolean). 235 // The first argument should be `true` for functions that return `true` on 236 // success, or `false` for functions that return `false` on success. The second 237 // argument specifies the lock that is locked on success. If unspecified, this 238 // lock is assumed to be `this`. 239 #if PW_HAVE_ATTRIBUTE(exclusive_trylock_function) 240 #define PW_EXCLUSIVE_TRYLOCK_FUNCTION(...) \ 241 __attribute__((exclusive_trylock_function(__VA_ARGS__))) 242 #else 243 #define PW_EXCLUSIVE_TRYLOCK_FUNCTION(...) 244 #endif 245 246 #if PW_HAVE_ATTRIBUTE(shared_trylock_function) 247 #define PW_SHARED_TRYLOCK_FUNCTION(...) \ 248 __attribute__((shared_trylock_function(__VA_ARGS__))) 249 #else 250 #define PW_SHARED_TRYLOCK_FUNCTION(...) 251 #endif 252 253 // PW_ASSERT_EXCLUSIVE_LOCK() / PW_ASSERT_SHARED_LOCK() 254 // 255 // Documents functions that dynamically check to see if a lock is held, and fail 256 // if it is not held. 257 #if PW_HAVE_ATTRIBUTE(assert_exclusive_lock) 258 #define PW_ASSERT_EXCLUSIVE_LOCK(...) \ 259 __attribute__((assert_exclusive_lock(__VA_ARGS__))) 260 #else 261 #define PW_ASSERT_EXCLUSIVE_LOCK(...) 262 #endif 263 264 #if PW_HAVE_ATTRIBUTE(assert_shared_lock) 265 #define PW_ASSERT_SHARED_LOCK(...) \ 266 __attribute__((assert_shared_lock(__VA_ARGS__))) 267 #else 268 #define PW_ASSERT_SHARED_LOCK(...) 269 #endif 270 271 // PW_NO_LOCK_SAFETY_ANALYSIS 272 // 273 // Turns off thread safety checking within the body of a particular function. 274 // This annotation is used to mark functions that are known to be correct, but 275 // the locking behavior is more complicated than the analyzer can handle. 276 #if PW_HAVE_ATTRIBUTE(no_thread_safety_analysis) 277 #define PW_NO_LOCK_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis)) 278 #else 279 #define PW_NO_LOCK_SAFETY_ANALYSIS 280 #endif 281