1*67e74705SXin Li 2*67e74705SXin Li====================== 3*67e74705SXin LiThread Safety Analysis 4*67e74705SXin Li====================== 5*67e74705SXin Li 6*67e74705SXin LiIntroduction 7*67e74705SXin Li============ 8*67e74705SXin Li 9*67e74705SXin LiClang Thread Safety Analysis is a C++ language extension which warns about 10*67e74705SXin Lipotential race conditions in code. The analysis is completely static (i.e. 11*67e74705SXin Licompile-time); there is no run-time overhead. The analysis is still 12*67e74705SXin Liunder active development, but it is mature enough to be deployed in an 13*67e74705SXin Liindustrial setting. It is being developed by Google, in collaboration with 14*67e74705SXin LiCERT/SEI, and is used extensively in Google's internal code base. 15*67e74705SXin Li 16*67e74705SXin LiThread safety analysis works very much like a type system for multi-threaded 17*67e74705SXin Liprograms. In addition to declaring the *type* of data (e.g. ``int``, ``float``, 18*67e74705SXin Lietc.), the programmer can (optionally) declare how access to that data is 19*67e74705SXin Licontrolled in a multi-threaded environment. For example, if ``foo`` is 20*67e74705SXin Li*guarded by* the mutex ``mu``, then the analysis will issue a warning whenever 21*67e74705SXin Lia piece of code reads or writes to ``foo`` without first locking ``mu``. 22*67e74705SXin LiSimilarly, if there are particular routines that should only be called by 23*67e74705SXin Lithe GUI thread, then the analysis will warn if other threads call those 24*67e74705SXin Liroutines. 25*67e74705SXin Li 26*67e74705SXin LiGetting Started 27*67e74705SXin Li---------------- 28*67e74705SXin Li 29*67e74705SXin Li.. code-block:: c++ 30*67e74705SXin Li 31*67e74705SXin Li #include "mutex.h" 32*67e74705SXin Li 33*67e74705SXin Li class BankAccount { 34*67e74705SXin Li private: 35*67e74705SXin Li Mutex mu; 36*67e74705SXin Li int balance GUARDED_BY(mu); 37*67e74705SXin Li 38*67e74705SXin Li void depositImpl(int amount) { 39*67e74705SXin Li balance += amount; // WARNING! Cannot write balance without locking mu. 40*67e74705SXin Li } 41*67e74705SXin Li 42*67e74705SXin Li void withdrawImpl(int amount) REQUIRES(mu) { 43*67e74705SXin Li balance -= amount; // OK. Caller must have locked mu. 44*67e74705SXin Li } 45*67e74705SXin Li 46*67e74705SXin Li public: 47*67e74705SXin Li void withdraw(int amount) { 48*67e74705SXin Li mu.Lock(); 49*67e74705SXin Li withdrawImpl(amount); // OK. We've locked mu. 50*67e74705SXin Li } // WARNING! Failed to unlock mu. 51*67e74705SXin Li 52*67e74705SXin Li void transferFrom(BankAccount& b, int amount) { 53*67e74705SXin Li mu.Lock(); 54*67e74705SXin Li b.withdrawImpl(amount); // WARNING! Calling withdrawImpl() requires locking b.mu. 55*67e74705SXin Li depositImpl(amount); // OK. depositImpl() has no requirements. 56*67e74705SXin Li mu.Unlock(); 57*67e74705SXin Li } 58*67e74705SXin Li }; 59*67e74705SXin Li 60*67e74705SXin LiThis example demonstrates the basic concepts behind the analysis. The 61*67e74705SXin Li``GUARDED_BY`` attribute declares that a thread must lock ``mu`` before it can 62*67e74705SXin Liread or write to ``balance``, thus ensuring that the increment and decrement 63*67e74705SXin Lioperations are atomic. Similarly, ``REQUIRES`` declares that 64*67e74705SXin Lithe calling thread must lock ``mu`` before calling ``withdrawImpl``. 65*67e74705SXin LiBecause the caller is assumed to have locked ``mu``, it is safe to modify 66*67e74705SXin Li``balance`` within the body of the method. 67*67e74705SXin Li 68*67e74705SXin LiThe ``depositImpl()`` method does not have ``REQUIRES``, so the 69*67e74705SXin Lianalysis issues a warning. Thread safety analysis is not inter-procedural, so 70*67e74705SXin Licaller requirements must be explicitly declared. 71*67e74705SXin LiThere is also a warning in ``transferFrom()``, because although the method 72*67e74705SXin Lilocks ``this->mu``, it does not lock ``b.mu``. The analysis understands 73*67e74705SXin Lithat these are two separate mutexes, in two different objects. 74*67e74705SXin Li 75*67e74705SXin LiFinally, there is a warning in the ``withdraw()`` method, because it fails to 76*67e74705SXin Liunlock ``mu``. Every lock must have a corresponding unlock, and the analysis 77*67e74705SXin Liwill detect both double locks, and double unlocks. A function is allowed to 78*67e74705SXin Liacquire a lock without releasing it, (or vice versa), but it must be annotated 79*67e74705SXin Lias such (using ``ACQUIRE``/``RELEASE``). 80*67e74705SXin Li 81*67e74705SXin Li 82*67e74705SXin LiRunning The Analysis 83*67e74705SXin Li-------------------- 84*67e74705SXin Li 85*67e74705SXin LiTo run the analysis, simply compile with the ``-Wthread-safety`` flag, e.g. 86*67e74705SXin Li 87*67e74705SXin Li.. code-block:: bash 88*67e74705SXin Li 89*67e74705SXin Li clang -c -Wthread-safety example.cpp 90*67e74705SXin Li 91*67e74705SXin LiNote that this example assumes the presence of a suitably annotated 92*67e74705SXin Li:ref:`mutexheader` that declares which methods perform locking, 93*67e74705SXin Liunlocking, and so on. 94*67e74705SXin Li 95*67e74705SXin Li 96*67e74705SXin LiBasic Concepts: Capabilities 97*67e74705SXin Li============================ 98*67e74705SXin Li 99*67e74705SXin LiThread safety analysis provides a way of protecting *resources* with 100*67e74705SXin Li*capabilities*. A resource is either a data member, or a function/method 101*67e74705SXin Lithat provides access to some underlying resource. The analysis ensures that 102*67e74705SXin Lithe calling thread cannot access the *resource* (i.e. call the function, or 103*67e74705SXin Liread/write the data) unless it has the *capability* to do so. 104*67e74705SXin Li 105*67e74705SXin LiCapabilities are associated with named C++ objects which declare specific 106*67e74705SXin Limethods to acquire and release the capability. The name of the object serves 107*67e74705SXin Lito identify the capability. The most common example is a mutex. For example, 108*67e74705SXin Liif ``mu`` is a mutex, then calling ``mu.Lock()`` causes the calling thread 109*67e74705SXin Lito acquire the capability to access data that is protected by ``mu``. Similarly, 110*67e74705SXin Licalling ``mu.Unlock()`` releases that capability. 111*67e74705SXin Li 112*67e74705SXin LiA thread may hold a capability either *exclusively* or *shared*. An exclusive 113*67e74705SXin Licapability can be held by only one thread at a time, while a shared capability 114*67e74705SXin Lican be held by many threads at the same time. This mechanism enforces a 115*67e74705SXin Limultiple-reader, single-writer pattern. Write operations to protected data 116*67e74705SXin Lirequire exclusive access, while read operations require only shared access. 117*67e74705SXin Li 118*67e74705SXin LiAt any given moment during program execution, a thread holds a specific set of 119*67e74705SXin Licapabilities (e.g. the set of mutexes that it has locked.) These act like keys 120*67e74705SXin Lior tokens that allow the thread to access a given resource. Just like physical 121*67e74705SXin Lisecurity keys, a thread cannot make copy of a capability, nor can it destroy 122*67e74705SXin Lione. A thread can only release a capability to another thread, or acquire one 123*67e74705SXin Lifrom another thread. The annotations are deliberately agnostic about the 124*67e74705SXin Liexact mechanism used to acquire and release capabilities; it assumes that the 125*67e74705SXin Liunderlying implementation (e.g. the Mutex implementation) does the handoff in 126*67e74705SXin Lian appropriate manner. 127*67e74705SXin Li 128*67e74705SXin LiThe set of capabilities that are actually held by a given thread at a given 129*67e74705SXin Lipoint in program execution is a run-time concept. The static analysis works 130*67e74705SXin Liby calculating an approximation of that set, called the *capability 131*67e74705SXin Lienvironment*. The capability environment is calculated for every program point, 132*67e74705SXin Liand describes the set of capabilities that are statically known to be held, or 133*67e74705SXin Linot held, at that particular point. This environment is a conservative 134*67e74705SXin Liapproximation of the full set of capabilities that will actually held by a 135*67e74705SXin Lithread at run-time. 136*67e74705SXin Li 137*67e74705SXin Li 138*67e74705SXin LiReference Guide 139*67e74705SXin Li=============== 140*67e74705SXin Li 141*67e74705SXin LiThe thread safety analysis uses attributes to declare threading constraints. 142*67e74705SXin LiAttributes must be attached to named declarations, such as classes, methods, 143*67e74705SXin Liand data members. Users are *strongly advised* to define macros for the various 144*67e74705SXin Liattributes; example definitions can be found in :ref:`mutexheader`, below. 145*67e74705SXin LiThe following documentation assumes the use of macros. 146*67e74705SXin Li 147*67e74705SXin LiFor historical reasons, prior versions of thread safety used macro names that 148*67e74705SXin Liwere very lock-centric. These macros have since been renamed to fit a more 149*67e74705SXin Ligeneral capability model. The prior names are still in use, and will be 150*67e74705SXin Limentioned under the tag *previously* where appropriate. 151*67e74705SXin Li 152*67e74705SXin Li 153*67e74705SXin LiGUARDED_BY(c) and PT_GUARDED_BY(c) 154*67e74705SXin Li---------------------------------- 155*67e74705SXin Li 156*67e74705SXin Li``GUARDED_BY`` is an attribute on data members, which declares that the data 157*67e74705SXin Limember is protected by the given capability. Read operations on the data 158*67e74705SXin Lirequire shared access, while write operations require exclusive access. 159*67e74705SXin Li 160*67e74705SXin Li``PT_GUARDED_BY`` is similar, but is intended for use on pointers and smart 161*67e74705SXin Lipointers. There is no constraint on the data member itself, but the *data that 162*67e74705SXin Liit points to* is protected by the given capability. 163*67e74705SXin Li 164*67e74705SXin Li.. code-block:: c++ 165*67e74705SXin Li 166*67e74705SXin Li Mutex mu; 167*67e74705SXin Li int *p1 GUARDED_BY(mu); 168*67e74705SXin Li int *p2 PT_GUARDED_BY(mu); 169*67e74705SXin Li unique_ptr<int> p3 PT_GUARDED_BY(mu); 170*67e74705SXin Li 171*67e74705SXin Li void test() { 172*67e74705SXin Li p1 = 0; // Warning! 173*67e74705SXin Li 174*67e74705SXin Li *p2 = 42; // Warning! 175*67e74705SXin Li p2 = new int; // OK. 176*67e74705SXin Li 177*67e74705SXin Li *p3 = 42; // Warning! 178*67e74705SXin Li p3.reset(new int); // OK. 179*67e74705SXin Li } 180*67e74705SXin Li 181*67e74705SXin Li 182*67e74705SXin LiREQUIRES(...), REQUIRES_SHARED(...) 183*67e74705SXin Li----------------------------------- 184*67e74705SXin Li 185*67e74705SXin Li*Previously*: ``EXCLUSIVE_LOCKS_REQUIRED``, ``SHARED_LOCKS_REQUIRED`` 186*67e74705SXin Li 187*67e74705SXin Li``REQUIRES`` is an attribute on functions or methods, which 188*67e74705SXin Lideclares that the calling thread must have exclusive access to the given 189*67e74705SXin Licapabilities. More than one capability may be specified. The capabilities 190*67e74705SXin Limust be held on entry to the function, *and must still be held on exit*. 191*67e74705SXin Li 192*67e74705SXin Li``REQUIRES_SHARED`` is similar, but requires only shared access. 193*67e74705SXin Li 194*67e74705SXin Li.. code-block:: c++ 195*67e74705SXin Li 196*67e74705SXin Li Mutex mu1, mu2; 197*67e74705SXin Li int a GUARDED_BY(mu1); 198*67e74705SXin Li int b GUARDED_BY(mu2); 199*67e74705SXin Li 200*67e74705SXin Li void foo() REQUIRES(mu1, mu2) { 201*67e74705SXin Li a = 0; 202*67e74705SXin Li b = 0; 203*67e74705SXin Li } 204*67e74705SXin Li 205*67e74705SXin Li void test() { 206*67e74705SXin Li mu1.Lock(); 207*67e74705SXin Li foo(); // Warning! Requires mu2. 208*67e74705SXin Li mu1.Unlock(); 209*67e74705SXin Li } 210*67e74705SXin Li 211*67e74705SXin Li 212*67e74705SXin LiACQUIRE(...), ACQUIRE_SHARED(...), RELEASE(...), RELEASE_SHARED(...) 213*67e74705SXin Li-------------------------------------------------------------------- 214*67e74705SXin Li 215*67e74705SXin Li*Previously*: ``EXCLUSIVE_LOCK_FUNCTION``, ``SHARED_LOCK_FUNCTION``, 216*67e74705SXin Li``UNLOCK_FUNCTION`` 217*67e74705SXin Li 218*67e74705SXin Li``ACQUIRE`` is an attribute on functions or methods, which 219*67e74705SXin Lideclares that the function acquires a capability, but does not release it. The 220*67e74705SXin Licaller must not hold the given capability on entry, and it will hold the 221*67e74705SXin Licapability on exit. ``ACQUIRE_SHARED`` is similar. 222*67e74705SXin Li 223*67e74705SXin Li``RELEASE`` and ``RELEASE_SHARED`` declare that the function releases the given 224*67e74705SXin Licapability. The caller must hold the capability on entry, and will no longer 225*67e74705SXin Lihold it on exit. It does not matter whether the given capability is shared or 226*67e74705SXin Liexclusive. 227*67e74705SXin Li 228*67e74705SXin Li.. code-block:: c++ 229*67e74705SXin Li 230*67e74705SXin Li Mutex mu; 231*67e74705SXin Li MyClass myObject GUARDED_BY(mu); 232*67e74705SXin Li 233*67e74705SXin Li void lockAndInit() ACQUIRE(mu) { 234*67e74705SXin Li mu.Lock(); 235*67e74705SXin Li myObject.init(); 236*67e74705SXin Li } 237*67e74705SXin Li 238*67e74705SXin Li void cleanupAndUnlock() RELEASE(mu) { 239*67e74705SXin Li myObject.cleanup(); 240*67e74705SXin Li } // Warning! Need to unlock mu. 241*67e74705SXin Li 242*67e74705SXin Li void test() { 243*67e74705SXin Li lockAndInit(); 244*67e74705SXin Li myObject.doSomething(); 245*67e74705SXin Li cleanupAndUnlock(); 246*67e74705SXin Li myObject.doSomething(); // Warning, mu is not locked. 247*67e74705SXin Li } 248*67e74705SXin Li 249*67e74705SXin LiIf no argument is passed to ``ACQUIRE`` or ``RELEASE``, then the argument is 250*67e74705SXin Liassumed to be ``this``, and the analysis will not check the body of the 251*67e74705SXin Lifunction. This pattern is intended for use by classes which hide locking 252*67e74705SXin Lidetails behind an abstract interface. For example: 253*67e74705SXin Li 254*67e74705SXin Li.. code-block:: c++ 255*67e74705SXin Li 256*67e74705SXin Li template <class T> 257*67e74705SXin Li class CAPABILITY("mutex") Container { 258*67e74705SXin Li private: 259*67e74705SXin Li Mutex mu; 260*67e74705SXin Li T* data; 261*67e74705SXin Li 262*67e74705SXin Li public: 263*67e74705SXin Li // Hide mu from public interface. 264*67e74705SXin Li void Lock() ACQUIRE() { mu.Lock(); } 265*67e74705SXin Li void Unlock() RELEASE() { mu.Unlock(); } 266*67e74705SXin Li 267*67e74705SXin Li T& getElem(int i) { return data[i]; } 268*67e74705SXin Li }; 269*67e74705SXin Li 270*67e74705SXin Li void test() { 271*67e74705SXin Li Container<int> c; 272*67e74705SXin Li c.Lock(); 273*67e74705SXin Li int i = c.getElem(0); 274*67e74705SXin Li c.Unlock(); 275*67e74705SXin Li } 276*67e74705SXin Li 277*67e74705SXin Li 278*67e74705SXin LiEXCLUDES(...) 279*67e74705SXin Li------------- 280*67e74705SXin Li 281*67e74705SXin Li*Previously*: ``LOCKS_EXCLUDED`` 282*67e74705SXin Li 283*67e74705SXin Li``EXCLUDES`` is an attribute on functions or methods, which declares that 284*67e74705SXin Lithe caller must *not* hold the given capabilities. This annotation is 285*67e74705SXin Liused to prevent deadlock. Many mutex implementations are not re-entrant, so 286*67e74705SXin Lideadlock can occur if the function acquires the mutex a second time. 287*67e74705SXin Li 288*67e74705SXin Li.. code-block:: c++ 289*67e74705SXin Li 290*67e74705SXin Li Mutex mu; 291*67e74705SXin Li int a GUARDED_BY(mu); 292*67e74705SXin Li 293*67e74705SXin Li void clear() EXCLUDES(mu) { 294*67e74705SXin Li mu.Lock(); 295*67e74705SXin Li a = 0; 296*67e74705SXin Li mu.Unlock(); 297*67e74705SXin Li } 298*67e74705SXin Li 299*67e74705SXin Li void reset() { 300*67e74705SXin Li mu.Lock(); 301*67e74705SXin Li clear(); // Warning! Caller cannot hold 'mu'. 302*67e74705SXin Li mu.Unlock(); 303*67e74705SXin Li } 304*67e74705SXin Li 305*67e74705SXin LiUnlike ``REQUIRES``, ``EXCLUDES`` is optional. The analysis will not issue a 306*67e74705SXin Liwarning if the attribute is missing, which can lead to false negatives in some 307*67e74705SXin Licases. This issue is discussed further in :ref:`negative`. 308*67e74705SXin Li 309*67e74705SXin Li 310*67e74705SXin LiNO_THREAD_SAFETY_ANALYSIS 311*67e74705SXin Li------------------------- 312*67e74705SXin Li 313*67e74705SXin Li``NO_THREAD_SAFETY_ANALYSIS`` is an attribute on functions or methods, which 314*67e74705SXin Liturns off thread safety checking for that method. It provides an escape hatch 315*67e74705SXin Lifor functions which are either (1) deliberately thread-unsafe, or (2) are 316*67e74705SXin Lithread-safe, but too complicated for the analysis to understand. Reasons for 317*67e74705SXin Li(2) will be described in the :ref:`limitations`, below. 318*67e74705SXin Li 319*67e74705SXin Li.. code-block:: c++ 320*67e74705SXin Li 321*67e74705SXin Li class Counter { 322*67e74705SXin Li Mutex mu; 323*67e74705SXin Li int a GUARDED_BY(mu); 324*67e74705SXin Li 325*67e74705SXin Li void unsafeIncrement() NO_THREAD_SAFETY_ANALYSIS { a++; } 326*67e74705SXin Li }; 327*67e74705SXin Li 328*67e74705SXin LiUnlike the other attributes, NO_THREAD_SAFETY_ANALYSIS is not part of the 329*67e74705SXin Liinterface of a function, and should thus be placed on the function definition 330*67e74705SXin Li(in the ``.cc`` or ``.cpp`` file) rather than on the function declaration 331*67e74705SXin Li(in the header). 332*67e74705SXin Li 333*67e74705SXin Li 334*67e74705SXin LiRETURN_CAPABILITY(c) 335*67e74705SXin Li-------------------- 336*67e74705SXin Li 337*67e74705SXin Li*Previously*: ``LOCK_RETURNED`` 338*67e74705SXin Li 339*67e74705SXin Li``RETURN_CAPABILITY`` is an attribute on functions or methods, which declares 340*67e74705SXin Lithat the function returns a reference to the given capability. It is used to 341*67e74705SXin Liannotate getter methods that return mutexes. 342*67e74705SXin Li 343*67e74705SXin Li.. code-block:: c++ 344*67e74705SXin Li 345*67e74705SXin Li class MyClass { 346*67e74705SXin Li private: 347*67e74705SXin Li Mutex mu; 348*67e74705SXin Li int a GUARDED_BY(mu); 349*67e74705SXin Li 350*67e74705SXin Li public: 351*67e74705SXin Li Mutex* getMu() RETURN_CAPABILITY(mu) { return μ } 352*67e74705SXin Li 353*67e74705SXin Li // analysis knows that getMu() == mu 354*67e74705SXin Li void clear() REQUIRES(getMu()) { a = 0; } 355*67e74705SXin Li }; 356*67e74705SXin Li 357*67e74705SXin Li 358*67e74705SXin LiACQUIRED_BEFORE(...), ACQUIRED_AFTER(...) 359*67e74705SXin Li----------------------------------------- 360*67e74705SXin Li 361*67e74705SXin Li``ACQUIRED_BEFORE`` and ``ACQUIRED_AFTER`` are attributes on member 362*67e74705SXin Lideclarations, specifically declarations of mutexes or other capabilities. 363*67e74705SXin LiThese declarations enforce a particular order in which the mutexes must be 364*67e74705SXin Liacquired, in order to prevent deadlock. 365*67e74705SXin Li 366*67e74705SXin Li.. code-block:: c++ 367*67e74705SXin Li 368*67e74705SXin Li Mutex m1; 369*67e74705SXin Li Mutex m2 ACQUIRED_AFTER(m1); 370*67e74705SXin Li 371*67e74705SXin Li // Alternative declaration 372*67e74705SXin Li // Mutex m2; 373*67e74705SXin Li // Mutex m1 ACQUIRED_BEFORE(m2); 374*67e74705SXin Li 375*67e74705SXin Li void foo() { 376*67e74705SXin Li m2.Lock(); 377*67e74705SXin Li m1.Lock(); // Warning! m2 must be acquired after m1. 378*67e74705SXin Li m1.Unlock(); 379*67e74705SXin Li m2.Unlock(); 380*67e74705SXin Li } 381*67e74705SXin Li 382*67e74705SXin Li 383*67e74705SXin LiCAPABILITY(<string>) 384*67e74705SXin Li-------------------- 385*67e74705SXin Li 386*67e74705SXin Li*Previously*: ``LOCKABLE`` 387*67e74705SXin Li 388*67e74705SXin Li``CAPABILITY`` is an attribute on classes, which specifies that objects of the 389*67e74705SXin Liclass can be used as a capability. The string argument specifies the kind of 390*67e74705SXin Licapability in error messages, e.g. ``"mutex"``. See the ``Container`` example 391*67e74705SXin Ligiven above, or the ``Mutex`` class in :ref:`mutexheader`. 392*67e74705SXin Li 393*67e74705SXin Li 394*67e74705SXin LiSCOPED_CAPABILITY 395*67e74705SXin Li----------------- 396*67e74705SXin Li 397*67e74705SXin Li*Previously*: ``SCOPED_LOCKABLE`` 398*67e74705SXin Li 399*67e74705SXin Li``SCOPED_CAPABILITY`` is an attribute on classes that implement RAII-style 400*67e74705SXin Lilocking, in which a capability is acquired in the constructor, and released in 401*67e74705SXin Lithe destructor. Such classes require special handling because the constructor 402*67e74705SXin Liand destructor refer to the capability via different names; see the 403*67e74705SXin Li``MutexLocker`` class in :ref:`mutexheader`, below. 404*67e74705SXin Li 405*67e74705SXin Li 406*67e74705SXin LiTRY_ACQUIRE(<bool>, ...), TRY_ACQUIRE_SHARED(<bool>, ...) 407*67e74705SXin Li--------------------------------------------------------- 408*67e74705SXin Li 409*67e74705SXin Li*Previously:* ``EXCLUSIVE_TRYLOCK_FUNCTION``, ``SHARED_TRYLOCK_FUNCTION`` 410*67e74705SXin Li 411*67e74705SXin LiThese are attributes on a function or method that tries to acquire the given 412*67e74705SXin Licapability, and returns a boolean value indicating success or failure. 413*67e74705SXin LiThe first argument must be ``true`` or ``false``, to specify which return value 414*67e74705SXin Liindicates success, and the remaining arguments are interpreted in the same way 415*67e74705SXin Lias ``ACQUIRE``. See :ref:`mutexheader`, below, for example uses. 416*67e74705SXin Li 417*67e74705SXin Li 418*67e74705SXin LiASSERT_CAPABILITY(...) and ASSERT_SHARED_CAPABILITY(...) 419*67e74705SXin Li-------------------------------------------------------- 420*67e74705SXin Li 421*67e74705SXin Li*Previously:* ``ASSERT_EXCLUSIVE_LOCK``, ``ASSERT_SHARED_LOCK`` 422*67e74705SXin Li 423*67e74705SXin LiThese are attributes on a function or method that does a run-time test to see 424*67e74705SXin Liwhether the calling thread holds the given capability. The function is assumed 425*67e74705SXin Lito fail (no return) if the capability is not held. See :ref:`mutexheader`, 426*67e74705SXin Libelow, for example uses. 427*67e74705SXin Li 428*67e74705SXin Li 429*67e74705SXin LiGUARDED_VAR and PT_GUARDED_VAR 430*67e74705SXin Li------------------------------ 431*67e74705SXin Li 432*67e74705SXin LiUse of these attributes has been deprecated. 433*67e74705SXin Li 434*67e74705SXin Li 435*67e74705SXin LiWarning flags 436*67e74705SXin Li------------- 437*67e74705SXin Li 438*67e74705SXin Li* ``-Wthread-safety``: Umbrella flag which turns on the following three: 439*67e74705SXin Li 440*67e74705SXin Li + ``-Wthread-safety-attributes``: Sanity checks on attribute syntax. 441*67e74705SXin Li + ``-Wthread-safety-analysis``: The core analysis. 442*67e74705SXin Li + ``-Wthread-safety-precise``: Requires that mutex expressions match precisely. 443*67e74705SXin Li This warning can be disabled for code which has a lot of aliases. 444*67e74705SXin Li + ``-Wthread-safety-reference``: Checks when guarded members are passed by reference. 445*67e74705SXin Li 446*67e74705SXin Li 447*67e74705SXin Li:ref:`negative` are an experimental feature, which are enabled with: 448*67e74705SXin Li 449*67e74705SXin Li* ``-Wthread-safety-negative``: Negative capabilities. Off by default. 450*67e74705SXin Li 451*67e74705SXin LiWhen new features and checks are added to the analysis, they can often introduce 452*67e74705SXin Liadditional warnings. Those warnings are initially released as *beta* warnings 453*67e74705SXin Lifor a period of time, after which they are migrated into the standard analysis. 454*67e74705SXin Li 455*67e74705SXin Li* ``-Wthread-safety-beta``: New features. Off by default. 456*67e74705SXin Li 457*67e74705SXin Li 458*67e74705SXin Li.. _negative: 459*67e74705SXin Li 460*67e74705SXin LiNegative Capabilities 461*67e74705SXin Li===================== 462*67e74705SXin Li 463*67e74705SXin LiThread Safety Analysis is designed to prevent both race conditions and 464*67e74705SXin Lideadlock. The GUARDED_BY and REQUIRES attributes prevent race conditions, by 465*67e74705SXin Liensuring that a capability is held before reading or writing to guarded data, 466*67e74705SXin Liand the EXCLUDES attribute prevents deadlock, by making sure that a mutex is 467*67e74705SXin Li*not* held. 468*67e74705SXin Li 469*67e74705SXin LiHowever, EXCLUDES is an optional attribute, and does not provide the same 470*67e74705SXin Lisafety guarantee as REQUIRES. In particular: 471*67e74705SXin Li 472*67e74705SXin Li * A function which acquires a capability does not have to exclude it. 473*67e74705SXin Li * A function which calls a function that excludes a capability does not 474*67e74705SXin Li have transitively exclude that capability. 475*67e74705SXin Li 476*67e74705SXin LiAs a result, EXCLUDES can easily produce false negatives: 477*67e74705SXin Li 478*67e74705SXin Li.. code-block:: c++ 479*67e74705SXin Li 480*67e74705SXin Li class Foo { 481*67e74705SXin Li Mutex mu; 482*67e74705SXin Li 483*67e74705SXin Li void foo() { 484*67e74705SXin Li mu.Lock(); 485*67e74705SXin Li bar(); // No warning. 486*67e74705SXin Li baz(); // No warning. 487*67e74705SXin Li mu.Unlock(); 488*67e74705SXin Li } 489*67e74705SXin Li 490*67e74705SXin Li void bar() { // No warning. (Should have EXCLUDES(mu)). 491*67e74705SXin Li mu.Lock(); 492*67e74705SXin Li // ... 493*67e74705SXin Li mu.Unlock(); 494*67e74705SXin Li } 495*67e74705SXin Li 496*67e74705SXin Li void baz() { 497*67e74705SXin Li bif(); // No warning. (Should have EXCLUDES(mu)). 498*67e74705SXin Li } 499*67e74705SXin Li 500*67e74705SXin Li void bif() EXCLUDES(mu); 501*67e74705SXin Li }; 502*67e74705SXin Li 503*67e74705SXin Li 504*67e74705SXin LiNegative requirements are an alternative EXCLUDES that provide 505*67e74705SXin Lia stronger safety guarantee. A negative requirement uses the REQUIRES 506*67e74705SXin Liattribute, in conjunction with the ``!`` operator, to indicate that a capability 507*67e74705SXin Lishould *not* be held. 508*67e74705SXin Li 509*67e74705SXin LiFor example, using ``REQUIRES(!mu)`` instead of ``EXCLUDES(mu)`` will produce 510*67e74705SXin Lithe appropriate warnings: 511*67e74705SXin Li 512*67e74705SXin Li.. code-block:: c++ 513*67e74705SXin Li 514*67e74705SXin Li class FooNeg { 515*67e74705SXin Li Mutex mu; 516*67e74705SXin Li 517*67e74705SXin Li void foo() REQUIRES(!mu) { // foo() now requires !mu. 518*67e74705SXin Li mu.Lock(); 519*67e74705SXin Li bar(); 520*67e74705SXin Li baz(); 521*67e74705SXin Li mu.Unlock(); 522*67e74705SXin Li } 523*67e74705SXin Li 524*67e74705SXin Li void bar() { 525*67e74705SXin Li mu.Lock(); // WARNING! Missing REQUIRES(!mu). 526*67e74705SXin Li // ... 527*67e74705SXin Li mu.Unlock(); 528*67e74705SXin Li } 529*67e74705SXin Li 530*67e74705SXin Li void baz() { 531*67e74705SXin Li bif(); // WARNING! Missing REQUIRES(!mu). 532*67e74705SXin Li } 533*67e74705SXin Li 534*67e74705SXin Li void bif() REQUIRES(!mu); 535*67e74705SXin Li }; 536*67e74705SXin Li 537*67e74705SXin Li 538*67e74705SXin LiNegative requirements are an experimental feature which is off by default, 539*67e74705SXin Libecause it will produce many warnings in existing code. It can be enabled 540*67e74705SXin Liby passing ``-Wthread-safety-negative``. 541*67e74705SXin Li 542*67e74705SXin Li 543*67e74705SXin Li.. _faq: 544*67e74705SXin Li 545*67e74705SXin LiFrequently Asked Questions 546*67e74705SXin Li========================== 547*67e74705SXin Li 548*67e74705SXin Li(Q) Should I put attributes in the header file, or in the .cc/.cpp/.cxx file? 549*67e74705SXin Li 550*67e74705SXin Li(A) Attributes are part of the formal interface of a function, and should 551*67e74705SXin Lialways go in the header, where they are visible to anything that includes 552*67e74705SXin Lithe header. Attributes in the .cpp file are not visible outside of the 553*67e74705SXin Liimmediate translation unit, which leads to false negatives and false positives. 554*67e74705SXin Li 555*67e74705SXin Li 556*67e74705SXin Li(Q) "*Mutex is not locked on every path through here?*" What does that mean? 557*67e74705SXin Li 558*67e74705SXin Li(A) See :ref:`conditional_locks`, below. 559*67e74705SXin Li 560*67e74705SXin Li 561*67e74705SXin Li.. _limitations: 562*67e74705SXin Li 563*67e74705SXin LiKnown Limitations 564*67e74705SXin Li================= 565*67e74705SXin Li 566*67e74705SXin LiLexical scope 567*67e74705SXin Li------------- 568*67e74705SXin Li 569*67e74705SXin LiThread safety attributes contain ordinary C++ expressions, and thus follow 570*67e74705SXin Liordinary C++ scoping rules. In particular, this means that mutexes and other 571*67e74705SXin Licapabilities must be declared before they can be used in an attribute. 572*67e74705SXin LiUse-before-declaration is okay within a single class, because attributes are 573*67e74705SXin Liparsed at the same time as method bodies. (C++ delays parsing of method bodies 574*67e74705SXin Liuntil the end of the class.) However, use-before-declaration is not allowed 575*67e74705SXin Libetween classes, as illustrated below. 576*67e74705SXin Li 577*67e74705SXin Li.. code-block:: c++ 578*67e74705SXin Li 579*67e74705SXin Li class Foo; 580*67e74705SXin Li 581*67e74705SXin Li class Bar { 582*67e74705SXin Li void bar(Foo* f) REQUIRES(f->mu); // Error: mu undeclared. 583*67e74705SXin Li }; 584*67e74705SXin Li 585*67e74705SXin Li class Foo { 586*67e74705SXin Li Mutex mu; 587*67e74705SXin Li }; 588*67e74705SXin Li 589*67e74705SXin Li 590*67e74705SXin LiPrivate Mutexes 591*67e74705SXin Li--------------- 592*67e74705SXin Li 593*67e74705SXin LiGood software engineering practice dictates that mutexes should be private 594*67e74705SXin Limembers, because the locking mechanism used by a thread-safe class is part of 595*67e74705SXin Liits internal implementation. However, private mutexes can sometimes leak into 596*67e74705SXin Lithe public interface of a class. 597*67e74705SXin LiThread safety attributes follow normal C++ access restrictions, so if ``mu`` 598*67e74705SXin Liis a private member of ``c``, then it is an error to write ``c.mu`` in an 599*67e74705SXin Liattribute. 600*67e74705SXin Li 601*67e74705SXin LiOne workaround is to (ab)use the ``RETURN_CAPABILITY`` attribute to provide a 602*67e74705SXin Lipublic *name* for a private mutex, without actually exposing the underlying 603*67e74705SXin Limutex. For example: 604*67e74705SXin Li 605*67e74705SXin Li.. code-block:: c++ 606*67e74705SXin Li 607*67e74705SXin Li class MyClass { 608*67e74705SXin Li private: 609*67e74705SXin Li Mutex mu; 610*67e74705SXin Li 611*67e74705SXin Li public: 612*67e74705SXin Li // For thread safety analysis only. Does not actually return mu. 613*67e74705SXin Li Mutex* getMu() RETURN_CAPABILITY(mu) { return 0; } 614*67e74705SXin Li 615*67e74705SXin Li void doSomething() REQUIRES(mu); 616*67e74705SXin Li }; 617*67e74705SXin Li 618*67e74705SXin Li void doSomethingTwice(MyClass& c) REQUIRES(c.getMu()) { 619*67e74705SXin Li // The analysis thinks that c.getMu() == c.mu 620*67e74705SXin Li c.doSomething(); 621*67e74705SXin Li c.doSomething(); 622*67e74705SXin Li } 623*67e74705SXin Li 624*67e74705SXin LiIn the above example, ``doSomethingTwice()`` is an external routine that 625*67e74705SXin Lirequires ``c.mu`` to be locked, which cannot be declared directly because ``mu`` 626*67e74705SXin Liis private. This pattern is discouraged because it 627*67e74705SXin Liviolates encapsulation, but it is sometimes necessary, especially when adding 628*67e74705SXin Liannotations to an existing code base. The workaround is to define ``getMu()`` 629*67e74705SXin Lias a fake getter method, which is provided only for the benefit of thread 630*67e74705SXin Lisafety analysis. 631*67e74705SXin Li 632*67e74705SXin Li 633*67e74705SXin Li.. _conditional_locks: 634*67e74705SXin Li 635*67e74705SXin LiNo conditionally held locks. 636*67e74705SXin Li---------------------------- 637*67e74705SXin Li 638*67e74705SXin LiThe analysis must be able to determine whether a lock is held, or not held, at 639*67e74705SXin Lievery program point. Thus, sections of code where a lock *might be held* will 640*67e74705SXin Ligenerate spurious warnings (false positives). For example: 641*67e74705SXin Li 642*67e74705SXin Li.. code-block:: c++ 643*67e74705SXin Li 644*67e74705SXin Li void foo() { 645*67e74705SXin Li bool b = needsToLock(); 646*67e74705SXin Li if (b) mu.Lock(); 647*67e74705SXin Li ... // Warning! Mutex 'mu' is not held on every path through here. 648*67e74705SXin Li if (b) mu.Unlock(); 649*67e74705SXin Li } 650*67e74705SXin Li 651*67e74705SXin Li 652*67e74705SXin LiNo checking inside constructors and destructors. 653*67e74705SXin Li------------------------------------------------ 654*67e74705SXin Li 655*67e74705SXin LiThe analysis currently does not do any checking inside constructors or 656*67e74705SXin Lidestructors. In other words, every constructor and destructor is treated as 657*67e74705SXin Liif it was annotated with ``NO_THREAD_SAFETY_ANALYSIS``. 658*67e74705SXin LiThe reason for this is that during initialization, only one thread typically 659*67e74705SXin Lihas access to the object which is being initialized, and it is thus safe (and 660*67e74705SXin Licommon practice) to initialize guarded members without acquiring any locks. 661*67e74705SXin LiThe same is true of destructors. 662*67e74705SXin Li 663*67e74705SXin LiIdeally, the analysis would allow initialization of guarded members inside the 664*67e74705SXin Liobject being initialized or destroyed, while still enforcing the usual access 665*67e74705SXin Lirestrictions on everything else. However, this is difficult to enforce in 666*67e74705SXin Lipractice, because in complex pointer-based data structures, it is hard to 667*67e74705SXin Lidetermine what data is owned by the enclosing object. 668*67e74705SXin Li 669*67e74705SXin LiNo inlining. 670*67e74705SXin Li------------ 671*67e74705SXin Li 672*67e74705SXin LiThread safety analysis is strictly intra-procedural, just like ordinary type 673*67e74705SXin Lichecking. It relies only on the declared attributes of a function, and will 674*67e74705SXin Linot attempt to inline any method calls. As a result, code such as the 675*67e74705SXin Lifollowing will not work: 676*67e74705SXin Li 677*67e74705SXin Li.. code-block:: c++ 678*67e74705SXin Li 679*67e74705SXin Li template<class T> 680*67e74705SXin Li class AutoCleanup { 681*67e74705SXin Li T* object; 682*67e74705SXin Li void (T::*mp)(); 683*67e74705SXin Li 684*67e74705SXin Li public: 685*67e74705SXin Li AutoCleanup(T* obj, void (T::*imp)()) : object(obj), mp(imp) { } 686*67e74705SXin Li ~AutoCleanup() { (object->*mp)(); } 687*67e74705SXin Li }; 688*67e74705SXin Li 689*67e74705SXin Li Mutex mu; 690*67e74705SXin Li void foo() { 691*67e74705SXin Li mu.Lock(); 692*67e74705SXin Li AutoCleanup<Mutex>(&mu, &Mutex::Unlock); 693*67e74705SXin Li // ... 694*67e74705SXin Li } // Warning, mu is not unlocked. 695*67e74705SXin Li 696*67e74705SXin LiIn this case, the destructor of ``Autocleanup`` calls ``mu.Unlock()``, so 697*67e74705SXin Lithe warning is bogus. However, 698*67e74705SXin Lithread safety analysis cannot see the unlock, because it does not attempt to 699*67e74705SXin Liinline the destructor. Moreover, there is no way to annotate the destructor, 700*67e74705SXin Libecause the destructor is calling a function that is not statically known. 701*67e74705SXin LiThis pattern is simply not supported. 702*67e74705SXin Li 703*67e74705SXin Li 704*67e74705SXin LiNo alias analysis. 705*67e74705SXin Li------------------ 706*67e74705SXin Li 707*67e74705SXin LiThe analysis currently does not track pointer aliases. Thus, there can be 708*67e74705SXin Lifalse positives if two pointers both point to the same mutex. 709*67e74705SXin Li 710*67e74705SXin Li 711*67e74705SXin Li.. code-block:: c++ 712*67e74705SXin Li 713*67e74705SXin Li class MutexUnlocker { 714*67e74705SXin Li Mutex* mu; 715*67e74705SXin Li 716*67e74705SXin Li public: 717*67e74705SXin Li MutexUnlocker(Mutex* m) RELEASE(m) : mu(m) { mu->Unlock(); } 718*67e74705SXin Li ~MutexUnlocker() ACQUIRE(mu) { mu->Lock(); } 719*67e74705SXin Li }; 720*67e74705SXin Li 721*67e74705SXin Li Mutex mutex; 722*67e74705SXin Li void test() REQUIRES(mutex) { 723*67e74705SXin Li { 724*67e74705SXin Li MutexUnlocker munl(&mutex); // unlocks mutex 725*67e74705SXin Li doSomeIO(); 726*67e74705SXin Li } // Warning: locks munl.mu 727*67e74705SXin Li } 728*67e74705SXin Li 729*67e74705SXin LiThe MutexUnlocker class is intended to be the dual of the MutexLocker class, 730*67e74705SXin Lidefined in :ref:`mutexheader`. However, it doesn't work because the analysis 731*67e74705SXin Lidoesn't know that munl.mu == mutex. The SCOPED_CAPABILITY attribute handles 732*67e74705SXin Lialiasing for MutexLocker, but does so only for that particular pattern. 733*67e74705SXin Li 734*67e74705SXin Li 735*67e74705SXin LiACQUIRED_BEFORE(...) and ACQUIRED_AFTER(...) are currently unimplemented. 736*67e74705SXin Li------------------------------------------------------------------------- 737*67e74705SXin Li 738*67e74705SXin LiTo be fixed in a future update. 739*67e74705SXin Li 740*67e74705SXin Li 741*67e74705SXin Li.. _mutexheader: 742*67e74705SXin Li 743*67e74705SXin Limutex.h 744*67e74705SXin Li======= 745*67e74705SXin Li 746*67e74705SXin LiThread safety analysis can be used with any threading library, but it does 747*67e74705SXin Lirequire that the threading API be wrapped in classes and methods which have the 748*67e74705SXin Liappropriate annotations. The following code provides ``mutex.h`` as an example; 749*67e74705SXin Lithese methods should be filled in to call the appropriate underlying 750*67e74705SXin Liimplementation. 751*67e74705SXin Li 752*67e74705SXin Li 753*67e74705SXin Li.. code-block:: c++ 754*67e74705SXin Li 755*67e74705SXin Li 756*67e74705SXin Li #ifndef THREAD_SAFETY_ANALYSIS_MUTEX_H 757*67e74705SXin Li #define THREAD_SAFETY_ANALYSIS_MUTEX_H 758*67e74705SXin Li 759*67e74705SXin Li // Enable thread safety attributes only with clang. 760*67e74705SXin Li // The attributes can be safely erased when compiling with other compilers. 761*67e74705SXin Li #if defined(__clang__) && (!defined(SWIG)) 762*67e74705SXin Li #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) 763*67e74705SXin Li #else 764*67e74705SXin Li #define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op 765*67e74705SXin Li #endif 766*67e74705SXin Li 767*67e74705SXin Li #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) 768*67e74705SXin Li 769*67e74705SXin Li #define CAPABILITY(x) \ 770*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(capability(x)) 771*67e74705SXin Li 772*67e74705SXin Li #define SCOPED_CAPABILITY \ 773*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) 774*67e74705SXin Li 775*67e74705SXin Li #define GUARDED_BY(x) \ 776*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) 777*67e74705SXin Li 778*67e74705SXin Li #define PT_GUARDED_BY(x) \ 779*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) 780*67e74705SXin Li 781*67e74705SXin Li #define ACQUIRED_BEFORE(...) \ 782*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__)) 783*67e74705SXin Li 784*67e74705SXin Li #define ACQUIRED_AFTER(...) \ 785*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__)) 786*67e74705SXin Li 787*67e74705SXin Li #define REQUIRES(...) \ 788*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__)) 789*67e74705SXin Li 790*67e74705SXin Li #define REQUIRES_SHARED(...) \ 791*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__)) 792*67e74705SXin Li 793*67e74705SXin Li #define ACQUIRE(...) \ 794*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__)) 795*67e74705SXin Li 796*67e74705SXin Li #define ACQUIRE_SHARED(...) \ 797*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__)) 798*67e74705SXin Li 799*67e74705SXin Li #define RELEASE(...) \ 800*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__)) 801*67e74705SXin Li 802*67e74705SXin Li #define RELEASE_SHARED(...) \ 803*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__)) 804*67e74705SXin Li 805*67e74705SXin Li #define TRY_ACQUIRE(...) \ 806*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__)) 807*67e74705SXin Li 808*67e74705SXin Li #define TRY_ACQUIRE_SHARED(...) \ 809*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__)) 810*67e74705SXin Li 811*67e74705SXin Li #define EXCLUDES(...) \ 812*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) 813*67e74705SXin Li 814*67e74705SXin Li #define ASSERT_CAPABILITY(x) \ 815*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x)) 816*67e74705SXin Li 817*67e74705SXin Li #define ASSERT_SHARED_CAPABILITY(x) \ 818*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x)) 819*67e74705SXin Li 820*67e74705SXin Li #define RETURN_CAPABILITY(x) \ 821*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) 822*67e74705SXin Li 823*67e74705SXin Li #define NO_THREAD_SAFETY_ANALYSIS \ 824*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) 825*67e74705SXin Li 826*67e74705SXin Li 827*67e74705SXin Li // Defines an annotated interface for mutexes. 828*67e74705SXin Li // These methods can be implemented to use any internal mutex implementation. 829*67e74705SXin Li class CAPABILITY("mutex") Mutex { 830*67e74705SXin Li public: 831*67e74705SXin Li // Acquire/lock this mutex exclusively. Only one thread can have exclusive 832*67e74705SXin Li // access at any one time. Write operations to guarded data require an 833*67e74705SXin Li // exclusive lock. 834*67e74705SXin Li void Lock() ACQUIRE(); 835*67e74705SXin Li 836*67e74705SXin Li // Acquire/lock this mutex for read operations, which require only a shared 837*67e74705SXin Li // lock. This assumes a multiple-reader, single writer semantics. Multiple 838*67e74705SXin Li // threads may acquire the mutex simultaneously as readers, but a writer 839*67e74705SXin Li // must wait for all of them to release the mutex before it can acquire it 840*67e74705SXin Li // exclusively. 841*67e74705SXin Li void ReaderLock() ACQUIRE_SHARED(); 842*67e74705SXin Li 843*67e74705SXin Li // Release/unlock an exclusive mutex. 844*67e74705SXin Li void Unlock() RELEASE(); 845*67e74705SXin Li 846*67e74705SXin Li // Release/unlock a shared mutex. 847*67e74705SXin Li void ReaderUnlock() RELEASE_SHARED(); 848*67e74705SXin Li 849*67e74705SXin Li // Try to acquire the mutex. Returns true on success, and false on failure. 850*67e74705SXin Li bool TryLock() TRY_ACQUIRE(true); 851*67e74705SXin Li 852*67e74705SXin Li // Try to acquire the mutex for read operations. 853*67e74705SXin Li bool ReaderTryLock() TRY_ACQUIRE_SHARED(true); 854*67e74705SXin Li 855*67e74705SXin Li // Assert that this mutex is currently held by the calling thread. 856*67e74705SXin Li void AssertHeld() ASSERT_CAPABILITY(this); 857*67e74705SXin Li 858*67e74705SXin Li // Assert that is mutex is currently held for read operations. 859*67e74705SXin Li void AssertReaderHeld() ASSERT_SHARED_CAPABILITY(this); 860*67e74705SXin Li 861*67e74705SXin Li // For negative capabilities. 862*67e74705SXin Li const Mutex& operator!() const { return *this; } 863*67e74705SXin Li }; 864*67e74705SXin Li 865*67e74705SXin Li 866*67e74705SXin Li // MutexLocker is an RAII class that acquires a mutex in its constructor, and 867*67e74705SXin Li // releases it in its destructor. 868*67e74705SXin Li class SCOPED_CAPABILITY MutexLocker { 869*67e74705SXin Li private: 870*67e74705SXin Li Mutex* mut; 871*67e74705SXin Li 872*67e74705SXin Li public: 873*67e74705SXin Li MutexLocker(Mutex *mu) ACQUIRE(mu) : mut(mu) { 874*67e74705SXin Li mu->Lock(); 875*67e74705SXin Li } 876*67e74705SXin Li ~MutexLocker() RELEASE() { 877*67e74705SXin Li mut->Unlock(); 878*67e74705SXin Li } 879*67e74705SXin Li }; 880*67e74705SXin Li 881*67e74705SXin Li 882*67e74705SXin Li #ifdef USE_LOCK_STYLE_THREAD_SAFETY_ATTRIBUTES 883*67e74705SXin Li // The original version of thread safety analysis the following attribute 884*67e74705SXin Li // definitions. These use a lock-based terminology. They are still in use 885*67e74705SXin Li // by existing thread safety code, and will continue to be supported. 886*67e74705SXin Li 887*67e74705SXin Li // Deprecated. 888*67e74705SXin Li #define PT_GUARDED_VAR \ 889*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded) 890*67e74705SXin Li 891*67e74705SXin Li // Deprecated. 892*67e74705SXin Li #define GUARDED_VAR \ 893*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(guarded) 894*67e74705SXin Li 895*67e74705SXin Li // Replaced by REQUIRES 896*67e74705SXin Li #define EXCLUSIVE_LOCKS_REQUIRED(...) \ 897*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__)) 898*67e74705SXin Li 899*67e74705SXin Li // Replaced by REQUIRES_SHARED 900*67e74705SXin Li #define SHARED_LOCKS_REQUIRED(...) \ 901*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__)) 902*67e74705SXin Li 903*67e74705SXin Li // Replaced by CAPABILITY 904*67e74705SXin Li #define LOCKABLE \ 905*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(lockable) 906*67e74705SXin Li 907*67e74705SXin Li // Replaced by SCOPED_CAPABILITY 908*67e74705SXin Li #define SCOPED_LOCKABLE \ 909*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) 910*67e74705SXin Li 911*67e74705SXin Li // Replaced by ACQUIRE 912*67e74705SXin Li #define EXCLUSIVE_LOCK_FUNCTION(...) \ 913*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__)) 914*67e74705SXin Li 915*67e74705SXin Li // Replaced by ACQUIRE_SHARED 916*67e74705SXin Li #define SHARED_LOCK_FUNCTION(...) \ 917*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__)) 918*67e74705SXin Li 919*67e74705SXin Li // Replaced by RELEASE and RELEASE_SHARED 920*67e74705SXin Li #define UNLOCK_FUNCTION(...) \ 921*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__)) 922*67e74705SXin Li 923*67e74705SXin Li // Replaced by TRY_ACQUIRE 924*67e74705SXin Li #define EXCLUSIVE_TRYLOCK_FUNCTION(...) \ 925*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__)) 926*67e74705SXin Li 927*67e74705SXin Li // Replaced by TRY_ACQUIRE_SHARED 928*67e74705SXin Li #define SHARED_TRYLOCK_FUNCTION(...) \ 929*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__)) 930*67e74705SXin Li 931*67e74705SXin Li // Replaced by ASSERT_CAPABILITY 932*67e74705SXin Li #define ASSERT_EXCLUSIVE_LOCK(...) \ 933*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__)) 934*67e74705SXin Li 935*67e74705SXin Li // Replaced by ASSERT_SHARED_CAPABILITY 936*67e74705SXin Li #define ASSERT_SHARED_LOCK(...) \ 937*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_lock(__VA_ARGS__)) 938*67e74705SXin Li 939*67e74705SXin Li // Replaced by EXCLUDE_CAPABILITY. 940*67e74705SXin Li #define LOCKS_EXCLUDED(...) \ 941*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) 942*67e74705SXin Li 943*67e74705SXin Li // Replaced by RETURN_CAPABILITY 944*67e74705SXin Li #define LOCK_RETURNED(x) \ 945*67e74705SXin Li THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) 946*67e74705SXin Li 947*67e74705SXin Li #endif // USE_LOCK_STYLE_THREAD_SAFETY_ATTRIBUTES 948*67e74705SXin Li 949*67e74705SXin Li #endif // THREAD_SAFETY_ANALYSIS_MUTEX_H 950*67e74705SXin Li 951