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
114#if PW_HAVE_ATTRIBUTE(acquired_before)
115#define PW_ACQUIRED_BEFORE(...) __attribute__((acquired_before(__VA_ARGS__)))
116#else
117#define PW_ACQUIRED_BEFORE(...)
118#endif
119
143#if PW_HAVE_ATTRIBUTE(exclusive_locks_required)
144#define PW_EXCLUSIVE_LOCKS_REQUIRED(...) \
145 __attribute__((exclusive_locks_required(__VA_ARGS__)))
146#else
147#define PW_EXCLUSIVE_LOCKS_REQUIRED(...)
148#endif
149
151#if PW_HAVE_ATTRIBUTE(shared_locks_required)
152#define PW_SHARED_LOCKS_REQUIRED(...) \
153 __attribute__((shared_locks_required(__VA_ARGS__)))
154#else
155#define PW_SHARED_LOCKS_REQUIRED(...)
156#endif
157
175#if PW_HAVE_ATTRIBUTE(locks_excluded)
176#define PW_LOCKS_EXCLUDED(...) __attribute__((locks_excluded(__VA_ARGS__)))
177#else
178#define PW_LOCKS_EXCLUDED(...)
179#endif
180
196#if PW_HAVE_ATTRIBUTE(lock_returned)
197#define PW_LOCK_RETURNED(x) __attribute__((lock_returned(x)))
198#else
199#define PW_LOCK_RETURNED(x)
200#endif
201
205#if PW_HAVE_ATTRIBUTE(capability)
206#define PW_LOCKABLE(name) __attribute__((capability(name)))
207#elif PW_HAVE_ATTRIBUTE(lockable)
208#define PW_LOCKABLE(name) __attribute__((lockable))
209#else
210#define PW_LOCKABLE(name)
211#endif
212
220#if PW_HAVE_ATTRIBUTE(scoped_lockable)
221#define PW_SCOPED_LOCKABLE __attribute__((scoped_lockable))
222#else
223#define PW_SCOPED_LOCKABLE
224#endif
225
228#if PW_HAVE_ATTRIBUTE(exclusive_lock_function)
229#define PW_EXCLUSIVE_LOCK_FUNCTION(...) \
230 __attribute__((exclusive_lock_function(__VA_ARGS__)))
231#else
232#define PW_EXCLUSIVE_LOCK_FUNCTION(...)
233#endif
234
237#if PW_HAVE_ATTRIBUTE(shared_lock_function)
238#define PW_SHARED_LOCK_FUNCTION(...) \
239 __attribute__((shared_lock_function(__VA_ARGS__)))
240#else
241#define PW_SHARED_LOCK_FUNCTION(...)
242#endif
243
246#if PW_HAVE_ATTRIBUTE(unlock_function)
247#define PW_UNLOCK_FUNCTION(...) __attribute__((unlock_function(__VA_ARGS__)))
248#else
249#define PW_UNLOCK_FUNCTION(...)
250#endif
251
258#if PW_HAVE_ATTRIBUTE(exclusive_trylock_function)
259#define PW_EXCLUSIVE_TRYLOCK_FUNCTION(...) \
260 __attribute__((exclusive_trylock_function(__VA_ARGS__)))
261#else
262#define PW_EXCLUSIVE_TRYLOCK_FUNCTION(...)
263#endif
264
266#if PW_HAVE_ATTRIBUTE(shared_trylock_function)
267#define PW_SHARED_TRYLOCK_FUNCTION(...) \
268 __attribute__((shared_trylock_function(__VA_ARGS__)))
269#else
270#define PW_SHARED_TRYLOCK_FUNCTION(...)
271#endif
272
275#if PW_HAVE_ATTRIBUTE(assert_exclusive_lock)
276#define PW_ASSERT_EXCLUSIVE_LOCK(...) \
277 __attribute__((assert_exclusive_lock(__VA_ARGS__)))
278#else
279#define PW_ASSERT_EXCLUSIVE_LOCK(...)
280#endif
281
283#if PW_HAVE_ATTRIBUTE(assert_shared_lock)
284#define PW_ASSERT_SHARED_LOCK(...) \
285 __attribute__((assert_shared_lock(__VA_ARGS__)))
286#else
287#define PW_ASSERT_SHARED_LOCK(...)
288#endif
289
293#if PW_HAVE_ATTRIBUTE(no_thread_safety_analysis)
294#define PW_NO_LOCK_SAFETY_ANALYSIS __attribute__((no_thread_safety_analysis))
295#else
296#define PW_NO_LOCK_SAFETY_ANALYSIS
297#endif
298