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 /// @def 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 44 /// to 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 /// @code 50 /// class Foo { 51 /// Mutex mu_; 52 /// int p1_ PW_GUARDED_BY(mu_); 53 /// ... 54 /// }; 55 /// @endcode 56 /// 57 #if PW_HAVE_ATTRIBUTE(guarded_by) 58 #define PW_GUARDED_BY(x) __attribute__((guarded_by(x))) 59 #else 60 #define PW_GUARDED_BY(x) 61 #endif 62 63 /// @def PW_PT_GUARDED_BY 64 /// 65 /// Documents if the memory location pointed to by a pointer should be guarded 66 /// by a lock when dereferencing the pointer. 67 /// 68 /// Example: 69 /// 70 /// @code 71 /// class Foo { 72 /// Mutex mu_; 73 /// int *p1_ PW_PT_GUARDED_BY(mu_); 74 /// ... 75 /// }; 76 /// @endcode 77 /// 78 /// @note A pointer variable to a shared memory location could itself be a 79 /// shared variable. 80 /// 81 /// Example: 82 /// 83 /// @code 84 /// // `q_`, guarded by `mu1_`, points to a shared memory location that is 85 /// // guarded by `mu2_`: 86 /// int *q_ PW_GUARDED_BY(mu1_) PW_PT_GUARDED_BY(mu2_); 87 /// @endcode 88 #if PW_HAVE_ATTRIBUTE(pt_guarded_by) 89 #define PW_PT_GUARDED_BY(x) __attribute__((pt_guarded_by(x))) 90 #else 91 #define PW_PT_GUARDED_BY(x) 92 #endif 93 94 /// @def PW_ACQUIRED_AFTER 95 /// @def PW_ACQUIRED_BEFORE 96 /// 97 /// Documents the acquisition order between locks that can be held 98 /// simultaneously by a thread. For any two locks that need to be annotated 99 /// to establish an acquisition order, only one of them needs the annotation. 100 /// (i.e. You don't have to annotate both locks with both `PW_ACQUIRED_AFTER()` 101 /// and `PW_ACQUIRED_BEFORE()`.) 102 /// 103 /// As with `PW_GUARDED_BY()`, this is only applicable to locks that are shared 104 /// fields or global variables. 105 /// 106 /// Example: 107 /// 108 /// @code 109 /// Mutex m1_; 110 /// Mutex m2_ PW_ACQUIRED_AFTER(m1_); 111 /// @endcode 112 #if PW_HAVE_ATTRIBUTE(acquired_after) 113 #define PW_ACQUIRED_AFTER(...) __attribute__((acquired_after(__VA_ARGS__))) 114 #else 115 #define PW_ACQUIRED_AFTER(...) 116 #endif 117 118 #if PW_HAVE_ATTRIBUTE(acquired_before) 119 #define PW_ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__))) 120 #else 121 #define PW_ACQUIRED_BEFORE(...) 122 #endif 123 124 /// @def PW_EXCLUSIVE_LOCKS_REQUIRED 125 /// @def PW_SHARED_LOCKS_REQUIRED 126 /// 127 /// Documents a function that expects a lock to be held prior to entry. 128 /// The lock is expected to be held both on entry to, and exit from, the 129 /// function. 130 /// 131 /// An exclusive lock allows read-write access to the guarded data member(s), 132 /// and only one thread can acquire a lock exclusively at any one time. A shared 133 /// lock allows read-only access, and any number of threads can acquire a shared 134 /// lock concurrently. 135 /// 136 /// Generally, non-const methods should be annotated with 137 /// `PW_EXCLUSIVE_LOCKS_REQUIRED()`, while const methods should be annotated 138 /// with `PW_SHARED_LOCKS_REQUIRED()`. 139 /// 140 /// Example: 141 /// 142 /// @code 143 /// Mutex mu1, mu2; 144 /// int a PW_GUARDED_BY(mu1); 145 /// int b PW_GUARDED_BY(mu2); 146 /// 147 /// void foo() PW_EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2) { ... } 148 /// void bar() const PW_SHARED_LOCKS_REQUIRED(mu1, mu2) { ... } 149 /// @endcode 150 #if PW_HAVE_ATTRIBUTE(exclusive_locks_required) 151 #define PW_EXCLUSIVE_LOCKS_REQUIRED(...) \ 152 __attribute__((exclusive_locks_required(__VA_ARGS__))) 153 #else 154 #define PW_EXCLUSIVE_LOCKS_REQUIRED(...) 155 #endif 156 157 #if PW_HAVE_ATTRIBUTE(shared_locks_required) 158 #define PW_SHARED_LOCKS_REQUIRED(...) \ 159 __attribute__((shared_locks_required(__VA_ARGS__))) 160 #else 161 #define PW_SHARED_LOCKS_REQUIRED(...) 162 #endif 163 164 /// @def PW_LOCKS_EXCLUDED 165 /// 166 /// Documents that the caller must not hold the given lock. This annotation is 167 /// often used to prevent deadlocks. Pigweed's mutex implementation is not 168 /// re-entrant, so a deadlock will occur if the function acquires the mutex a 169 /// second time. 170 /// 171 /// Example: 172 /// 173 /// @code 174 /// Mutex mu; 175 /// int a PW_GUARDED_BY(mu); 176 /// 177 /// void foo() PW_LOCKS_EXCLUDED(mu) { 178 /// mu.lock(); 179 /// ... 180 /// mu.unlock(); 181 /// } 182 /// @endcode 183 #if PW_HAVE_ATTRIBUTE(locks_excluded) 184 #define PW_LOCKS_EXCLUDED(...) __attribute__((locks_excluded(__VA_ARGS__))) 185 #else 186 #define PW_LOCKS_EXCLUDED(...) 187 #endif 188 189 /// @def PW_LOCK_RETURNED 190 /// 191 /// Documents a function that returns a lock without acquiring it. For example, 192 /// a public getter method that returns a pointer to a private lock should 193 /// be annotated with `PW_LOCK_RETURNED()`. 194 /// 195 /// Example: 196 /// 197 /// @code 198 /// class Foo { 199 /// public: 200 /// Mutex* mu() PW_LOCK_RETURNED(mu) { return μ } 201 /// 202 /// private: 203 /// Mutex mu; 204 /// }; 205 /// @endcode 206 #if PW_HAVE_ATTRIBUTE(lock_returned) 207 #define PW_LOCK_RETURNED(x) __attribute__((lock_returned(x))) 208 #else 209 #define PW_LOCK_RETURNED(x) 210 #endif 211 212 /// @def PW_LOCKABLE 213 /// 214 /// Documents if a class/type is a lockable type (such as the `pw::sync::Mutex` 215 /// class). The name is used in the warning messages. This can also be useful on 216 /// classes which have locking like semantics but aren't actually locks. 217 #if PW_HAVE_ATTRIBUTE(capability) 218 #define PW_LOCKABLE(name) __attribute__((capability(name))) 219 #elif PW_HAVE_ATTRIBUTE(lockable) 220 #define PW_LOCKABLE(name) __attribute__((lockable)) 221 #else 222 #define PW_LOCKABLE(name) 223 #endif 224 225 /// @def PW_SCOPED_LOCKABLE 226 /// 227 /// Documents if a class does RAII locking. The name is used in the warning 228 /// messages. 229 /// 230 /// The constructor should use `LOCK_FUNCTION()` to specify the lock that is 231 /// acquired, and the destructor should use `UNLOCK_FUNCTION()` with no 232 /// arguments; the analysis will assume that the destructor unlocks whatever the 233 /// constructor locked. 234 #if PW_HAVE_ATTRIBUTE(scoped_lockable) 235 #define PW_SCOPED_LOCKABLE __attribute__((scoped_lockable)) 236 #else 237 #define PW_SCOPED_LOCKABLE 238 #endif 239 240 /// @def PW_EXCLUSIVE_LOCK_FUNCTION 241 /// 242 /// Documents functions that acquire a lock in the body of a function, and do 243 /// not release it. 244 #if PW_HAVE_ATTRIBUTE(exclusive_lock_function) 245 #define PW_EXCLUSIVE_LOCK_FUNCTION(...) \ 246 __attribute__((exclusive_lock_function(__VA_ARGS__))) 247 #else 248 #define PW_EXCLUSIVE_LOCK_FUNCTION(...) 249 #endif 250 251 /// @def PW_SHARED_LOCK_FUNCTION 252 /// 253 /// Documents functions that acquire a shared (reader) lock in the body of a 254 /// function, and do not release it. 255 #if PW_HAVE_ATTRIBUTE(shared_lock_function) 256 #define PW_SHARED_LOCK_FUNCTION(...) \ 257 __attribute__((shared_lock_function(__VA_ARGS__))) 258 #else 259 #define PW_SHARED_LOCK_FUNCTION(...) 260 #endif 261 262 /// @def PW_UNLOCK_FUNCTION 263 /// 264 /// Documents functions that expect a lock to be held on entry to the function, 265 /// and release it in the body of the function. 266 #if PW_HAVE_ATTRIBUTE(unlock_function) 267 #define PW_UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__))) 268 #else 269 #define PW_UNLOCK_FUNCTION(...) 270 #endif 271 272 /// @def PW_EXCLUSIVE_TRYLOCK_FUNCTION 273 /// @def PW_SHARED_TRYLOCK_FUNCTION 274 /// 275 /// Documents functions that try to acquire a lock, and return success or 276 /// failure (or a non-boolean value that can be interpreted as a boolean). The 277 /// first argument should be `true` for functions that return `true` on success, 278 /// or `false` for functions that return `false` on success. The second argument 279 /// specifies the lock that is locked on success. If unspecified, this lock is 280 /// assumed to be `this`. 281 #if PW_HAVE_ATTRIBUTE(exclusive_trylock_function) 282 #define PW_EXCLUSIVE_TRYLOCK_FUNCTION(...) \ 283 __attribute__((exclusive_trylock_function(__VA_ARGS__))) 284 #else 285 #define PW_EXCLUSIVE_TRYLOCK_FUNCTION(...) 286 #endif 287 288 #if PW_HAVE_ATTRIBUTE(shared_trylock_function) 289 #define PW_SHARED_TRYLOCK_FUNCTION(...) \ 290 __attribute__((shared_trylock_function(__VA_ARGS__))) 291 #else 292 #define PW_SHARED_TRYLOCK_FUNCTION(...) 293 #endif 294 295 /// @def PW_ASSERT_EXCLUSIVE_LOCK 296 /// @def PW_ASSERT_SHARED_LOCK 297 /// 298 /// Documents functions that dynamically check to see if a lock is held, and 299 /// fail if it is not held. 300 #if PW_HAVE_ATTRIBUTE(assert_exclusive_lock) 301 #define PW_ASSERT_EXCLUSIVE_LOCK(...) \ 302 __attribute__((assert_exclusive_lock(__VA_ARGS__))) 303 #else 304 #define PW_ASSERT_EXCLUSIVE_LOCK(...) 305 #endif 306 307 #if PW_HAVE_ATTRIBUTE(assert_shared_lock) 308 #define PW_ASSERT_SHARED_LOCK(...) \ 309 __attribute__((assert_shared_lock(__VA_ARGS__))) 310 #else 311 #define PW_ASSERT_SHARED_LOCK(...) 312 #endif 313 314 /// @def PW_NO_LOCK_SAFETY_ANALYSIS 315 /// 316 /// Turns off thread safety checking within the body of a particular function. 317 /// This annotation is used to mark functions that are known to be correct, but 318 /// the locking behavior is more complicated than the analyzer can handle. 319 #if PW_HAVE_ATTRIBUTE(no_thread_safety_analysis) 320 #define PW_NO_LOCK_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis)) 321 #else 322 #define PW_NO_LOCK_SAFETY_ANALYSIS 323 #endif 324