• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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