blob: dfef80b69fa294545666c7d15c009d68b96ff909 [file] [log] [blame]
Stephen Hines651f13c2014-04-23 16:59:28 -07001
2======================
3Thread Safety Analysis
4======================
5
6Introduction
7============
8
9Clang Thread Safety Analysis is a C++ language extension which warns about
10potential race conditions in code. The analysis is completely static (i.e.
11compile-time); there is no run-time overhead. The analysis is still
12under active development, but it is mature enough to be deployed in an
13industrial setting. It being developed by Google, and is used extensively
14on their internal code base.
15
16Thread safety analysis works very much like a type system for multi-threaded
17programs. In addition to declaring the *type* of data (e.g. ``int``, ``float``,
18etc.), the programmer can (optionally) declare how access to that data is
19controlled in a multi-threaded environment. For example, if ``foo`` is
20*guarded by* the mutex ``mu``, then the analysis will issue a warning whenever
21a piece of code reads or writes to ``foo`` without first locking ``mu``.
22Similarly, if there are particular routines that should only be called by
23the GUI thread, then the analysis will warn if other threads call those
24routines.
25
26Getting Started
27----------------
28
29.. code-block:: c++
30
31 #include "mutex.h"
32
33 class BankAccount {
34 private:
35 Mutex mu;
36 int balance GUARDED_BY(mu);
37
38 void depositImpl(int amount) {
39 balance += amount; // WARNING! Cannot write balance without locking mu.
40 }
41
42 void withdrawImpl(int amount) EXCLUSIVE_LOCKS_REQUIRED(mu) {
43 balance -= amount; // OK. Caller must have locked mu.
44 }
45
46 public:
47 void withdraw(int amount) {
48 mu.Lock();
49 withdrawImpl(amount); // OK. We've locked mu.
50 } // WARNING! Failed to unlock mu.
51
52 void transferFrom(BankAccount& b, int amount) {
53 mu.Lock();
54 b.withdrawImpl(amount); // WARNING! Calling withdrawImpl() requires locking b.mu.
55 depositImpl(amount); // OK. depositImpl() has no requirements.
56 mu.Unlock();
57 }
58 };
59
60This example demonstrates the basic concepts behind the analysis. The
61``GUARDED_BY`` attribute declares that a thread must lock ``mu`` before it can
62read or write to ``balance``, thus ensuring that the increment and decrement
63operations are atomic. Similarly, ``EXCLUSIVE_LOCKS_REQUIRED`` declares that
64the calling thread must lock ``mu`` before calling ``withdrawImpl``.
65Because the caller is assumed to have locked ``mu``, it is safe to modify
66``balance`` within the body of the method.
67
68The ``depositImpl()`` method does not have ``EXCLUSIVE_LOCKS_REQUIRED``, so the
69analysis issues a warning. Thread safety analysis is not inter-procedural, so
70caller requirements must be explicitly declared.
71There is also a warning in ``transferFrom()``, because although the method
72locks ``this->mu``, it does not lock ``b.mu``. The analysis understands
73that these are two separate mutexes, in two different objects.
74
75Finally, there is a warning in the ``withdraw()`` method, because it fails to
76unlock ``mu``. Every lock must have a corresponding unlock, and the analysis
77will detect both double locks, and double unlocks. A function is allowed to
78acquire a lock without releasing it, (or vice versa), but it must be annotated
79as such (using ``LOCK``/``UNLOCK_FUNCTION``).
80
81
82Running The Analysis
83--------------------
84
85To run the analysis, simply compile with the ``-Wthread-safety`` flag, e.g.
86
87.. code-block:: bash
88
89 clang -c -Wthread-safety example.cpp
90
91Note that this example assumes the presence of a suitably annotated
92:ref:`mutexheader` that declares which methods perform locking,
93unlocking, and so on.
94
95
96Basic Concepts: Capabilities
97============================
98
99Thread safety analysis provides a way of protecting *resources* with
100*capabilities*. A resource is either a data member, or a function/method
101that provides access to some underlying resource. The analysis ensures that
102the calling thread cannot access the *resource* (i.e. call the function, or
103read/write the data) unless it has the *capability* to do so.
104
105Capabilities are associated with named C++ objects which declare specific
106methods to acquire and release the capability. The name of the object serves
107to identify the capability. The most common example is a mutex. For example,
108if ``mu`` is a mutex, then calling ``mu.Lock()`` causes the calling thread
109to acquire the capability to access data that is protected by ``mu``. Similarly,
110calling ``mu.Unlock()`` releases that capability.
111
112A thread may hold a capability either *exclusively* or *shared*. An exclusive
113capability can be held by only one thread at a time, while a shared capability
114can be held by many threads at the same time. This mechanism enforces a
115multiple-reader, single-writer pattern. Write operations to protected data
116require exclusive access, while read operations require only shared access.
117
118At any given moment during program execution, a thread holds a specific set of
119capabilities (e.g. the set of mutexes that it has locked.) These act like keys
120or tokens that allow the thread to access a given resource. Just like physical
121security keys, a thread cannot make copy of a capability, nor can it destroy
122one. A thread can only release a capability to another thread, or acquire one
123from another thread. The annotations are deliberately agnostic about the
124exact mechanism used to acquire and release capabilities; it assumes that the
125underlying implementation (e.g. the Mutex implementation) does the handoff in
126an appropriate manner.
127
128The set of capabilities that are actually held by a given thread at a given
129point in program execution is a run-time concept. The static analysis works
130by calculating an approximation of that set, called the *capability
131environment*. The capability environment is calculated for every program point,
132and describes the set of capabilities that are statically known to be held, or
133not held, at that particular point. This environment is a conservative
134approximation of the full set of capabilities that will actually held by a
135thread at run-time.
136
137
138Reference Guide
139===============
140
141The thread safety analysis uses attributes to declare threading constraints.
142Attributes must be attached to named declarations, such as classes, methods,
143and data members. Users are *strongly advised* to define macros for the various
144attributes; example definitions can be found in :ref:`mutexheader`, below.
145The following documentation assumes the use of macros.
146
147
148GUARDED_BY(c) and PT_GUARDED_BY(c)
149----------------------------------
150
151``GUARDED_BY`` is an attribute on data members, which declares that the data
152member is protected by the given capability. Read operations on the data
153require shared access, while write operations require exclusive access.
154
155``PT_GUARDED_BY`` is similar, but is intended for use on pointers and smart
156pointers. There is no constraint on the data member itself, but the *data that
157it points to* is protected by the given capability.
158
159.. code-block:: c++
160
161 Mutex mu;
162 int *p1 GUARDED_BY(mu);
163 int *p2 PT_GUARDED_BY(mu);
164 unique_ptr<int> p3 PT_GUARDED_BY(mu);
165
166 void test() {
167 p1 = 0; // Warning!
168
169 p2 = new int; // OK.
170 *p2 = 42; // Warning!
171
172 p3.reset(new int); // OK.
173 *p3 = 42; // Warning!
174 }
175
176
177EXCLUSIVE_LOCKS_REQUIRED(...), SHARED_LOCKS_REQUIRED(...)
178---------------------------------------------------------
179
180``EXCLUSIVE_LOCKS_REQUIRED`` is an attribute on functions or methods, which
181declares that the calling thread must have exclusive access to the given
182capabilities. More than one capability may be specified. The capabilities
183must be held on entry to the function, *and must still be held on exit*.
184
185``SHARED_LOCKS_REQUIRED`` is similar, but requires only shared access.
186
187.. code-block:: c++
188
189 Mutex mu1, mu2;
190 int a GUARDED_BY(mu1);
191 int b GUARDED_BY(mu2);
192
193 void foo() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2) {
194 a = 0;
195 b = 0;
196 }
197
198 void test() {
199 mu1.Lock();
200 foo(); // Warning! Requires mu2.
201 mu1.Unlock();
202 }
203
204
205EXCLUSIVE_LOCK_FUNCTION(...), SHARED_LOCK_FUNCTION(...), UNLOCK_FUNCTION(...)
206-----------------------------------------------------------------------------
207
208``EXCLUSIVE_LOCK_FUNCTION`` is an attribute on functions or methods, which
209declares that the function acquires a capability, but does not release it. The
210caller must not hold the given capability on entry, and it will hold the
211capability on exit. ``SHARED_LOCK_FUNCTION`` is similar.
212
213``UNLOCK_FUNCTION`` declares that the function releases the given capability.
214The caller must hold the capability on entry, and will no longer hold it on
215exit. It does not matter whether the given capability is shared or exclusive.
216
217.. code-block:: c++
218
219 Mutex mu;
220 MyClass myObject GUARDED_BY(mu);
221
222 void lockAndInit() EXCLUSIVE_LOCK_FUNCTION(mu) {
223 mu.Lock();
224 myObject.init();
225 }
226
227 void cleanupAndUnlock() UNLOCK_FUNCTION(mu) {
228 myObject.cleanup();
229 } // Warning! Need to unlock mu.
230
231 void test() {
232 lockAndInit();
233 myObject.doSomething();
234 cleanupAndUnlock();
235 myObject.doSomething(); // Warning, mu is not locked.
236 }
237
238If no argument is passed to ``(UN)LOCK_FUNCTION``, then the argument is assumed
239to be ``this``, and the analysis will not check the body of the function. This
240pattern is intended for use by classes which hide locking details behind an
241abstract interface. E.g.
242
243.. code-block:: c++
244
245 template <class T>
246 class LOCKABLE Container {
247 private:
248 Mutex mu;
249 T* data;
250
251 public:
252 // Hide mu from public interface.
253 void Lock() EXCLUSIVE_LOCK_FUNCTION() { mu.Lock(); }
254 void Unlock() UNLOCK_FUNCTION() { mu.Unlock(); }
255
256 T& getElem(int i) { return data[i]; }
257 };
258
259 void test() {
260 Container<int> c;
261 c.Lock();
262 int i = c.getElem(0);
263 c.Unlock();
264 }
265
266
267LOCKS_EXCLUDED(...)
268-------------------
269
270``LOCKS_EXCLUDED`` is an attribute on functions or methods, which declares that
271the caller must *not* hold the given capabilities. This annotation is
272used to prevent deadlock. Many mutex implementations are not re-entrant, so
273deadlock can occur if the function in question acquires the mutex a second time.
274
275.. code-block:: c++
276
277 Mutex mu;
278 int a GUARDED_BY(mu);
279
280 void clear() LOCKS_EXCLUDED(mu) {
281 mu.Lock();
282 a = 0;
283 mu.Unlock();
284 }
285
286 void reset() {
287 mu.Lock();
288 clear(); // Warning! Caller cannot hold 'mu'.
289 mu.Unlock();
290 }
291
292Unlike ``LOCKS_REQUIRED``, ``LOCKS_EXCLUDED`` is optional. The analysis will
293not issue a warning if the attribute is missing. See :ref:`limitations`.
294
295
296NO_THREAD_SAFETY_ANALYSIS
297-------------------------
298
299``NO_THREAD_SAFETY_ANALYSIS`` is an attribute on functions or methods, which
300turns off thread safety checking for that method. It provides an escape hatch
301for functions which are either (1) deliberately thread-unsafe, or (2) are
302thread-safe, but too complicated for the analysis to understand. Reasons for
303(2) will be described in the :ref:`limitations`, below.
304
305.. code-block:: c++
306
307 class Counter {
308 Mutex mu;
309 int a GUARDED_BY(mu);
310
311 void unsafeIncrement() NO_THREAD_SAFETY_ANALYSIS { a++; }
312 };
313
314
315LOCK_RETURNED(c)
316----------------
317
318``LOCK_RETURNED`` is an attribute on functions or methods, which declares that
319the function returns a reference to the given capability. It is used to
320annotate getter methods that return mutexes.
321
322.. code-block:: c++
323
324 class MyClass {
325 private:
326 Mutex mu;
327 int a GUARDED_BY(mu);
328
329 public:
330 Mutex* getMu() LOCK_RETURNED(mu) { return &mu; }
331
332 // analysis knows that getMu() == mu
333 void clear() EXCLUSIVE_LOCKS_REQUIRED(getMu()) { a = 0; }
334 };
335
336
337ACQUIRED_BEFORE(...), ACQUIRED_AFTER(...)
338-----------------------------------------
339
340``ACQUIRED_BEFORE`` and ``ACQUIRED_AFTER`` are attributes on member
341declarations, specifically declarations of mutexes or other capabilities.
342These declarations enforce a particular order in which the mutexes must be
343acquired, in order to prevent deadlock.
344
345.. code-block:: c++
346
347 Mutex m1;
348 Mutex m2 ACQUIRED_AFTER(m1);
349
350 // Alternative declaration
351 // Mutex m2;
352 // Mutex m1 ACQUIRED_BEFORE(m2);
353
354 void foo() {
355 m2.Lock();
356 m1.Lock(); // Warning! m2 must be acquired after m1.
357 m1.Unlock();
358 m2.Unlock();
359 }
360
361
362LOCKABLE
363--------
364
365``LOCKABLE`` is an attribute on classes, which specifies that objects of the
366class can be used as a capability. See the ``Container`` example given above,
367or the ``Mutex`` class in :ref:`mutexheader`.
368
369
370SCOPED_LOCKABLE
371---------------
372
373``SCOPED_LOCKABLE`` is an attribute on classes that implement RAII-style
374locking, in which a capability is acquired in the constructor, and released in
375the destructor. Such classes require special handling because the constructor
376and destructor refer to the capability via different names; see the
377``MutexLocker`` class in :ref:`mutexheader`, below.
378
379
380EXCLUSIVE_TRYLOCK_FUNCTION(<bool>, ...), SHARED_TRYLOCK_FUNCTION(<bool>, ...)
381-----------------------------------------------------------------------------
382
383These are attributes on a function or method that tries to acquire the given
384capability, and returns a boolean value indicating success or failure.
385The first argument must be ``true`` or ``false``, to specify which return value
386indicates success, and the remaining arguments are interpreted in the same way
387as ``(UN)LOCK_FUNCTION``. See :ref:`mutexheader`, below, for example uses.
388
389
390ASSERT_EXCLUSIVE_LOCK(...) and ASSERT_SHARED_LOCK(...)
391------------------------------------------------------
392
393These are attributes on a function or method that does a run-time test to see
394whether the calling thread holds the given capability. The function is assumed
395to fail (no return) if the capability is not held. See :ref:`mutexheader`,
396below, for example uses.
397
398
399GUARDED_VAR and PT_GUARDED_VAR
400------------------------------
401
402Use of these attributes has been deprecated.
403
404
405Warning flags
406-------------
407
408* ``-Wthread-safety``: Umbrella flag which turns on the following three:
409
410 + ``-Wthread-safety-attributes``: Sanity checks on attribute syntax.
411 + ``-Wthread-safety-analysis``: The core analysis.
412 + ``-Wthread-safety-precise``: Requires that mutex expressions match precisely.
413 This warning can be disabled for code which has a lot of aliases.
414
415When new features and checks are added to the analysis, they can often introduce
416additional warnings. Those warnings are initially released as *beta* warnings
417for a period of time, after which they are migrated to the standard analysis.
418
419* ``-Wthread-safety-beta``: New features. Off by default.
420
421
422.. _faq:
423
424Frequently Asked Questions
425==========================
426
427(Q) Should I put attributes in the header file, or in the .cc/.cpp/.cxx file?
428
429(A) Attributes should always go in the header.
430
431
432(Q) "*Mutex is not locked on every path through here?*" What does that mean?
433
434(A) See :ref:`conditional_locks`, below.
435
436
437.. _limitations:
438
439Known Limitations
440=================
441
442Lexical scope
443-------------
444
445Thread safety attributes contain ordinary C++ expressions, and thus follow
446ordinary C++ scoping rules. In particular, this means that mutexes and other
447capabilities must be declared before they can be used in an attribute.
448Use-before-declaration is okay within a single class, because attributes are
449parsed at the same time as method bodies. (C++ delays parsing of method bodies
450until the end of the class.) However, use-before-declaration is not allowed
451between classes, as illustrated below.
452
453.. code-block:: c++
454
455 class Foo;
456
457 class Bar {
458 void bar(Foo* f) EXCLUSIVE_LOCKS_REQUIRED(f->mu); // Error: mu undeclared.
459 };
460
461 class Foo {
462 Mutex mu;
463 };
464
465
466Private Mutexes
467---------------
468
469Good software engineering practice dictates that mutexes should be private
470members, because the locking mechanism used by a thread-safe class is part of
471its internal implementation. However, private mutexes can sometimes leak into
472the public interface of a class.
473Thread safety attributes follow normal C++ access restrictions, so if ``mu``
474is a private member of ``c``, then it is an error to write ``c.mu`` in an
475attribute.
476
477One workround is to (ab)use the ``LOCK_RETURNED`` attribute to provide a public
478*name* for a private mutex, without actually exposing the underlying mutex.
479For example:
480
481.. code-block:: c++
482
483 class MyClass {
484 private:
485 Mutex mu;
486
487 public:
488 // For thread safety analysis only. Does not actually return mu.
489 Mutex* getMu() LOCK_RETURNED(mu) { return 0; }
490
491 void doSomething() EXCLUSIVE_LOCKS_REQUIRED(mu);
492 };
493
494 void doSomethingTwice(MyClass& c) EXCLUSIVE_LOCKS_REQUIRED(c.getMu()) {
495 // The analysis thinks that c.getMu() == c.mu
496 c.doSomething();
497 c.doSomething();
498 }
499
500In the above example, ``doSomethingTwice()`` is an external routine that
501requires ``c.mu`` to be locked, which cannot be declared directly because ``mu``
502is private. This pattern is discouraged because it
503violates encapsulation, but it is sometimes necessary, especially when adding
504annotations to an existing code base. The workaround is to define ``getMu()``
505as a fake getter method, which is provided only for the benefit of thread
506safety analysis.
507
508
509False negatives on pass by reference.
510-------------------------------------
511
512The current version of the analysis only checks operations which refer to
513guarded data members directly by name. If the data members are accessed
514indirectly, via a pointer or reference, then no warning is generated. Thus,
515no warnings will be generated for the following code:
516
517.. code-block:: c++
518
519 Mutex mu;
520 int a GUARDED_BY(mu);
521
522 void clear(int& ra) { ra = 0; }
523
524 void test() {
525 int *p = &a;
526 *p = 0; // No warning. *p is an alias to a.
527
528 clear(a); // No warning. 'a' is passed by reference.
529 }
530
531This issue is by far the biggest source of false negatives in the current
532version of the analysis. At a fundamental level, the
533false negatives are caused by the fact that annotations are attached to data
534members, rather than types. The type of ``&a`` should really be
535``int GUARDED_BY(mu)*``, rather than ``int*``, and the statement ``p = &a``
536should thus generate a type error. However, attaching attributes to types
537would be an invasive change to the C++ type system, with potential
538ramifications with respect to template instantation, function overloading,
539and so on. Thus, a complete solution to this issue is simply not feasible.
540
541Future versions of the analysis will include better support for pointer
542alias analysis, along with limited checking of guarded types, in order to
543reduce the number of false negatives.
544
545
546.. _conditional_locks:
547
548No conditionally held locks.
549----------------------------
550
551The analysis must be able to determine whether a lock is held, or not held, at
552every program point. Thus, sections of code where a lock *might be held* will
553generate spurious warnings (false positives). For example:
554
555.. code-block:: c++
556
557 void foo() {
558 bool b = needsToLock();
559 if (b) mu.Lock();
560 ... // Warning! Mutex 'mu' is not held on every path through here.
561 if (b) mu.Unlock();
562 }
563
564
565No checking inside constructors and destructors.
566------------------------------------------------
567
568The analysis currently does not do any checking inside constructors or
569destructors. In other words, every constructor and destructor is treated as
570if it was annotated with ``NO_THREAD_SAFETY_ANALYSIS``.
571The reason for this is that during initialization, only one thread typically
572has access to the object which is being initialized, and it is thus safe (and
573common practice) to initialize guarded members without acquiring any locks.
574The same is true of destructors.
575
576Ideally, the analysis would allow initialization of guarded members inside the
577object being initialized or destroyed, while still enforcing the usual access
578restrictions on everything else. However, this is difficult to enforce in
579practice, because in complex pointer-based data structures, it is hard to
580determine what data is "owned by" the enclosing object.
581
582No inlining.
583------------
584
585Thread safety analysis is strictly intra-procedural, just like ordinary type
586checking. It relies only on the declared attributes of a function, and will
587not attempt to "step inside", or inline any method calls. As a result, code
588such as the following will not work:
589
590.. code-block:: c++
591
592 template<class T>
593 class AutoCleanup {
594 T* object;
595 void (T::*mp)();
596
597 public:
598 AutoCleanup(T* obj, void (T::*imp)()) : object(obj), mp(imp) { }
599 ~AutoCleanup() { (object->*mp)(); }
600 };
601
602 Mutex mu;
603 void foo() {
604 mu.Lock();
605 AutoCleanup<Mutex>(&mu, &Mutex::Unlock);
606 ...
607 } // Warning, mu is not unlocked.
608
609In this case, the destructor of ``Autocleanup`` calls ``mu.Unlock()``, so
610the warning is bogus. However,
611thread safety analysis cannot see the unlock, because it does not attempt to
612inline the destructor. Moreover, there is no way to annotate the destructor,
613because the destructor is calling a function that is not statically known.
614This pattern is simply not supported.
615
616
617LOCKS_EXCLUDED is not transitive.
618---------------------------------
619
620A function which calls a method marked with LOCKS_EXCLUDED is not required to
621put LOCKS_EXCLUDED in its own interface. LOCKS_EXCLUDED behaves differently
622from LOCKS_REQUIRED in this respect, and it can result in false negatives:
623
624.. code-block:: c++
625
626 class Foo {
627 Mutex mu;
628
629 void foo() {
630 mu.Lock();
631 bar(); // No warning
632 mu.Unlock();
633 }
634
635 void bar() { baz(); } // No warning. (Should have LOCKS_EXCLUDED(mu).)
636
637 void baz() LOCKS_EXCLUDED(mu);
638 };
639
640The lack of transitivity is due to the fact that LOCKS_EXCLUDED can easily
641break encapsulation; it would be a bad idea to require functions to list the
642names private locks which happen to be acquired internally.
643
644
645No alias analysis.
646------------------
647
648The analysis currently does not track pointer aliases. Thus, there can be
649false positives if two pointers both point to the same mutex.
650
651
652.. code-block:: c++
653
654 class MutexUnlocker {
655 Mutex* mu;
656
657 public:
658 MutexUnlocker(Mutex* m) UNLOCK_FUNCTION(m) : mu(m) { mu->Unlock(); }
659 ~MutexUnlocker() EXCLUSIVE_LOCK_FUNCTION(mu) { mu->Lock(); }
660 };
661
662 Mutex mutex;
663 void test() EXCLUSIVE_LOCKS_REQUIRED(mutex) {
664 {
665 MutexUnlocker munl(&mutex); // unlocks mutex
666 doSomeIO();
667 } // Warning: locks munl.mu
668 }
669
670The MutexUnlocker class is intended to be the dual of the MutexLocker class,
671defined in :ref:`mutexheader`. However, it doesn't work because the analysis
672doesn't know that munl.mu == mutex. The SCOPED_LOCKABLE attribute handles
673aliasing
674
675
676ACQUIRED_BEFORE(...) and ACQUIRED_AFTER(...) are currently unimplemented.
677-------------------------------------------------------------------------
678
679To be fixed in a future update.
680
681
682.. _mutexheader:
683
684mutex.h
685=======
686
687Thread safety analysis can be used with any threading library, but it does
688require that the threading API be wrapped in classes and methods which have the
689appropriate annotations. The following code provides ``mutex.h`` as an example;
690these methods should be filled in to call the appropriate underlying
691implementation.
692
693
694.. code-block:: c++
695
696 #ifndef THREAD_SAFETY_ANALYSIS_MUTEX_H
697 #define THREAD_SAFETY_ANALYSIS_MUTEX_H
698
699 // Enable thread safety attributes only with clang.
700 // The attributes can be safely erased when compiling with other compilers.
701 #if defined(__clang__) && (!defined(SWIG))
702 #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
703 #else
704 #define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
705 #endif
706
707 #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
708
709 #define GUARDED_BY(x) \
710 THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
711
712 #define GUARDED_VAR \
713 THREAD_ANNOTATION_ATTRIBUTE__(guarded)
714
715 #define PT_GUARDED_BY(x) \
716 THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
717
718 #define PT_GUARDED_VAR \
719 THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded)
720
721 #define ACQUIRED_AFTER(...) \
722 THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
723
724 #define ACQUIRED_BEFORE(...) \
725 THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
726
727 #define EXCLUSIVE_LOCKS_REQUIRED(...) \
728 THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__))
729
730 #define SHARED_LOCKS_REQUIRED(...) \
731 THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__))
732
733 #define LOCKS_EXCLUDED(...) \
734 THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
735
736 #define LOCK_RETURNED(x) \
737 THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
738
739 #define LOCKABLE \
740 THREAD_ANNOTATION_ATTRIBUTE__(lockable)
741
742 #define SCOPED_LOCKABLE \
743 THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
744
745 #define EXCLUSIVE_LOCK_FUNCTION(...) \
746 THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
747
748 #define SHARED_LOCK_FUNCTION(...) \
749 THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__))
750
751 #define ASSERT_EXCLUSIVE_LOCK(...) \
752 THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__))
753
754 #define ASSERT_SHARED_LOCK(...) \
755 THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_lock(__VA_ARGS__))
756
757 #define EXCLUSIVE_TRYLOCK_FUNCTION(...) \
758 THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
759
760 #define SHARED_TRYLOCK_FUNCTION(...) \
761 THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__))
762
763 #define UNLOCK_FUNCTION(...) \
764 THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
765
766 #define NO_THREAD_SAFETY_ANALYSIS \
767 THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
768
769
770 // Defines an annotated interface for mutexes.
771 // These methods can be implemented to use any internal mutex implementation.
772 class LOCKABLE Mutex {
773 public:
774 // Acquire/lock this mutex exclusively. Only one thread can have exclusive
775 // access at any one time. Write operations to guarded data require an
776 // exclusive lock.
777 void Lock() EXCLUSIVE_LOCK_FUNCTION();
778
779 // Acquire/lock this mutex for read operations, which require only a shared
780 // lock. This assumes a multiple-reader, single writer semantics. Multiple
781 // threads may acquire the mutex simultaneously as readers, but a writer must
782 // wait for all of them to release the mutex before it can acquire it
783 // exclusively.
784 void ReaderLock() SHARED_LOCK_FUNCTION();
785
786 // Release/unlock the mutex, regardless of whether it is exclusive or shared.
787 void Unlock() UNLOCK_FUNCTION();
788
789 // Try to acquire the mutex. Returns true on success, and false on failure.
790 bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true);
791
792 // Try to acquire the mutex for read operations.
793 bool ReaderTryLock() SHARED_TRYLOCK_FUNCTION(true);
794
795 // Assert that this mutex is currently held by the calling thread.
796 void AssertHeld() ASSERT_EXCLUSIVE_LOCK();
797
798 // Assert that is mutex is currently held for read operations.
799 void AssertReaderHeld() ASSERT_SHARED_LOCK();
800 };
801
802
803 // MutexLocker is an RAII class that acquires a mutex in its constructor, and
804 // releases it in its destructor.
805 class SCOPED_LOCKABLE MutexLocker {
806 private:
807 Mutex* mut;
808
809 public:
810 MutexLocker(Mutex *mu) EXCLUSIVE_LOCK_FUNCTION(mu) : mut(mu) {
811 mu->Lock();
812 }
813 ~MutexLocker() UNLOCK_FUNCTION() {
814 mut->Unlock();
815 }
816 };
817
818 #endif // THREAD_SAFETY_ANALYSIS_MUTEX_H