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