blob: 45cf0be0f76549b3853e44241173d0dd67e14154 [file] [log] [blame]
Victor Costan70f81b0a7fe2018-01-31 23:09:501// Copyright (c) 2018 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// This header file contains macro definitions for thread safety annotations
6// that allow developers to document the locking policies of multi-threaded
7// code. The annotations can also help program analysis tools to identify
8// potential thread safety issues.
9//
Thiabaud Engelbrechtf6eb7142021-08-05 19:31:0510// Note that no analysis is done inside constructors and destructors,
11// regardless of what attributes are used. See
12// https://clang.llvm.org/docs/ThreadSafetyAnalysis.html#no-checking-inside-constructors-and-destructors
13// for details.
14//
Victor Costan70f81b0a7fe2018-01-31 23:09:5015// Note that the annotations we use are described as deprecated in the Clang
16// documentation, linked below. E.g. we use EXCLUSIVE_LOCKS_REQUIRED where the
17// Clang docs use REQUIRES.
18//
19// http://clang.llvm.org/docs/ThreadSafetyAnalysis.html
20//
21// We use the deprecated Clang annotations to match Abseil (relevant header
22// linked below) and its ecosystem of libraries. We will follow Abseil with
23// respect to upgrading to more modern annotations.
24//
25// https://github.com/abseil/abseil-cpp/blob/master/absl/base/thread_annotations.h
26//
27// These annotations are implemented using compiler attributes. Using the macros
28// defined here instead of raw attributes allow for portability and future
29// compatibility.
30//
31// When referring to mutexes in the arguments of the attributes, you should
32// use variable names or more complex expressions (e.g. my_object->mutex_)
33// that evaluate to a concrete mutex object whenever possible. If the mutex
34// you want to refer to is not in scope, you may use a member pointer
35// (e.g. &MyClass::mutex_) to refer to a mutex in some (unknown) object.
36
Lukasz Anforowicz5e71bd42018-09-17 19:28:5737#ifndef BASE_THREAD_ANNOTATIONS_H_
38#define BASE_THREAD_ANNOTATIONS_H_
Victor Costan70f81b0a7fe2018-01-31 23:09:5039
David Sandersfc1f17fa2022-04-15 00:15:4940#include "base/dcheck_is_on.h"
Lukasz Anforowicz5e71bd42018-09-17 19:28:5741#include "build/build_config.h"
42
Lukasz Anforowiczdca7cc82018-10-01 22:59:4943#if defined(__clang__)
Victor Costan70f81b0a7fe2018-01-31 23:09:5044#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
45#else
46#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
47#endif
48
49// GUARDED_BY()
50//
51// Documents if a shared field or global variable needs to be protected by a
52// mutex. GUARDED_BY() allows the user to specify a particular mutex that
53// should be held when accessing the annotated variable.
54//
55// Example:
56//
57// Mutex mu;
58// int p1 GUARDED_BY(mu);
59#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
60
61// PT_GUARDED_BY()
62//
63// Documents if the memory location pointed to by a pointer should be guarded
64// by a mutex when dereferencing the pointer.
65//
66// Example:
67// Mutex mu;
68// int *p1 PT_GUARDED_BY(mu);
69//
70// Note that a pointer variable to a shared memory location could itself be a
71// shared variable.
72//
73// Example:
74//
75// // `q`, guarded by `mu1`, points to a shared memory location that is
76// // guarded by `mu2`:
77// int *q GUARDED_BY(mu1) PT_GUARDED_BY(mu2);
78#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
79
80// ACQUIRED_AFTER() / ACQUIRED_BEFORE()
81//
82// Documents the acquisition order between locks that can be held
83// simultaneously by a thread. For any two locks that need to be annotated
84// to establish an acquisition order, only one of them needs the annotation.
85// (i.e. You don't have to annotate both locks with both ACQUIRED_AFTER
86// and ACQUIRED_BEFORE.)
87//
88// Example:
89//
90// Mutex m1;
91// Mutex m2 ACQUIRED_AFTER(m1);
92#define ACQUIRED_AFTER(...) \
93 THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
94
95#define ACQUIRED_BEFORE(...) \
96 THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
97
98// EXCLUSIVE_LOCKS_REQUIRED() / SHARED_LOCKS_REQUIRED()
99//
100// Documents a function that expects a mutex to be held prior to entry.
101// The mutex is expected to be held both on entry to, and exit from, the
102// function.
103//
104// Example:
105//
106// Mutex mu1, mu2;
107// int a GUARDED_BY(mu1);
108// int b GUARDED_BY(mu2);
109//
110// void foo() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2) { ... };
111#define EXCLUSIVE_LOCKS_REQUIRED(...) \
112 THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__))
113
114#define SHARED_LOCKS_REQUIRED(...) \
115 THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__))
116
117// LOCKS_EXCLUDED()
118//
119// Documents the locks acquired in the body of the function. These locks
120// cannot be held when calling this function (as Abseil's `Mutex` locks are
121// non-reentrant).
122#define LOCKS_EXCLUDED(...) \
123 THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
124
125// LOCK_RETURNED()
126//
127// Documents a function that returns a mutex without acquiring it. For example,
128// a public getter method that returns a pointer to a private mutex should
129// be annotated with LOCK_RETURNED.
130#define LOCK_RETURNED(x) THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
131
132// LOCKABLE
133//
134// Documents if a class/type is a lockable type (such as the `Mutex` class).
135#define LOCKABLE THREAD_ANNOTATION_ATTRIBUTE__(lockable)
136
137// SCOPED_LOCKABLE
138//
139// Documents if a class does RAII locking (such as the `MutexLock` class).
140// The constructor should use `LOCK_FUNCTION()` to specify the mutex that is
141// acquired, and the destructor should use `UNLOCK_FUNCTION()` with no
142// arguments; the analysis will assume that the destructor unlocks whatever the
143// constructor locked.
144#define SCOPED_LOCKABLE THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
145
146// EXCLUSIVE_LOCK_FUNCTION()
147//
148// Documents functions that acquire a lock in the body of a function, and do
149// not release it.
150#define EXCLUSIVE_LOCK_FUNCTION(...) \
151 THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
152
153// SHARED_LOCK_FUNCTION()
154//
155// Documents functions that acquire a shared (reader) lock in the body of a
156// function, and do not release it.
157#define SHARED_LOCK_FUNCTION(...) \
158 THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__))
159
160// UNLOCK_FUNCTION()
161//
162// Documents functions that expect a lock to be held on entry to the function,
163// and release it in the body of the function.
164#define UNLOCK_FUNCTION(...) \
165 THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
166
167// EXCLUSIVE_TRYLOCK_FUNCTION() / SHARED_TRYLOCK_FUNCTION()
168//
169// Documents functions that try to acquire a lock, and return success or failure
170// (or a non-boolean value that can be interpreted as a boolean).
171// The first argument should be `true` for functions that return `true` on
172// success, or `false` for functions that return `false` on success. The second
173// argument specifies the mutex that is locked on success. If unspecified, this
174// mutex is assumed to be `this`.
175#define EXCLUSIVE_TRYLOCK_FUNCTION(...) \
176 THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
177
178#define SHARED_TRYLOCK_FUNCTION(...) \
179 THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__))
180
181// ASSERT_EXCLUSIVE_LOCK() / ASSERT_SHARED_LOCK()
182//
183// Documents functions that dynamically check to see if a lock is held, and fail
184// if it is not held.
185#define ASSERT_EXCLUSIVE_LOCK(...) \
186 THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__))
187
188#define ASSERT_SHARED_LOCK(...) \
189 THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_lock(__VA_ARGS__))
190
191// NO_THREAD_SAFETY_ANALYSIS
192//
193// Turns off thread safety checking within the body of a particular function.
194// This annotation is used to mark functions that are known to be correct, but
195// the locking behavior is more complicated than the analyzer can handle.
196#define NO_THREAD_SAFETY_ANALYSIS \
197 THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
198
199//------------------------------------------------------------------------------
200// Tool-Supplied Annotations
201//------------------------------------------------------------------------------
202
203// TS_UNCHECKED should be placed around lock expressions that are not valid
204// C++ syntax, but which are present for documentation purposes. These
205// annotations will be ignored by the analysis.
206#define TS_UNCHECKED(x) ""
207
208// TS_FIXME is used to mark lock expressions that are not valid C++ syntax.
209// It is used by automated tools to mark and disable invalid expressions.
210// The annotation should either be fixed, or changed to TS_UNCHECKED.
211#define TS_FIXME(x) ""
212
213// Like NO_THREAD_SAFETY_ANALYSIS, this turns off checking within the body of
214// a particular function. However, this attribute is used to mark functions
215// that are incorrect and need to be fixed. It is used by automated tools to
216// avoid breaking the build when the analysis is updated.
217// Code owners are expected to eventually fix the routine.
218#define NO_THREAD_SAFETY_ANALYSIS_FIXME NO_THREAD_SAFETY_ANALYSIS
219
220// Similar to NO_THREAD_SAFETY_ANALYSIS_FIXME, this macro marks a GUARDED_BY
221// annotation that needs to be fixed, because it is producing thread safety
222// warning. It disables the GUARDED_BY.
223#define GUARDED_BY_FIXME(x)
224
225// Disables warnings for a single read operation. This can be used to avoid
226// warnings when it is known that the read is not actually involved in a race,
227// but the compiler cannot confirm that.
228#define TS_UNCHECKED_READ(x) thread_safety_analysis::ts_unchecked_read(x)
229
230namespace thread_safety_analysis {
231
232// Takes a reference to a guarded data member, and returns an unguarded
233// reference.
234template <typename T>
235inline const T& ts_unchecked_read(const T& v) NO_THREAD_SAFETY_ANALYSIS {
236 return v;
237}
238
239template <typename T>
240inline T& ts_unchecked_read(T& v) NO_THREAD_SAFETY_ANALYSIS {
241 return v;
242}
243
244} // namespace thread_safety_analysis
245
Etienne Pierre-doray841f3e82020-01-14 17:10:25246// The above is imported as-is from abseil-cpp. The following Chromium-specific
247// synonyms are added for Chromium concepts (SequenceChecker/ThreadChecker).
248#if DCHECK_IS_ON()
249
250// Equivalent to GUARDED_BY for SequenceChecker/ThreadChecker. Currently,
Etienne Pierre-doray841f3e82020-01-14 17:10:25251#define GUARDED_BY_CONTEXT(name) GUARDED_BY(name)
252
253// Equivalent to EXCLUSIVE_LOCKS_REQUIRED for SequenceChecker/ThreadChecker.
Etienne Pierre-doray841f3e82020-01-14 17:10:25254#define VALID_CONTEXT_REQUIRED(name) EXCLUSIVE_LOCKS_REQUIRED(name)
255
256#else // DCHECK_IS_ON()
257
258#define GUARDED_BY_CONTEXT(name)
259#define VALID_CONTEXT_REQUIRED(name)
260
261#endif // DCHECK_IS_ON()
262
Lukasz Anforowicz5e71bd42018-09-17 19:28:57263#endif // BASE_THREAD_ANNOTATIONS_H_