1 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 is being developed by Google, in collaboration with 14CERT/SEI, and is used extensively in Google's 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) REQUIRES(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, ``REQUIRES`` 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 ``REQUIRES``, 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 ``ACQUIRE``/``RELEASE``). 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 147For historical reasons, prior versions of thread safety used macro names that 148were very lock-centric. These macros have since been renamed to fit a more 149general capability model. The prior names are still in use, and will be 150mentioned under the tag *previously* where appropriate. 151 152 153GUARDED_BY(c) and PT_GUARDED_BY(c) 154---------------------------------- 155 156``GUARDED_BY`` is an attribute on data members, which declares that the data 157member is protected by the given capability. Read operations on the data 158require shared access, while write operations require exclusive access. 159 160``PT_GUARDED_BY`` is similar, but is intended for use on pointers and smart 161pointers. There is no constraint on the data member itself, but the *data that 162it points to* is protected by the given capability. 163 164.. code-block:: c++ 165 166 Mutex mu; 167 int *p1 GUARDED_BY(mu); 168 int *p2 PT_GUARDED_BY(mu); 169 unique_ptr<int> p3 PT_GUARDED_BY(mu); 170 171 void test() { 172 p1 = 0; // Warning! 173 174 *p2 = 42; // Warning! 175 p2 = new int; // OK. 176 177 *p3 = 42; // Warning! 178 p3.reset(new int); // OK. 179 } 180 181 182REQUIRES(...), REQUIRES_SHARED(...) 183----------------------------------- 184 185*Previously*: ``EXCLUSIVE_LOCKS_REQUIRED``, ``SHARED_LOCKS_REQUIRED`` 186 187``REQUIRES`` is an attribute on functions or methods, which 188declares that the calling thread must have exclusive access to the given 189capabilities. More than one capability may be specified. The capabilities 190must be held on entry to the function, *and must still be held on exit*. 191 192``REQUIRES_SHARED`` is similar, but requires only shared access. 193 194.. code-block:: c++ 195 196 Mutex mu1, mu2; 197 int a GUARDED_BY(mu1); 198 int b GUARDED_BY(mu2); 199 200 void foo() REQUIRES(mu1, mu2) { 201 a = 0; 202 b = 0; 203 } 204 205 void test() { 206 mu1.Lock(); 207 foo(); // Warning! Requires mu2. 208 mu1.Unlock(); 209 } 210 211 212ACQUIRE(...), ACQUIRE_SHARED(...), RELEASE(...), RELEASE_SHARED(...) 213-------------------------------------------------------------------- 214 215*Previously*: ``EXCLUSIVE_LOCK_FUNCTION``, ``SHARED_LOCK_FUNCTION``, 216``UNLOCK_FUNCTION`` 217 218``ACQUIRE`` is an attribute on functions or methods, which 219declares that the function acquires a capability, but does not release it. The 220caller must not hold the given capability on entry, and it will hold the 221capability on exit. ``ACQUIRE_SHARED`` is similar. 222 223``RELEASE`` and ``RELEASE_SHARED`` declare that the function releases the given 224capability. The caller must hold the capability on entry, and will no longer 225hold it on exit. It does not matter whether the given capability is shared or 226exclusive. 227 228.. code-block:: c++ 229 230 Mutex mu; 231 MyClass myObject GUARDED_BY(mu); 232 233 void lockAndInit() ACQUIRE(mu) { 234 mu.Lock(); 235 myObject.init(); 236 } 237 238 void cleanupAndUnlock() RELEASE(mu) { 239 myObject.cleanup(); 240 } // Warning! Need to unlock mu. 241 242 void test() { 243 lockAndInit(); 244 myObject.doSomething(); 245 cleanupAndUnlock(); 246 myObject.doSomething(); // Warning, mu is not locked. 247 } 248 249If no argument is passed to ``ACQUIRE`` or ``RELEASE``, then the argument is 250assumed to be ``this``, and the analysis will not check the body of the 251function. This pattern is intended for use by classes which hide locking 252details behind an abstract interface. For example: 253 254.. code-block:: c++ 255 256 template <class T> 257 class CAPABILITY("mutex") Container { 258 private: 259 Mutex mu; 260 T* data; 261 262 public: 263 // Hide mu from public interface. 264 void Lock() ACQUIRE() { mu.Lock(); } 265 void Unlock() RELEASE() { mu.Unlock(); } 266 267 T& getElem(int i) { return data[i]; } 268 }; 269 270 void test() { 271 Container<int> c; 272 c.Lock(); 273 int i = c.getElem(0); 274 c.Unlock(); 275 } 276 277 278EXCLUDES(...) 279------------- 280 281*Previously*: ``LOCKS_EXCLUDED`` 282 283``EXCLUDES`` is an attribute on functions or methods, which declares that 284the caller must *not* hold the given capabilities. This annotation is 285used to prevent deadlock. Many mutex implementations are not re-entrant, so 286deadlock can occur if the function acquires the mutex a second time. 287 288.. code-block:: c++ 289 290 Mutex mu; 291 int a GUARDED_BY(mu); 292 293 void clear() EXCLUDES(mu) { 294 mu.Lock(); 295 a = 0; 296 mu.Unlock(); 297 } 298 299 void reset() { 300 mu.Lock(); 301 clear(); // Warning! Caller cannot hold 'mu'. 302 mu.Unlock(); 303 } 304 305Unlike ``REQUIRES``, ``EXCLUDES`` is optional. The analysis will not issue a 306warning if the attribute is missing, which can lead to false negatives in some 307cases. This issue is discussed further in :ref:`negative`. 308 309 310NO_THREAD_SAFETY_ANALYSIS 311------------------------- 312 313``NO_THREAD_SAFETY_ANALYSIS`` is an attribute on functions or methods, which 314turns off thread safety checking for that method. It provides an escape hatch 315for functions which are either (1) deliberately thread-unsafe, or (2) are 316thread-safe, but too complicated for the analysis to understand. Reasons for 317(2) will be described in the :ref:`limitations`, below. 318 319.. code-block:: c++ 320 321 class Counter { 322 Mutex mu; 323 int a GUARDED_BY(mu); 324 325 void unsafeIncrement() NO_THREAD_SAFETY_ANALYSIS { a++; } 326 }; 327 328Unlike the other attributes, NO_THREAD_SAFETY_ANALYSIS is not part of the 329interface of a function, and should thus be placed on the function definition 330(in the ``.cc`` or ``.cpp`` file) rather than on the function declaration 331(in the header). 332 333 334RETURN_CAPABILITY(c) 335-------------------- 336 337*Previously*: ``LOCK_RETURNED`` 338 339``RETURN_CAPABILITY`` is an attribute on functions or methods, which declares 340that the function returns a reference to the given capability. It is used to 341annotate getter methods that return mutexes. 342 343.. code-block:: c++ 344 345 class MyClass { 346 private: 347 Mutex mu; 348 int a GUARDED_BY(mu); 349 350 public: 351 Mutex* getMu() RETURN_CAPABILITY(mu) { return μ } 352 353 // analysis knows that getMu() == mu 354 void clear() REQUIRES(getMu()) { a = 0; } 355 }; 356 357 358ACQUIRED_BEFORE(...), ACQUIRED_AFTER(...) 359----------------------------------------- 360 361``ACQUIRED_BEFORE`` and ``ACQUIRED_AFTER`` are attributes on member 362declarations, specifically declarations of mutexes or other capabilities. 363These declarations enforce a particular order in which the mutexes must be 364acquired, in order to prevent deadlock. 365 366.. code-block:: c++ 367 368 Mutex m1; 369 Mutex m2 ACQUIRED_AFTER(m1); 370 371 // Alternative declaration 372 // Mutex m2; 373 // Mutex m1 ACQUIRED_BEFORE(m2); 374 375 void foo() { 376 m2.Lock(); 377 m1.Lock(); // Warning! m2 must be acquired after m1. 378 m1.Unlock(); 379 m2.Unlock(); 380 } 381 382 383CAPABILITY(<string>) 384-------------------- 385 386*Previously*: ``LOCKABLE`` 387 388``CAPABILITY`` is an attribute on classes, which specifies that objects of the 389class can be used as a capability. The string argument specifies the kind of 390capability in error messages, e.g. ``"mutex"``. See the ``Container`` example 391given above, or the ``Mutex`` class in :ref:`mutexheader`. 392 393 394SCOPED_CAPABILITY 395----------------- 396 397*Previously*: ``SCOPED_LOCKABLE`` 398 399``SCOPED_CAPABILITY`` is an attribute on classes that implement RAII-style 400locking, in which a capability is acquired in the constructor, and released in 401the destructor. Such classes require special handling because the constructor 402and destructor refer to the capability via different names; see the 403``MutexLocker`` class in :ref:`mutexheader`, below. 404 405 406TRY_ACQUIRE(<bool>, ...), TRY_ACQUIRE_SHARED(<bool>, ...) 407--------------------------------------------------------- 408 409*Previously:* ``EXCLUSIVE_TRYLOCK_FUNCTION``, ``SHARED_TRYLOCK_FUNCTION`` 410 411These are attributes on a function or method that tries to acquire the given 412capability, and returns a boolean value indicating success or failure. 413The first argument must be ``true`` or ``false``, to specify which return value 414indicates success, and the remaining arguments are interpreted in the same way 415as ``ACQUIRE``. See :ref:`mutexheader`, below, for example uses. 416 417 418ASSERT_CAPABILITY(...) and ASSERT_SHARED_CAPABILITY(...) 419-------------------------------------------------------- 420 421*Previously:* ``ASSERT_EXCLUSIVE_LOCK``, ``ASSERT_SHARED_LOCK`` 422 423These are attributes on a function or method that does a run-time test to see 424whether the calling thread holds the given capability. The function is assumed 425to fail (no return) if the capability is not held. See :ref:`mutexheader`, 426below, for example uses. 427 428 429GUARDED_VAR and PT_GUARDED_VAR 430------------------------------ 431 432Use of these attributes has been deprecated. 433 434 435Warning flags 436------------- 437 438* ``-Wthread-safety``: Umbrella flag which turns on the following three: 439 440 + ``-Wthread-safety-attributes``: Sanity checks on attribute syntax. 441 + ``-Wthread-safety-analysis``: The core analysis. 442 + ``-Wthread-safety-precise``: Requires that mutex expressions match precisely. 443 This warning can be disabled for code which has a lot of aliases. 444 + ``-Wthread-safety-reference``: Checks when guarded members are passed by reference. 445 446 447:ref:`negative` are an experimental feature, which are enabled with: 448 449* ``-Wthread-safety-negative``: Negative capabilities. Off by default. 450 451When new features and checks are added to the analysis, they can often introduce 452additional warnings. Those warnings are initially released as *beta* warnings 453for a period of time, after which they are migrated into the standard analysis. 454 455* ``-Wthread-safety-beta``: New features. Off by default. 456 457 458.. _negative: 459 460Negative Capabilities 461===================== 462 463Thread Safety Analysis is designed to prevent both race conditions and 464deadlock. The GUARDED_BY and REQUIRES attributes prevent race conditions, by 465ensuring that a capability is held before reading or writing to guarded data, 466and the EXCLUDES attribute prevents deadlock, by making sure that a mutex is 467*not* held. 468 469However, EXCLUDES is an optional attribute, and does not provide the same 470safety guarantee as REQUIRES. In particular: 471 472 * A function which acquires a capability does not have to exclude it. 473 * A function which calls a function that excludes a capability does not 474 have transitively exclude that capability. 475 476As a result, EXCLUDES can easily produce false negatives: 477 478.. code-block:: c++ 479 480 class Foo { 481 Mutex mu; 482 483 void foo() { 484 mu.Lock(); 485 bar(); // No warning. 486 baz(); // No warning. 487 mu.Unlock(); 488 } 489 490 void bar() { // No warning. (Should have EXCLUDES(mu)). 491 mu.Lock(); 492 // ... 493 mu.Unlock(); 494 } 495 496 void baz() { 497 bif(); // No warning. (Should have EXCLUDES(mu)). 498 } 499 500 void bif() EXCLUDES(mu); 501 }; 502 503 504Negative requirements are an alternative EXCLUDES that provide 505a stronger safety guarantee. A negative requirement uses the REQUIRES 506attribute, in conjunction with the ``!`` operator, to indicate that a capability 507should *not* be held. 508 509For example, using ``REQUIRES(!mu)`` instead of ``EXCLUDES(mu)`` will produce 510the appropriate warnings: 511 512.. code-block:: c++ 513 514 class FooNeg { 515 Mutex mu; 516 517 void foo() REQUIRES(!mu) { // foo() now requires !mu. 518 mu.Lock(); 519 bar(); 520 baz(); 521 mu.Unlock(); 522 } 523 524 void bar() { 525 mu.Lock(); // WARNING! Missing REQUIRES(!mu). 526 // ... 527 mu.Unlock(); 528 } 529 530 void baz() { 531 bif(); // WARNING! Missing REQUIRES(!mu). 532 } 533 534 void bif() REQUIRES(!mu); 535 }; 536 537 538Negative requirements are an experimental feature which is off by default, 539because it will produce many warnings in existing code. It can be enabled 540by passing ``-Wthread-safety-negative``. 541 542 543.. _faq: 544 545Frequently Asked Questions 546========================== 547 548(Q) Should I put attributes in the header file, or in the .cc/.cpp/.cxx file? 549 550(A) Attributes are part of the formal interface of a function, and should 551always go in the header, where they are visible to anything that includes 552the header. Attributes in the .cpp file are not visible outside of the 553immediate translation unit, which leads to false negatives and false positives. 554 555 556(Q) "*Mutex is not locked on every path through here?*" What does that mean? 557 558(A) See :ref:`conditional_locks`, below. 559 560 561.. _limitations: 562 563Known Limitations 564================= 565 566Lexical scope 567------------- 568 569Thread safety attributes contain ordinary C++ expressions, and thus follow 570ordinary C++ scoping rules. In particular, this means that mutexes and other 571capabilities must be declared before they can be used in an attribute. 572Use-before-declaration is okay within a single class, because attributes are 573parsed at the same time as method bodies. (C++ delays parsing of method bodies 574until the end of the class.) However, use-before-declaration is not allowed 575between classes, as illustrated below. 576 577.. code-block:: c++ 578 579 class Foo; 580 581 class Bar { 582 void bar(Foo* f) REQUIRES(f->mu); // Error: mu undeclared. 583 }; 584 585 class Foo { 586 Mutex mu; 587 }; 588 589 590Private Mutexes 591--------------- 592 593Good software engineering practice dictates that mutexes should be private 594members, because the locking mechanism used by a thread-safe class is part of 595its internal implementation. However, private mutexes can sometimes leak into 596the public interface of a class. 597Thread safety attributes follow normal C++ access restrictions, so if ``mu`` 598is a private member of ``c``, then it is an error to write ``c.mu`` in an 599attribute. 600 601One workaround is to (ab)use the ``RETURN_CAPABILITY`` attribute to provide a 602public *name* for a private mutex, without actually exposing the underlying 603mutex. For example: 604 605.. code-block:: c++ 606 607 class MyClass { 608 private: 609 Mutex mu; 610 611 public: 612 // For thread safety analysis only. Does not actually return mu. 613 Mutex* getMu() RETURN_CAPABILITY(mu) { return 0; } 614 615 void doSomething() REQUIRES(mu); 616 }; 617 618 void doSomethingTwice(MyClass& c) REQUIRES(c.getMu()) { 619 // The analysis thinks that c.getMu() == c.mu 620 c.doSomething(); 621 c.doSomething(); 622 } 623 624In the above example, ``doSomethingTwice()`` is an external routine that 625requires ``c.mu`` to be locked, which cannot be declared directly because ``mu`` 626is private. This pattern is discouraged because it 627violates encapsulation, but it is sometimes necessary, especially when adding 628annotations to an existing code base. The workaround is to define ``getMu()`` 629as a fake getter method, which is provided only for the benefit of thread 630safety analysis. 631 632 633.. _conditional_locks: 634 635No conditionally held locks. 636---------------------------- 637 638The analysis must be able to determine whether a lock is held, or not held, at 639every program point. Thus, sections of code where a lock *might be held* will 640generate spurious warnings (false positives). For example: 641 642.. code-block:: c++ 643 644 void foo() { 645 bool b = needsToLock(); 646 if (b) mu.Lock(); 647 ... // Warning! Mutex 'mu' is not held on every path through here. 648 if (b) mu.Unlock(); 649 } 650 651 652No checking inside constructors and destructors. 653------------------------------------------------ 654 655The analysis currently does not do any checking inside constructors or 656destructors. In other words, every constructor and destructor is treated as 657if it was annotated with ``NO_THREAD_SAFETY_ANALYSIS``. 658The reason for this is that during initialization, only one thread typically 659has access to the object which is being initialized, and it is thus safe (and 660common practice) to initialize guarded members without acquiring any locks. 661The same is true of destructors. 662 663Ideally, the analysis would allow initialization of guarded members inside the 664object being initialized or destroyed, while still enforcing the usual access 665restrictions on everything else. However, this is difficult to enforce in 666practice, because in complex pointer-based data structures, it is hard to 667determine what data is owned by the enclosing object. 668 669No inlining. 670------------ 671 672Thread safety analysis is strictly intra-procedural, just like ordinary type 673checking. It relies only on the declared attributes of a function, and will 674not attempt to inline any method calls. As a result, code such as the 675following will not work: 676 677.. code-block:: c++ 678 679 template<class T> 680 class AutoCleanup { 681 T* object; 682 void (T::*mp)(); 683 684 public: 685 AutoCleanup(T* obj, void (T::*imp)()) : object(obj), mp(imp) { } 686 ~AutoCleanup() { (object->*mp)(); } 687 }; 688 689 Mutex mu; 690 void foo() { 691 mu.Lock(); 692 AutoCleanup<Mutex>(&mu, &Mutex::Unlock); 693 // ... 694 } // Warning, mu is not unlocked. 695 696In this case, the destructor of ``Autocleanup`` calls ``mu.Unlock()``, so 697the warning is bogus. However, 698thread safety analysis cannot see the unlock, because it does not attempt to 699inline the destructor. Moreover, there is no way to annotate the destructor, 700because the destructor is calling a function that is not statically known. 701This pattern is simply not supported. 702 703 704No alias analysis. 705------------------ 706 707The analysis currently does not track pointer aliases. Thus, there can be 708false positives if two pointers both point to the same mutex. 709 710 711.. code-block:: c++ 712 713 class MutexUnlocker { 714 Mutex* mu; 715 716 public: 717 MutexUnlocker(Mutex* m) RELEASE(m) : mu(m) { mu->Unlock(); } 718 ~MutexUnlocker() ACQUIRE(mu) { mu->Lock(); } 719 }; 720 721 Mutex mutex; 722 void test() REQUIRES(mutex) { 723 { 724 MutexUnlocker munl(&mutex); // unlocks mutex 725 doSomeIO(); 726 } // Warning: locks munl.mu 727 } 728 729The MutexUnlocker class is intended to be the dual of the MutexLocker class, 730defined in :ref:`mutexheader`. However, it doesn't work because the analysis 731doesn't know that munl.mu == mutex. The SCOPED_CAPABILITY attribute handles 732aliasing for MutexLocker, but does so only for that particular pattern. 733 734 735ACQUIRED_BEFORE(...) and ACQUIRED_AFTER(...) are currently unimplemented. 736------------------------------------------------------------------------- 737 738To be fixed in a future update. 739 740 741.. _mutexheader: 742 743mutex.h 744======= 745 746Thread safety analysis can be used with any threading library, but it does 747require that the threading API be wrapped in classes and methods which have the 748appropriate annotations. The following code provides ``mutex.h`` as an example; 749these methods should be filled in to call the appropriate underlying 750implementation. 751 752 753.. code-block:: c++ 754 755 756 #ifndef THREAD_SAFETY_ANALYSIS_MUTEX_H 757 #define THREAD_SAFETY_ANALYSIS_MUTEX_H 758 759 // Enable thread safety attributes only with clang. 760 // The attributes can be safely erased when compiling with other compilers. 761 #if defined(__clang__) && (!defined(SWIG)) 762 #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) 763 #else 764 #define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op 765 #endif 766 767 #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) 768 769 #define CAPABILITY(x) \ 770 THREAD_ANNOTATION_ATTRIBUTE__(capability(x)) 771 772 #define SCOPED_CAPABILITY \ 773 THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) 774 775 #define GUARDED_BY(x) \ 776 THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) 777 778 #define PT_GUARDED_BY(x) \ 779 THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) 780 781 #define ACQUIRED_BEFORE(...) \ 782 THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__)) 783 784 #define ACQUIRED_AFTER(...) \ 785 THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__)) 786 787 #define REQUIRES(...) \ 788 THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__)) 789 790 #define REQUIRES_SHARED(...) \ 791 THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__)) 792 793 #define ACQUIRE(...) \ 794 THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__)) 795 796 #define ACQUIRE_SHARED(...) \ 797 THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__)) 798 799 #define RELEASE(...) \ 800 THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__)) 801 802 #define RELEASE_SHARED(...) \ 803 THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__)) 804 805 #define TRY_ACQUIRE(...) \ 806 THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__)) 807 808 #define TRY_ACQUIRE_SHARED(...) \ 809 THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__)) 810 811 #define EXCLUDES(...) \ 812 THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) 813 814 #define ASSERT_CAPABILITY(x) \ 815 THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x)) 816 817 #define ASSERT_SHARED_CAPABILITY(x) \ 818 THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x)) 819 820 #define RETURN_CAPABILITY(x) \ 821 THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) 822 823 #define NO_THREAD_SAFETY_ANALYSIS \ 824 THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) 825 826 827 // Defines an annotated interface for mutexes. 828 // These methods can be implemented to use any internal mutex implementation. 829 class CAPABILITY("mutex") Mutex { 830 public: 831 // Acquire/lock this mutex exclusively. Only one thread can have exclusive 832 // access at any one time. Write operations to guarded data require an 833 // exclusive lock. 834 void Lock() ACQUIRE(); 835 836 // Acquire/lock this mutex for read operations, which require only a shared 837 // lock. This assumes a multiple-reader, single writer semantics. Multiple 838 // threads may acquire the mutex simultaneously as readers, but a writer 839 // must wait for all of them to release the mutex before it can acquire it 840 // exclusively. 841 void ReaderLock() ACQUIRE_SHARED(); 842 843 // Release/unlock an exclusive mutex. 844 void Unlock() RELEASE(); 845 846 // Release/unlock a shared mutex. 847 void ReaderUnlock() RELEASE_SHARED(); 848 849 // Try to acquire the mutex. Returns true on success, and false on failure. 850 bool TryLock() TRY_ACQUIRE(true); 851 852 // Try to acquire the mutex for read operations. 853 bool ReaderTryLock() TRY_ACQUIRE_SHARED(true); 854 855 // Assert that this mutex is currently held by the calling thread. 856 void AssertHeld() ASSERT_CAPABILITY(this); 857 858 // Assert that is mutex is currently held for read operations. 859 void AssertReaderHeld() ASSERT_SHARED_CAPABILITY(this); 860 861 // For negative capabilities. 862 const Mutex& operator!() const { return *this; } 863 }; 864 865 866 // MutexLocker is an RAII class that acquires a mutex in its constructor, and 867 // releases it in its destructor. 868 class SCOPED_CAPABILITY MutexLocker { 869 private: 870 Mutex* mut; 871 872 public: 873 MutexLocker(Mutex *mu) ACQUIRE(mu) : mut(mu) { 874 mu->Lock(); 875 } 876 ~MutexLocker() RELEASE() { 877 mut->Unlock(); 878 } 879 }; 880 881 882 #ifdef USE_LOCK_STYLE_THREAD_SAFETY_ATTRIBUTES 883 // The original version of thread safety analysis the following attribute 884 // definitions. These use a lock-based terminology. They are still in use 885 // by existing thread safety code, and will continue to be supported. 886 887 // Deprecated. 888 #define PT_GUARDED_VAR \ 889 THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded) 890 891 // Deprecated. 892 #define GUARDED_VAR \ 893 THREAD_ANNOTATION_ATTRIBUTE__(guarded) 894 895 // Replaced by REQUIRES 896 #define EXCLUSIVE_LOCKS_REQUIRED(...) \ 897 THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__)) 898 899 // Replaced by REQUIRES_SHARED 900 #define SHARED_LOCKS_REQUIRED(...) \ 901 THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__)) 902 903 // Replaced by CAPABILITY 904 #define LOCKABLE \ 905 THREAD_ANNOTATION_ATTRIBUTE__(lockable) 906 907 // Replaced by SCOPED_CAPABILITY 908 #define SCOPED_LOCKABLE \ 909 THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) 910 911 // Replaced by ACQUIRE 912 #define EXCLUSIVE_LOCK_FUNCTION(...) \ 913 THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__)) 914 915 // Replaced by ACQUIRE_SHARED 916 #define SHARED_LOCK_FUNCTION(...) \ 917 THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__)) 918 919 // Replaced by RELEASE and RELEASE_SHARED 920 #define UNLOCK_FUNCTION(...) \ 921 THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__)) 922 923 // Replaced by TRY_ACQUIRE 924 #define EXCLUSIVE_TRYLOCK_FUNCTION(...) \ 925 THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__)) 926 927 // Replaced by TRY_ACQUIRE_SHARED 928 #define SHARED_TRYLOCK_FUNCTION(...) \ 929 THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__)) 930 931 // Replaced by ASSERT_CAPABILITY 932 #define ASSERT_EXCLUSIVE_LOCK(...) \ 933 THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__)) 934 935 // Replaced by ASSERT_SHARED_CAPABILITY 936 #define ASSERT_SHARED_LOCK(...) \ 937 THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_lock(__VA_ARGS__)) 938 939 // Replaced by EXCLUDE_CAPABILITY. 940 #define LOCKS_EXCLUDED(...) \ 941 THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) 942 943 // Replaced by RETURN_CAPABILITY 944 #define LOCK_RETURNED(x) \ 945 THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) 946 947 #endif // USE_LOCK_STYLE_THREAD_SAFETY_ATTRIBUTES 948 949 #endif // THREAD_SAFETY_ANALYSIS_MUTEX_H 950 951