C/C++ API Reference
Loading...
Searching...
No Matches
lock_annotations.h
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
38
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
86#if PW_HAVE_ATTRIBUTE(pt_guarded_by)
87#define PW_PT_GUARDED_BY(x) __attribute__((pt_guarded_by(x)))
88#else
89#define PW_PT_GUARDED_BY(x)
90#endif
91
107#if PW_HAVE_ATTRIBUTE(acquired_after)
108#define PW_ACQUIRED_AFTER(...) __attribute__((acquired_after(__VA_ARGS__)))
109#else
110#define PW_ACQUIRED_AFTER(...)
111#endif
112
113#if PW_HAVE_ATTRIBUTE(acquired_before)
114#define PW_ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__)))
115#else
116#define PW_ACQUIRED_BEFORE(...)
117#endif
118
142#if PW_HAVE_ATTRIBUTE(exclusive_locks_required)
143#define PW_EXCLUSIVE_LOCKS_REQUIRED(...) \
144 __attribute__((exclusive_locks_required(__VA_ARGS__)))
145#else
146#define PW_EXCLUSIVE_LOCKS_REQUIRED(...)
147#endif
148
149#if PW_HAVE_ATTRIBUTE(shared_locks_required)
150#define PW_SHARED_LOCKS_REQUIRED(...) \
151 __attribute__((shared_locks_required(__VA_ARGS__)))
152#else
153#define PW_SHARED_LOCKS_REQUIRED(...)
154#endif
155
173#if PW_HAVE_ATTRIBUTE(locks_excluded)
174#define PW_LOCKS_EXCLUDED(...) __attribute__((locks_excluded(__VA_ARGS__)))
175#else
176#define PW_LOCKS_EXCLUDED(...)
177#endif
178
194#if PW_HAVE_ATTRIBUTE(lock_returned)
195#define PW_LOCK_RETURNED(x) __attribute__((lock_returned(x)))
196#else
197#define PW_LOCK_RETURNED(x)
198#endif
199
203#if PW_HAVE_ATTRIBUTE(capability)
204#define PW_LOCKABLE(name) __attribute__((capability(name)))
205#elif PW_HAVE_ATTRIBUTE(lockable)
206#define PW_LOCKABLE(name) __attribute__((lockable))
207#else
208#define PW_LOCKABLE(name)
209#endif
210
218#if PW_HAVE_ATTRIBUTE(scoped_lockable)
219#define PW_SCOPED_LOCKABLE __attribute__((scoped_lockable))
220#else
221#define PW_SCOPED_LOCKABLE
222#endif
223
226#if PW_HAVE_ATTRIBUTE(exclusive_lock_function)
227#define PW_EXCLUSIVE_LOCK_FUNCTION(...) \
228 __attribute__((exclusive_lock_function(__VA_ARGS__)))
229#else
230#define PW_EXCLUSIVE_LOCK_FUNCTION(...)
231#endif
232
235#if PW_HAVE_ATTRIBUTE(shared_lock_function)
236#define PW_SHARED_LOCK_FUNCTION(...) \
237 __attribute__((shared_lock_function(__VA_ARGS__)))
238#else
239#define PW_SHARED_LOCK_FUNCTION(...)
240#endif
241
244#if PW_HAVE_ATTRIBUTE(unlock_function)
245#define PW_UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__)))
246#else
247#define PW_UNLOCK_FUNCTION(...)
248#endif
249
256#if PW_HAVE_ATTRIBUTE(exclusive_trylock_function)
257#define PW_EXCLUSIVE_TRYLOCK_FUNCTION(...) \
258 __attribute__((exclusive_trylock_function(__VA_ARGS__)))
259#else
260#define PW_EXCLUSIVE_TRYLOCK_FUNCTION(...)
261#endif
262
263#if PW_HAVE_ATTRIBUTE(shared_trylock_function)
264#define PW_SHARED_TRYLOCK_FUNCTION(...) \
265 __attribute__((shared_trylock_function(__VA_ARGS__)))
266#else
267#define PW_SHARED_TRYLOCK_FUNCTION(...)
268#endif
269
272#if PW_HAVE_ATTRIBUTE(assert_exclusive_lock)
273#define PW_ASSERT_EXCLUSIVE_LOCK(...) \
274 __attribute__((assert_exclusive_lock(__VA_ARGS__)))
275#else
276#define PW_ASSERT_EXCLUSIVE_LOCK(...)
277#endif
278
279#if PW_HAVE_ATTRIBUTE(assert_shared_lock)
280#define PW_ASSERT_SHARED_LOCK(...) \
281 __attribute__((assert_shared_lock(__VA_ARGS__)))
282#else
283#define PW_ASSERT_SHARED_LOCK(...)
284#endif
285
289#if PW_HAVE_ATTRIBUTE(no_thread_safety_analysis)
290#define PW_NO_LOCK_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
291#else
292#define PW_NO_LOCK_SAFETY_ANALYSIS
293#endif
294